From f62390eb5cf9b25a621061fc59a06842a7c3f939 Mon Sep 17 00:00:00 2001 From: Fabio Proietti Date: Thu, 23 Jul 2026 12:58:19 +0200 Subject: [PATCH 1/2] MCO-2244: Update MCO dependencies to Kubernetes 1.36 --- Dockerfile | 6 +- go.mod | 188 +- go.sum | 334 +- pkg/controller/drain/drain_controller.go | 4 +- .../kubelet-config/kubelet_config_nodes.go | 6 +- pkg/controller/node/node_controller.go | 2 +- pkg/daemon/daemon.go | 20 +- pkg/daemon/drain.go | 2 +- pkg/daemon/update.go | 22 +- pkg/operator/status.go | 8 +- vendor/cyphar.com/go-pathrs/handle_linux.go | 8 +- .../go-pathrs/procfs/procfs_linux.go | 8 - vendor/cyphar.com/go-pathrs/root_linux.go | 28 +- vendor/github.com/armon/circbuf/.gitignore | 22 - vendor/github.com/armon/circbuf/LICENSE | 20 - vendor/github.com/armon/circbuf/README.md | 28 - vendor/github.com/armon/circbuf/circbuf.go | 92 - .../aws/arn/arn.go | 5 +- vendor/github.com/aws/aws-sdk-go/NOTICE.txt | 3 - .../v2/config/shared/errors/errors.go | 2 +- .../v2/config/v3_4/translate/translate.go | 28 - .../v2/config/v3_4/types/directory.go | 1 + .../ignition/v2/config/v3_4/types/file.go | 1 + .../ignition/v2/config/v3_4/types/mode.go | 10 + .../ignition/v2/config/v3_4/types/url.go | 2 +- .../v2/config/v3_5/types/directory.go | 1 + .../ignition/v2/config/v3_5/types/file.go | 1 + .../ignition/v2/config/v3_5/types/mode.go | 10 + .../ignition/v2/config/v3_5/types/url.go | 2 +- .../ignition/v2/config/validate/validate.go | 4 +- .../docker/go-connections/tlsconfig/config.go | 100 +- .../tlsconfig/config_client_ciphers.go | 14 - .../fxamacker/cbor/v2/.golangci.yml | 176 +- vendor/github.com/fxamacker/cbor/v2/README.md | 29 +- vendor/github.com/fxamacker/cbor/v2/cache.go | 257 +- vendor/github.com/fxamacker/cbor/v2/decode.go | 442 +- .../fxamacker/cbor/v2/decode_map_utils.go | 98 + .../github.com/fxamacker/cbor/v2/diagnose.go | 25 +- vendor/github.com/fxamacker/cbor/v2/doc.go | 20 +- vendor/github.com/fxamacker/cbor/v2/encode.go | 55 +- .../fxamacker/cbor/v2/simplevalue.go | 2 +- vendor/github.com/fxamacker/cbor/v2/stream.go | 177 +- .../fxamacker/cbor/v2/structfields.go | 65 +- vendor/github.com/fxamacker/cbor/v2/tag.go | 5 + vendor/github.com/fxamacker/cbor/v2/valid.go | 20 +- vendor/github.com/godbus/dbus/v5/.cirrus.yml | 7 +- .../github.com/godbus/dbus/v5/.golangci.yml | 10 +- vendor/github.com/godbus/dbus/v5/auth.go | 4 +- .../godbus/dbus/v5/auth_default_other.go | 7 + .../godbus/dbus/v5/auth_default_windows.go | 5 + .../v5/{auth_sha1.go => auth_sha1_windows.go} | 7 + vendor/github.com/godbus/dbus/v5/call.go | 6 +- vendor/github.com/godbus/dbus/v5/conn.go | 48 +- .../github.com/godbus/dbus/v5/conn_other.go | 10 +- vendor/github.com/godbus/dbus/v5/conn_unix.go | 24 +- vendor/github.com/godbus/dbus/v5/dbus.go | 12 +- vendor/github.com/godbus/dbus/v5/decoder.go | 15 +- .../godbus/dbus/v5/default_handler.go | 14 +- vendor/github.com/godbus/dbus/v5/encoder.go | 4 +- vendor/github.com/godbus/dbus/v5/export.go | 74 +- vendor/github.com/godbus/dbus/v5/homedir.go | 25 - vendor/github.com/godbus/dbus/v5/message.go | 4 +- vendor/github.com/godbus/dbus/v5/object.go | 26 +- .../godbus/dbus/v5/server_interfaces.go | 10 +- vendor/github.com/godbus/dbus/v5/sig.go | 26 +- .../godbus/dbus/v5/transport_nonce_tcp.go | 3 +- .../godbus/dbus/v5/transport_unix.go | 23 +- .../dbus/v5/transport_unixcred_linux.go | 2 +- vendor/github.com/godbus/dbus/v5/variant.go | 31 +- .../godbus/dbus/v5/variant_lexer.go | 2 +- .../godbus/dbus/v5/variant_parser.go | 44 +- .../google/cadvisor/cache/memory/memory.go | 84 +- .../cadvisor/collector/generic_collector.go | 10 +- .../collector/prometheus_collector.go | 4 +- .../google/cadvisor/collector/util.go | 9 +- .../container/common/container_hints.go | 2 + .../cadvisor/container/common/fsHandler.go | 2 + .../cadvisor/container/common/helpers.go | 19 +- .../container/common/inotify_watcher.go | 2 + .../google/cadvisor/container/container.go | 6 +- .../cadvisor/container/containerd/client.go | 34 +- .../cadvisor/container/containerd/factory.go | 4 +- .../cadvisor/container/containerd/grpc.go | 6 +- .../cadvisor/container/containerd/handler.go | 15 +- .../container/containerd/install/install.go | 2 + .../containerd/pkg/dialer/dialer_unix.go | 1 - .../cadvisor/container/containerd/plugin.go | 2 + .../google/cadvisor/container/crio/client.go | 6 +- .../google/cadvisor/container/crio/factory.go | 2 + .../google/cadvisor/container/crio/handler.go | 6 + .../container/crio/install/install.go | 2 + .../google/cadvisor/container/crio/plugin.go | 2 + .../google/cadvisor/container/factory.go | 1 - .../container/libcontainer/handler.go | 10 +- .../container/libcontainer/helpers.go | 2 + .../google/cadvisor/container/raw/factory.go | 2 + .../google/cadvisor/container/raw/handler.go | 6 + .../google/cadvisor/container/raw/watcher.go | 2 + .../cadvisor/container/systemd/factory.go | 2 +- .../cadvisor/devicemapper/thin_ls_client.go | 2 +- .../devicemapper/thin_pool_watcher.go | 43 +- .../cadvisor/fs/btrfs/install/install.go | 31 + .../google/cadvisor/fs/btrfs/mount.go | 63 + .../google/cadvisor/fs/btrfs/plugin.go | 87 + .../fs/devicemapper/install/install.go | 29 + .../google/cadvisor/fs/devicemapper/plugin.go | 66 + .../google/cadvisor/fs/devicemapper/stats.go | 113 + vendor/github.com/google/cadvisor/fs/fs.go | 304 +- .../google/cadvisor/fs/nfs/install/install.go | 31 + .../google/cadvisor/fs/nfs/plugin.go | 85 + .../cadvisor/fs/overlay/install/install.go | 31 + .../google/cadvisor/fs/overlay/plugin.go | 76 + .../github.com/google/cadvisor/fs/plugin.go | 179 + .../cadvisor/fs/tmpfs/install/install.go | 31 + .../google/cadvisor/fs/tmpfs/plugin.go | 80 + .../google/cadvisor/fs/vfs/install/install.go | 31 + .../google/cadvisor/fs/vfs/plugin.go | 97 + .../google/cadvisor/fs/vfs/stats.go | 63 + .../google/cadvisor/fs/zfs/install/install.go | 29 + .../google/cadvisor/fs/zfs/plugin.go | 70 + .../google/cadvisor/fs/zfs/stats.go | 31 + .../google/cadvisor/fs/zfs/watcher.go | 123 + .../google/cadvisor/info/v1/container.go | 28 + .../google/cadvisor/info/v1/machine.go | 8 + .../google/cadvisor/info/v2/container.go | 4 + .../google/cadvisor/machine/info.go | 9 +- .../google/cadvisor/machine/machine.go | 46 +- .../cadvisor/machine/operatingsystem_unix.go | 10 +- .../google/cadvisor/manager/container.go | 40 +- .../google/cadvisor/manager/manager.go | 227 +- .../google/cadvisor/metrics/prometheus.go | 93 + .../cadvisor/metrics/prometheus_fake.go | 33 +- .../cadvisor/metrics/prometheus_machine.go | 16 + .../google/cadvisor/nvm/machine_libipmctl.go | 1 - .../cadvisor/nvm/machine_no_libipmctl.go | 1 - .../google/cadvisor/perf/collector_libpfm.go | 1 - .../cadvisor/perf/collector_no_libpfm.go | 1 - .../google/cadvisor/perf/manager_libpfm.go | 1 - .../google/cadvisor/perf/manager_no_libpfm.go | 1 - .../google/cadvisor/perf/types_libpfm.go | 1 - .../google/cadvisor/perf/uncore_libpfm.go | 1 - .../google/cadvisor/summary/percentiles.go | 20 + .../google/cadvisor/utils/cpuload/cpuload.go | 2 + .../utils/cpuload/cpuload_unsupported.go | 40 + .../cadvisor/utils/cpuload/netlink/conn.go | 2 + .../cadvisor/utils/cpuload/netlink/netlink.go | 2 + .../cadvisor/utils/cpuload/netlink/reader.go | 2 + .../cadvisor/utils/oomparser/oomparser.go | 2 + .../google/cadvisor/utils/sysfs/sysfs.go | 6 + .../cadvisor/utils/sysfs/sysfs_notx86.go | 1 - .../google/cadvisor/utils/sysfs/sysfs_x86.go | 1 - .../google/cadvisor/utils/sysinfo/sysinfo.go | 2 +- .../google/pprof/profile/profile.go | 2 +- .../github.com/google/pprof/profile/proto.go | 19 +- .../gregjones/httpcache/.travis.yml | 18 - .../github.com/gregjones/httpcache/README.md | 29 - .../providers/prometheus}/LICENSE | 0 .../providers/prometheus/client_metrics.go | 117 + .../providers/prometheus/client_options.go | 77 + .../providers/prometheus/constants.go | 23 + .../providers/prometheus/doc.go | 8 + .../providers/prometheus/options.go | 152 + .../providers/prometheus/reporter.go | 139 + .../providers/prometheus/server_metrics.go | 163 + .../providers/prometheus/server_options.go | 56 + .../go-grpc-middleware/v2/COPYRIGHT | 2 + .../go-grpc-middleware/v2/LICENSE | 201 + .../v2/interceptors/callmeta.go | 67 + .../v2/interceptors/client.go | 80 + .../go-grpc-middleware/v2/interceptors/doc.go | 12 + .../v2/interceptors/reporter.go | 73 + .../v2/interceptors/server.go | 65 + .../go-grpc-prometheus/.gitignore | 201 - .../go-grpc-prometheus/.travis.yml | 23 - .../go-grpc-prometheus/CHANGELOG.md | 28 - .../go-grpc-prometheus/README.md | 256 - .../go-grpc-prometheus/client.go | 57 - .../go-grpc-prometheus/client_metrics.go | 244 - .../go-grpc-prometheus/client_reporter.go | 79 - .../go-grpc-prometheus/makefile | 14 - .../go-grpc-prometheus/metric_options.go | 41 - .../packages/grpcstatus/grpcstatus.go | 57 - .../packages/grpcstatus/native_unwrap1.12-.go | 11 - .../packages/grpcstatus/native_unwrap1.13+.go | 17 - .../go-grpc-prometheus/server.go | 48 - .../go-grpc-prometheus/server_metrics.go | 186 - .../go-grpc-prometheus/server_reporter.go | 46 - .../grpc-ecosystem/go-grpc-prometheus/util.go | 50 - .../github.com/karrick/godirwalk/.gitignore | 19 - vendor/github.com/karrick/godirwalk/LICENSE | 25 - vendor/github.com/karrick/godirwalk/README.md | 324 - .../karrick/godirwalk/azure-pipelines.yml | 53 - vendor/github.com/karrick/godirwalk/bench.sh | 7 - .../karrick/godirwalk/debug_development.go | 14 - .../karrick/godirwalk/debug_release.go | 6 - vendor/github.com/karrick/godirwalk/dirent.go | 104 - vendor/github.com/karrick/godirwalk/doc.go | 42 - .../karrick/godirwalk/inoWithFileno.go | 9 - .../karrick/godirwalk/inoWithIno.go | 9 - .../github.com/karrick/godirwalk/modeType.go | 22 - .../karrick/godirwalk/modeTypeWithType.go | 37 - .../karrick/godirwalk/modeTypeWithoutType.go | 18 - .../karrick/godirwalk/nameWithNamlen.go | 29 - .../karrick/godirwalk/nameWithoutNamlen.go | 42 - .../github.com/karrick/godirwalk/readdir.go | 53 - .../karrick/godirwalk/readdir_unix.go | 131 - .../karrick/godirwalk/readdir_windows.go | 66 - .../karrick/godirwalk/reclenFromNamlen.go | 9 - .../karrick/godirwalk/reclenFromReclen.go | 9 - .../karrick/godirwalk/scandir_unix.go | 181 - .../karrick/godirwalk/scandir_windows.go | 149 - .../github.com/karrick/godirwalk/scanner.go | 44 - vendor/github.com/karrick/godirwalk/walk.go | 379 -- .../libopenstorage/openstorage/api/README.md | 79 - .../libopenstorage/openstorage/api/api.go | 365 -- .../libopenstorage/openstorage/api/api.pb.go | 2042 ------ .../libopenstorage/openstorage/api/api.proto | 471 -- .../openstorage/api/client/client.go | 178 - .../openstorage/api/client/request.go | 332 - .../openstorage/api/client/volume/client.go | 403 -- .../openstorage/api/client/volume/volume.go | 67 - .../openstorage/api/spec/spec_handler.go | 353 - .../libopenstorage/openstorage/api/status.go | 53 - .../openstorage/pkg/parser/labels.go | 74 - .../openstorage/pkg/units/units.go | 139 - .../openstorage/volume/README.md | 41 - .../openstorage/volume/volume.go | 217 - .../volume/volume_driver_registry.go | 71 - .../volume/volume_not_supported.go | 74 - vendor/github.com/moby/spdystream/NOTICE | 12 + .../github.com/moby/spdystream/connection.go | 11 +- .../github.com/moby/spdystream/spdy/LICENSE | 27 + .../github.com/moby/spdystream/spdy/PATENTS | 22 + .../moby/spdystream/spdy/dictionary.go | 16 - .../moby/spdystream/spdy/options.go | 25 + .../github.com/moby/spdystream/spdy/read.go | 58 +- .../github.com/moby/spdystream/spdy/types.go | 49 +- .../github.com/moby/spdystream/spdy/write.go | 81 +- vendor/github.com/mohae/deepcopy/.gitignore | 26 - vendor/github.com/mohae/deepcopy/.travis.yml | 11 - vendor/github.com/mohae/deepcopy/LICENSE | 21 - vendor/github.com/mohae/deepcopy/README.md | 8 - vendor/github.com/mohae/deepcopy/deepcopy.go | 125 - vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md | 38 + vendor/github.com/onsi/ginkgo/v2/README.md | 4 +- vendor/github.com/onsi/ginkgo/v2/core_dsl.go | 23 +- .../onsi/ginkgo/v2/decorator_dsl.go | 21 + .../onsi/ginkgo/v2/ginkgo/command/command.go | 6 +- .../onsi/ginkgo/v2/ginkgo/internal/run.go | 15 +- .../onsi/ginkgo/v2/ginkgo/run/run_command.go | 2 +- .../onsi/ginkgo/v2/internal/focus.go | 21 +- .../onsi/ginkgo/v2/internal/group.go | 35 +- .../onsi/ginkgo/v2/internal/node.go | 111 +- .../v2/internal/output_interceptor_unix.go | 18 + .../v2/internal/output_interceptor_wasm.go | 7 + .../v2/internal/output_interceptor_win.go | 9 + .../ginkgo/v2/internal/reporters/gojson.go | 47 +- .../onsi/ginkgo/v2/internal/suite.go | 28 +- .../onsi/ginkgo/v2/internal/suite_patch.go | 75 +- .../internal/testingtproxy/testing_t_proxy.go | 7 +- .../ginkgo/v2/reporters/default_reporter.go | 27 +- .../onsi/ginkgo/v2/reporters/junit_report.go | 20 + .../ginkgo/v2/reporters/teamcity_report.go | 8 + .../github.com/onsi/ginkgo/v2/types/errors.go | 9 + .../onsi/ginkgo/v2/types/semver_filter.go | 91 +- .../github.com/onsi/ginkgo/v2/types/types.go | 159 +- .../onsi/ginkgo/v2/types/version.go | 2 +- vendor/github.com/onsi/gomega/CHANGELOG.md | 15 + .../github.com/onsi/gomega/format/format.go | 26 +- vendor/github.com/onsi/gomega/gomega_dsl.go | 2 +- vendor/github.com/onsi/gomega/matchers.go | 22 +- .../onsi/gomega/matchers/have_key_matcher.go | 2 +- .../matchers/have_key_with_value_matcher.go | 2 +- .../matchers/match_error_strictly_matcher.go | 39 + .../matchers/support/goraph/edge/edge.go | 13 +- .../opencontainers/cgroups/cgroups.go | 5 + .../opencontainers/cgroups/config_linux.go | 4 +- .../opencontainers/cgroups/fs/cpuacct.go | 12 +- .../opencontainers/cgroups/fs/fs.go | 29 + .../opencontainers/cgroups/fs/pids.go | 27 +- .../opencontainers/cgroups/fs2/freezer.go | 32 +- .../opencontainers/cgroups/fs2/fs2.go | 13 + .../opencontainers/cgroups/fs2/hugetlb.go | 5 +- .../opencontainers/cgroups/fs2/io.go | 19 +- .../opencontainers/cgroups/fs2/pids.go | 20 +- .../opencontainers/cgroups/stats.go | 4 + .../opencontainers/cgroups/systemd/common.go | 15 + .../opencontainers/cgroups/systemd/dbus.go | 26 +- .../opencontainers/cgroups/systemd/v1.go | 32 +- .../opencontainers/cgroups/systemd/v2.go | 25 +- .../pkg/cmd/cmdrun/runsuite.go | 26 +- .../pkg/cmd/cmdrun/runtest.go | 7 + .../pkg/extension/extensiontests/scheduler.go | 367 ++ .../pkg/extension/extensiontests/spec.go | 79 +- .../pkg/extension/extensiontests/types.go | 14 +- .../pkg/extension/types.go | 3 + .../pkg/flags/output.go | 5 +- .../pkg/ginkgo/parallel.go | 79 +- .../pkg/ginkgo/util.go | 58 +- .../github.com/openshift/api/.golangci.yaml | 4 + vendor/github.com/openshift/api/Makefile | 4 +- .../api/config/v1/types_infrastructure.go | 1 - .../openshift/api/config/v1/types_ingress.go | 36 + ...hentications-TechPreviewNoUpgrade.crd.yaml | 428 ++ ..._01_criocredentialproviderconfigs.crd.yaml | 4 +- ...ator_01_ingresses-CustomNoUpgrade.crd.yaml | 593 ++ ...fig-operator_01_ingresses-Default.crd.yaml | 546 ++ ..._01_ingresses-DevPreviewNoUpgrade.crd.yaml | 593 ++ ...config-operator_01_ingresses-OKD.crd.yaml} | 3 + ...01_ingresses-TechPreviewNoUpgrade.crd.yaml | 593 ++ .../api/config/v1/zz_generated.deepcopy.go | 11 +- ..._generated.featuregated-crd-manifests.yaml | 4 +- .../v1/zz_generated.swagger_doc_generated.go | 3 +- vendor/github.com/openshift/api/features.md | 5 +- .../openshift/api/features/features.go | 26 +- ..._generated.featuregated-crd-manifests.yaml | 1 - .../api/operator/v1/types_authentication.go | 88 + .../operator/v1/types_csi_cluster_driver.go | 20 +- .../operator/v1/types_ingresscontroller.go | 53 + ...1_authentications-CustomNoUpgrade.crd.yaml | 107 + ...thentications-DevPreviewNoUpgrade.crd.yaml | 107 + ...hentications-TechPreviewNoUpgrade.crd.yaml | 107 + .../0000_50_console_01_consoles.crd.yaml | 28 +- ...clustercsidrivers-CustomNoUpgrade.crd.yaml | 12 +- ...iver_01_clustercsidrivers-Default.crd.yaml | 12 +- ...tercsidrivers-DevPreviewNoUpgrade.crd.yaml | 12 +- ...i-driver_01_clustercsidrivers-OKD.crd.yaml | 12 +- ...ercsidrivers-TechPreviewNoUpgrade.crd.yaml | 12 +- ...ngresscontrollers-CustomNoUpgrade.crd.yaml | 40 + ...sscontrollers-DevPreviewNoUpgrade.crd.yaml | 40 + ...scontrollers-TechPreviewNoUpgrade.crd.yaml | 40 + .../api/operator/v1/zz_generated.deepcopy.go | 39 + ..._generated.featuregated-crd-manifests.yaml | 2 + .../operator/v1/zz_generated.model_name.go | 10 + .../v1/zz_generated.swagger_doc_generated.go | 35 +- .../api/operator/v1alpha1/types_clusterapi.go | 15 +- ...000_30_cluster-api_01_clusterapis.crd.yaml | 7 +- .../github.com/openshift/api/osin/v1/types.go | 5 + .../v1/zz_generated.swagger_doc_generated.go | 1 + .../applyconfigurations/internal/internal.go | 30 +- .../config/v1/componentroutespec.go | 32 + .../config/v1/ingressspec.go | 1 + .../applyconfigurations/internal/internal.go | 60 +- .../versioned/fake/clientset_generated.go | 10 +- .../externalversions/config/v1/apiserver.go | 48 +- .../config/v1/authentication.go | 48 +- .../externalversions/config/v1/build.go | 48 +- .../config/v1/clusterimagepolicy.go | 48 +- .../config/v1/clusteroperator.go | 48 +- .../config/v1/clusterversion.go | 48 +- .../externalversions/config/v1/console.go | 48 +- .../config/v1/criocredentialproviderconfig.go | 48 +- .../externalversions/config/v1/dns.go | 48 +- .../externalversions/config/v1/featuregate.go | 48 +- .../externalversions/config/v1/image.go | 48 +- .../config/v1/imagecontentpolicy.go | 48 +- .../config/v1/imagedigestmirrorset.go | 48 +- .../externalversions/config/v1/imagepolicy.go | 48 +- .../config/v1/imagetagmirrorset.go | 48 +- .../config/v1/infrastructure.go | 48 +- .../externalversions/config/v1/ingress.go | 48 +- .../config/v1/insightsdatagather.go | 48 +- .../externalversions/config/v1/network.go | 48 +- .../externalversions/config/v1/node.go | 48 +- .../externalversions/config/v1/oauth.go | 48 +- .../externalversions/config/v1/operatorhub.go | 48 +- .../externalversions/config/v1/project.go | 48 +- .../externalversions/config/v1/proxy.go | 48 +- .../externalversions/config/v1/scheduler.go | 48 +- .../config/v1alpha1/backup.go | 48 +- .../config/v1alpha1/clustermonitoring.go | 48 +- .../v1alpha1/criocredentialproviderconfig.go | 48 +- .../config/v1alpha1/insightsdatagather.go | 48 +- .../externalversions/config/v1alpha1/pki.go | 48 +- .../config/v1alpha2/insightsdatagather.go | 48 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../versioned/fake/clientset_generated.go | 10 +- .../informers/externalversions/factory.go | 110 +- .../externalversions/image/v1/image.go | 48 +- .../externalversions/image/v1/imagestream.go | 48 +- .../internalinterfaces/factory_interfaces.go | 19 + .../versioned/fake/clientset_generated.go | 10 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../machine/v1/controlplanemachineset.go | 48 +- .../machine/v1beta1/machine.go | 48 +- .../machine/v1beta1/machinehealthcheck.go | 48 +- .../machine/v1beta1/machineset.go | 48 +- .../versioned/fake/clientset_generated.go | 10 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../v1/containerruntimeconfig.go | 48 +- .../v1/controllerconfig.go | 48 +- .../v1/internalreleaseimage.go | 48 +- .../machineconfiguration/v1/kubeletconfig.go | 48 +- .../machineconfiguration/v1/machineconfig.go | 48 +- .../v1/machineconfignode.go | 48 +- .../v1/machineconfigpool.go | 48 +- .../machineconfiguration/v1/machineosbuild.go | 48 +- .../v1/machineosconfig.go | 48 +- .../machineconfiguration/v1/osimagestream.go | 48 +- .../machineconfiguration/v1/pinnedimageset.go | 48 +- .../v1alpha1/internalreleaseimage.go | 48 +- .../v1alpha1/osimagestream.go | 48 +- .../applyconfigurations/internal/internal.go | 111 + .../v1/authenticationconfigmapreference.go | 30 + .../operator/v1/authenticationproxyconfig.go | 79 + .../operator/v1/authenticationspec.go | 16 + .../operator/v1/customsecretrotation.go | 20 +- .../operator/v1/ingresscontrollerspec.go | 29 + .../operator/v1/ingresscontrollerstatus.go | 18 + .../operator/applyconfigurations/utils.go | 4 + .../versioned/fake/clientset_generated.go | 10 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../operator/v1/authentication.go | 48 +- .../operator/v1/cloudcredential.go | 48 +- .../operator/v1/clustercsidriver.go | 48 +- .../externalversions/operator/v1/config.go | 48 +- .../externalversions/operator/v1/console.go | 48 +- .../operator/v1/csisnapshotcontroller.go | 48 +- .../externalversions/operator/v1/dns.go | 48 +- .../externalversions/operator/v1/etcd.go | 48 +- .../operator/v1/ingresscontroller.go | 48 +- .../operator/v1/insightsoperator.go | 48 +- .../operator/v1/kubeapiserver.go | 48 +- .../operator/v1/kubecontrollermanager.go | 48 +- .../operator/v1/kubescheduler.go | 48 +- .../operator/v1/kubestorageversionmigrator.go | 48 +- .../operator/v1/machineconfiguration.go | 48 +- .../externalversions/operator/v1/network.go | 48 +- .../externalversions/operator/v1/olm.go | 48 +- .../operator/v1/openshiftapiserver.go | 48 +- .../operator/v1/openshiftcontrollermanager.go | 48 +- .../externalversions/operator/v1/serviceca.go | 48 +- .../operator/v1/servicecatalogapiserver.go | 48 +- .../v1/servicecatalogcontrollermanager.go | 48 +- .../externalversions/operator/v1/storage.go | 48 +- .../operator/v1alpha1/clusterapi.go | 48 +- .../v1alpha1/clusterversionoperator.go | 48 +- .../operator/v1alpha1/etcdbackup.go | 48 +- .../v1alpha1/imagecontentsourcepolicy.go | 48 +- .../externalversions/operator/v1alpha1/olm.go | 48 +- .../versioned/fake/clientset_generated.go | 10 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../externalversions/route/v1/route.go | 48 +- .../openshift/library-go/pkg/crypto/crypto.go | 95 +- .../client_cert_rotation_controller.go | 2 +- .../pkg/operator/v1helpers/test_helpers.go | 41 +- .../prometheus/common/expfmt/decode.go | 14 +- .../prometheus/common/expfmt/expfmt.go | 1 + .../prometheus/common/expfmt/fuzz.go | 1 - .../common/expfmt/openmetrics_create.go | 59 +- .../prometheus/common/expfmt/text_create.go | 58 +- .../prometheus/common/expfmt/text_parse.go | 102 +- .../prometheus/procfs/.golangci.yml | 28 +- vendor/github.com/prometheus/procfs/Makefile | 2 +- .../prometheus/procfs/Makefile.common | 2 +- vendor/github.com/prometheus/procfs/arp.go | 9 +- .../github.com/prometheus/procfs/buddyinfo.go | 10 +- .../github.com/prometheus/procfs/cmdline.go | 2 +- .../github.com/prometheus/procfs/cpuinfo.go | 2 +- .../prometheus/procfs/cpuinfo_armx.go | 2 +- .../prometheus/procfs/cpuinfo_loong64.go | 2 +- .../prometheus/procfs/cpuinfo_mipsx.go | 2 +- .../prometheus/procfs/cpuinfo_others.go | 2 +- .../prometheus/procfs/cpuinfo_ppcx.go | 2 +- .../prometheus/procfs/cpuinfo_riscvx.go | 2 +- .../prometheus/procfs/cpuinfo_s390x.go | 2 +- .../prometheus/procfs/cpuinfo_x86.go | 2 +- vendor/github.com/prometheus/procfs/crypto.go | 2 +- vendor/github.com/prometheus/procfs/doc.go | 2 +- vendor/github.com/prometheus/procfs/fs.go | 2 +- .../prometheus/procfs/fs_statfs_notype.go | 2 +- .../prometheus/procfs/fs_statfs_type.go | 2 +- .../github.com/prometheus/procfs/fscache.go | 9 +- .../prometheus/procfs/internal/fs/fs.go | 2 +- .../prometheus/procfs/internal/util/parse.go | 2 +- .../procfs/internal/util/readfile.go | 2 +- .../procfs/internal/util/sysreadfile.go | 2 +- .../internal/util/sysreadfile_compat.go | 2 +- .../procfs/internal/util/valueparser.go | 2 +- vendor/github.com/prometheus/procfs/ipvs.go | 2 +- .../prometheus/procfs/kernel_hung.go | 45 + .../prometheus/procfs/kernel_random.go | 2 +- .../github.com/prometheus/procfs/loadavg.go | 2 +- vendor/github.com/prometheus/procfs/mdstat.go | 118 +- .../github.com/prometheus/procfs/meminfo.go | 4 +- .../github.com/prometheus/procfs/mountinfo.go | 23 +- .../prometheus/procfs/mountstats.go | 4 +- .../prometheus/procfs/net_conntrackstat.go | 2 +- .../github.com/prometheus/procfs/net_dev.go | 2 +- .../prometheus/procfs/net_dev_snmp6.go | 7 +- .../prometheus/procfs/net_ip_socket.go | 2 +- .../prometheus/procfs/net_protocols.go | 4 +- .../github.com/prometheus/procfs/net_route.go | 2 +- .../prometheus/procfs/net_sockstat.go | 5 +- .../prometheus/procfs/net_softnet.go | 2 +- .../github.com/prometheus/procfs/net_tcp.go | 2 +- .../prometheus/procfs/net_tls_stat.go | 2 +- .../github.com/prometheus/procfs/net_udp.go | 2 +- .../github.com/prometheus/procfs/net_unix.go | 2 +- .../prometheus/procfs/net_wireless.go | 2 +- .../github.com/prometheus/procfs/net_xfrm.go | 2 +- .../github.com/prometheus/procfs/netstat.go | 2 +- .../prometheus/procfs/nfnetlink_queue.go | 85 + vendor/github.com/prometheus/procfs/proc.go | 4 +- .../prometheus/procfs/proc_cgroup.go | 2 +- .../prometheus/procfs/proc_cgroups.go | 8 +- .../prometheus/procfs/proc_environ.go | 2 +- .../prometheus/procfs/proc_fdinfo.go | 13 +- .../prometheus/procfs/proc_interrupts.go | 2 +- .../github.com/prometheus/procfs/proc_io.go | 2 +- .../prometheus/procfs/proc_limits.go | 7 +- .../github.com/prometheus/procfs/proc_maps.go | 2 +- .../prometheus/procfs/proc_netstat.go | 2 +- .../github.com/prometheus/procfs/proc_ns.go | 2 +- .../github.com/prometheus/procfs/proc_psi.go | 2 +- .../prometheus/procfs/proc_smaps.go | 2 +- .../github.com/prometheus/procfs/proc_snmp.go | 2 +- .../prometheus/procfs/proc_snmp6.go | 2 +- .../github.com/prometheus/procfs/proc_stat.go | 2 +- .../prometheus/procfs/proc_statm.go | 4 +- .../prometheus/procfs/proc_status.go | 9 +- .../github.com/prometheus/procfs/proc_sys.go | 2 +- .../github.com/prometheus/procfs/schedstat.go | 2 +- vendor/github.com/prometheus/procfs/slab.go | 2 +- .../github.com/prometheus/procfs/softirqs.go | 2 +- vendor/github.com/prometheus/procfs/stat.go | 5 +- vendor/github.com/prometheus/procfs/swaps.go | 2 +- vendor/github.com/prometheus/procfs/thread.go | 2 +- vendor/github.com/prometheus/procfs/vm.go | 2 +- .../github.com/prometheus/procfs/zoneinfo.go | 8 +- .../go.etcd.io/etcd/api/v3/version/version.go | 2 +- .../emicklei/go-restful/otelrestful/LICENSE | 30 + .../emicklei/go-restful/otelrestful/config.go | 15 +- .../emicklei/go-restful/otelrestful/doc.go | 13 +- .../otelrestful/internal/semconv/client.go | 287 + .../otelrestful/internal/semconv/gen.go | 15 + .../otelrestful/internal/semconv/server.go | 403 ++ .../otelrestful/internal/semconv/util.go | 127 + .../otelrestful/internal/semconvutil/gen.go | 21 - .../internal/semconvutil/httpconv.go | 552 -- .../internal/semconvutil/netconv.go | 368 -- .../go-restful/otelrestful/restful.go | 39 +- .../go-restful/otelrestful/version.go | 25 +- .../google.golang.org/grpc/otelgrpc/config.go | 197 +- .../grpc/otelgrpc/interceptor.go | 2 +- .../grpc/otelgrpc/internal/parse.go | 18 +- .../grpc/otelgrpc/metadata_supplier.go | 40 +- .../grpc/otelgrpc/stats_handler.go | 111 +- .../grpc/otelgrpc/version.go | 5 +- .../net/http/otelhttp/client.go | 50 - .../net/http/otelhttp/common.go | 2 +- .../net/http/otelhttp/config.go | 21 +- .../instrumentation/net/http/otelhttp/doc.go | 3 +- .../net/http/otelhttp/handler.go | 19 +- .../http/otelhttp/internal/semconv/client.go | 287 + .../net/http/otelhttp/internal/semconv/env.go | 248 - .../net/http/otelhttp/internal/semconv/gen.go | 8 +- .../otelhttp/internal/semconv/httpconv.go | 517 -- .../http/otelhttp/internal/semconv/server.go | 403 ++ .../http/otelhttp/internal/semconv/util.go | 2 +- .../net/http/otelhttp/transport.go | 35 +- .../net/http/otelhttp/version.go | 5 +- vendor/go.opentelemetry.io/otel/.golangci.yml | 1 + vendor/go.opentelemetry.io/otel/CHANGELOG.md | 22 +- vendor/go.opentelemetry.io/otel/Makefile | 2 +- vendor/go.opentelemetry.io/otel/README.md | 7 + .../otel/baggage/baggage.go | 109 +- .../otel/dependencies.Dockerfile | 2 +- .../internal/errorhandler/errorhandler.go | 96 + .../otel/internal/global/handler.go | 34 +- .../otel/internal/global/state.go | 36 +- .../otel/metric/asyncfloat64.go | 3 + .../otel/metric/asyncint64.go | 3 + .../go.opentelemetry.io/otel/metric/meter.go | 54 +- .../otel/metric/syncfloat64.go | 24 + .../otel/metric/syncint64.go | 24 + .../otel/propagation/baggage.go | 24 +- .../otel/semconv/v1.37.0/rpcconv/metric.go | 1010 --- .../{v1.37.0 => v1.39.0}/httpconv/metric.go | 17 +- .../otel/semconv/v1.39.0/rpcconv/metric.go | 1131 ++++ .../otel/trace/tracestate.go | 3 + vendor/go.opentelemetry.io/otel/version.go | 2 +- vendor/go.opentelemetry.io/otel/versions.yaml | 8 +- vendor/golang.org/x/net/context/context.go | 118 - .../golang.org/x/net/http2/transport_wrap.go | 24 +- vendor/golang.org/x/net/idna/idna.go | 6 +- .../grpc/reflection/README.md | 18 + .../grpc/reflection/adapt.go | 57 + .../grpc_reflection_v1/reflection.pb.go | 777 +++ .../grpc_reflection_v1/reflection_grpc.pb.go | 138 + .../grpc_reflection_v1alpha/reflection.pb.go | 847 +++ .../reflection_grpc.pb.go | 135 + .../grpc/reflection/internal/internal.go | 436 ++ .../grpc/reflection/serverreflection.go | 160 + .../encoding/protodelim/protodelim.go | 9 +- .../protobuf/encoding/protojson/decode.go | 12 + .../encoding/protojson/well_known_types.go | 5 +- .../protobuf/encoding/prototext/decode.go | 18 + .../protobuf/internal/descfmt/stringer.go | 269 +- .../protobuf/internal/version/version.go | 2 +- .../protobuf/reflect/protodesc/desc_init.go | 1 + .../k8s.io/api/admission/v1/generated.proto | 7 + .../admission/v1/generated.protomessage.pb.go | 28 - vendor/k8s.io/api/admission/v1/types.go | 7 + .../api/admission/v1beta1/generated.proto | 7 + vendor/k8s.io/api/admission/v1beta1/types.go | 7 + .../admissionregistration/v1/generated.pb.go | 4760 ++++++++++---- .../admissionregistration/v1/generated.proto | 450 +- .../v1/generated.protomessage.pb.go | 76 - .../api/admissionregistration/v1/register.go | 4 + .../api/admissionregistration/v1/types.go | 478 +- .../v1/types_swagger_doc_generated.go | 239 +- .../v1/zz_generated.deepcopy.go | 252 + .../v1/zz_generated.model_name.go | 45 + .../v1/zz_generated.prerelease-lifecycle.go | 24 + .../v1alpha1/generated.proto | 89 +- .../v1alpha1/generated.protomessage.pb.go | 74 - .../admissionregistration/v1alpha1/types.go | 85 +- .../v1alpha1/types_swagger_doc_generated.go | 80 +- .../v1beta1/generated.proto | 155 +- .../v1beta1/generated.protomessage.pb.go | 90 - .../admissionregistration/v1beta1/types.go | 159 +- .../v1beta1/types_swagger_doc_generated.go | 148 +- .../zz_generated.prerelease-lifecycle.go | 24 + .../api/apidiscovery/v2/generated.proto | 2 +- vendor/k8s.io/api/apidiscovery/v2/types.go | 2 +- .../api/apidiscovery/v2beta1/generated.proto | 2 +- .../k8s.io/api/apidiscovery/v2beta1/types.go | 2 +- .../v1alpha1/generated.proto | 41 +- .../v1alpha1/generated.protomessage.pb.go | 34 - .../api/apiserverinternal/v1alpha1/types.go | 41 +- .../v1alpha1/types_swagger_doc_generated.go | 32 +- .../api/apps/v1/generated.protomessage.pb.go | 82 - .../k8s.io/api/apps/v1beta1/generated.proto | 4 +- .../apps/v1beta1/generated.protomessage.pb.go | 68 - vendor/k8s.io/api/apps/v1beta1/types.go | 6 +- .../k8s.io/api/apps/v1beta2/generated.proto | 4 +- .../apps/v1beta2/generated.protomessage.pb.go | 88 - vendor/k8s.io/api/apps/v1beta2/types.go | 6 +- .../api/authentication/v1/generated.proto | 64 +- .../v1/generated.protomessage.pb.go | 44 - vendor/k8s.io/api/authentication/v1/types.go | 64 +- .../v1/types_swagger_doc_generated.go | 56 +- .../authentication/v1alpha1/generated.proto | 7 +- .../api/authentication/v1alpha1/types.go | 7 +- .../v1alpha1/types_swagger_doc_generated.go | 6 +- .../authentication/v1beta1/generated.proto | 36 +- .../v1beta1/generated.protomessage.pb.go | 36 - .../api/authentication/v1beta1/types.go | 36 +- .../v1beta1/types_swagger_doc_generated.go | 32 +- .../api/authorization/v1/generated.proto | 96 +- .../v1/generated.protomessage.pb.go | 54 - vendor/k8s.io/api/authorization/v1/types.go | 96 +- .../v1/types_swagger_doc_generated.go | 92 +- .../api/authorization/v1beta1/generated.proto | 96 +- .../v1beta1/generated.protomessage.pb.go | 50 - .../k8s.io/api/authorization/v1beta1/types.go | 96 +- .../v1beta1/types_swagger_doc_generated.go | 92 +- .../k8s.io/api/autoscaling/v1/generated.proto | 12 +- .../v1/generated.protomessage.pb.go | 64 - vendor/k8s.io/api/autoscaling/v1/types.go | 16 +- .../k8s.io/api/autoscaling/v2/generated.proto | 8 +- .../v2/generated.protomessage.pb.go | 70 - vendor/k8s.io/api/autoscaling/v2/types.go | 10 +- .../api/autoscaling/v2beta1/generated.pb.go | 5106 --------------- .../api/autoscaling/v2beta1/generated.proto | 474 -- .../v2beta1/generated.protomessage.pb.go | 58 - .../k8s.io/api/autoscaling/v2beta1/types.go | 486 -- .../v2beta1/types_swagger_doc_generated.go | 247 - .../v2beta1/zz_generated.deepcopy.go | 525 -- .../v2beta1/zz_generated.model_name.go | 112 - .../zz_generated.prerelease-lifecycle.go | 74 - .../api/autoscaling/v2beta2/generated.pb.go | 5817 ----------------- .../api/autoscaling/v2beta2/generated.proto | 493 -- .../v2beta2/generated.protomessage.pb.go | 70 - .../k8s.io/api/autoscaling/v2beta2/types.go | 578 -- .../v2beta2/types_swagger_doc_generated.go | 297 - .../v2beta2/zz_generated.deepcopy.go | 610 -- .../v2beta2/zz_generated.model_name.go | 142 - .../zz_generated.prerelease-lifecycle.go | 68 - vendor/k8s.io/api/batch/v1/generated.proto | 4 +- .../api/batch/v1/generated.protomessage.pb.go | 56 - vendor/k8s.io/api/batch/v1/types.go | 4 +- .../k8s.io/api/batch/v1beta1/generated.proto | 4 +- .../v1beta1/generated.protomessage.pb.go | 32 - vendor/k8s.io/api/batch/v1beta1/types.go | 4 +- .../api/certificates/v1/generated.proto | 16 +- .../v1/generated.protomessage.pb.go | 34 - vendor/k8s.io/api/certificates/v1/types.go | 16 +- .../v1alpha1/generated.protomessage.pb.go | 28 - .../api/certificates/v1beta1/generated.pb.go | 46 + .../api/certificates/v1beta1/generated.proto | 60 +- .../v1beta1/generated.protomessage.pb.go | 48 - .../k8s.io/api/certificates/v1beta1/types.go | 62 +- .../v1beta1/types_swagger_doc_generated.go | 5 +- .../v1beta1/zz_generated.deepcopy.go | 5 + .../zz_generated.prerelease-lifecycle.go | 8 +- .../v1/generated.protomessage.pb.go | 28 - .../api/coordination/v1alpha2/generated.proto | 2 +- .../v1alpha2/generated.protomessage.pb.go | 28 - .../k8s.io/api/coordination/v1alpha2/types.go | 2 +- .../api/coordination/v1beta1/generated.proto | 2 +- .../v1beta1/generated.protomessage.pb.go | 34 - .../k8s.io/api/coordination/v1beta1/types.go | 2 +- vendor/k8s.io/api/core/v1/generated.pb.go | 1697 +++-- vendor/k8s.io/api/core/v1/generated.proto | 179 +- .../api/core/v1/generated.protomessage.pb.go | 498 -- vendor/k8s.io/api/core/v1/types.go | 189 +- .../core/v1/types_swagger_doc_generated.go | 114 +- .../api/core/v1/zz_generated.deepcopy.go | 132 +- .../api/core/v1/zz_generated.model_name.go | 25 +- .../k8s.io/api/discovery/v1/generated.proto | 8 + .../discovery/v1/generated.protomessage.pb.go | 38 - vendor/k8s.io/api/discovery/v1/types.go | 9 + .../api/discovery/v1beta1/generated.proto | 7 + .../v1beta1/generated.protomessage.pb.go | 38 - vendor/k8s.io/api/discovery/v1beta1/types.go | 9 + .../events/v1/generated.protomessage.pb.go | 28 - .../api/extensions/v1beta1/generated.proto | 11 +- .../v1beta1/generated.protomessage.pb.go | 112 - vendor/k8s.io/api/extensions/v1beta1/types.go | 13 +- .../v1beta1/zz_generated.validations.go | 193 +- .../k8s.io/api/flowcontrol/v1/generated.proto | 13 + .../v1/generated.protomessage.pb.go | 68 - vendor/k8s.io/api/flowcontrol/v1/types.go | 13 + .../api/flowcontrol/v1beta1/generated.proto | 13 + .../v1beta1/generated.protomessage.pb.go | 68 - .../k8s.io/api/flowcontrol/v1beta1/types.go | 13 + .../api/flowcontrol/v1beta2/generated.proto | 13 + .../v1beta2/generated.protomessage.pb.go | 68 - .../k8s.io/api/flowcontrol/v1beta2/types.go | 13 + .../api/flowcontrol/v1beta3/generated.proto | 13 + .../v1beta3/generated.protomessage.pb.go | 68 - .../k8s.io/api/flowcontrol/v1beta3/types.go | 13 + .../api/imagepolicy/v1alpha1/generated.proto | 2 + .../v1alpha1/generated.protomessage.pb.go | 30 - .../k8s.io/api/imagepolicy/v1alpha1/types.go | 2 + .../k8s.io/api/networking/v1/generated.proto | 18 +- .../v1/generated.protomessage.pb.go | 92 - vendor/k8s.io/api/networking/v1/types.go | 18 +- .../api/networking/v1beta1/generated.proto | 11 +- .../v1beta1/generated.protomessage.pb.go | 72 - vendor/k8s.io/api/networking/v1beta1/types.go | 11 +- vendor/k8s.io/api/node/v1/generated.proto | 4 + .../api/node/v1/generated.protomessage.pb.go | 30 - vendor/k8s.io/api/node/v1/types.go | 4 + .../k8s.io/api/node/v1alpha1/generated.proto | 5 + .../v1alpha1/generated.protomessage.pb.go | 32 - vendor/k8s.io/api/node/v1alpha1/types.go | 5 + .../k8s.io/api/node/v1beta1/generated.proto | 4 + .../node/v1beta1/generated.protomessage.pb.go | 30 - vendor/k8s.io/api/node/v1beta1/types.go | 4 + vendor/k8s.io/api/policy/v1/generated.proto | 4 + .../policy/v1/generated.protomessage.pb.go | 32 - vendor/k8s.io/api/policy/v1/types.go | 4 + .../k8s.io/api/policy/v1beta1/generated.proto | 4 + .../v1beta1/generated.protomessage.pb.go | 32 - vendor/k8s.io/api/policy/v1beta1/types.go | 4 + vendor/k8s.io/api/rbac/v1/generated.proto | 15 +- .../api/rbac/v1/generated.protomessage.pb.go | 46 - vendor/k8s.io/api/rbac/v1/types.go | 15 +- .../k8s.io/api/rbac/v1alpha1/generated.proto | 15 +- .../v1alpha1/generated.protomessage.pb.go | 46 - vendor/k8s.io/api/rbac/v1alpha1/types.go | 15 +- .../k8s.io/api/rbac/v1beta1/generated.proto | 15 +- .../rbac/v1beta1/generated.protomessage.pb.go | 46 - vendor/k8s.io/api/rbac/v1beta1/types.go | 15 +- vendor/k8s.io/api/resource/v1/generated.pb.go | 641 ++ vendor/k8s.io/api/resource/v1/generated.proto | 405 +- .../resource/v1/generated.protomessage.pb.go | 108 - vendor/k8s.io/api/resource/v1/types.go | 450 +- .../v1/types_swagger_doc_generated.go | 89 +- .../api/resource/v1/zz_generated.deepcopy.go | 53 + .../resource/v1/zz_generated.model_name.go | 5 + .../api/resource/v1alpha3/generated.pb.go | 1762 ++++- .../api/resource/v1alpha3/generated.proto | 220 +- .../v1alpha3/generated.protomessage.pb.go | 38 - .../k8s.io/api/resource/v1alpha3/register.go | 2 + vendor/k8s.io/api/resource/v1alpha3/types.go | 244 +- .../v1alpha3/types_swagger_doc_generated.go | 63 +- .../v1alpha3/zz_generated.deepcopy.go | 177 + .../v1alpha3/zz_generated.model_name.go | 25 + .../zz_generated.prerelease-lifecycle.go | 36 + .../api/resource/v1beta1/generated.pb.go | 641 ++ .../api/resource/v1beta1/generated.proto | 384 +- .../v1beta1/generated.protomessage.pb.go | 108 - vendor/k8s.io/api/resource/v1beta1/types.go | 411 +- .../v1beta1/types_swagger_doc_generated.go | 75 +- .../resource/v1beta1/zz_generated.deepcopy.go | 53 + .../v1beta1/zz_generated.model_name.go | 5 + .../api/resource/v1beta2/generated.pb.go | 2038 +++++- .../api/resource/v1beta2/generated.proto | 496 +- .../v1beta2/generated.protomessage.pb.go | 108 - .../k8s.io/api/resource/v1beta2/register.go | 2 + vendor/k8s.io/api/resource/v1beta2/types.go | 564 +- .../v1beta2/types_swagger_doc_generated.go | 128 +- .../resource/v1beta2/zz_generated.deepcopy.go | 190 + .../v1beta2/zz_generated.model_name.go | 30 + .../zz_generated.prerelease-lifecycle.go | 36 + .../k8s.io/api/scheduling/v1/generated.proto | 1 + .../v1/generated.protomessage.pb.go | 26 - vendor/k8s.io/api/scheduling/v1/types.go | 1 + .../api/scheduling/v1alpha1/generated.pb.go | 2010 ------ .../api/scheduling/v1alpha1/generated.proto | 190 - .../v1alpha1/generated.protomessage.pb.go | 42 - .../k8s.io/api/scheduling/v1alpha1/types.go | 201 - .../v1alpha1/types_swagger_doc_generated.go | 131 - .../v1alpha1/zz_generated.deepcopy.go | 270 - .../v1alpha1/zz_generated.model_name.go | 72 - .../scheduling/{v1alpha1 => v1alpha2}/doc.go | 6 +- .../api/scheduling/v1alpha2/generated.pb.go | 3828 +++++++++++ .../api/scheduling/v1alpha2/generated.proto | 550 ++ .../{v1alpha1 => v1alpha2}/register.go | 13 +- .../k8s.io/api/scheduling/v1alpha2/types.go | 601 ++ .../v1alpha2/types_swagger_doc_generated.go | 217 + .../v1alpha2/zz_generated.deepcopy.go | 484 ++ .../v1alpha2/zz_generated.model_name.go | 112 + .../api/scheduling/v1beta1/generated.proto | 1 + vendor/k8s.io/api/scheduling/v1beta1/types.go | 1 + vendor/k8s.io/api/storage/v1/generated.pb.go | 35 + vendor/k8s.io/api/storage/v1/generated.proto | 40 +- .../storage/v1/generated.protomessage.pb.go | 64 - vendor/k8s.io/api/storage/v1/types.go | 41 +- .../storage/v1/types_swagger_doc_generated.go | 5 +- .../api/storage/v1/zz_generated.deepcopy.go | 5 + .../api/storage/v1alpha1/generated.proto | 6 + .../v1alpha1/generated.protomessage.pb.go | 42 - vendor/k8s.io/api/storage/v1alpha1/types.go | 7 + .../api/storage/v1beta1/generated.pb.go | 35 + .../api/storage/v1beta1/generated.proto | 36 +- .../v1beta1/generated.protomessage.pb.go | 64 - vendor/k8s.io/api/storage/v1beta1/types.go | 37 +- .../v1beta1/types_swagger_doc_generated.go | 1 + .../storage/v1beta1/zz_generated.deepcopy.go | 5 + .../v1beta1/generated.protomessage.pb.go | 30 - .../v1/generated.protomessage.pb.go | 76 - .../pkg/apis/apiextensions/v1/types.go | 3 + .../v1beta1/generated.protomessage.pb.go | 74 - .../v1/customresourcedefinition.go | 48 +- .../v1beta1/customresourcedefinition.go | 48 +- .../informers/externalversions/factory.go | 110 +- .../internalinterfaces/factory_interfaces.go | 19 + .../pkg/features/kube_features.go | 1 + .../apimachinery/pkg/api/equality/semantic.go | 3 + .../pkg/api/validate/content/errors.go | 6 + .../pkg/api/validate/content/path.go | 63 + .../pkg/api/validate/discriminator.go | 71 + .../apimachinery/pkg/api/validate/limits.go | 85 +- .../apimachinery/pkg/api/validate/strfmt.go | 17 + .../apimachinery/pkg/api/validate/union.go | 19 +- .../pkg/api/validation/objectmeta.go | 2 +- .../pkg/api/validation/path/name.go | 68 - .../apis/meta/internalversion/conversion.go} | 21 +- .../pkg/apis/meta/internalversion/types.go | 5 + .../zz_generated.conversion.go | 16 +- .../apimachinery/pkg/apis/meta/v1/fieldsv1.go | 170 + .../pkg/apis/meta/v1/fieldsv1_byte.go | 105 + .../pkg/apis/meta/v1/fieldsv1_string.go | 113 + .../pkg/apis/meta/v1/generated.pb.go | 353 +- .../pkg/apis/meta/v1/generated.proto | 56 + .../apis/meta/v1/generated.protomessage.pb.go | 112 - .../apimachinery/pkg/apis/meta/v1/helpers.go | 27 +- .../apimachinery/pkg/apis/meta/v1/meta.go | 9 + .../pkg/apis/meta/v1/micro_time_fuzz.go | 1 - .../pkg/apis/meta/v1/time_fuzz.go | 1 - .../apimachinery/pkg/apis/meta/v1/types.go | 73 +- .../meta/v1/types_swagger_doc_generated.go | 19 +- .../apis/meta/v1/zz_generated.conversion.go | 7 + .../pkg/apis/meta/v1/zz_generated.deepcopy.go | 45 +- .../apis/meta/v1/zz_generated.model_name.go | 5 + .../pkg/runtime/generated.protomessage.pb.go | 28 - .../schema/generated.protomessage.pb.go | 22 - .../pkg/runtime/serializer/cbor/raw.go | 4 +- .../apimachinery/pkg/sharding/accessor.go | 50 + .../pkg/sharding/hash.go} | 20 +- .../apimachinery/pkg/sharding/selector.go | 137 + .../k8s.io/apimachinery/pkg/sharding/types.go | 32 + .../k8s.io/apimachinery/pkg/util/diff/diff.go | 5 +- .../apimachinery/pkg/util/diff/legacy_diff.go | 2 +- .../apimachinery/pkg/util/httpstream/doc.go | 5 +- .../pkg/util/httpstream/spdy}/doc.go | 10 +- .../pkg/util/httpstream/spdy/spdy.go | 236 + .../pkg/util/httpstream/wsstream/doc.go | 53 +- .../pkg/util/httpstream/wsstream/wsstream.go | 91 + .../pkg/util/intstr/instr_fuzz.go | 1 - .../pkg/util/managedfields/extract.go | 3 +- .../pkg/util/managedfields/internal/fields.go | 7 +- .../apimachinery/pkg/util/mergepatch/util.go | 2 +- .../k8s.io/apimachinery/pkg/util/net/http.go | 5 + .../apimachinery/pkg/util/net/interface.go | 112 +- .../apimachinery/pkg/util/proxy/dial.go | 6 +- .../apimachinery/pkg/util/proxy/transport.go | 4 +- .../pkg/util/proxy/upgradeaware.go | 33 +- .../apimachinery/pkg/util/runtime/runtime.go | 33 +- .../pkg/util/strategicpatch/patch.go | 8 +- .../util/validation/field/error_matcher.go | 40 +- .../pkg/util/validation/field/errors.go | 232 +- .../apimachinery/pkg/util/validation/ip.go | 4 +- .../forked/golang/reflect/deep_equal.go | 4 +- .../k8s.io/apiserver/pkg/admission/config.go | 2 +- .../k8s.io/apiserver/pkg/admission/handler.go | 4 +- .../pkg/admission/initializer/apiserver_id.go | 43 + .../pkg/admission/initializer/interfaces.go | 39 + .../pkg/admission/plugin/cel/composition.go | 128 +- .../pkg/admission/plugin/manifest/loader.go | 120 + .../plugin/manifest/metrics/metrics.go | 161 + .../admission/plugin/manifest/validation.go | 74 + .../plugin/namespace/lifecycle/admission.go | 8 +- .../policy/config/apis/policyconfig/doc.go | 20 + .../config/apis/policyconfig}/register.go | 31 +- .../policy/config/apis/policyconfig/types.go | 63 + .../policy/config/apis/policyconfig/v1/doc.go | 21 + .../config/apis/policyconfig/v1}/register.go | 9 +- .../config/apis/policyconfig/v1/types.go | 53 + .../v1/zz_generated.conversion.go | 98 + .../policyconfig/v1/zz_generated.deepcopy.go | 76 + .../policyconfig/zz_generated.deepcopy.go | 76 + .../admission/plugin/policy/config/config.go | 97 + .../policy/generic/composite_policy_source.go | 119 + .../admission/plugin/policy/generic/plugin.go | 192 +- .../policy/generic/policy_test_context.go | 4 +- .../policy/internal/generic/controller.go | 36 +- .../plugin/policy/manifest/source/source.go | 192 + .../plugin/policy/mutating/accessor.go | 42 +- .../plugin/policy/mutating/compilation.go | 29 +- .../plugin/policy/mutating/dispatcher.go | 8 +- .../plugin/policy/mutating/plugin.go | 76 +- .../plugin/policy/validating/interface.go | 2 + .../plugin/policy/validating/plugin.go | 63 +- .../plugin/policy/validating/typechecking.go | 33 +- .../plugin/policy/validating/validator.go | 21 +- .../config/apis/webhookadmission/types.go | 10 + .../config/apis/webhookadmission/v1/types.go | 10 + .../v1/zz_generated.conversion.go | 2 + .../apis/webhookadmission/v1alpha1/doc.go | 23 - .../v1alpha1/zz_generated.conversion.go | 68 - .../plugin/webhook/config/kubeconfig.go | 57 +- .../generic/composite_webhook_source.go | 99 + .../plugin/webhook/generic/webhook.go | 158 +- .../plugin/webhook/manifest/loader/loader.go | 220 + .../plugin/webhook/manifest/source/source.go | 218 + .../plugin/webhook/mutating/plugin.go | 19 +- .../webhook/mutating/reinvocationcontext.go | 10 +- .../plugin/webhook/validating/plugin.go | 18 + .../apiserver/pkg/apis/apiserver/types.go | 4 + .../pkg/apis/apiserver/v1alpha1/types.go | 4 + .../v1alpha1/zz_generated.conversion.go | 2 + .../pkg/apis/apiserver/v1beta1/types.go | 4 + .../v1beta1/zz_generated.conversion.go | 2 + .../apis/apiserver/validation/validation.go | 10 +- .../apiserver/validation/validation_patch.go | 39 + .../k8s.io/apiserver/pkg/apis/audit/types.go | 1 + .../pkg/apis/audit/v1/generated.proto | 1 + .../audit/v1/generated.protomessage.pb.go | 38 - .../apiserver/pkg/apis/audit/v1/types.go | 1 + .../pkg/apis/audit/validation/validation.go | 2 +- .../apiserver/pkg/audit/policy/checker.go | 2 +- vendor/k8s.io/apiserver/pkg/audit/union.go | 1 - .../headerrequest/requestheader_controller.go | 2 +- .../request/websocket/protocol.go | 2 +- .../k8s.io/apiserver/pkg/cel/library/cidr.go | 36 +- .../apiserver/pkg/cel/library/format.go | 72 +- vendor/k8s.io/apiserver/pkg/cel/library/ip.go | 48 +- .../apiserver/pkg/cel/library/quantity.go | 36 +- .../apiserver/pkg/cel/openapi/adaptor.go | 3 - .../pkg/cel/openapi/resolver/refs.go | 8 +- .../endpoints/discovery/aggregated/handler.go | 10 +- .../apiserver/pkg/endpoints/filters/audit.go | 3 +- .../endpoints/filters/impersonation/cache.go | 66 +- .../constrained_impersonation.go | 73 +- .../filters/impersonation/metrics/metrics.go | 99 + .../pkg/endpoints/handlers/delete.go | 2 +- .../apiserver/pkg/endpoints/handlers/get.go | 245 +- .../pkg/endpoints/handlers/metrics/OWNERS | 3 +- .../handlers/responsewriters/writers.go | 2 +- .../apiserver/pkg/endpoints/handlers/watch.go | 65 +- .../apiserver/pkg/endpoints/metrics/OWNERS | 3 +- .../pkg/endpoints/metrics/metrics.go | 15 +- .../pkg/endpoints/request/requestinfo.go | 4 +- .../pkg/endpoints/request/webhook_duration.go | 17 + .../apiserver/pkg/features/kube_features.go | 79 +- .../apiserver/pkg/quota/v1/resources.go | 6 +- .../pkg/registry/generic/registry/store.go | 32 +- .../apiserver/pkg/registry/rest/create.go | 11 +- .../apiserver/pkg/registry/rest/update.go | 3 +- .../apiserver/pkg/registry/rest/validate.go | 206 +- vendor/k8s.io/apiserver/pkg/server/config.go | 21 + .../configmap_cafile_content.go | 2 +- .../dynamic_cafile_content.go | 2 +- .../dynamic_serving_content.go | 2 +- .../server/egressselector/egress_selector.go | 1 + .../pkg/server/flagz/api/v1alpha1/doc.go | 2 +- .../pkg/server/flagz/api/v1beta1}/doc.go | 9 +- .../pkg/server/flagz/api/v1beta1}/register.go | 35 +- .../flagz/api/v1beta1}/types.go | 26 +- .../api/v1beta1}/zz_generated.deepcopy.go | 20 +- .../api/v1beta1/zz_generated.model_name.go} | 15 +- .../apiserver/pkg/server/flagz/flagz.go | 180 +- .../pkg/server/flagz/negotiate/negotiation.go | 27 +- .../apiserver/pkg/server/genericapiserver.go | 22 +- vendor/k8s.io/apiserver/pkg/server/hooks.go | 3 +- .../apiserver/pkg/server/options/admission.go | 2 +- .../pkg/server/options/api_enablement.go | 38 +- .../apiserver/pkg/server/options/audit.go | 12 +- .../server/options/encryptionconfig/config.go | 10 - .../encryptionconfig/controller/controller.go | 6 +- .../apiserver/pkg/server/options/etcd.go | 101 +- .../pkg/server/options/recommended.go | 2 +- .../apiserver/pkg/server/options/serving.go | 25 + .../pkg/server/options/serving_unix.go | 1 - .../pkg/server/options/serving_windows.go | 1 - .../server/options/serving_with_loopback.go | 60 +- .../pkg/server/resourceconfig/helpers.go | 19 +- .../apiserver/pkg/server/routes/metrics.go | 2 + .../apiserver/pkg/server/routes/openapi.go | 109 +- .../apiserver/pkg/server/secure_serving.go | 3 + .../apiserver/pkg/server/signal_posix.go | 1 - .../pkg/server/statusz/api/v1alpha1/doc.go | 2 +- .../pkg/server/statusz/api/v1beta1}/doc.go | 9 +- .../server/statusz/api/v1beta1/register.go | 47 + .../pkg/server/statusz/api/v1beta1/types.go | 50 + .../api/v1beta1/zz_generated.deepcopy.go | 58 + .../api/v1beta1/zz_generated.model_name.go} | 11 +- .../server/statusz/negotiate/negotiation.go | 29 +- .../apiserver/pkg/server/statusz/statusz.go | 195 +- .../pkg/server/statusz/textserializer.go | 6 +- .../k8s.io/apiserver/pkg/sharding/parser.go | 217 + vendor/k8s.io/apiserver/pkg/storage/OWNERS | 2 + .../pkg/storage/cacher/cache_watcher.go | 6 +- .../apiserver/pkg/storage/cacher/cacher.go | 59 +- .../apiserver/pkg/storage/cacher/delegator.go | 67 +- .../pkg/storage/cacher/metrics/metrics.go | 49 +- .../storage/cacher/progress/watch_progress.go | 2 +- .../pkg/storage/cacher/{ => store}/store.go | 32 +- .../storage/cacher/{ => store}/store_btree.go | 76 +- .../pkg/storage/cacher/watch_cache.go | 39 +- .../storage/cacher/watch_cache_interval.go | 9 +- .../pkg/storage/etcd3/metrics/metrics.go | 20 +- .../apiserver/pkg/storage/etcd3/store.go | 8 +- .../apiserver/pkg/storage/etcd3/watcher.go | 11 +- .../feature/feature_support_checker.go | 2 +- .../pkg/storage/selection_predicate.go | 35 + .../storage/storagebackend/factory/etcd3.go | 17 +- vendor/k8s.io/apiserver/pkg/storage/util.go | 6 +- .../value/encrypt/envelope/grpc_service.go | 2 +- .../value/encrypt/envelope/kmsv2/envelope.go | 1 - .../encrypt/envelope/kmsv2/grpc_service.go | 2 +- .../pkg/util/filesystem/watchuntil.go | 149 + .../pkg/util/peerproxy/metrics/metrics.go | 58 +- vendor/k8s.io/apiserver/pkg/util/proxy/doc.go | 36 + .../apiserver/pkg/util/proxy/endpointslice.go | 114 + .../pkg/util/proxy/metrics/metrics.go | 101 + .../k8s.io/apiserver/pkg/util/proxy/proxy.go | 187 + .../pkg/util/proxy/streamtranslator.go | 187 + .../apiserver/pkg/util/proxy/streamtunnel.go | 470 ++ .../pkg/util/proxy/translatinghandler.go | 51 + .../apiserver/pkg/util/proxy/websocket.go | 200 + .../plugin/pkg/authorizer/webhook/webhook.go | 27 +- .../k8s.io/cli-runtime/pkg/printers/kyaml.go | 2 + .../cli-runtime/pkg/resource/visitor.go | 1 - .../v1/applyconfiguration.go | 81 + .../v1/expressionwarning.go | 4 +- .../admissionregistration/v1/jsonpatch.go | 105 + .../v1/matchcondition.go | 4 +- .../v1/matchresources.go | 8 +- .../v1/mutatingadmissionpolicy.go | 274 + .../v1/mutatingadmissionpolicybinding.go | 284 + .../v1/mutatingadmissionpolicybindingspec.go | 75 + .../v1/mutatingadmissionpolicyspec.go | 172 + .../v1/mutatingwebhook.go | 20 +- .../v1/mutatingwebhookconfiguration.go | 4 +- .../admissionregistration/v1/mutation.go | 72 + .../v1/namedrulewithoperations.go | 2 +- .../admissionregistration/v1/paramkind.go | 4 +- .../admissionregistration/v1/paramref.go | 2 +- .../admissionregistration/v1/rule.go | 6 +- .../v1/rulewithoperations.go | 2 +- .../v1/servicereference.go | 8 +- .../admissionregistration/v1/typechecking.go | 2 +- .../v1/validatingadmissionpolicy.go | 6 +- .../v1/validatingadmissionpolicybinding.go | 4 +- .../validatingadmissionpolicybindingspec.go | 4 +- .../v1/validatingadmissionpolicyspec.go | 10 +- .../v1/validatingadmissionpolicystatus.go | 6 +- .../v1/validatingwebhook.go | 20 +- .../v1/validatingwebhookconfiguration.go | 4 +- .../admissionregistration/v1/validation.go | 6 +- .../admissionregistration/v1/variable.go | 4 +- .../v1/webhookclientconfig.go | 6 +- .../v1alpha1/expressionwarning.go | 4 +- .../v1alpha1/matchcondition.go | 4 +- .../v1alpha1/matchresources.go | 8 +- .../v1alpha1/mutatingadmissionpolicy.go | 4 +- .../mutatingadmissionpolicybinding.go | 4 +- .../v1alpha1/namedrulewithoperations.go | 2 +- .../v1alpha1/paramkind.go | 4 +- .../v1alpha1/paramref.go | 4 +- .../v1alpha1/typechecking.go | 2 +- .../v1alpha1/validatingadmissionpolicy.go | 6 +- .../validatingadmissionpolicybinding.go | 4 +- .../validatingadmissionpolicybindingspec.go | 4 +- .../v1alpha1/validatingadmissionpolicyspec.go | 10 +- .../validatingadmissionpolicystatus.go | 6 +- .../v1alpha1/validation.go | 6 +- .../v1alpha1/variable.go | 4 +- .../v1beta1/expressionwarning.go | 4 +- .../v1beta1/matchcondition.go | 4 +- .../v1beta1/matchresources.go | 8 +- .../v1beta1/mutatingadmissionpolicy.go | 4 +- .../v1beta1/mutatingadmissionpolicybinding.go | 4 +- .../v1beta1/mutatingwebhook.go | 20 +- .../v1beta1/mutatingwebhookconfiguration.go | 4 +- .../v1beta1/namedrulewithoperations.go | 2 +- .../v1beta1/paramkind.go | 4 +- .../admissionregistration/v1beta1/paramref.go | 2 +- .../v1beta1/servicereference.go | 10 +- .../v1beta1/typechecking.go | 2 +- .../v1beta1/validatingadmissionpolicy.go | 6 +- .../validatingadmissionpolicybinding.go | 4 +- .../validatingadmissionpolicybindingspec.go | 4 +- .../v1beta1/validatingadmissionpolicyspec.go | 10 +- .../validatingadmissionpolicystatus.go | 6 +- .../v1beta1/validatingwebhook.go | 20 +- .../v1beta1/validatingwebhookconfiguration.go | 4 +- .../v1beta1/validation.go | 6 +- .../admissionregistration/v1beta1/variable.go | 4 +- .../v1beta1/webhookclientconfig.go | 6 +- .../v1alpha1/serverstorageversion.go | 7 +- .../v1alpha1/storageversion.go | 5 +- .../v1alpha1/storageversioncondition.go | 12 +- .../v1alpha1/storageversionstatus.go | 9 +- .../v2beta1/containerresourcemetricsource.go | 87 - .../v2beta1/containerresourcemetricstatus.go | 88 - .../v2beta1/crossversionobjectreference.go | 62 - .../v2beta1/externalmetricsource.go | 83 - .../v2beta1/externalmetricstatus.go | 80 - .../horizontalpodautoscalercondition.go | 91 - .../v2beta1/horizontalpodautoscalerspec.go | 89 - .../v2beta1/horizontalpodautoscalerstatus.go | 110 - .../autoscaling/v2beta1/metricspec.go | 113 - .../autoscaling/v2beta1/metricstatus.go | 112 - .../autoscaling/v2beta1/objectmetricsource.go | 91 - .../autoscaling/v2beta1/objectmetricstatus.go | 91 - .../autoscaling/v2beta1/podsmetricsource.go | 73 - .../autoscaling/v2beta1/podsmetricstatus.go | 71 - .../v2beta1/resourcemetricsource.go | 77 - .../v2beta1/resourcemetricstatus.go | 78 - .../v2beta2/containerresourcemetricsource.go | 72 - .../v2beta2/containerresourcemetricstatus.go | 70 - .../v2beta2/crossversionobjectreference.go | 62 - .../v2beta2/externalmetricsource.go | 54 - .../v2beta2/externalmetricstatus.go | 53 - .../horizontalpodautoscalerbehavior.go | 60 - .../v2beta2/horizontalpodautoscalerspec.go | 102 - .../v2beta2/horizontalpodautoscalerstatus.go | 110 - .../autoscaling/v2beta2/hpascalingpolicy.go | 68 - .../autoscaling/v2beta2/hpascalingrules.go | 83 - .../autoscaling/v2beta2/metricidentifier.go | 58 - .../autoscaling/v2beta2/metricspec.go | 113 - .../autoscaling/v2beta2/metricstatus.go | 112 - .../autoscaling/v2beta2/metrictarget.go | 81 - .../autoscaling/v2beta2/metricvaluestatus.go | 69 - .../autoscaling/v2beta2/objectmetricsource.go | 62 - .../autoscaling/v2beta2/objectmetricstatus.go | 62 - .../autoscaling/v2beta2/podsmetricsource.go | 55 - .../autoscaling/v2beta2/podsmetricstatus.go | 53 - .../v2beta2/resourcemetricsource.go | 62 - .../v2beta2/resourcemetricstatus.go | 60 - .../v1beta1/podcertificaterequestspec.go | 48 +- .../core/v1/imagevolumestatus.go | 44 + .../v1/nodeallocatableresourceclaimstatus.go | 75 + .../core/v1/persistentvolumesource.go | 3 +- .../core/v1/podcondition.go | 1 - .../core/v1/podresourceclaim.go | 18 + .../core/v1/podresourceclaimstatus.go | 13 +- .../core/v1/podschedulinggroup.go | 46 + .../applyconfigurations/core/v1/podspec.go | 28 +- .../applyconfigurations/core/v1/podstatus.go | 19 + .../core/v1/resourcehealth.go | 11 + .../core/v1/securitycontext.go | 1 - .../core/v1/volumemountstatus.go | 11 + .../core/v1/volumesource.go | 5 +- .../core/v1/volumestatus.go | 43 + .../core/v1/workloadreference.go | 74 - .../applyconfigurations/internal/internal.go | 1498 ++--- .../resource/v1/allocationresult.go | 2 +- .../resource/v1/celdeviceselector.go | 8 + .../applyconfigurations/resource/v1/device.go | 35 +- .../resource/v1/deviceattribute.go | 56 + .../resource/v1/deviceclass.go | 3 - .../resource/v1/deviceclassspec.go | 2 +- .../resource/v1/deviceconstraint.go | 10 + .../v1/devicerequestallocationresult.go | 9 +- .../resource/v1/devicesubrequest.go | 2 +- .../resource/v1/devicetaint.go | 11 +- .../resource/v1/exactdevicerequest.go | 5 +- .../resource/v1/networkdevicedata.go | 4 +- .../v1/nodeallocatableresourcemapping.go | 84 + .../resource/v1/resourceclaim.go | 3 - .../resource/v1/resourceclaimtemplate.go | 3 - .../resource/v1/resourceslice.go | 3 - .../resource/v1alpha3/devicetaint.go | 11 +- .../resource/v1alpha3/poolstatus.go | 152 + .../v1alpha3/resourcepoolstatusrequest.go} | 165 +- .../v1alpha3/resourcepoolstatusrequestspec.go | 73 + .../resourcepoolstatusrequeststatus.go | 87 + .../resource/v1beta1/allocationresult.go | 2 +- .../resource/v1beta1/basicdevice.go | 35 +- .../resource/v1beta1/celdeviceselector.go | 8 + .../resource/v1beta1/deviceattribute.go | 56 + .../resource/v1beta1/deviceclassspec.go | 2 +- .../resource/v1beta1/deviceconstraint.go | 10 + .../resource/v1beta1/devicerequest.go | 2 +- .../v1beta1/devicerequestallocationresult.go | 6 +- .../resource/v1beta1/devicesubrequest.go | 2 +- .../resource/v1beta1/devicetaint.go | 11 +- .../resource/v1beta1/networkdevicedata.go | 4 +- .../v1beta1/nodeallocatableresourcemapping.go | 84 + .../resource/v1beta2/allocationresult.go | 2 +- .../resource/v1beta2/celdeviceselector.go | 8 + .../resource/v1beta2/device.go | 35 +- .../resource/v1beta2/deviceattribute.go | 56 + .../resource/v1beta2/deviceclassspec.go | 2 +- .../resource/v1beta2/deviceconstraint.go | 10 + .../v1beta2/devicerequestallocationresult.go | 6 +- .../resource/v1beta2/devicesubrequest.go | 2 +- .../resource/v1beta2/devicetaint.go | 11 +- .../v1beta2/devicetaintrule.go} | 128 +- .../resource/v1beta2/devicetaintrulespec.go | 55 + .../resource/v1beta2/devicetaintrulestatus.go | 70 + .../resource/v1beta2/devicetaintselector.go | 76 + .../resource/v1beta2/exactdevicerequest.go | 2 +- .../resource/v1beta2/networkdevicedata.go | 4 +- .../v1beta2/nodeallocatableresourcemapping.go | 84 + .../scheduling/v1alpha1/podgroup.go | 53 - .../gangschedulingpolicy.go | 2 +- .../v1alpha2/podgroup.go} | 126 +- .../v1alpha2/podgroupresourceclaim.go | 89 + .../v1alpha2/podgroupresourceclaimstatus.go | 59 + .../v1alpha2/podgroupschedulingconstraints.go | 48 + .../podgroupschedulingpolicy.go} | 23 +- .../scheduling/v1alpha2/podgroupspec.go | 145 + .../scheduling/v1alpha2/podgroupstatus.go | 81 + .../scheduling/v1alpha2/podgrouptemplate.go | 136 + .../v1alpha2/podgrouptemplatereference.go | 44 + .../scheduling/v1alpha2/topologyconstraint.go | 45 + .../typedlocalobjectreference.go | 2 +- .../{v1alpha1 => v1alpha2}/workload.go | 19 +- .../workloadpodgrouptemplatereference.go | 52 + .../{v1alpha1 => v1alpha2}/workloadspec.go | 20 +- .../storage/v1/csidriverspec.go | 28 +- .../storage/v1/volumeerror.go | 2 +- .../storage/v1beta1/csidriverspec.go | 26 + .../client-go/applyconfigurations/utils.go | 184 +- .../discovery/cached/disk/round_tripper.go | 4 +- .../k8s.io/client-go/dynamic/fake/simple.go | 6 +- vendor/k8s.io/client-go/features/envvar.go | 35 +- vendor/k8s.io/client-go/features/features.go | 6 +- .../client-go/features/known_features.go | 40 + .../admissionregistration/v1/interface.go | 14 + .../v1/mutatingadmissionpolicy.go | 115 + .../v1/mutatingadmissionpolicybinding.go | 115 + .../v1/mutatingwebhookconfiguration.go | 48 +- .../v1/validatingadmissionpolicy.go | 48 +- .../v1/validatingadmissionpolicybinding.go | 48 +- .../v1/validatingwebhookconfiguration.go | 48 +- .../v1alpha1/mutatingadmissionpolicy.go | 48 +- .../mutatingadmissionpolicybinding.go | 48 +- .../v1alpha1/validatingadmissionpolicy.go | 48 +- .../validatingadmissionpolicybinding.go | 48 +- .../v1beta1/mutatingadmissionpolicy.go | 48 +- .../v1beta1/mutatingadmissionpolicybinding.go | 48 +- .../v1beta1/mutatingwebhookconfiguration.go | 48 +- .../v1beta1/validatingadmissionpolicy.go | 48 +- .../validatingadmissionpolicybinding.go | 48 +- .../v1beta1/validatingwebhookconfiguration.go | 48 +- .../v1alpha1/storageversion.go | 48 +- .../informers/apps/v1/controllerrevision.go | 48 +- .../client-go/informers/apps/v1/daemonset.go | 48 +- .../client-go/informers/apps/v1/deployment.go | 48 +- .../client-go/informers/apps/v1/replicaset.go | 48 +- .../informers/apps/v1/statefulset.go | 48 +- .../apps/v1beta1/controllerrevision.go | 48 +- .../informers/apps/v1beta1/deployment.go | 48 +- .../informers/apps/v1beta1/statefulset.go | 48 +- .../apps/v1beta2/controllerrevision.go | 48 +- .../informers/apps/v1beta2/daemonset.go | 48 +- .../informers/apps/v1beta2/deployment.go | 48 +- .../informers/apps/v1beta2/replicaset.go | 48 +- .../informers/apps/v1beta2/statefulset.go | 48 +- .../informers/autoscaling/interface.go | 16 - .../autoscaling/v1/horizontalpodautoscaler.go | 48 +- .../autoscaling/v2/horizontalpodautoscaler.go | 48 +- .../v2beta1/horizontalpodautoscaler.go | 102 - .../autoscaling/v2beta1/interface.go | 45 - .../v2beta2/horizontalpodautoscaler.go | 102 - .../autoscaling/v2beta2/interface.go | 45 - .../client-go/informers/batch/v1/cronjob.go | 48 +- .../client-go/informers/batch/v1/job.go | 48 +- .../informers/batch/v1beta1/cronjob.go | 48 +- .../v1/certificatesigningrequest.go | 48 +- .../v1alpha1/clustertrustbundle.go | 48 +- .../v1beta1/certificatesigningrequest.go | 48 +- .../v1beta1/clustertrustbundle.go | 48 +- .../v1beta1/podcertificaterequest.go | 48 +- .../informers/coordination/v1/lease.go | 48 +- .../coordination/v1alpha2/leasecandidate.go | 48 +- .../informers/coordination/v1beta1/lease.go | 48 +- .../coordination/v1beta1/leasecandidate.go | 48 +- .../informers/core/v1/componentstatus.go | 48 +- .../client-go/informers/core/v1/configmap.go | 48 +- .../client-go/informers/core/v1/endpoints.go | 48 +- .../client-go/informers/core/v1/event.go | 48 +- .../client-go/informers/core/v1/limitrange.go | 48 +- .../client-go/informers/core/v1/namespace.go | 48 +- .../client-go/informers/core/v1/node.go | 48 +- .../informers/core/v1/persistentvolume.go | 48 +- .../core/v1/persistentvolumeclaim.go | 48 +- .../k8s.io/client-go/informers/core/v1/pod.go | 48 +- .../informers/core/v1/podtemplate.go | 48 +- .../core/v1/replicationcontroller.go | 48 +- .../informers/core/v1/resourcequota.go | 48 +- .../client-go/informers/core/v1/secret.go | 48 +- .../client-go/informers/core/v1/service.go | 48 +- .../informers/core/v1/serviceaccount.go | 48 +- .../informers/discovery/v1/endpointslice.go | 48 +- .../discovery/v1beta1/endpointslice.go | 48 +- .../client-go/informers/events/v1/event.go | 48 +- .../informers/events/v1beta1/event.go | 48 +- .../informers/extensions/v1beta1/daemonset.go | 48 +- .../extensions/v1beta1/deployment.go | 48 +- .../informers/extensions/v1beta1/ingress.go | 48 +- .../extensions/v1beta1/networkpolicy.go | 48 +- .../extensions/v1beta1/replicaset.go | 48 +- vendor/k8s.io/client-go/informers/factory.go | 110 +- .../informers/flowcontrol/v1/flowschema.go | 48 +- .../v1/prioritylevelconfiguration.go | 48 +- .../flowcontrol/v1beta1/flowschema.go | 48 +- .../v1beta1/prioritylevelconfiguration.go | 48 +- .../flowcontrol/v1beta2/flowschema.go | 48 +- .../v1beta2/prioritylevelconfiguration.go | 48 +- .../flowcontrol/v1beta3/flowschema.go | 48 +- .../v1beta3/prioritylevelconfiguration.go | 48 +- vendor/k8s.io/client-go/informers/generic.go | 30 +- .../internalinterfaces/factory_interfaces.go | 19 + .../informers/networking/v1/ingress.go | 48 +- .../informers/networking/v1/ingressclass.go | 48 +- .../informers/networking/v1/ipaddress.go | 48 +- .../informers/networking/v1/networkpolicy.go | 48 +- .../informers/networking/v1/servicecidr.go | 48 +- .../informers/networking/v1beta1/ingress.go | 48 +- .../networking/v1beta1/ingressclass.go | 48 +- .../informers/networking/v1beta1/ipaddress.go | 48 +- .../networking/v1beta1/servicecidr.go | 48 +- .../informers/node/v1/runtimeclass.go | 48 +- .../informers/node/v1alpha1/runtimeclass.go | 48 +- .../informers/node/v1beta1/runtimeclass.go | 48 +- .../policy/v1/poddisruptionbudget.go | 48 +- .../policy/v1beta1/poddisruptionbudget.go | 48 +- .../informers/rbac/v1/clusterrole.go | 48 +- .../informers/rbac/v1/clusterrolebinding.go | 48 +- .../client-go/informers/rbac/v1/role.go | 48 +- .../informers/rbac/v1/rolebinding.go | 48 +- .../informers/rbac/v1alpha1/clusterrole.go | 48 +- .../rbac/v1alpha1/clusterrolebinding.go | 48 +- .../client-go/informers/rbac/v1alpha1/role.go | 48 +- .../informers/rbac/v1alpha1/rolebinding.go | 48 +- .../informers/rbac/v1beta1/clusterrole.go | 48 +- .../rbac/v1beta1/clusterrolebinding.go | 48 +- .../client-go/informers/rbac/v1beta1/role.go | 48 +- .../informers/rbac/v1beta1/rolebinding.go | 48 +- .../informers/resource/v1/deviceclass.go | 48 +- .../informers/resource/v1/resourceclaim.go | 48 +- .../resource/v1/resourceclaimtemplate.go | 48 +- .../informers/resource/v1/resourceslice.go | 48 +- .../resource/v1alpha3/devicetaintrule.go | 48 +- .../informers/resource/v1alpha3/interface.go | 7 + .../v1alpha3/resourcepoolstatusrequest.go | 115 + .../informers/resource/v1beta1/deviceclass.go | 48 +- .../resource/v1beta1/resourceclaim.go | 48 +- .../resource/v1beta1/resourceclaimtemplate.go | 48 +- .../resource/v1beta1/resourceslice.go | 48 +- .../informers/resource/v1beta2/deviceclass.go | 48 +- .../resource/v1beta2/devicetaintrule.go | 115 + .../informers/resource/v1beta2/interface.go | 7 + .../resource/v1beta2/resourceclaim.go | 48 +- .../resource/v1beta2/resourceclaimtemplate.go | 48 +- .../resource/v1beta2/resourceslice.go | 48 +- .../informers/scheduling/interface.go | 12 +- .../informers/scheduling/v1/priorityclass.go | 48 +- .../scheduling/v1alpha1/priorityclass.go | 101 - .../informers/scheduling/v1alpha1/workload.go | 102 - .../{v1alpha1 => v1alpha2}/interface.go | 12 +- .../informers/scheduling/v1alpha2/podgroup.go | 116 + .../informers/scheduling/v1alpha2/workload.go | 116 + .../scheduling/v1beta1/priorityclass.go | 48 +- .../informers/storage/v1/csidriver.go | 48 +- .../client-go/informers/storage/v1/csinode.go | 48 +- .../storage/v1/csistoragecapacity.go | 48 +- .../informers/storage/v1/storageclass.go | 48 +- .../informers/storage/v1/volumeattachment.go | 48 +- .../storage/v1/volumeattributesclass.go | 48 +- .../storage/v1alpha1/csistoragecapacity.go | 48 +- .../storage/v1alpha1/volumeattachment.go | 48 +- .../storage/v1alpha1/volumeattributesclass.go | 48 +- .../informers/storage/v1beta1/csidriver.go | 48 +- .../informers/storage/v1beta1/csinode.go | 48 +- .../storage/v1beta1/csistoragecapacity.go | 48 +- .../informers/storage/v1beta1/storageclass.go | 48 +- .../storage/v1beta1/volumeattachment.go | 48 +- .../storage/v1beta1/volumeattributesclass.go | 48 +- .../v1beta1/storageversionmigration.go | 48 +- .../k8s.io/client-go/kubernetes/clientset.go | 42 +- .../kubernetes/fake/clientset_generated.go | 34 +- .../client-go/kubernetes/fake/register.go | 8 +- .../client-go/kubernetes/scheme/register.go | 8 +- .../v1/admissionregistration_client.go | 10 + .../fake/fake_admissionregistration_client.go | 8 + .../v1/fake/fake_mutatingadmissionpolicy.go | 53 + .../fake_mutatingadmissionpolicybinding.go | 53 + .../v1/generated_expansion.go | 4 + .../v1/mutatingadmissionpolicy.go | 75 + .../v1/mutatingadmissionpolicybinding.go | 75 + .../autoscaling/v2beta1/autoscaling_client.go | 101 - .../v2beta1/fake/fake_autoscaling_client.go | 40 - .../fake/fake_horizontalpodautoscaler.go | 53 - .../v2beta1/horizontalpodautoscaler.go | 79 - .../autoscaling/v2beta2/autoscaling_client.go | 101 - .../v2beta2/fake/fake_autoscaling_client.go | 40 - .../fake/fake_horizontalpodautoscaler.go | 53 - .../v2beta2/horizontalpodautoscaler.go | 79 - .../typed/core/v1/fake/fake_pod_expansion.go | 21 +- .../v1alpha3/fake/fake_resource_client.go | 4 + .../fake/fake_resourcepoolstatusrequest.go | 53 + .../resource/v1alpha3/generated_expansion.go | 2 + .../resource/v1alpha3/resource_client.go | 5 + .../v1alpha3/resourcepoolstatusrequest.go | 79 + .../typed/resource/v1beta2/devicetaintrule.go | 75 + .../v1beta2/fake/fake_devicetaintrule.go | 53 + .../v1beta2/fake/fake_resource_client.go | 4 + .../resource/v1beta2/generated_expansion.go | 2 + .../typed/resource/v1beta2/resource_client.go | 5 + .../v1alpha1/fake/fake_priorityclass.go | 53 - .../scheduling/v1alpha1/fake/fake_workload.go | 51 - .../scheduling/v1alpha1/priorityclass.go | 71 - .../v2beta2 => scheduling/v1alpha2}/doc.go | 2 +- .../v1alpha2}/fake/doc.go | 0 .../scheduling/v1alpha2/fake/fake_podgroup.go | 51 + .../fake/fake_scheduling_client.go | 12 +- .../scheduling/v1alpha2/fake/fake_workload.go | 51 + .../generated_expansion.go | 4 +- .../typed/scheduling/v1alpha2/podgroup.go | 75 + .../scheduling_client.go | 42 +- .../{v1alpha1 => v1alpha2}/workload.go | 30 +- .../v1/expansion_generated.go | 8 + .../v1/mutatingadmissionpolicy.go | 48 + .../v1/mutatingadmissionpolicybinding.go | 48 + .../v2beta1/expansion_generated.go | 27 - .../v2beta1/horizontalpodautoscaler.go | 70 - .../v2beta2/expansion_generated.go | 27 - .../v2beta2/horizontalpodautoscaler.go | 70 - .../resource/v1alpha3/expansion_generated.go | 4 + .../v1alpha3/resourcepoolstatusrequest.go | 48 + .../v1beta2/devicetaintrule.go} | 30 +- .../resource/v1beta2/expansion_generated.go | 4 + .../expansion_generated.go | 12 +- .../listers/scheduling/v1alpha2/podgroup.go | 70 + .../{v1alpha1 => v1alpha2}/workload.go | 18 +- .../plugin/pkg/client/auth/exec/exec.go | 20 +- vendor/k8s.io/client-go/testing/doc.go | 70 + vendor/k8s.io/client-go/testing/fixture.go | 122 +- .../third_party/forked/httpcache/LICENSE} | 0 .../forked}/httpcache/httpcache.go | 9 +- vendor/k8s.io/client-go/tools/cache/OWNERS | 1 + .../client-go/tools/cache/controller.go | 171 +- .../client-go/tools/cache/delta_fifo.go | 95 +- .../tools/cache/event_handler_name.go | 121 + .../client-go/tools/cache/expiration_cache.go | 12 +- vendor/k8s.io/client-go/tools/cache/fifo.go | 79 +- .../client-go/tools/cache/fifo_metrics.go | 122 + .../k8s.io/client-go/tools/cache/identity.go | 217 + .../k8s.io/client-go/tools/cache/reflector.go | 199 +- .../tools/cache/reflector_metrics.go | 6 + .../client-go/tools/cache/shared_informer.go | 350 +- vendor/k8s.io/client-go/tools/cache/store.go | 54 +- .../tools/cache/synctrack/synctrack.go | 132 +- .../client-go/tools/cache/the_real_fifo.go | 459 +- .../tools/cache/thread_safe_store.go | 128 +- .../client-go/tools/clientcmd/api/types.go | 6 +- .../tools/clientcmd/client_config.go | 2 + .../client-go/tools/clientcmd/config.go | 1 + .../client-go/tools/clientcmd/loader.go | 2 + .../tools/clientcmd/merged_client_builder.go | 2 + .../tools/leaderelection/leaderelection.go | 42 +- .../tools/leaderelection/leasecandidate.go | 21 +- .../leaderelection/resourcelock/leaselock.go | 2 +- .../k8s.io/client-go/tools/metrics/metrics.go | 78 +- .../tools/portforward/fallback_dialer.go | 31 + .../tools/portforward/portforward.go | 98 + .../tools/portforward/tunneling_dialer.go | 65 +- vendor/k8s.io/client-go/tools/record/event.go | 5 +- .../tools/remotecommand/errorstream.go | 5 +- .../client-go/tools/remotecommand/fallback.go | 2 +- .../tools/remotecommand/remotecommand.go | 5 +- .../client-go/tools/remotecommand/spdy.go | 9 +- .../client-go/tools/remotecommand/v1.go | 12 +- .../client-go/tools/remotecommand/v2.go | 35 +- .../client-go/tools/remotecommand/v3.go | 21 +- .../client-go/tools/remotecommand/v4.go | 17 +- .../client-go/tools/remotecommand/v5.go | 6 +- .../tools/remotecommand/websocket.go | 57 +- .../client-go/tools/watch/retrywatcher.go | 2 +- .../k8s.io/client-go/transport/ca_rotation.go | 154 + vendor/k8s.io/client-go/transport/cache.go | 153 +- vendor/k8s.io/client-go/transport/config.go | 3 +- .../client-go/transport/round_trippers.go | 2 +- .../k8s.io/client-go/transport/spdy/spdy.go | 214 +- .../k8s.io/client-go/transport/transport.go | 25 +- .../transport/websocket/roundtripper.go | 4 +- .../client-go/util/certificate/csr/csr.go | 4 +- .../client-go/util/watchlist/watch_list.go | 3 + vendor/k8s.io/cloud-provider/OWNERS | 10 +- .../controllers/node/config/types.go | 4 + .../controllers/node/config/v1alpha1/types.go | 4 + .../v1alpha1/zz_generated.conversion.go | 2 + .../cloud-provider/options/nodecontroller.go | 12 + .../k8s.io/cloud-provider/options/options.go | 4 +- .../k8s.io/cloud-provider/options/webhook.go | 89 +- .../fake/generator_fake_for_clientset.go | 10 +- .../cmd/deepcopy-gen/args/args.go | 3 - .../cmd/deepcopy-gen/generators/deepcopy.go | 16 +- .../cmd/defaulter-gen/generators/defaulter.go | 19 +- .../cmd/go-to-protobuf/protobuf/cmd.go | 6 +- .../cmd/go-to-protobuf/protobuf/package.go | 6 +- .../cmd/go-to-protobuf/protobuf/parser.go | 41 +- .../cmd/informer-gen/generators/factory.go | 171 +- .../generators/factoryinterface.go | 21 + .../cmd/informer-gen/generators/informer.go | 58 +- .../cmd/informer-gen/generators/types.go | 9 + vendor/k8s.io/code-generator/kube_codegen.sh | 34 + vendor/k8s.io/code-generator/tools.go | 1 - .../component-base/cli/flag/curves_flag.go | 50 + .../k8s.io/component-base/cli/withoutrace.go | 1 - vendor/k8s.io/component-base/cli/withrace.go | 1 - vendor/k8s.io/component-base/configz/OWNERS | 4 - .../k8s.io/component-base/configz/configz.go | 41 +- .../featuregate/feature_gate.go | 108 +- .../logs/api/v1/options_no_slog.go | 1 - .../logs/api/v1/options_slog.go | 1 - vendor/k8s.io/component-base/metrics/OWNERS | 3 +- .../component-base/metrics/api/v1/config.go | 127 + .../component-base/metrics/api/v1/doc.go | 34 + .../component-base/metrics/api/v1/types.go | 39 + .../metrics/api/v1/zz_generated.deepcopy.go | 50 + vendor/k8s.io/component-base/metrics/desc.go | 2 +- .../metrics/features/kube_features.go | 26 +- .../component-base/metrics/histogram.go | 23 +- .../metrics/internal/nativehistograms.go | 57 + .../k8s.io/component-base/metrics/metric.go | 4 +- .../k8s.io/component-base/metrics/options.go | 257 +- vendor/k8s.io/component-base/metrics/opts.go | 82 +- .../metrics/processstarttime_others.go | 1 - .../metrics/processstarttime_windows.go | 1 - .../metrics/prometheus/workqueue/metrics.go | 14 +- .../k8s.io/component-base/metrics/registry.go | 73 +- .../metrics/testutil/metrics.go | 5 + .../metrics/testutil/testutil.go | 73 + .../k8s.io/component-base/metrics/version.go | 2 +- vendor/k8s.io/component-base/version/base.go | 2 +- .../zpages/features/kube_features.go | 3 + .../nodedeclaredfeatures/.mockery.yaml | 13 - .../nodedeclaredfeatures/OWNERS | 10 + .../nodedeclaredfeatures/bitmap.go | 125 + .../nodedeclaredfeatures/features/OWNERS | 6 + .../extendwebsocketstokubelet/feature.go | 62 + .../inplacepodresize/guaranteed_cpu_resize.go | 85 - .../nonsidecar_initcontainers_resize.go | 72 + .../pod_level_resource_resize.go | 21 +- .../nodedeclaredfeatures/features/registry.go | 10 +- .../restart_all_containers.go | 16 +- .../user_namespaces_host_network.go | 77 + .../nodedeclaredfeatures/featureset.go | 110 + .../nodedeclaredfeatures/framework.go | 107 +- .../nodedeclaredfeatures/types.go | 68 +- .../nodedeclaredfeatures/types/types.go | 108 + .../component-helpers/resource/helpers.go | 12 + .../pkg/features/kube_features.go | 8 + .../cri-api/pkg/apis/runtime/v1/api.pb.go | 4613 +++++++------ .../cri-api/pkg/apis/runtime/v1/api.proto | 199 +- .../pkg/apis/runtime/v1/api_grpc.pb.go | 427 +- vendor/k8s.io/cri-api/pkg/apis/services.go | 4 +- .../pkg/apis/testing/fake_image_service.go | 2 +- .../pkg/apis/testing/fake_runtime_service.go | 2 +- .../pkg/connection_target.go} | 28 +- vendor/k8s.io/cri-client/pkg/logs/logs.go | 110 +- .../k8s.io/cri-client/pkg/logs/logs_other.go | 1 - .../cri-client/pkg/logs/logs_windows.go | 1 - vendor/k8s.io/cri-client/pkg/remote_image.go | 110 +- .../k8s.io/cri-client/pkg/remote_runtime.go | 481 +- .../k8s.io/cri-client/pkg/util/util_unix.go | 1 - .../cri-client/pkg/util/util_unsupported.go | 1 - .../cri-client/pkg/util/util_windows.go | 1 - .../cri-streaming/LICENSE} | 0 .../pkg/streaming/.import-restrictions | 5 + .../pkg/streaming/doc.go} | 7 +- .../pkg}/streaming/errors.go | 0 .../internal/httpresponse/writer.go} | 38 +- .../pkg}/streaming/portforward/constants.go | 14 + .../pkg}/streaming/portforward/httpstream.go | 40 +- .../pkg}/streaming/portforward/portforward.go | 9 +- .../pkg}/streaming/portforward/websocket.go | 20 +- .../pkg}/streaming/remotecommand/attach.go | 16 +- .../pkg/streaming/remotecommand/constants.go | 75 + .../pkg}/streaming/remotecommand/doc.go | 0 .../pkg}/streaming/remotecommand/exec.go | 29 +- .../streaming/remotecommand/httpstream.go | 101 +- .../pkg/streaming/remotecommand/resize.go} | 9 +- .../pkg/streaming/remotecommand/status.go | 71 + .../pkg}/streaming/remotecommand/websocket.go | 8 +- .../pkg}/streaming/request_cache.go | 0 .../pkg}/streaming/server.go | 21 +- .../dynamic-resource-allocation/api/OWNERS | 1 + .../dynamic-resource-allocation/api/types.go | 25 +- .../api/zz_generated.conversion.go | 2 + .../cel/compile.go | 168 +- .../extendedresourcecache.go | 3 + .../resourceclaim/resourceclaim.go | 159 +- .../resourceslice/tracker/tracker.go | 64 +- .../structured/allocator.go | 31 +- .../structured/internal/allocatedstate.go | 26 + .../experimental/allocator_experimental.go | 290 +- .../internal/experimental/constraint.go | 32 + .../experimental/pools_experimental.go | 165 +- .../incubating/allocator_incubating.go | 392 +- .../internal/incubating/constraint.go | 131 + .../incubating/consumable_capacity.go | 211 + .../internal/incubating/pools_incubating.go | 161 +- .../internal/stable/allocator_stable.go | 308 +- .../internal/stable/pools_stable.go | 394 +- .../structured/internal/types.go | 14 + .../structured/schedulerapi/types.go | 4 + vendor/k8s.io/klog/v2/ktesting/options.go | 132 + vendor/k8s.io/klog/v2/ktesting/setup.go | 38 + .../k8s.io/klog/v2/ktesting/testinglogger.go | 407 ++ .../v1/generated.protomessage.pb.go | 34 - .../v1beta1/generated.protomessage.pb.go | 34 - .../apiregistration/v1/apiservice.go | 292 + .../v1/apiservicecondition.go} | 45 +- .../apiregistration/v1/apiservicespec.go | 124 + .../apiregistration/v1/apiservicestatus.go | 47 + .../apiregistration/v1/servicereference.go | 64 + .../applyconfiguration/internal/internal.go | 369 ++ .../typed/apiregistration/v1/apiservice.go | 8 +- .../go-json-experiment/json/alias.go | 967 --- .../go-json-experiment/json/arshal.go | 2 - .../go-json-experiment/json/arshal_any.go | 2 - .../go-json-experiment/json/arshal_default.go | 2 - .../go-json-experiment/json/arshal_funcs.go | 2 - .../go-json-experiment/json/arshal_inlined.go | 2 - .../go-json-experiment/json/arshal_methods.go | 2 - .../go-json-experiment/json/arshal_time.go | 2 - .../go-json-experiment/json/doc.go | 2 - .../go-json-experiment/json/errors.go | 2 - .../go-json-experiment/json/fields.go | 2 - .../go-json-experiment/json/fold.go | 2 - .../go-json-experiment/json/intern.go | 2 - .../json/internal/internal.go | 2 - .../json/internal/jsonflags/flags.go | 2 - .../json/internal/jsonopts/options.go | 2 - .../json/internal/jsonwire/decode.go | 2 - .../json/internal/jsonwire/encode.go | 2 - .../json/internal/jsonwire/wire.go | 2 - .../go-json-experiment/json/jsontext/alias.go | 536 -- .../json/jsontext/decode.go | 2 - .../go-json-experiment/json/jsontext/doc.go | 2 - .../json/jsontext/encode.go | 2 - .../json/jsontext/errors.go | 2 - .../json/jsontext/export.go | 2 - .../json/jsontext/options.go | 2 - .../go-json-experiment/json/jsontext/pools.go | 2 - .../go-json-experiment/json/jsontext/quote.go | 2 - .../go-json-experiment/json/jsontext/state.go | 2 - .../go-json-experiment/json/jsontext/token.go | 2 - .../go-json-experiment/json/jsontext/value.go | 2 - .../go-json-experiment/json/options.go | 2 - .../kube-openapi/pkg/schemaconv/openapi.go | 5 +- .../k8s.io/kube-scheduler/config/v1/types.go | 10 +- .../config/v1/zz_generated.deepcopy.go | 2 + .../kube-scheduler/framework/cycle_state.go | 47 + .../kube-scheduler/framework/interface.go | 148 +- .../kube-scheduler/framework/listers.go | 60 +- .../kube-scheduler/framework/signers.go | 26 +- .../k8s.io/kube-scheduler/framework/types.go | 66 +- vendor/k8s.io/kubectl/pkg/drain/filters.go | 5 +- vendor/k8s.io/kubectl/pkg/scale/scale.go | 31 +- vendor/k8s.io/kubectl/pkg/scheme/install.go | 2 - vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go | 4 +- .../kubectl/pkg/util/term/resizeevents.go | 1 - vendor/k8s.io/kubectl/pkg/util/term/term.go | 25 + vendor/k8s.io/kubelet/config/v1beta1/types.go | 44 +- .../config/v1beta1/zz_generated.deepcopy.go | 5 + .../pkg/apis/dra-health/v1alpha1/api.pb.go | 61 +- .../pkg/apis/dra-health/v1alpha1/api.proto | 5 + .../kubelet/pkg/apis/pods/v1alpha1/api.pb.go | 471 ++ .../kubelet/pkg/apis/pods/v1alpha1/api.proto | 61 + .../pkg/apis/pods/v1alpha1/api_grpc.pb.go | 227 + .../pkg/cri/streaming/.import-restrictions | 5 - .../k8s.io/kubernetes/cmd/kubelet/app/auth.go | 19 +- .../kubernetes/cmd/kubelet/app/init_others.go | 1 - .../cmd/kubelet/app/init_windows.go | 1 - .../kubelet/app/options/globalflags_linux.go | 1 - .../kubelet/app/options/globalflags_other.go | 1 - .../cmd/kubelet/app/options/options.go | 11 +- .../cmd/kubelet/app/options/osflags_others.go | 1 - .../kubelet/app/options/osflags_windows.go | 1 - .../kubernetes/cmd/kubelet/app/plugins.go | 9 +- .../cmd/kubelet/app/plugins_providers.go | 70 - .../kubernetes/cmd/kubelet/app/server.go | 152 +- .../cmd/kubelet/app/server_others.go | 1 - .../cmd/kubelet/app/server_unsupported.go | 1 - .../cmd/kubelet/app/server_windows.go | 1 - vendor/k8s.io/kubernetes/pkg/api/pod/util.go | 188 +- .../kubernetes/pkg/api/service/warnings.go | 5 + .../pkg/apis/autoscaling/annotations.go | 8 +- .../kubernetes/pkg/apis/autoscaling/types.go | 2 + .../kubernetes/pkg/apis/certificates/types.go | 44 +- .../certificates/zz_generated.deepcopy.go | 5 + .../pkg/apis/core/helper/helpers.go | 3 + .../k8s.io/kubernetes/pkg/apis/core/types.go | 172 +- .../pkg/apis/core/v1/helper/qos/qos.go | 13 +- .../apis/core/v1/zz_generated.conversion.go | 168 +- .../apis/core/v1/zz_generated.validations.go | 40 +- .../pkg/apis/core/validation/validation.go | 246 +- .../pkg/apis/core/zz_generated.deepcopy.go | 132 +- .../pkg/apis/scheduling/register.go | 2 + .../kubernetes/pkg/apis/scheduling/types.go | 400 +- .../apis/scheduling/zz_generated.deepcopy.go | 295 +- .../pkg/controller/controller_utils.go | 14 +- .../controller/daemon/daemon_controller.go | 103 +- .../pkg/controller/daemon/metrics/metrics.go | 48 + .../util/consistency/consistency.go | 217 + .../kubernetes/pkg/features/kube_features.go | 466 +- .../kubelet/allocation/allocation_manager.go | 273 +- .../pkg/kubelet/allocation/features_linux.go | 5 - .../allocation/features_unsupported.go | 1 - .../kubelet/allocation/features_windows.go | 1 - .../pkg/kubelet/allocation/handlers.go | 151 + .../pkg/kubelet/allocation/state/state.go | 3 +- .../allocation/state/state_checkpoint.go | 31 +- .../pkg/kubelet/allocation/state/state_mem.go | 25 +- .../pkg/kubelet/apis/config/types.go | 36 +- .../kubelet/apis/config/v1beta1/defaults.go | 6 +- .../config/v1beta1/zz_generated.conversion.go | 4 + .../apis/config/validation/validation.go | 14 + .../config/validation/validation_linux.go | 1 - .../config/validation/validation_others.go | 1 - .../config/validation/validation_windows.go | 1 - .../apis/config/zz_generated.deepcopy.go | 5 + .../pkg/kubelet/apis/podresources/OWNERS | 10 + .../kubelet/apis/podresources/server_v1.go | 19 +- .../pkg/kubelet/apis/pods/constants.go | 26 + .../pkg/kubelet/apis/pods/server.go | 348 + .../pkg/kubelet/cadvisor/cadvisor_linux.go | 41 +- .../kubelet/cadvisor/cadvisor_unsupported.go | 8 +- .../pkg/kubelet/cadvisor/cadvisor_windows.go | 8 +- .../pkg/kubelet/cadvisor/helpers_linux.go | 1 - .../kubelet/cadvisor/helpers_unsupported.go | 1 - .../pkg/kubelet/cm/admission/errors.go | 23 +- .../pkg/kubelet/cm/cgroup_manager_linux.go | 4 +- .../kubelet/cm/cgroup_manager_unsupported.go | 1 - .../pkg/kubelet/cm/container_manager.go | 15 +- .../pkg/kubelet/cm/container_manager_linux.go | 90 +- .../cm/container_manager_unsupported.go | 1 - .../kubelet/cm/container_manager_windows.go | 11 +- .../pkg/kubelet/cm/cpumanager/cpu_manager.go | 51 +- .../cm/cpumanager/cpu_manager_others.go | 1 - .../cm/cpumanager/cpu_manager_windows.go | 1 - .../kubelet/cm/cpumanager/fake_cpu_manager.go | 19 +- .../pkg/kubelet/cm/cpumanager/policy.go | 2 + .../pkg/kubelet/cm/cpumanager/policy_none.go | 4 + .../kubelet/cm/cpumanager/policy_options.go | 2 +- .../kubelet/cm/cpumanager/policy_static.go | 375 +- .../kubelet/cm/cpumanager/state/checkpoint.go | 90 +- .../pkg/kubelet/cm/cpumanager/state/state.go | 62 +- .../cm/cpumanager/state/state_checkpoint.go | 258 +- .../kubelet/cm/cpumanager/state/state_mem.go | 69 +- .../pkg/kubelet/cm/devicemanager/manager.go | 43 +- .../cm/devicemanager/plugin/v1beta1/client.go | 2 +- .../cm/devicemanager/topology_hints.go | 43 +- .../pkg/kubelet/cm/devicemanager/types.go | 3 + .../kubernetes/pkg/kubelet/cm/dra/OWNERS | 3 + .../pkg/kubelet/cm/dra/claiminfo.go | 12 +- .../pkg/kubelet/cm/dra/healthinfo.go | 40 +- .../kubernetes/pkg/kubelet/cm/dra/manager.go | 382 +- .../pkg/kubelet/cm/dra/plugin/dra_plugin.go | 84 +- .../cm/dra/plugin/dra_plugin_manager.go | 8 +- .../pkg/kubelet/cm/dra/state/state.go | 4 + .../pkg/kubelet/cm/fake_container_manager.go | 7 +- .../kubernetes/pkg/kubelet/cm/helpers.go | 3 +- .../pkg/kubelet/cm/helpers_linux.go | 34 +- .../pkg/kubelet/cm/helpers_unsupported.go | 4 +- .../cm/internal_container_lifecycle_linux.go | 1 - ...nternal_container_lifecycle_unsupported.go | 1 - .../internal_container_lifecycle_windows.go | 1 - .../cm/memorymanager/fake_memory_manager.go | 6 + .../cm/memorymanager/memory_manager.go | 19 + .../pkg/kubelet/cm/memorymanager/policy.go | 2 + .../cm/memorymanager/policy_best_effort.go | 8 +- .../kubelet/cm/memorymanager/policy_none.go | 4 + .../kubelet/cm/memorymanager/policy_static.go | 528 +- .../cm/memorymanager/state/checkpoint.go | 109 +- .../kubelet/cm/memorymanager/state/state.go | 18 + .../memorymanager/state/state_checkpoint.go | 173 +- .../cm/memorymanager/state/state_mem.go | 75 +- .../cm/node_container_manager_linux.go | 7 +- .../kubelet/cm/pod_container_manager_linux.go | 28 +- .../kubernetes/pkg/kubelet/cm/qos/doc.go | 21 + .../kubernetes/pkg/kubelet/cm/qos/helpers.go | 43 + .../pkg/kubelet/cm/qos/types.go} | 24 +- .../kubelet/cm/qos_container_manager_linux.go | 109 +- .../topologymanager/fake_topology_manager.go | 14 +- .../pkg/kubelet/cm/topologymanager/scope.go | 22 +- .../cm/topologymanager/scope_container.go | 8 +- .../kubelet/cm/topologymanager/scope_none.go | 2 +- .../kubelet/cm/topologymanager/scope_pod.go | 82 +- .../cm/topologymanager/topology_manager.go | 37 +- .../kubelet/cm/util/cgroups_unsupported.go | 1 - .../pkg/kubelet/config/apiserver.go | 7 +- .../kubernetes/pkg/kubelet/config/config.go | 188 +- .../kubernetes/pkg/kubelet/config/file.go | 13 +- .../pkg/kubelet/config/file_linux.go | 6 +- .../pkg/kubelet/config/file_unsupported.go | 1 - .../kubernetes/pkg/kubelet/config/http.go | 11 +- .../kubernetes/pkg/kubelet/config/mux.go | 12 +- .../kubernetes/pkg/kubelet/container/cache.go | 44 +- .../pkg/kubelet/container/helpers.go | 24 +- .../pkg/kubelet/container/runtime.go | 25 +- .../pkg/kubelet/container/sync_result.go | 4 - .../kubelet/container/testing/fake_cache.go | 9 +- .../kubelet/container/testing/fake_runtime.go | 23 +- .../container/testing/fake_runtime_helper.go | 18 +- .../pkg/kubelet/container/testing/mocks.go | 110 +- .../kubernetes/pkg/kubelet/events/event.go | 1 + .../kubernetes/pkg/kubelet/events/resize.go | 24 +- .../pkg/kubelet/eviction/defaults_linux.go | 1 - .../pkg/kubelet/eviction/defaults_others.go | 1 - .../pkg/kubelet/eviction/defaults_windows.go | 1 - .../pkg/kubelet/eviction/eviction_manager.go | 2 +- .../pkg/kubelet/eviction/helpers_others.go | 1 - .../pkg/kubelet/eviction/helpers_windows.go | 1 - .../memory_threshold_notifier_others.go | 1 - .../memory_threshold_notifier_windows.go | 1 - .../threshold_notifier_unsupported.go | 1 - .../pkg/kubelet/images/image_gc_manager.go | 5 +- .../pkg/kubelet/images/image_manager.go | 3 +- .../kubernetes/pkg/kubelet/images/metrics.go | 4 +- .../images/pullmanager/fs_pullrecords.go | 22 +- .../images/pullmanager/image_pull_manager.go | 19 +- .../images/pullmanager/image_pull_policies.go | 51 +- .../kubelet/images/pullmanager/interfaces.go | 11 +- .../images/pullmanager/mem_pullrecords.go | 30 +- .../pkg/kubelet/images/pullmanager/metrics.go | 54 +- .../images/pullmanager/noop_pull_manager.go | 3 +- .../k8s.io/kubernetes/pkg/kubelet/kubelet.go | 787 ++- .../kubernetes/pkg/kubelet/kubelet_getters.go | 46 +- .../kubernetes/pkg/kubelet/kubelet_network.go | 9 +- .../pkg/kubelet/kubelet_network_linux.go | 25 +- .../pkg/kubelet/kubelet_network_others.go | 5 +- .../kubelet/kubelet_node_declared_features.go | 14 +- .../pkg/kubelet/kubelet_node_status.go | 110 +- .../pkg/kubelet/kubelet_node_status_others.go | 1 - .../kubelet/kubelet_node_status_windows.go | 1 - .../pkg/kubelet/kubelet_nodecache.go | 2 +- .../kubernetes/pkg/kubelet/kubelet_pods.go | 356 +- .../pkg/kubelet/kubelet_resources.go | 5 +- .../pkg/kubelet/kubelet_server_journal.go | 2 +- .../kubernetes/pkg/kubelet/kubelet_volumes.go | 28 +- .../pkg/kubelet/kubeletconfig/defaults.go | 1 + .../pkg/kubelet/kuberuntime/convert.go | 4 +- .../kuberuntime/fake_kuberuntime_manager.go | 6 +- .../pkg/kubelet/kuberuntime/helpers.go | 47 +- .../pkg/kubelet/kuberuntime/helpers_linux.go | 22 +- .../kuberuntime/helpers_unsupported.go | 1 - .../kuberuntime/instrumented_services.go | 10 +- .../kuberuntime/kuberuntime_container.go | 136 +- .../kuberuntime_container_linux.go | 21 +- .../kuberuntime_container_unsupported.go | 1 - .../kuberuntime_container_windows.go | 1 - .../pkg/kubelet/kuberuntime/kuberuntime_gc.go | 8 +- .../kubelet/kuberuntime/kuberuntime_image.go | 8 +- .../kubelet/kuberuntime/kuberuntime_logs.go | 19 +- .../kuberuntime/kuberuntime_manager.go | 352 +- .../kuberuntime/kuberuntime_sandbox.go | 51 +- .../kuberuntime/kuberuntime_sandbox_linux.go | 1 - .../kuberuntime_sandbox_unsupported.go | 1 - .../kuberuntime_sandbox_windows.go | 1 - .../kubelet/kuberuntime/security_context.go | 5 +- .../kuberuntime/security_context_others.go | 1 - .../kuberuntime/security_context_windows.go | 1 - .../pkg/kubelet/kuberuntime/util/util.go | 5 +- .../pkg/kubelet/lifecycle/features_linux.go | 1 - .../kubelet/lifecycle/features_unsupported.go | 1 - .../pkg/kubelet/lifecycle/features_windows.go | 1 - .../pkg/kubelet/lifecycle/handlers.go | 16 +- .../pkg/kubelet/lifecycle/interfaces.go | 14 +- .../pkg/kubelet/lifecycle/predicate.go | 18 + .../kubernetes/pkg/kubelet/managed/managed.go | 9 +- .../kubernetes/pkg/kubelet/metrics/metrics.go | 130 +- .../kubernetes/pkg/kubelet/network/dns/dns.go | 22 +- .../pkg/kubelet/network/dns/dns_other.go | 1 - .../pkg/kubelet/network/dns/dns_windows.go | 1 - .../nodeshutdown/nodeshutdown_manager.go | 6 +- .../nodeshutdown_manager_linux.go | 14 +- .../nodeshutdown_manager_others.go | 1 - .../nodeshutdown_manager_windows.go | 8 +- .../nodeshutdown/systemd/inhibit_linux.go | 1 - .../nodeshutdown/systemd/inhibit_others.go | 1 - .../pkg/kubelet/nodestatus/setters.go | 28 +- .../pkg/kubelet/oom/oom_watcher_linux.go | 9 +- .../kubelet/oom/oom_watcher_unsupported.go | 1 - .../kubernetes/pkg/kubelet/pleg/evented.go | 8 +- .../kubernetes/pkg/kubelet/pleg/generic.go | 391 +- .../kubernetes/pkg/kubelet/pleg/pleg.go | 27 +- .../operationexecutor/operation_generator.go | 3 + .../kubelet/pluginmanager/plugin_manager.go | 2 +- .../pluginwatcher/plugin_watcher_others.go | 1 - .../pluginwatcher/plugin_watcher_windows.go | 1 - .../kubernetes/pkg/kubelet/pod_workers.go | 208 +- .../podcertificate/podcertificatemanager.go | 133 +- .../kubernetes/pkg/kubelet/prober/prober.go | 6 +- .../pkg/kubelet/prober/prober_manager.go | 2 +- .../kubernetes/pkg/kubelet/prober/worker.go | 22 +- .../k8s.io/kubernetes/pkg/kubelet/runtime.go | 7 +- .../kubernetes/pkg/kubelet/server/auth.go | 7 +- .../pkg/kubelet/server/metrics/metrics.go | 44 + .../kubernetes/pkg/kubelet/server/server.go | 165 +- .../pkg/kubelet/server/stats/handler.go | 2 +- .../pkg/kubelet/server/stats/summary.go | 4 +- .../server/stats/summary_sys_containers.go | 1 - .../stats/summary_sys_containers_windows.go | 1 - .../pkg/kubelet/stats/cri_stats_provider.go | 55 +- .../kubelet/stats/cri_stats_provider_linux.go | 22 +- .../stats/cri_stats_provider_others.go | 7 +- .../stats/cri_stats_provider_windows.go | 66 +- .../kubelet/stats/pidlimit/pidlimit_linux.go | 1 - .../stats/pidlimit/pidlimit_unsupported.go | 1 - .../pkg/kubelet/status/status_manager.go | 149 +- .../pkg/kubelet/types/pod_update.go | 4 +- .../kubernetes/pkg/kubelet/userns/types.go | 7 +- .../pkg/kubelet/userns/userns_manager.go | 6 +- .../kubelet/userns/userns_manager_windows.go | 2 +- .../pkg/kubelet/util/boottime_util_darwin.go | 1 - .../pkg/kubelet/util/boottime_util_freebsd.go | 1 - .../pkg/kubelet/util/boottime_util_linux.go | 1 - .../util/manager/cache_based_manager.go | 7 +- .../util/pod_startup_latency_tracker.go | 196 +- .../kubernetes/pkg/kubelet/util/util.go | 6 +- .../kubernetes/pkg/kubelet/util/util_linux.go | 1 - .../pkg/kubelet/util/util_others.go | 1 - .../kubernetes/pkg/kubelet/util/util_unix.go | 1 - .../pkg/kubelet/util/util_unsupported.go | 1 - .../pkg/kubelet/util/util_windows.go | 1 - .../kubernetes/pkg/kubelet/volume_host.go | 13 +- .../kubelet/volumemanager/volume_manager.go | 28 +- .../pkg/kubelet/watchdog/watchdog_linux.go | 1 - .../kubelet/watchdog/watchdog_unsupported.go | 1 - .../pkg/kubelet/winstats/cpu_topology.go | 1 - .../pkg/kubelet/winstats/network_stats.go | 1 - .../winstats/perfcounter_nodestats_windows.go | 1 - .../pkg/kubelet/winstats/perfcounters.go | 1 - .../pkg/kubelet/winstats/version.go | 1 - .../pkg/kubelet/winstats/winstats.go | 1 - .../kubernetes/pkg/kubemark/hollow_kubelet.go | 2 - .../kubernetes/pkg/probe/dialer_others.go | 1 - .../kubernetes/pkg/probe/dialer_windows.go | 1 - .../pkg/scheduler/apis/config/types.go | 12 +- .../apis/config/v1/default_plugins.go | 10 + .../pkg/scheduler/apis/config/v1/defaults.go | 2 + .../apis/config/v1/zz_generated.conversion.go | 12 + .../validation/validation_pluginargs.go | 12 +- .../apis/config/zz_generated.deepcopy.go | 2 + .../pkg/scheduler/backend/cache/cache.go | 301 +- .../backend/cache/debugger/signal.go | 1 - .../pkg/scheduler/backend/cache/interface.go | 50 +- .../scheduler/backend/cache/podgroupstate.go | 397 ++ .../pkg/scheduler/backend/cache/snapshot.go | 291 +- .../scheduler/backend/queue/active_queue.go | 66 +- .../backend/queue/scheduling_queue.go | 156 +- .../backend/queue/unschedulable_pods.go | 46 +- .../backend/workloadmanager/podgroupinfo.go | 197 - .../workloadmanager/workloadmanager.go | 129 - .../kubernetes/pkg/scheduler/eventhandlers.go | 62 +- .../pkg/scheduler/framework/cycle_state.go | 41 + .../pkg/scheduler/framework/interface.go | 44 +- .../framework/parallelize/error_channel.go | 59 - .../framework/parallelize/result_channel.go | 60 + .../defaultpreemption/default_preemption.go | 69 +- .../dynamicresources/allocateddevices.go | 7 + .../plugins/dynamicresources/claims.go | 23 +- .../plugins/dynamicresources/dra_manager.go | 279 +- .../dynamicresources/dynamicresources.go | 635 +- .../extendeddynamicresources.go | 22 +- .../nodeallocatabledynamicresources.go | 449 ++ .../framework/plugins/feature/feature.go | 14 +- .../plugins/gangscheduling/gangscheduling.go | 167 +- .../framework/plugins/helper/podgroup.go} | 21 +- .../plugins/imagelocality/image_locality.go | 11 +- .../plugins/interpodaffinity/plugin.go | 40 +- .../framework/plugins/names/names.go | 2 + .../nodedeclaredfeatures.go | 23 +- .../noderesources/balanced_allocation.go | 36 +- .../framework/plugins/noderesources/fit.go | 117 +- .../plugins/noderesources/least_allocated.go | 4 +- .../plugins/noderesources/most_allocated.go | 4 +- .../requested_to_capacity_ratio.go | 6 +- .../noderesources/resource_allocation.go | 106 +- .../plugins/noderesources/test_util.go | 57 - .../framework/plugins/nodevolumelimits/csi.go | 71 +- .../plugins/nodevolumelimits/utils.go | 28 +- .../podgrouppodscount/podgroup_pods_count.go | 87 + .../plugins/podtopologyspread/plugin.go | 9 +- .../scheduler/framework/plugins/registry.go | 4 + .../topologyaware/topology_placement.go | 142 + .../framework/plugins/volumebinding/binder.go | 8 +- .../plugins/volumebinding/volume_binding.go | 11 +- .../framework/preemption/executor.go | 512 ++ .../preemption/podgrouppreemption.go | 289 + .../framework/preemption/preemption.go | 455 +- .../scheduler/framework/preemption/types.go | 276 + .../pkg/scheduler/framework/runtime/batch.go | 41 +- .../scheduler/framework/runtime/framework.go | 534 +- .../framework/runtime/pods_in_prebind_map.go | 98 + .../framework/runtime/waiting_pods_map.go | 25 +- .../pkg/scheduler/framework/types.go | 164 +- .../pkg/scheduler/metrics/metric_recorder.go | 6 + .../pkg/scheduler/metrics/metrics.go | 128 +- .../pkg/scheduler/metrics/profile_metrics.go | 36 +- .../pkg/scheduler/profile/profile.go | 4 +- .../kubernetes/pkg/scheduler/schedule_one.go | 406 +- .../pkg/scheduler/schedule_one_podgroup.go | 779 +++ .../kubernetes/pkg/scheduler/scheduler.go | 48 +- .../util/assumecache/assume_cache.go | 26 +- .../kubernetes/pkg/scheduler/util/utils.go | 58 +- .../security/apparmor/validate_disabled.go | 1 - .../pkg/util/filesystem/util_unix.go | 1 - .../pkg/util/filesystem/util_windows.go | 1 - .../kubernetes/pkg/util/filesystem/watcher.go | 132 +- .../kubernetes/pkg/util/flock/flock_other.go | 1 - .../kubernetes/pkg/util/flock/flock_unix.go | 1 - .../k8s.io/kubernetes/pkg/util/hash/hash.go | 2 +- .../kubernetes/pkg/util/iptables/iptables.go | 1 - .../pkg/util/iptables/iptables_linux.go | 1 - .../pkg/util/iptables/save_restore.go | 1 - .../kubernetes/pkg/util/kernel/constants.go | 6 + .../kubernetes/pkg/util/oom/oom_linux.go | 1 - .../pkg/util/oom/oom_unsupported.go | 1 - .../pkg/util/rlimit/rlimit_linux.go | 1 - .../pkg/util/rlimit/rlimit_unsupported.go | 1 - .../k8s.io/kubernetes/pkg/util/slice/slice.go | 75 - .../kubernetes/pkg/volume/csi/csi_client.go | 3 + .../kubernetes/pkg/volume/csi/csi_mounter.go | 16 +- .../kubernetes/pkg/volume/csi/csi_plugin.go | 2 +- .../csi/nodeinfomanager/nodeinfomanager.go | 35 - .../pkg/volume/csimigration/plugin_manager.go | 22 +- .../pkg/volume/emptydir/empty_dir.go | 3 +- .../pkg/volume/emptydir/empty_dir_linux.go | 11 +- .../volume/emptydir/empty_dir_unsupported.go | 1 - .../pkg/volume/flexvolume/fake_watcher.go | 4 +- .../pkg/volume/flexvolume/plugin.go | 8 +- .../kubernetes/pkg/volume/flexvolume/probe.go | 7 +- .../kubernetes/pkg/volume/iscsi/iscsi.go | 2 +- .../k8s.io/kubernetes/pkg/volume/plugins.go | 3 - .../kubernetes/pkg/volume/portworx/OWNERS | 9 - .../kubernetes/pkg/volume/portworx/doc.go | 19 - .../pkg/volume/portworx/portworx.go | 464 -- .../pkg/volume/portworx/portworx_util.go | 387 -- .../pkg/volume/util/atomic_writer.go | 13 +- .../pkg/volume/util/atomic_writer_linux.go | 8 +- .../volume/util/atomic_writer_unsupported.go | 6 +- .../pkg/volume/util/attach_limit.go | 48 - .../pkg/volume/util/device_util_linux.go | 1 - .../volume/util/device_util_unsupported.go | 1 - .../kubernetes/pkg/volume/util/fs/fs.go | 1 - .../pkg/volume/util/fs/fs_unsupported.go | 1 - .../pkg/volume/util/fs/fs_windows.go | 1 - .../util/fsquota/common/quota_common_linux.go | 1 - .../fsquota/common/quota_common_linux_impl.go | 1 - .../pkg/volume/util/fsquota/project.go | 1 - .../pkg/volume/util/fsquota/quota_linux.go | 1 - .../volume/util/fsquota/quota_unsupported.go | 1 - .../volume/util/hostutil/hostutil_linux.go | 14 +- .../util/hostutil/hostutil_unsupported.go | 1 - .../volume/util/hostutil/hostutil_windows.go | 1 - .../util/operationexecutor/node_expander.go | 4 +- .../operationexecutor/operation_generator.go | 67 +- .../pkg/volume/util/subpath/subpath_linux.go | 1 - .../util/subpath/subpath_unsupported.go | 1 - .../volume/util/subpath/subpath_windows.go | 1 - .../k8s.io/kubernetes/pkg/volume/util/util.go | 8 +- .../volume_path_handler_linux.go | 1 - .../volume_path_handler_unsupported.go | 1 - .../pkg/volume/validation/pv_validation.go | 7 +- vendor/k8s.io/kubernetes/pkg/volume/volume.go | 11 + .../kubernetes/pkg/volume/volume_linux.go | 1 - .../pkg/volume/volume_unsupported.go | 1 - .../kubernetes/pkg/windows/service/service.go | 1 - .../test/e2e/common/node/container_probe.go | 18 +- .../common/node/container_restart_policy.go | 555 ++ .../test/e2e/common/node/downwardapi.go | 4 +- .../test/e2e/common/node/file_key.go | 3 +- .../common/node/framework/cgroups/cgroups.go | 80 +- .../common/node/framework/podresize/resize.go | 38 +- .../common/node/image_credential_provider.go | 2 +- .../test/e2e/common/node/image_volume.go | 123 + .../test/e2e/common/node/lifecycle_hook.go | 232 +- .../test/e2e/common/node/node_lease.go | 2 +- .../e2e/common/node/pod_hostnameoverride.go | 4 +- .../e2e/common/node/pod_level_resources.go | 10 +- .../common/node/pod_level_resources_resize.go | 49 +- .../test/e2e/common/node/pod_resize.go | 165 +- .../kubernetes/test/e2e/common/node/pods.go | 4 +- .../test/e2e/common/node/runtime.go | 2 +- .../test/e2e/common/node/security_context.go | 136 +- .../e2e/common/storage/configmap_volume.go | 10 +- .../e2e/common/storage/downwardapi_volume.go | 4 +- .../test/e2e/common/storage/empty_dir.go | 4 +- .../e2e/common/storage/projected_configmap.go | 10 +- .../common/storage/projected_downwardapi.go | 4 +- .../e2e/common/storage/projected_secret.go | 4 +- .../test/e2e/common/storage/secrets_volume.go | 4 +- vendor/k8s.io/kubernetes/test/e2e/e2e.go | 5 - .../kubernetes/test/e2e/feature/feature.go | 41 +- .../framework/debug/log_size_monitoring.go | 2 +- .../test/e2e/framework/framework.go | 116 +- .../test/e2e/framework/ginkgologger.go | 2 +- .../test/e2e/framework/ginkgowrapper.go | 166 +- .../e2e/framework/kubectl/kubectl_utils.go | 2 +- .../test/e2e/framework/network/utils.go | 19 +- .../test/e2e/framework/node/node_killer.go | 94 - .../test/e2e/framework/node/resource.go | 71 +- .../e2e/framework/node/util_sampledevice.go | 57 + .../kubernetes/test/e2e/framework/pod/dial.go | 8 +- .../test/e2e/framework/pod/exec_util.go | 23 +- .../test/e2e/framework/pod/output/output.go | 1 - .../test/e2e/framework/pod/pod_client.go | 22 +- .../kubernetes/test/e2e/framework/pv/pv.go | 2 +- .../test/e2e/framework/registry/registry.go | 4 + .../kubernetes/test/e2e/framework/ssh/ssh.go | 24 +- .../test/e2e/framework/test_context.go | 38 +- .../test/e2e/framework/volume/fixtures.go | 20 +- .../test/e2e/invariants/logcheck/logcheck.go | 667 ++ .../test/e2e/invariants/logcheck/waitgroup.go | 91 + .../k8s.io/kubernetes/test/e2e/patch_e2e.go | 2 + .../drivers/csi-test/mock/service/service.go | 8 +- .../test/e2e/storage/drivers/csi.go | 37 +- .../openshift_group_snapshot_driver.go | 18 + .../test/e2e/storage/drivers/proxy/io.go | 6 +- .../e2e/storage/drivers/proxy/portproxy.go | 4 +- .../storage/framework/snapshot_resource.go | 4 +- .../test/e2e/storage/framework/testdriver.go | 16 + .../test/e2e/storage/framework/testpattern.go | 41 +- .../volume_group_snapshot_resource.go | 638 +- .../test/e2e/storage/podlogs/podlogs.go | 184 +- .../test/e2e/storage/utils/create.go | 229 +- .../e2e/storage/utils/snapshot-metadata.go | 274 + .../test/e2e/storage/utils/utils.go | 61 + vendor/k8s.io/kubernetes/test/e2e/suites.go | 3 - .../test/e2e/testing-manifests/dra/OWNERS | 1 + .../dra/dra-test-driver-proxy.yaml | 2 +- .../kubectl/agnhost-primary-pod.yaml | 4 +- .../statefulset/etcd/statefulset.yaml | 2 +- .../backup-client-rbac.yaml | 47 + ...orage.k8s.io_snapshotmetadataservices.yaml | 76 + .../external-snapshot-metadata/rbac.yaml | 42 + .../run_snapshot_metadata_e2e.sh | 325 + .../csi-hostpath-plugin.yaml | 16 +- .../storage-csi/gce-pd/controller_ss.yaml | 6 +- .../storage-csi/gce-pd/node_ds.yaml | 2 +- .../hostpath/csi-hostpath-plugin.yaml | 37 +- .../hostpath/csi-hostpath-testing.yaml | 2 +- .../mock/csi-mock-driver-attacher.yaml | 2 +- .../mock/csi-mock-driver-resizer.yaml | 2 +- .../mock/csi-mock-driver-snapshotter.yaml | 2 +- .../storage-csi/mock/csi-mock-driver.yaml | 6 +- .../storage-csi/mock/csi-mock-proxy.yaml | 6 +- vendor/k8s.io/kubernetes/test/utils/audit.go | 36 +- .../kubernetes/test/utils/density_utils.go | 4 +- .../kubernetes/test/utils/deployment.go | 2 +- .../kubernetes/test/utils/image/manifest.go | 44 +- .../kubernetes/test/utils/ktesting/assert.go | 349 + .../test/utils/ktesting/clientcontext.go | 53 + .../test/utils/ktesting/contexthelper.go | 105 + .../kubernetes/test/utils/ktesting/doc.go | 32 + .../test/utils/ktesting/errorcontext.go | 245 + .../utils/ktesting/initoption/initoption.go | 40 + .../test/utils/ktesting/internal/config.go} | 10 +- .../test/utils/ktesting/klogcontext.go} | 25 +- .../test/utils/ktesting/ktesting.go | 55 + .../kubernetes/test/utils/ktesting/signals.go | 236 + .../test/utils/ktesting/signals_non_win.go} | 18 +- .../test/utils/ktesting/signals_win.go} | 14 +- .../test/utils/ktesting/stepcontext.go | 77 + .../test/utils/ktesting/tcontext.go | 595 ++ .../test/utils/ktesting/withcontext.go | 73 + .../k8s.io/kubernetes/test/utils/runners.go | 6 +- .../kubernetes/test/utils/update_resources.go | 2 +- .../apparmor/apparmor_unsupported.go | 1 - .../k8s.io/mount-utils/mount_helper_unix.go | 1 - .../mount-utils/mount_helper_windows.go | 1 - vendor/k8s.io/mount-utils/mount_linux.go | 1 - .../k8s.io/mount-utils/mount_unsupported.go | 1 - vendor/k8s.io/mount-utils/mount_windows.go | 1 - vendor/k8s.io/mount-utils/resizefs_linux.go | 1 - .../mount-utils/resizefs_unsupported.go | 1 - .../pod-security-admission/policy/registry.go | 6 +- .../test/fixtures_procMount.go | 6 +- .../openstorage => k8s.io/streaming}/LICENSE | 13 +- .../pkg/httpstream}/doc.go | 9 +- .../streaming/pkg/httpstream/httpstream.go | 201 + .../pkg}/httpstream/spdy/connection.go | 4 +- .../pkg}/httpstream/spdy/roundtripper.go | 255 +- .../pkg}/httpstream/spdy/upgrade.go | 8 +- .../pkg}/httpstream/wsstream/conn.go | 44 +- .../streaming/pkg/httpstream/wsstream/doc.go | 69 + .../pkg}/httpstream/wsstream/stream.go | 28 +- .../k8s.io/streaming/pkg/runtime/runtime.go | 62 + vendor/k8s.io/utils/cpuset/cpuset.go | 4 +- vendor/k8s.io/utils/cpuset/numcpu.go | 50 + .../pkg/util => utils}/dump/dump.go | 6 +- vendor/k8s.io/utils/inotify/inotify_linux.go | 1 - .../forked/golang/golang-lru/lru.go | 16 +- .../third_party/forked/golang/net/ip.go | 2 +- vendor/k8s.io/utils/io/read.go | 2 +- vendor/k8s.io/utils/lru/lru.go | 6 +- vendor/k8s.io/utils/ptr/OWNERS | 2 + vendor/k8s.io/utils/ptr/ptr.go | 8 +- vendor/k8s.io/utils/strings/line_delimiter.go | 3 +- .../utils/third_party/forked/golang/LICENSE | 27 + .../utils/third_party/forked/golang/PATENTS | 22 + .../third_party/forked/golang/btree/LICENSE | 202 + .../third_party/forked/golang/btree/README.md | 7 + .../third_party/forked/golang/btree/btree.go | 856 +++ vendor/k8s.io/utils/trace/trace.go | 2 +- vendor/modules.txt | 422 +- .../proto/client/client.pb.go | 1 - .../pkg/client/apiutil/errors.go | 4 +- .../pkg/client/apiutil/restmapper.go | 3 +- .../pkg/client/applyconfigurations.go | 22 - .../controller-runtime/pkg/client/options.go | 13 +- .../pkg/client/typed_client.go | 53 +- .../controller-runtime/pkg/envtest/crd.go | 3 +- .../internal/testing/process/procattr_unix.go | 2 +- .../pkg/internal/testing/process/process.go | 6 +- .../internal/testing/process/signal_other.go} | 18 +- .../internal/testing/process/signal_unix.go} | 18 +- .../controller-runtime/pkg/scheme/scheme.go | 29 + .../kustomize/api/filters/nameref/nameref.go | 6 +- .../api/filters/replacement/replacement.go | 185 +- .../builtins/AnnotationsTransformer.go | 2 - .../internal/builtins/ConfigMapGenerator.go | 2 - .../api/internal/builtins/HashTransformer.go | 2 - .../builtins/HelmChartInflationGenerator.go | 29 +- .../internal/builtins/IAMPolicyGenerator.go | 2 - .../internal/builtins/ImageTagTransformer.go | 2 - .../api/internal/builtins/LabelTransformer.go | 2 - .../internal/builtins/NamespaceTransformer.go | 7 +- .../builtins/PatchJson6902Transformer.go | 2 - .../PatchStrategicMergeTransformer.go | 2 - .../api/internal/builtins/PatchTransformer.go | 23 +- .../internal/builtins/PrefixTransformer.go | 2 - .../builtins/ReplacementTransformer.go | 2 - .../builtins/ReplicaCountTransformer.go | 2 - .../api/internal/builtins/SecretGenerator.go | 2 - .../internal/builtins/SortOrderTransformer.go | 2 - .../internal/builtins/SuffixTransformer.go | 2 - .../internal/builtins/ValueAddTransformer.go | 2 - .../api/internal/loader/fileloader.go | 8 +- .../kustomize/api/internal/loader/loader.go | 2 +- .../internal/plugins/execplugin/execplugin.go | 10 +- .../api/internal/plugins/loader/loader.go | 2 +- .../api/internal/target/kusttarget.go | 25 +- .../target/kusttarget_configplugin.go | 18 +- .../kustomize/api/konfig/general.go | 3 + .../kustomize/api/resmap/reswrangler.go | 2 +- .../kustomize/api/resource/resource.go | 3 + .../sigs.k8s.io/kustomize/api/types/patch.go | 8 +- .../kustomize/api/types/patchargs.go | 13 + .../kustomize/api/types/replacement.go | 47 + .../kustomize/kyaml/filesys/filesystem.go | 4 +- .../kustomize/kyaml/fn/runtime/exec/exec.go | 2 +- .../kustomize/kyaml/kio/kioutil/kioutil.go | 2 +- .../kustomize/kyaml/kio/pkgio_reader.go | 4 +- .../kustomize/kyaml/runfn/runfn.go | 2 +- .../sigs.k8s.io/kustomize/kyaml/yaml/fns.go | 4 + .../sigs.k8s.io/kustomize/kyaml/yaml/match.go | 44 +- .../sigs.k8s.io/kustomize/kyaml/yaml/rnode.go | 31 +- .../v6/fieldpath/element.go | 28 +- .../v6/fieldpath/pathelementmap.go | 25 +- .../v6/fieldpath/serialize-pe.go | 18 +- .../v6/fieldpath/serialize.go | 11 + .../structured-merge-diff/v6/fieldpath/set.go | 24 +- .../v6/schema/elements.go | 4 + .../structured-merge-diff/v6/schema/equals.go | 3 + .../v6/schema/schemaschema.go | 3 + .../structured-merge-diff/v6/typed/remove.go | 33 +- .../v6/value/allocator.go | 80 +- .../v6/value/jsontagutil.go | 7 +- .../v6/value/reflectcache.go | 77 +- .../structured-merge-diff/v6/value/value.go | 5 + 2314 files changed, 99396 insertions(+), 65384 deletions(-) delete mode 100644 vendor/github.com/armon/circbuf/.gitignore delete mode 100644 vendor/github.com/armon/circbuf/LICENSE delete mode 100644 vendor/github.com/armon/circbuf/README.md delete mode 100644 vendor/github.com/armon/circbuf/circbuf.go rename vendor/github.com/aws/{aws-sdk-go => aws-sdk-go-v2}/aws/arn/arn.go (94%) delete mode 100644 vendor/github.com/aws/aws-sdk-go/NOTICE.txt delete mode 100644 vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go create mode 100644 vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go create mode 100644 vendor/github.com/godbus/dbus/v5/auth_default_other.go create mode 100644 vendor/github.com/godbus/dbus/v5/auth_default_windows.go rename vendor/github.com/godbus/dbus/v5/{auth_sha1.go => auth_sha1_windows.go} (95%) delete mode 100644 vendor/github.com/godbus/dbus/v5/homedir.go create mode 100644 vendor/github.com/google/cadvisor/fs/btrfs/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/btrfs/mount.go create mode 100644 vendor/github.com/google/cadvisor/fs/btrfs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/devicemapper/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/devicemapper/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/devicemapper/stats.go create mode 100644 vendor/github.com/google/cadvisor/fs/nfs/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/nfs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/overlay/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/overlay/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/tmpfs/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/tmpfs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/vfs/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/vfs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/vfs/stats.go create mode 100644 vendor/github.com/google/cadvisor/fs/zfs/install/install.go create mode 100644 vendor/github.com/google/cadvisor/fs/zfs/plugin.go create mode 100644 vendor/github.com/google/cadvisor/fs/zfs/stats.go create mode 100644 vendor/github.com/google/cadvisor/fs/zfs/watcher.go create mode 100644 vendor/github.com/google/cadvisor/utils/cpuload/cpuload_unsupported.go delete mode 100644 vendor/github.com/gregjones/httpcache/.travis.yml delete mode 100644 vendor/github.com/gregjones/httpcache/README.md rename vendor/github.com/grpc-ecosystem/{go-grpc-prometheus => go-grpc-middleware/providers/prometheus}/LICENSE (100%) create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/callmeta.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/grpcstatus.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.12-.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.13+.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go delete mode 100644 vendor/github.com/karrick/godirwalk/.gitignore delete mode 100644 vendor/github.com/karrick/godirwalk/LICENSE delete mode 100644 vendor/github.com/karrick/godirwalk/README.md delete mode 100644 vendor/github.com/karrick/godirwalk/azure-pipelines.yml delete mode 100644 vendor/github.com/karrick/godirwalk/bench.sh delete mode 100644 vendor/github.com/karrick/godirwalk/debug_development.go delete mode 100644 vendor/github.com/karrick/godirwalk/debug_release.go delete mode 100644 vendor/github.com/karrick/godirwalk/dirent.go delete mode 100644 vendor/github.com/karrick/godirwalk/doc.go delete mode 100644 vendor/github.com/karrick/godirwalk/inoWithFileno.go delete mode 100644 vendor/github.com/karrick/godirwalk/inoWithIno.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeType.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeTypeWithType.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeTypeWithoutType.go delete mode 100644 vendor/github.com/karrick/godirwalk/nameWithNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/nameWithoutNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir_unix.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir_windows.go delete mode 100644 vendor/github.com/karrick/godirwalk/reclenFromNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/reclenFromReclen.go delete mode 100644 vendor/github.com/karrick/godirwalk/scandir_unix.go delete mode 100644 vendor/github.com/karrick/godirwalk/scandir_windows.go delete mode 100644 vendor/github.com/karrick/godirwalk/scanner.go delete mode 100644 vendor/github.com/karrick/godirwalk/walk.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/README.md delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/api.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/api.pb.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/api.proto delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/client/client.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/client/request.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/api/status.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/pkg/units/units.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/volume/README.md delete mode 100644 vendor/github.com/libopenstorage/openstorage/volume/volume.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/volume/volume_driver_registry.go delete mode 100644 vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go create mode 100644 vendor/github.com/moby/spdystream/spdy/LICENSE create mode 100644 vendor/github.com/moby/spdystream/spdy/PATENTS create mode 100644 vendor/github.com/moby/spdystream/spdy/options.go delete mode 100644 vendor/github.com/mohae/deepcopy/.gitignore delete mode 100644 vendor/github.com/mohae/deepcopy/.travis.yml delete mode 100644 vendor/github.com/mohae/deepcopy/LICENSE delete mode 100644 vendor/github.com/mohae/deepcopy/README.md delete mode 100644 vendor/github.com/mohae/deepcopy/deepcopy.go create mode 100644 vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go create mode 100644 vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/scheduler.go create mode 100644 vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml create mode 100644 vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml create mode 100644 vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml rename vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/{0000_10_config-operator_01_ingresses.crd.yaml => 0000_10_config-operator_01_ingresses-OKD.crd.yaml} (99%) create mode 100644 vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml create mode 100644 vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationconfigmapreference.go create mode 100644 vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationproxyconfig.go create mode 100644 vendor/github.com/prometheus/procfs/kernel_hung.go create mode 100644 vendor/github.com/prometheus/procfs/nfnetlink_queue.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/client.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/gen.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/server.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/util.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/gen.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/httpconv.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/netconv.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go create mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go create mode 100644 vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go rename vendor/go.opentelemetry.io/otel/semconv/{v1.37.0 => v1.39.0}/httpconv/metric.go (98%) create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv/metric.go delete mode 100644 vendor/golang.org/x/net/context/context.go create mode 100644 vendor/google.golang.org/grpc/reflection/README.md create mode 100644 vendor/google.golang.org/grpc/reflection/adapt.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go create mode 100644 vendor/google.golang.org/grpc/reflection/internal/internal.go create mode 100644 vendor/google.golang.org/grpc/reflection/serverreflection.go delete mode 100644 vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/authentication/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/authorization/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/generated.proto delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/types.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.model_name.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.prerelease-lifecycle.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/generated.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/generated.proto delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/types.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.model_name.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.prerelease-lifecycle.go delete mode 100644 vendor/k8s.io/api/batch/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/certificates/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/certificates/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/coordination/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/coordination/v1alpha2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/coordination/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/core/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/discovery/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/discovery/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/events/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/flowcontrol/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/flowcontrol/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/flowcontrol/v1beta2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/flowcontrol/v1beta3/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/imagepolicy/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/networking/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/networking/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/node/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/node/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/node/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/policy/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/resource/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/resource/v1alpha3/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/resource/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/resource/v1beta2/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/scheduling/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/generated.proto delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.model_name.go rename vendor/k8s.io/api/scheduling/{v1alpha1 => v1alpha2}/doc.go (84%) create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/generated.pb.go create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/generated.proto rename vendor/k8s.io/api/scheduling/{v1alpha1 => v1alpha2}/register.go (90%) create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/types.go create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/types_swagger_doc_generated.go create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.model_name.go delete mode 100644 vendor/k8s.io/api/storage/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/api/storagemigration/v1beta1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.protomessage.pb.go create mode 100644 vendor/k8s.io/apimachinery/pkg/api/validate/content/path.go create mode 100644 vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go rename vendor/k8s.io/{apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.defaults.go => apimachinery/pkg/apis/meta/internalversion/conversion.go} (53%) create mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1.go create mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_byte.go create mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_string.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.protomessage.pb.go create mode 100644 vendor/k8s.io/apimachinery/pkg/sharding/accessor.go rename vendor/k8s.io/{api/authentication/v1alpha1/generated.protomessage.pb.go => apimachinery/pkg/sharding/hash.go} (66%) create mode 100644 vendor/k8s.io/apimachinery/pkg/sharding/selector.go create mode 100644 vendor/k8s.io/apimachinery/pkg/sharding/types.go rename vendor/k8s.io/{client-go/kubernetes/typed/scheduling/v1alpha1 => apimachinery/pkg/util/httpstream/spdy}/doc.go (72%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/spdy.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/wsstream.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/initializer/apiserver_id.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/loader.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/metrics/metrics.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/validation.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/doc.go rename vendor/k8s.io/{api/autoscaling/v2beta2 => apiserver/pkg/admission/plugin/policy/config/apis/policyconfig}/register.go (69%) create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/types.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/doc.go rename vendor/k8s.io/apiserver/pkg/admission/plugin/{webhook/config/apis/webhookadmission/v1alpha1 => policy/config/apis/policyconfig/v1}/register.go (91%) create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/types.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.conversion.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/config.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/composite_policy_source.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source/source.go delete mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.conversion.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/composite_webhook_source.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader/loader.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source/source.go create mode 100644 vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_patch.go delete mode 100644 vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.protomessage.pb.go create mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics/metrics.go rename vendor/k8s.io/{api/autoscaling/v2beta2 => apiserver/pkg/server/flagz/api/v1beta1}/doc.go (73%) rename vendor/k8s.io/{api/autoscaling/v2beta1 => apiserver/pkg/server/flagz/api/v1beta1}/register.go (53%) rename vendor/k8s.io/apiserver/pkg/{admission/plugin/webhook/config/apis/webhookadmission/v1alpha1 => server/flagz/api/v1beta1}/types.go (52%) rename vendor/k8s.io/apiserver/pkg/{admission/plugin/webhook/config/apis/webhookadmission/v1alpha1 => server/flagz/api/v1beta1}/zz_generated.deepcopy.go (75%) rename vendor/k8s.io/{api/events/v1beta1/generated.protomessage.pb.go => apiserver/pkg/server/flagz/api/v1beta1/zz_generated.model_name.go} (67%) rename vendor/k8s.io/{api/autoscaling/v2beta1 => apiserver/pkg/server/statusz/api/v1beta1}/doc.go (73%) create mode 100644 vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/register.go create mode 100644 vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/types.go create mode 100644 vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.deepcopy.go rename vendor/k8s.io/{apimachinery/pkg/apis/meta/v1beta1/generated.protomessage.pb.go => apiserver/pkg/server/statusz/api/v1beta1/zz_generated.model_name.go} (66%) create mode 100644 vendor/k8s.io/apiserver/pkg/sharding/parser.go rename vendor/k8s.io/apiserver/pkg/storage/cacher/{ => store}/store.go (92%) rename vendor/k8s.io/apiserver/pkg/storage/cacher/{ => store}/store_btree.go (86%) create mode 100644 vendor/k8s.io/apiserver/pkg/util/filesystem/watchuntil.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/doc.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/endpointslice.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/metrics/metrics.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/proxy.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/streamtunnel.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/translatinghandler.go create mode 100644 vendor/k8s.io/apiserver/pkg/util/proxy/websocket.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/applyconfiguration.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/jsonpatch.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybinding.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybindingspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicyspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutation.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/crossversionobjectreference.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalercondition.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerspec.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricspec.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/crossversionobjectreference.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerbehavior.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerspec.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingpolicy.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingrules.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricidentifier.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricspec.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metrictarget.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricvaluestatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricsource.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricstatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/imagevolumestatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/nodeallocatableresourceclaimstatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggroup.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/volumestatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/workloadreference.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1/nodeallocatableresourcemapping.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/poolstatus.go rename vendor/k8s.io/client-go/applyconfigurations/{scheduling/v1alpha1/priorityclass.go => resource/v1alpha3/resourcepoolstatusrequest.go} (57%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequestspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequeststatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/nodeallocatableresourcemapping.go rename vendor/k8s.io/client-go/applyconfigurations/{autoscaling/v2beta2/horizontalpodautoscaler.go => resource/v1beta2/devicetaintrule.go} (60%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulespec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulestatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintselector.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/nodeallocatableresourcemapping.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgroup.go rename vendor/k8s.io/client-go/applyconfigurations/scheduling/{v1alpha1 => v1alpha2}/gangschedulingpolicy.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/{autoscaling/v2beta1/horizontalpodautoscaler.go => scheduling/v1alpha2/podgroup.go} (61%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaim.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaimstatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingconstraints.go rename vendor/k8s.io/client-go/applyconfigurations/scheduling/{v1alpha1/podgrouppolicy.go => v1alpha2/podgroupschedulingpolicy.go} (60%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupstatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplate.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplatereference.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/topologyconstraint.go rename vendor/k8s.io/client-go/applyconfigurations/scheduling/{v1alpha1 => v1alpha2}/typedlocalobjectreference.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/scheduling/{v1alpha1 => v1alpha2}/workload.go (95%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadpodgrouptemplatereference.go rename vendor/k8s.io/client-go/applyconfigurations/scheduling/{v1alpha1 => v1alpha2}/workloadspec.go (75%) create mode 100644 vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicybinding.go delete mode 100644 vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go delete mode 100644 vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go create mode 100644 vendor/k8s.io/client-go/informers/resource/v1alpha3/resourcepoolstatusrequest.go create mode 100644 vendor/k8s.io/client-go/informers/resource/v1beta2/devicetaintrule.go delete mode 100644 vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go delete mode 100644 vendor/k8s.io/client-go/informers/scheduling/v1alpha1/workload.go rename vendor/k8s.io/client-go/informers/scheduling/{v1alpha1 => v1alpha2}/interface.go (82%) create mode 100644 vendor/k8s.io/client-go/informers/scheduling/v1alpha2/podgroup.go create mode 100644 vendor/k8s.io/client-go/informers/scheduling/v1alpha2/workload.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicybinding.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicybinding.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/autoscaling_client.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_autoscaling_client.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/autoscaling_client.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_autoscaling_client.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/horizontalpodautoscaler.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resourcepoolstatusrequest.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resourcepoolstatusrequest.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/devicetaintrule.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_devicetaintrule.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_workload.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/priorityclass.go rename vendor/k8s.io/client-go/kubernetes/typed/{autoscaling/v2beta2 => scheduling/v1alpha2}/doc.go (97%) rename vendor/k8s.io/client-go/kubernetes/typed/{autoscaling/v2beta1 => scheduling/v1alpha2}/fake/doc.go (100%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_podgroup.go rename vendor/k8s.io/client-go/kubernetes/typed/scheduling/{v1alpha1 => v1alpha2}/fake/fake_scheduling_client.go (70%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_workload.go rename vendor/k8s.io/client-go/kubernetes/typed/scheduling/{v1alpha1 => v1alpha2}/generated_expansion.go (91%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/podgroup.go rename vendor/k8s.io/client-go/kubernetes/typed/scheduling/{v1alpha1 => v1alpha2}/scheduling_client.go (67%) rename vendor/k8s.io/client-go/kubernetes/typed/scheduling/{v1alpha1 => v1alpha2}/workload.go (60%) create mode 100644 vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicybinding.go delete mode 100644 vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go delete mode 100644 vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go delete mode 100644 vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go delete mode 100644 vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go create mode 100644 vendor/k8s.io/client-go/listers/resource/v1alpha3/resourcepoolstatusrequest.go rename vendor/k8s.io/client-go/listers/{scheduling/v1alpha1/priorityclass.go => resource/v1beta2/devicetaintrule.go} (50%) rename vendor/k8s.io/client-go/listers/scheduling/{v1alpha1 => v1alpha2}/expansion_generated.go (75%) create mode 100644 vendor/k8s.io/client-go/listers/scheduling/v1alpha2/podgroup.go rename vendor/k8s.io/client-go/listers/scheduling/{v1alpha1 => v1alpha2}/workload.go (80%) create mode 100644 vendor/k8s.io/client-go/testing/doc.go rename vendor/{github.com/gregjones/httpcache/LICENSE.txt => k8s.io/client-go/third_party/forked/httpcache/LICENSE} (100%) rename vendor/{github.com/gregjones => k8s.io/client-go/third_party/forked}/httpcache/httpcache.go (98%) create mode 100644 vendor/k8s.io/client-go/tools/cache/event_handler_name.go create mode 100644 vendor/k8s.io/client-go/tools/cache/fifo_metrics.go create mode 100644 vendor/k8s.io/client-go/tools/cache/identity.go create mode 100644 vendor/k8s.io/client-go/transport/ca_rotation.go create mode 100644 vendor/k8s.io/component-base/cli/flag/curves_flag.go create mode 100644 vendor/k8s.io/component-base/metrics/api/v1/config.go create mode 100644 vendor/k8s.io/component-base/metrics/api/v1/doc.go create mode 100644 vendor/k8s.io/component-base/metrics/api/v1/types.go create mode 100644 vendor/k8s.io/component-base/metrics/api/v1/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/component-base/metrics/internal/nativehistograms.go delete mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/.mockery.yaml create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/OWNERS create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/bitmap.go create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/OWNERS create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet/feature.go delete mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/guaranteed_cpu_resize.go create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/nonsidecar_initcontainers_resize.go create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork/user_namespaces_host_network.go create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/featureset.go create mode 100644 vendor/k8s.io/component-helpers/nodedeclaredfeatures/types/types.go rename vendor/k8s.io/{api/apidiscovery/v2/generated.protomessage.pb.go => cri-client/pkg/connection_target.go} (52%) rename vendor/{github.com/aws/aws-sdk-go/LICENSE.txt => k8s.io/cri-streaming/LICENSE} (100%) create mode 100644 vendor/k8s.io/cri-streaming/pkg/streaming/.import-restrictions rename vendor/k8s.io/{client-go/kubernetes/typed/autoscaling/v2beta2/generated_expansion.go => cri-streaming/pkg/streaming/doc.go} (83%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/errors.go (100%) rename vendor/k8s.io/{api/apidiscovery/v2beta1/generated.protomessage.pb.go => cri-streaming/pkg/streaming/internal/httpresponse/writer.go} (56%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/portforward/constants.go (68%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/portforward/httpstream.go (90%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/portforward/portforward.go (79%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/portforward/websocket.go (89%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/remotecommand/attach.go (69%) create mode 100644 vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/constants.go rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/remotecommand/doc.go (100%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/remotecommand/exec.go (63%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/remotecommand/httpstream.go (83%) rename vendor/k8s.io/{client-go/kubernetes/typed/autoscaling/v2beta2/fake/doc.go => cri-streaming/pkg/streaming/remotecommand/resize.go} (79%) create mode 100644 vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/status.go rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/remotecommand/websocket.go (94%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/request_cache.go (100%) rename vendor/k8s.io/{kubelet/pkg/cri => cri-streaming/pkg}/streaming/server.go (92%) create mode 100644 vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/constraint.go create mode 100644 vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/consumable_capacity.go create mode 100644 vendor/k8s.io/klog/v2/ktesting/options.go create mode 100644 vendor/k8s.io/klog/v2/ktesting/setup.go create mode 100644 vendor/k8s.io/klog/v2/ktesting/testinglogger.go delete mode 100644 vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/generated.protomessage.pb.go delete mode 100644 vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1/generated.protomessage.pb.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservice.go rename vendor/k8s.io/{client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalercondition.go => kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicecondition.go} (55%) create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicespec.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicestatus.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/servicereference.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal/internal.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/alias.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/alias.go create mode 100644 vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.pb.go create mode 100644 vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto create mode 100644 vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api_grpc.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/cri/streaming/.import-restrictions delete mode 100644 vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins_providers.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/daemon/metrics/metrics.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/util/consistency/consistency.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/allocation/handlers.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/constants.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/server.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/doc.go create mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/helpers.go rename vendor/k8s.io/{apimachinery/pkg/util/diff/cmp.go => kubernetes/pkg/kubelet/cm/qos/types.go} (50%) create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/podgroupstate.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/podgroupinfo.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/workloadmanager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/result_channel.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/nodeallocatabledynamicresources.go rename vendor/k8s.io/{api/admission/v1beta1/generated.protomessage.pb.go => kubernetes/pkg/scheduler/framework/plugins/helper/podgroup.go} (58%) delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount/podgroup_pods_count.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware/topology_placement.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/executor.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/podgrouppreemption.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/types.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/pods_in_prebind_map.go create mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one_podgroup.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/slice/slice.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/volume/portworx/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/volume/portworx/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/common/node/container_restart_policy.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/common/node/image_volume.go delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/framework/node/util_sampledevice.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/logcheck.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/waitgroup.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot-metadata.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/backup-client-rbac.yaml create mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/cbt.storage.k8s.io_snapshotmetadataservices.yaml create mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/rbac.yaml create mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/run_snapshot_metadata_e2e.sh create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/assert.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/clientcontext.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/contexthelper.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/doc.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/errorcontext.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/initoption/initoption.go rename vendor/k8s.io/{client-go/kubernetes/typed/scheduling/v1alpha1/fake/doc.go => kubernetes/test/utils/ktesting/internal/config.go} (78%) rename vendor/k8s.io/{cri-client/pkg/internal/log.go => kubernetes/test/utils/ktesting/klogcontext.go} (62%) create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/ktesting.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/signals.go rename vendor/k8s.io/{apimachinery/pkg/util/intstr/generated.protomessage.pb.go => kubernetes/test/utils/ktesting/signals_non_win.go} (65%) rename vendor/k8s.io/{client-go/kubernetes/typed/autoscaling/v2beta1/generated_expansion.go => kubernetes/test/utils/ktesting/signals_win.go} (78%) create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/stepcontext.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/tcontext.go create mode 100644 vendor/k8s.io/kubernetes/test/utils/ktesting/withcontext.go rename vendor/{github.com/libopenstorage/openstorage => k8s.io/streaming}/LICENSE (94%) rename vendor/k8s.io/{client-go/kubernetes/typed/autoscaling/v2beta1 => streaming/pkg/httpstream}/doc.go (75%) create mode 100644 vendor/k8s.io/streaming/pkg/httpstream/httpstream.go rename vendor/k8s.io/{apimachinery/pkg/util => streaming/pkg}/httpstream/spdy/connection.go (97%) rename vendor/k8s.io/{apimachinery/pkg/util => streaming/pkg}/httpstream/spdy/roundtripper.go (65%) rename vendor/k8s.io/{apimachinery/pkg/util => streaming/pkg}/httpstream/spdy/upgrade.go (93%) rename vendor/k8s.io/{apimachinery/pkg/util => streaming/pkg}/httpstream/wsstream/conn.go (88%) create mode 100644 vendor/k8s.io/streaming/pkg/httpstream/wsstream/doc.go rename vendor/k8s.io/{apimachinery/pkg/util => streaming/pkg}/httpstream/wsstream/stream.go (81%) create mode 100644 vendor/k8s.io/streaming/pkg/runtime/runtime.go create mode 100644 vendor/k8s.io/utils/cpuset/numcpu.go rename vendor/k8s.io/{apimachinery/pkg/util => utils}/dump/dump.go (93%) create mode 100644 vendor/k8s.io/utils/third_party/forked/golang/LICENSE create mode 100644 vendor/k8s.io/utils/third_party/forked/golang/PATENTS create mode 100644 vendor/k8s.io/utils/third_party/forked/golang/btree/LICENSE create mode 100644 vendor/k8s.io/utils/third_party/forked/golang/btree/README.md create mode 100644 vendor/k8s.io/utils/third_party/forked/golang/btree/btree.go rename vendor/{k8s.io/apimachinery/pkg/api/resource/generated.protomessage.pb.go => sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_other.go} (65%) rename vendor/{k8s.io/api/scheduling/v1beta1/generated.protomessage.pb.go => sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_unix.go} (64%) create mode 100644 vendor/sigs.k8s.io/kustomize/api/types/patchargs.go diff --git a/Dockerfile b/Dockerfile index d17cfc0612..48f05de6c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,19 @@ # Use RHEL 9 as the primary builder base for the Machine Config Operator -FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.22 AS rhel9-builder +FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS rhel9-builder ARG TAGS="" WORKDIR /go/src/github.com/openshift/machine-config-operator COPY . . RUN make install DESTDIR=./instroot-rhel9 # Add a RHEL 8 builder to compile the RHEL 8 compatible binaries -FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.25-openshift-4.22 AS rhel8-builder +FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.26-openshift-5.0 AS rhel8-builder ARG TAGS="" WORKDIR /go/src/github.com/openshift/machine-config-operator # Copy the RHEL 8 machine-config-daemon binary and rename COPY . . RUN make install DESTDIR=./instroot-rhel8 -FROM registry.ci.openshift.org/ocp/4.22:base-rhel9 +FROM registry.ci.openshift.org/ocp/5.0:base-rhel9 ARG TAGS="" COPY install /manifests RUN if [ "${TAGS}" = "fcos" ]; then \ diff --git a/go.mod b/go.mod index 9a4fa87f9d..520baf68de 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openshift/machine-config-operator -go 1.25.5 +go 1.26.0 require ( github.com/Azure/ARO-RP v0.0.0-20250602035759-0693f32d5ccc @@ -23,7 +23,7 @@ require ( github.com/coreos/go-semver v0.3.1 github.com/coreos/ign-converter v0.0.0-20241125185625-2f773079ca81 github.com/coreos/ignition v0.35.0 - github.com/coreos/ignition/v2 v2.20.0 + github.com/coreos/ignition/v2 v2.26.0 github.com/coreos/rpmostree-client-go v0.0.0-20230914135003-fae0786302f7 github.com/coreos/stream-metadata-go v0.4.10-0.20250806142651-4a7d280a6c7b github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc @@ -37,14 +37,14 @@ require ( github.com/google/uuid v1.6.0 github.com/imdario/mergo v0.3.16 github.com/josephburnett/jd v1.9.2 - github.com/onsi/ginkgo/v2 v2.27.2 - github.com/onsi/gomega v1.38.2 + github.com/onsi/ginkgo/v2 v2.28.0 + github.com/onsi/gomega v1.39.1 github.com/opencontainers/go-digest v1.0.0 - github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 - github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c - github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a + github.com/openshift-eng/openshift-tests-extension v0.0.0-20260707142426-572a3e9deb7a + github.com/openshift/api v0.0.0-20260715165912-72066cc9718b + github.com/openshift/client-go v0.0.0-20260715172546-dac61734e0ec github.com/openshift/imagebuilder v1.2.21 - github.com/openshift/library-go v0.0.0-20260611115129-21dd5809a4b2 + github.com/openshift/library-go v0.0.0-20260720123941-85336565c3c7 github.com/openshift/runtime-utils v0.0.0-20230921210328-7bdb5b9c177b github.com/prometheus/client_golang v1.23.2 github.com/rs/zerolog v1.34.0 @@ -55,28 +55,28 @@ require ( github.com/tidwall/sjson v1.2.5 github.com/vincent-petithory/dataurl v1.0.0 github.com/vmware/govmomi v0.45.1 - golang.org/x/net v0.56.0 - golang.org/x/time v0.14.0 + golang.org/x/net v0.57.0 + golang.org/x/time v0.15.0 google.golang.org/grpc v1.79.3 - k8s.io/api v0.35.1 - k8s.io/apiextensions-apiserver v0.35.1 - k8s.io/apimachinery v0.35.1 - k8s.io/client-go v0.35.1 - k8s.io/code-generator v0.35.1 - k8s.io/component-base v0.35.1 - k8s.io/cri-api v0.35.0 - k8s.io/kubectl v0.35.0 - k8s.io/kubelet v0.35.0 - k8s.io/kubernetes v1.35.0 - k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 - sigs.k8s.io/controller-runtime v0.23.0 + k8s.io/api v0.36.2 + k8s.io/apiextensions-apiserver v0.36.2 + k8s.io/apimachinery v0.36.2 + k8s.io/client-go v0.36.2 + k8s.io/code-generator v0.36.2 + k8s.io/component-base v0.36.2 + k8s.io/cri-api v0.36.2 + k8s.io/kubectl v0.36.2 + k8s.io/kubelet v0.36.2 + k8s.io/kubernetes v1.36.2 + k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 + sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240522175850-2e9781e9fc60 ) require ( 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect cel.dev/expr v0.25.1 // indirect - cyphar.com/go-pathrs v0.2.1 // indirect + cyphar.com/go-pathrs v0.2.2 // indirect github.com/4meepo/tagalign v1.3.4 // indirect github.com/Abirdcfly/dupword v0.1.3 // indirect github.com/Antonboom/testifylint v1.5.2 // indirect @@ -92,8 +92,6 @@ require ( github.com/alecthomas/go-check-sumtype v0.3.1 // indirect github.com/alexkohler/nakedret/v2 v2.0.5 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect - github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect - github.com/aws/aws-sdk-go v1.55.7 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 // indirect @@ -120,7 +118,7 @@ require ( github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.2 // indirect github.com/ghostiam/protogetter v0.3.8 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -145,46 +143,43 @@ require ( github.com/go-openapi/validate v0.25.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect - github.com/godbus/dbus/v5 v5.1.1-0.20240921181615-a817f3cc4a9e // indirect + github.com/godbus/dbus/v5 v5.2.2 // indirect github.com/golangci/go-printf-func-name v0.1.0 // indirect github.com/golangci/modinfo v0.3.4 // indirect github.com/golangci/plugin-module-register v0.1.1 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/cadvisor v0.53.0 // indirect + github.com/google/cadvisor v0.56.2 // indirect github.com/google/cel-go v0.26.0 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f // indirect - github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect + github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect - github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/jjti/go-spancheck v0.6.4 // indirect github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect - github.com/karrick/godirwalk v1.17.0 // indirect github.com/kkHAIKE/contextcheck v1.1.5 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lasiar/canonicalheader v1.1.2 // indirect github.com/ldez/grignotin v0.7.0 // indirect - github.com/libopenstorage/openstorage v1.0.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/macabu/inamedparam v0.1.3 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/moby/buildkit v0.29.0 // indirect - github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/spdystream v0.5.1 // indirect github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nunnatsa/ginkgolinter v0.18.0 // indirect github.com/oklog/ulid/v2 v2.1.1 // indirect github.com/onsi/ginkgo v1.16.5 // indirect - github.com/opencontainers/cgroups v0.0.3 // indirect + github.com/opencontainers/cgroups v0.0.6 // indirect github.com/opencontainers/selinux v1.13.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect @@ -197,7 +192,6 @@ require ( github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sigstore/fulcio v1.6.6 // indirect github.com/sigstore/protobuf-specs v0.5.0 // indirect github.com/sigstore/rekor v1.5.0 // indirect @@ -214,47 +208,49 @@ require ( github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect go-simpler.org/musttag v0.13.0 // indirect go-simpler.org/sloglint v0.7.2 // indirect - go.etcd.io/etcd/api/v3 v3.6.5 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect - go.etcd.io/etcd/client/v3 v3.6.5 // indirect + go.etcd.io/etcd/api/v3 v3.6.8 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.8 // indirect + go.etcd.io/etcd/client/v3 v3.6.8 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect + go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.65.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect + go.opentelemetry.io/otel v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.41.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.podman.io/storage v1.62.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - k8s.io/cli-runtime v0.35.0 // indirect + k8s.io/cli-runtime v0.36.2 // indirect k8s.io/cloud-provider v0.0.0 // indirect - k8s.io/component-helpers v0.35.1 // indirect + k8s.io/component-helpers v0.36.2 // indirect k8s.io/controller-manager v0.32.1 // indirect k8s.io/cri-client v0.0.0 // indirect + k8s.io/cri-streaming v0.0.0 // indirect k8s.io/csi-translation-lib v0.0.0 // indirect - k8s.io/dynamic-resource-allocation v0.35.1 // indirect + k8s.io/dynamic-resource-allocation v0.36.2 // indirect k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect - k8s.io/kms v0.35.1 // indirect + k8s.io/kms v0.36.2 // indirect k8s.io/kube-scheduler v0.0.0 // indirect k8s.io/mount-utils v0.0.0 // indirect k8s.io/pod-security-admission v0.0.0 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/kustomize/api v0.20.1 // indirect - sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect + k8s.io/streaming v0.36.2 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/kustomize/api v0.21.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect ) require ( @@ -290,7 +286,7 @@ require ( github.com/docker/distribution v2.8.3+incompatible github.com/docker/docker v28.5.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.5 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/ettle/strcase v0.2.0 // indirect @@ -369,8 +365,8 @@ require ( github.com/polyfloyd/go-errorlint v1.7.0 // indirect github.com/proglottis/gpgme v0.1.4 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.17.0 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect @@ -411,7 +407,7 @@ require ( go.uber.org/zap v1.27.1 // indirect go4.org v0.0.0-20200104003542-c7e774b10ea0 // indirect golang.org/x/crypto v0.54.0 - golang.org/x/exp v0.0.0-20250911091902-df9299821621 + golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f // indirect golang.org/x/mod v0.37.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect @@ -420,15 +416,15 @@ require ( golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.40.0 // indirect golang.org/x/tools v0.47.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 honnef.co/go/tools v0.5.1 // indirect - k8s.io/apiserver v0.35.1 + k8s.io/apiserver v0.36.2 k8s.io/klog/v2 v2.140.0 - k8s.io/kube-aggregator v0.35.1 // indirect - k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288 // indirect + k8s.io/kube-aggregator v0.36.2 // indirect + k8s.io/kube-openapi v0.0.0-20260718133925-74c0ba7c0470 // indirect mvdan.cc/gofumpt v0.7.0 // indirect mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect @@ -437,37 +433,39 @@ require ( ) replace ( - github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7 + github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20260424201627-4d4cc33d669d - k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa - k8s.io/apiextensions-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260305123649-d18f3f005eaa - k8s.io/apimachinery => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa - k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260305123649-d18f3f005eaa - k8s.io/cli-runtime => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260305123649-d18f3f005eaa - k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260305123649-d18f3f005eaa - k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260305123649-d18f3f005eaa - k8s.io/cluster-bootstrap => github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260305123649-d18f3f005eaa - k8s.io/code-generator => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260305123649-d18f3f005eaa - k8s.io/component-base => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260305123649-d18f3f005eaa - k8s.io/component-helpers => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260305123649-d18f3f005eaa - k8s.io/controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260305123649-d18f3f005eaa - k8s.io/cri-api => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260305123649-d18f3f005eaa - k8s.io/cri-client => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260305123649-d18f3f005eaa - k8s.io/csi-translation-lib => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260305123649-d18f3f005eaa - k8s.io/dynamic-resource-allocation => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260305123649-d18f3f005eaa - k8s.io/endpointslice => github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260305123649-d18f3f005eaa - k8s.io/externaljwt => github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kube-controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kube-proxy => github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kube-scheduler => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kubectl => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260305123649-d18f3f005eaa - k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa - k8s.io/metrics => github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260305123649-d18f3f005eaa - k8s.io/mount-utils => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260305123649-d18f3f005eaa - k8s.io/pod-security-admission => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260305123649-d18f3f005eaa - k8s.io/sample-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260305123649-d18f3f005eaa - k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260305123649-d18f3f005eaa - k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260305123649-d18f3f005eaa + k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260716191900-78acd4d422b2 + k8s.io/apiextensions-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260716191900-78acd4d422b2 + k8s.io/apimachinery => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260716191900-78acd4d422b2 + k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cli-runtime => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260716191900-78acd4d422b2 + k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cluster-bootstrap => github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260716191900-78acd4d422b2 + k8s.io/code-generator => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260716191900-78acd4d422b2 + k8s.io/component-base => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260716191900-78acd4d422b2 + k8s.io/component-helpers => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260716191900-78acd4d422b2 + k8s.io/controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cri-api => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cri-client => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260716191900-78acd4d422b2 + k8s.io/cri-streaming => github.com/openshift/kubernetes/staging/src/k8s.io/cri-streaming v0.0.0-20260716191900-78acd4d422b2 + k8s.io/csi-translation-lib => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260716191900-78acd4d422b2 + k8s.io/dynamic-resource-allocation => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260716191900-78acd4d422b2 + k8s.io/endpointslice => github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260716191900-78acd4d422b2 + k8s.io/externaljwt => github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kube-controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kube-proxy => github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kube-scheduler => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kubectl => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260716191900-78acd4d422b2 + k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20260716191900-78acd4d422b2 + k8s.io/metrics => github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260716191900-78acd4d422b2 + k8s.io/mount-utils => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260716191900-78acd4d422b2 + k8s.io/pod-security-admission => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260716191900-78acd4d422b2 + k8s.io/sample-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260716191900-78acd4d422b2 + k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260716191900-78acd4d422b2 + k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260716191900-78acd4d422b2 + k8s.io/streaming => github.com/openshift/kubernetes/staging/src/k8s.io/streaming v0.0.0-20260716191900-78acd4d422b2 ) diff --git a/go.sum b/go.sum index 97833e104c..29759e9461 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= -cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= +cyphar.com/go-pathrs v0.2.2 h1:y9w7hxbkr3zEL78Fjzeg4HEhs2xNy+fbwHiHGJJY2Xo= +cyphar.com/go-pathrs v0.2.2/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= @@ -23,6 +23,8 @@ github.com/Azure/ARO-RP v0.0.0-20250602035759-0693f32d5ccc h1:j5zg78Ysu0iV+J53bh github.com/Azure/ARO-RP v0.0.0-20250602035759-0693f32d5ccc/go.mod h1:/1cmoOXPK2Gv+KQW1ocEw1y54ggd3JYFjoEVWAndPCg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= @@ -71,8 +73,6 @@ github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYW github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs= -github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= @@ -82,8 +82,6 @@ github.com/ashanbrown/makezero v1.2.0/go.mod h1:dxlPhHbDMC6N6xICzFBSK+4njQDdK8eu github.com/ashcrow/osrelease v0.0.0-20180626175927-9b292693c55c h1:icme0QhxrgZOxTBnT6K8dfGLwbKWSOVwPB95XTbo8Ws= github.com/ashcrow/osrelease v0.0.0-20180626175927-9b292693c55c/go.mod h1:BRljTyotlu+6N+Qlu5MhjxpdmccCnp9lDvZjNNV8qr4= github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= -github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek= github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM= github.com/aws/aws-sdk-go-v2/credentials v1.19.16 h1:r3RJBuU7X9ibt8RHbMjWE6y60QbKBiII6wSrXnapxSU= @@ -104,7 +102,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.44.0 h1:bLZ0PolJ8J+HkJHztcXORUpHXBye github.com/aws/aws-sdk-go-v2/service/sts v1.44.0/go.mod h1:9gdl4RrflIdpDb2TlXshWgR1F9TeCkvqDx77Vpr4Z/Q= github.com/aws/smithy-go v1.27.3 h1:F3Zb497UhhskkfpJmfkXswyo+t0sh9OTBnIHjogWbVY= github.com/aws/smithy-go v1.27.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= @@ -176,6 +173,8 @@ github.com/coreos/fcct v0.5.0 h1:f/z+MCoR2vULes+MyoPEApQ6iluy/JbXoRi6dahPItQ= github.com/coreos/fcct v0.5.0/go.mod h1:cbE+j77YSQwFB2fozWVB3qsI2Pi3YiVEbDz/b6Yywdo= github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb h1:rmqyI19j3Z/74bIRhuC59RB442rXUazKNueVpfJPxg4= github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb/go.mod h1:rcFZM3uxVvdyNmsAV2jopgPD1cs5SPWJWU5dOz2LUnw= +github.com/coreos/go-oidc v2.5.0+incompatible h1:6W0vGJR3Tu0r0PwfmjOrRZSlfxeEln8dsejt3ZWIvwo= +github.com/coreos/go-oidc v2.5.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= @@ -191,8 +190,8 @@ github.com/coreos/ign-converter v0.0.0-20241125185625-2f773079ca81/go.mod h1:Q7S github.com/coreos/ignition v0.35.0 h1:UFodoYq1mOPrbEjtxIsZbThcDyQwAI1owczRDqWmKkQ= github.com/coreos/ignition v0.35.0/go.mod h1:WJQapxzEn9DE0ryxsGvm8QnBajm/XsS/PkrDqSpz+bA= github.com/coreos/ignition/v2 v2.1.1/go.mod h1:RqmqU64zxarUJa3l4cHtbhcSwfQLpUhv0WVziZwoXvE= -github.com/coreos/ignition/v2 v2.20.0 h1:xQjrxhCbcSKpqrN2hOQavAc1rx0GOf6qh2QCauScwPU= -github.com/coreos/ignition/v2 v2.20.0/go.mod h1:l7EpXNWA7jBXmjUMvnVBlrrj+LX2wA/PAyD9kstwFDQ= +github.com/coreos/ignition/v2 v2.26.0 h1:Db4IO5ydZOMnJYINgbPuXlwAH1ul0/V71h20iKyBi6k= +github.com/coreos/ignition/v2 v2.26.0/go.mod h1:2f48nEXqnh1BU69Yq3lIWDvaYFSFQVZoFB7rB7wz7DY= github.com/coreos/rpmostree-client-go v0.0.0-20230914135003-fae0786302f7 h1:gpIn0B0F00GJPlI1iPjJbHMS01QoxDs7Bf8UgH9D3wg= github.com/coreos/rpmostree-client-go v0.0.0-20230914135003-fae0786302f7/go.mod h1:WiAXRoGnl4Lwr7OM5izCLWMLH6Y43sYWJREoeeHEg4E= github.com/coreos/stream-metadata-go v0.4.10-0.20250806142651-4a7d280a6c7b h1:CT6nMx5Ap/K6MT8zMqByrWz+RZV7O6pBGW5LhB/pwvY= @@ -228,8 +227,8 @@ github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaft github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -265,8 +264,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= @@ -279,10 +278,14 @@ github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZ github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-critic/go-critic v0.11.5 h1:TkDTOn5v7EEngMxu8KbuFqFR43USaaH8XRJLz1jhVYA= github.com/go-critic/go-critic v0.11.5/go.mod h1:wu6U7ny9PiaHaZHcvMDmdysMqvDem162Rh3zWTrqk8M= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU= +github.com/go-ldap/ldap/v3 v3.4.11/go.mod h1:bY7t0FLK8OAVpp/vV6sSlpz3EQDGcQwc8pF0ujLgKvM= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -372,8 +375,8 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.1-0.20240921181615-a817f3cc4a9e h1:znsZ+BW06LsAtZwQvY/rgWQ3o1q0mnR4SG4q8HCP+3Q= -github.com/godbus/dbus/v5 v5.1.1-0.20240921181615-a817f3cc4a9e/go.mod h1:nRJ+j259aT/CW6otoGCHPa1K/lNHLO+UGmW133FNj9s= +github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= +github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -417,8 +420,8 @@ github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNF github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= 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/cadvisor v0.53.0 h1:pmveUw2VBlr/T2SBE9Fsp8gdLhKWyOBkECGbaas9mcI= -github.com/google/cadvisor v0.53.0/go.mod h1:Tz3zf/exzFfdWd1T/U/9eNst0ZR2C6CIV62LJATj5tg= +github.com/google/cadvisor v0.56.2 h1:ra6p4Nxc4zT8VLbZscWUxhvjsqy+1AzMvuSdEM90o1w= +github.com/google/cadvisor v0.56.2/go.mod h1:CWidr4DqGbkN4aKuOEjLB7Bab3gl01Xxm3co38C3xRU= github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= @@ -441,8 +444,8 @@ github.com/google/goexpect v0.0.0-20210430020637-ab937bf7fd6f/go.mod h1:n1ej5+Fq github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f h1:5CjVwnuUcp5adK4gmY6i72gpVFVnZDP2h5TmPScB6u4= github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -467,15 +470,10 @@ github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 h1:JYghRBlGCZyCF2wNUJ8W0cwaQdtpcssJ4CgC406g+WU= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -513,8 +511,6 @@ github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ= github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY= github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos= github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= -github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= -github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg= github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= @@ -550,8 +546,6 @@ github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSio github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= -github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM= -github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= @@ -577,7 +571,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= github.com/mgechev/revive v1.5.1 h1:hE+QPeq0/wIzJwOphdVyUJ82njdd8Khp4fUIHGZHW3M= @@ -592,8 +585,12 @@ github.com/moby/buildkit v0.29.0 h1:wxLEFbCOJntEDjSNNN2YWd8zxltZxT5muDQ0LzpbtpU= github.com/moby/buildkit v0.29.0/go.mod h1:Dmv2FeDe34t75QuzeU87rBoZpAAkcpT5zeu4hXzmASc= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= +github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y= +github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= @@ -610,8 +607,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= @@ -642,10 +637,10 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/opencontainers/cgroups v0.0.3 h1:Jc9dWh/0YLGjdy6J/9Ln8NM5BfTA4W2BY0GMozy3aDU= -github.com/opencontainers/cgroups v0.0.3/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= +github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= +github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI= +github.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs= 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= @@ -654,66 +649,82 @@ github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5 github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE= github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg= -github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 h1:jJLE/aCAqDf8U4wc3bE1IEKgIxbb0ICjCNVFA49x/8s= -github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= -github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c h1:X1B6zMjD7kmKcuv9Cxs4Zhq/ruJLt7BsywSWKOA9Jn4= -github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c/go.mod h1:7WJ3IPaK6nmWT8bDcaNooHqd0H5WepjVqV/10VlkMEM= -github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a h1:RfmstmmWz5/23/Tt8gBipICzC1VHQLgGBeQUQ1aWoUA= -github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a/go.mod h1:fNuXvm6bMJff2AxiRb9CR5L3a9CLzVgcoSmHZ3l7FgU= +github.com/openshift-eng/openshift-tests-extension v0.0.0-20260707142426-572a3e9deb7a h1:ulT0JZ/x6S4hYhyjUJ9T49YAxDLl1i5idFOMm9RHBkY= +github.com/openshift-eng/openshift-tests-extension v0.0.0-20260707142426-572a3e9deb7a/go.mod h1:pHOS9c6BjZv91OkkHyIHAOWnYhxwcxWQkyYGEvPyUCE= +github.com/openshift/api v0.0.0-20260715165912-72066cc9718b h1:gN3SihCYEwoIksD+f24wHhwiEgvaV0RxNjgmkDvBBeg= +github.com/openshift/api v0.0.0-20260715165912-72066cc9718b/go.mod h1:k6qH5QOVa5GDln2VVm8Jz4NV3Z7R2SATHFLwGS6Wh3M= +github.com/openshift/apiserver-library-go v0.0.0-20260715200723-42e5e402ca43 h1:V9hWaBi9cnohNk1F0Ph6wpI0otMWqMHleJ3oj5603Bc= +github.com/openshift/apiserver-library-go v0.0.0-20260715200723-42e5e402ca43/go.mod h1:ZuzfEq1ccZpHNx05xEUKlm2TcMHt2iXVutb79kAuTfM= +github.com/openshift/client-go v0.0.0-20260715172546-dac61734e0ec h1:UDjX+mot5IVLpcChyBqLXG1oSB29s4UkqFmgNb0Xsqc= +github.com/openshift/client-go v0.0.0-20260715172546-dac61734e0ec/go.mod h1:iMHec0APKVjOH8GfL/RxddX8DuiuSvPlRe+s7KDqlyA= github.com/openshift/imagebuilder v1.2.21 h1:XX0tZVznWTxzYevvNVZ/0eeTzmgY6cfcT4/xjs5ToyU= github.com/openshift/imagebuilder v1.2.21/go.mod h1:+L09sXUQ0RPdCU1tmzKrfBhqMlYvZtaA3MHb7aTjVU8= -github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa h1:/gPMWR7fdCC3S4wHALD6Em+vztl1q9/cOpdMkFZwDus= -github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa/go.mod h1:1r2FIoYrPU0110cjYlWAwNcbiqRPLWAgmZK4d0YeEZw= -github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa h1:ifOqAFthJWnT1HS6Sq2AcLQWNSJ1+XEiyA9eo+PIcR0= -github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:eNGgWrtFriI8ZtgqOFkYKJZtb9u8Of/qabPD6ofXfUM= -github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260305123649-d18f3f005eaa h1:uAze0leOAEGaWK64CfUh8BSykt58wiVmMQkqZty+36Q= -github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:zI26jja87ZsXlEHBqIDmMljchbzM7tM1S3L6tJpvKg8= -github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa h1:EWjdbg75cdK6jOsaHKYnozDPs9uowwVpC9ksWB4khs4= -github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:4/sLxSO5FqhIFFJJFB3aGUIcEDlnzIXbrrRN0BZuHHs= -github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260305123649-d18f3f005eaa h1:PHXXIj7KPZJevTmdJd4u1NROdvSX2z5v4/1RQpBzqOA= -github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:jOGmIoa/3gNHtZNaRfe/WuxQFJPTXyP0LiKLyVto6mo= -github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260305123649-d18f3f005eaa h1:viWykf8+roy/PQglQ34ue110o0S5hx8/ioTq0kV9yjQ= -github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:+AYvhE/r9NxeUVGWWn1udEjFH9UxlH689/fzRPRlv0A= -github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260305123649-d18f3f005eaa h1:ZB3+zJeOHTwiXNzWsEIzzhwwDgqPoB93yWFk+45LObo= -github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:sxLPgzwe7FZzbSa2jq8GNA8cy11BWiWWruFwYo29fis= -github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260305123649-d18f3f005eaa h1:ODYEW80js7R0a40TjzSmpROX/b/Tnm+3hl0e0ICSVFE= -github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:0RXKUJuaCwy8B4rj3V35zJ52G26pF5n2P4vQVwpgKFk= -github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260305123649-d18f3f005eaa h1:HWwTDLhM2IZYG4uXBtViueeDzBB4qtUkLf0jDZ+bylE= -github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:gMUCCRWiGtUnB6NpqpXAoNTnvyjCF1Jn2/Af6Oa4Uj4= -github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260305123649-d18f3f005eaa h1:CkOnvmEcV2b7mruEnu1PNT9XPyS+N//J/RiDaM+LEE0= -github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:m/Alq7b5sIfnMrY0m5Y1dLmSL8ItLuzbSPlBXLXX44U= -github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260305123649-d18f3f005eaa h1:1jdTgSAMckJLnRHwv0dhyraa6Zbl6Gsx10oMuWs6BqA= -github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:UNoqyTPeVLhnE4PLihJHeu1Wn7s0/PVFxbbx901ww14= -github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260305123649-d18f3f005eaa h1:t008KI53JVcIcrkgEPX9wX0ktSrtIDgualN6dX0vbkc= -github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:hsDuZodkwwFzerI8kd6DDUytNskegBosWABgtd3GR9U= -github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260305123649-d18f3f005eaa h1:DRvS/tWR7n9q+79UypVii+Yoqtt5OM9w62OrrijlQNg= -github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:/0TYMxvHCmKuL9/v4ruc2T9uT0lwR7mrnLxrL0AR1Xc= -github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260305123649-d18f3f005eaa h1:UJDXQj+i1tTK9n8nzu+akj5o2YbreIzymSPDXjEeXbc= -github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:ltUz9C43ZJS19jflbPqrFx+gMmbuNiRIf+9Uv9L+Rpk= -github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260305123649-d18f3f005eaa h1:4WDZmY5DJLFWosd/ULxoi/zSPM2jeKCaN7rrOBiLKIE= -github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:nQc9/BMlPoto15Y6g4nagUjpvGODc5Lcq6vaisF2YVY= -github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260305123649-d18f3f005eaa h1:axgIMUtCYMQsWx30LcsAY5lVqPZVABz8j7LHStK1bLo= -github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:4FKIKl2F63rcuV5+BSUl8KODhDU98rlpCblbtwzTboY= -github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260305123649-d18f3f005eaa h1:v40DTowqf+HQkVtBLL9aohP+1HlhqQ8xkz8Uuioz42A= -github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:FHCbr8nVtId3zpAj4cLklM7K4wlljo+u+gidYk7d5Gk= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260305123649-d18f3f005eaa h1:YVt3eulmPO7jdbfe3q84BXLS53j4ho05RHehmd4Y3Jo= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:BA+xC9ETav9DYm/LnYjvZ8MpQt7TyB9vEc1iq5YnjGQ= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260305123649-d18f3f005eaa h1:Mb5DebVZ0S3FDM7cLCtczst+DeHHZ1btnkp5+9kwr6o= -github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:wpCY0+B3MgxzMjKdKDElI66KOceWEJhmzKRYxQVCNpc= -github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260305123649-d18f3f005eaa h1:2J2sh62iisisOW5PvSRRWzKYkKPaihjuDhO+EV8IMpI= -github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:gDOtf09z0LjXJasGFoCAFuIZTeAfFhW8RzjflX2kPmE= -github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260305123649-d18f3f005eaa h1:cJ6pBy1y5VPJzTZyMhy2UuRduTm6cBFTCVWaIYY+MD8= -github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:tVLbICv6U/B3LToFiDNSR7rsaNDV3iaPaQiN0Lph7Hc= -github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260305123649-d18f3f005eaa h1:P8iZEO9b1n3Y+3qBiuIfbqjqTy9OK3QsGK4mDGpihEQ= -github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:sL4snITWGw8a7Yqz2+zD+X44bEq+HtRTihlZLArDNqI= -github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260305123649-d18f3f005eaa h1:FZgsM71U1a5kznzvbjRag8o0zoW53SNJk/dtQXUsU8s= -github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:6wqqkK0+5hV+CLJ3uz9A1lkjxXRvkbq+5RnZdUZx/H8= -github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260305123649-d18f3f005eaa h1:JY4k94JmDGQp2Pj94Cw2xtIjs7MpPkU9n8zNPDTbiKo= -github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260305123649-d18f3f005eaa/go.mod h1:CnFDBq5NGnfOSMeOP8l4SNYJrxK6Z1kUaKdu3Qq9Uik= -github.com/openshift/library-go v0.0.0-20260611115129-21dd5809a4b2 h1:kH+vbMI//DZciIQXa6VhTX6BOH3ZJuZSN5IS8wQI76g= -github.com/openshift/library-go v0.0.0-20260611115129-21dd5809a4b2/go.mod h1:/HBhy6jm/igWI3Y1vYFwFG3ZCcXmnNsKUT6VBpPyM9A= -github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7 h1:02E4Ttpu+7yCQLQxtY42JfcfHU7TBGnje6uB2ytBSdU= -github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/openshift/kubernetes v1.30.1-0.20260716191900-78acd4d422b2 h1:+FIs6dK2DpIFH7oUGQOfxqtIUJmc4sp8NBHK++q0lGY= +github.com/openshift/kubernetes v1.30.1-0.20260716191900-78acd4d422b2/go.mod h1:bJ5h4TVP09ipVze5drR/0a1DQRP9Bbk+PKEU5/6Hvy4= +github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260716191900-78acd4d422b2 h1:GaKZPyZmsUqZ/BkOMIepQeKrKd47+GQyKg4AlHg3FFY= +github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260716191900-78acd4d422b2/go.mod h1:WFeUanJ4bJLzs4KvpRSx161VvNyssCv1mzTLbyXQo/g= +github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260716191900-78acd4d422b2 h1:pRWlE2wvSqShjpd/eJCdCgJ+X+6Nn6UBdJJsh7vjy2I= +github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260716191900-78acd4d422b2/go.mod h1:1S7ulDhL/H3I/xQoTDIWaMDpT0XrL9Eues3hudpq1sE= +github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260716191900-78acd4d422b2 h1:3ir/q2MJTux30HEvYoOjO4MOT9NzShI31oDT8Mzu548= +github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260716191900-78acd4d422b2/go.mod h1:f0cSbFc4+Ge2TL71tQL4WGoZ/KYnRlp4JVyu5H8VArQ= +github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260716191900-78acd4d422b2 h1:6rENaxdDwqi5si7vtp0GzyiDmqpZ9GlGZ7bDNedsuhQ= +github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260716191900-78acd4d422b2/go.mod h1:LzA/6WJPwhjMxn9+F/E4sdcqMG79fNvi/PNfTeiKlkI= +github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260716191900-78acd4d422b2 h1:25VP2BSDOLaH1nqPkOUblsb3ehxKSYMvalJrHIoOsNE= +github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260716191900-78acd4d422b2/go.mod h1:hHpSAi9AhME+eb1tS92Ykx6ZKQXzP3HHNpusxNESFGc= +github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260716191900-78acd4d422b2 h1:DAJ1yYMsmoDXSvcDABa5IwnHHP3XeCNz5hZ4HOOJHgQ= +github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260716191900-78acd4d422b2/go.mod h1:RptGI/CuNQRCF+BqKC7b93XGTrdfHGe9946l80zQQVw= +github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260716191900-78acd4d422b2 h1:P1hThv7stsKPAnFcvR/ROqH/EgHaFBNNtEY882Bmo7Q= +github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260716191900-78acd4d422b2/go.mod h1:0DsHTEToLIVK4Pix+wjdHKrM7xLZphQNRikFM0cg7UI= +github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260716191900-78acd4d422b2 h1:KIdC9ojPi/+JXRmMOeuOYh01vkvuZCZ7du+KL7sPv04= +github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260716191900-78acd4d422b2/go.mod h1:HNixeY2Jn3lbkaLQGj7H4ORem5IEkJxuKmxYcI6o0hg= +github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260716191900-78acd4d422b2 h1:irg6isRQjVe7abPSAJmbG7iw0xYlA7oR25TEPyGUV4c= +github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260716191900-78acd4d422b2/go.mod h1:wGru4PRrEMpss0FtTE5ViGgl+527iwyoGOw1ElKRWs8= +github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260716191900-78acd4d422b2 h1:1FCVgp624N9AWj4Z/GxDRzfJryWpWv5/qWog23FPth4= +github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260716191900-78acd4d422b2/go.mod h1:MAAOj484/2yPBTJ3AnUbqF+bPv/TwHts4bOfp1Ue5mg= +github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260716191900-78acd4d422b2 h1:BnzGs8xRhGRzGcCqLcOQCkhLt8lu3luAqxJzsPHUt0U= +github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260716191900-78acd4d422b2/go.mod h1:K4K0UWaPa9irw/Yd2kUhQDiX3xi4/ULaxaVgj8nWoAA= +github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260716191900-78acd4d422b2 h1:xROpfwpa5TApeat5oXwtGl809d35WBfp7FpOilOZAS8= +github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260716191900-78acd4d422b2/go.mod h1:XxcUQcNe9vgYEzDazOg6wQT5zfjbeYUhFtEkFZr2Ki8= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260716191900-78acd4d422b2 h1:jyt7DMvlsosWcvEbbM4VEm/djBmqCqjuc/cb0o6vxkY= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260716191900-78acd4d422b2/go.mod h1:Hm5M1QcpsIEiehfvhU/b2PXDRGs7JXmL8Hd7hccuEzk= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260716191900-78acd4d422b2 h1:YIaj3lmTZzTpCrQK/qtwceKsjdxSYRzqgAF1Q1coqw0= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260716191900-78acd4d422b2/go.mod h1:x9NAVqA35CiS1AkooxWwHkoig7ABK4fOPwC4vj/nDDw= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-streaming v0.0.0-20260716191900-78acd4d422b2 h1:XV2dGyq4V1QEhWl0EOGj66Mxnpri+iqSHMaGpt0zwrM= +github.com/openshift/kubernetes/staging/src/k8s.io/cri-streaming v0.0.0-20260716191900-78acd4d422b2/go.mod h1:loX4cwFqDVPXxUx4NLq+jJdrDN9x0YfZWTnwsvOXvC4= +github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260716191900-78acd4d422b2 h1:Jr/0qS4MXKNfR+iQVDnaiykqnK4pfGbgBsMz5AW1ymo= +github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260716191900-78acd4d422b2/go.mod h1:OMVtuBahCF0y3oZfCOHqxVerEIzAdPwUjio5Pw3KTF4= +github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260716191900-78acd4d422b2 h1:GgybPPNVYyJBTdZk5tq4T6EnvpOQ1o2bCNgp0hxskl4= +github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260716191900-78acd4d422b2/go.mod h1:d1EOn59s5pIpW4oPRXroriuXAUeFZ4NJjeJr1hu2V/0= +github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260716191900-78acd4d422b2 h1:/5UmHrQu4wY4dalUgrk4zCQStsER3It0Lsl+LXNOSDU= +github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260716191900-78acd4d422b2/go.mod h1:8tx+NEg+xYnxJC+FdDzkcvJvJ2sdan7nzWTm1BX8VPg= +github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260716191900-78acd4d422b2 h1:tFZwScuUB8fQc+hpH7h2vIQHuU6d7Freaa9uTkbfmoM= +github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260716191900-78acd4d422b2/go.mod h1:E1IRU9bxKSupRMgz8MlaD6XKD/XPMzHI3fds58dFFTY= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260716191900-78acd4d422b2 h1:iIIHJil7KopM7crn4+aQAwgJAjWc5Gv7rxNJ7tUj9/w= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260716191900-78acd4d422b2/go.mod h1:E2yZwg3UGnKqJ62o0OAk+K1hJtL2NFjj26ySFzf0vdI= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260716191900-78acd4d422b2 h1:XN02PqQy+fh0Yc6bXcboRUeMJRn9ShjJ9feKaIYgeoQ= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260716191900-78acd4d422b2/go.mod h1:wGCgLxesjAGh56ojb9YSwKtoEqVhq5ZnkYWDft01Nt0= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260716191900-78acd4d422b2 h1:Tw9uEENFk3+xLy+cNNSu/FxzdPnAYRuZzUOl0iM/KIQ= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260716191900-78acd4d422b2/go.mod h1:rg790Agei9hpvXnhDjeoyVd0n4V1duWbpPjD+msaUxQ= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260716191900-78acd4d422b2 h1:wgkqICG7JwKqjrSyPUJBHUhckhdm7GgChjt1six0rPU= +github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260716191900-78acd4d422b2/go.mod h1:TiRlofltClPoi5yeifRqTYWIVajl/TbvaYgII88iw70= +github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260716191900-78acd4d422b2 h1:z5z6eHeT55qWJv/Hf0YSAKGiaKDSRwuanF+hyvT1P78= +github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260716191900-78acd4d422b2/go.mod h1:Xrp//dzjM8FusHrqjL8GVi/NbX5+i/+VFYL2Dsx9BDA= +github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260716191900-78acd4d422b2 h1:XYToVXBDdiwtzghvwV5pnZJtABwSZa5C5BXwsq3UIAc= +github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260716191900-78acd4d422b2/go.mod h1:3JOrE2BhpzilTH9LwwDRx85o+D2yg/gDFv1bCURHQ4Q= +github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260716191900-78acd4d422b2 h1:wfiqtg5KzOvXAB1bgf9dgKmS8410pc2V+VzeZgWW/8c= +github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260716191900-78acd4d422b2/go.mod h1:8wIJDwiIaUUfAejq9ir/0Ah94X3JezNtpRwf7C8pk+Y= +github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260716191900-78acd4d422b2 h1:qLBd/sWTQriIDbdqfmjvz0InAj/JUfZ7sSFoCvGvav8= +github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260716191900-78acd4d422b2/go.mod h1:EQAYCSm9/JdAru6VKMPuj6Prtxivy/U22/6Z+yZA6HQ= +github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260716191900-78acd4d422b2 h1:yiseA80GtLi9WO+4guE3bTtLrGEoUmgLl0yDUcn56Ts= +github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260716191900-78acd4d422b2/go.mod h1:WWW2/ziq6y9S37BkoJa13Gw0lok0qo4FCpb/ehL75Jo= +github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260716191900-78acd4d422b2 h1:+Rg8Qzt3N3HeXNIdbZJWnn1rYnHZSL4tCTVpLxePWc8= +github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260716191900-78acd4d422b2/go.mod h1:0SHZupNKz3/FyUwe1xKMVbSz6mhU669ZvhqeMYCR2/U= +github.com/openshift/kubernetes/staging/src/k8s.io/streaming v0.0.0-20260716191900-78acd4d422b2 h1:nJF9woF3sw1YXRaFC9MEUSLqMgJp4+5BHgMNJQPy31I= +github.com/openshift/kubernetes/staging/src/k8s.io/streaming v0.0.0-20260716191900-78acd4d422b2/go.mod h1:4Gwh7yXFbEDvrWKGShCdU6vwFtbkZ4KUMy3TuJ6z0F4= +github.com/openshift/library-go v0.0.0-20260720123941-85336565c3c7 h1:ANCld7YKQ8EI3fwRGo3oSrYzF1aOwJdXOwN15HLNa3g= +github.com/openshift/library-go v0.0.0-20260720123941-85336565c3c7/go.mod h1:iWcB6wgeOhsByZAZGhmzBtEnrLQzABL0s3aeou8AmSI= +github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20260424201627-4d4cc33d669d h1:t+XyaZL4LpQx/AY2SETlMCQPLc9vd05ZZ7WXvD9doME= +github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20260424201627-4d4cc33d669d/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= github.com/openshift/runtime-utils v0.0.0-20230921210328-7bdb5b9c177b h1:oXzC1N6E9gw76/WH2gEA8GEHvuq09wuVQ9GoCuR8GF4= github.com/openshift/runtime-utils v0.0.0-20230921210328-7bdb5b9c177b/go.mod h1:l9/qeKZuAmYUMl0yicJlbkPGDsIycGhwxOvOAWyaP0E= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= @@ -738,26 +749,23 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polyfloyd/go-errorlint v1.7.0 h1:Zp6lzCK4hpBDj8y8a237YK4EPrMXQWvOe3nGoH4pFrU= github.com/polyfloyd/go-errorlint v1.7.0/go.mod h1:dGWKu85mGHnegQ2SWpEybFityCg3j7ZbwsVUxAOk9gY= +github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= +github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M= github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 h1:AHzMWDxNiAVscJL6+4wkvFRTpMnJqiaZFEKA/osaBXE= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0/go.mod h1:wAR5JopumPtAZnu0Cjv2PSqV4p4QB09LMhc6fZZTXuA= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= -github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 h1:+Wl/0aFp0hpuHM3H//KMft64WQ1yX9LdJY64Qm/gFCo= github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= @@ -804,8 +812,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.10.0 h1:l+H5ErcW0PAehBNrBxo github.com/secure-systems-lab/go-securesystemslib v0.10.0/go.mod h1:MRKONWmRoFzPNQ9USRF9i1mc7MvAVvF1LlW8X5VWDvk= github.com/securego/gosec/v2 v2.21.4 h1:Le8MSj0PDmOnHJgUATjD96PaXRvCpKC+DGJvwyy0Mlk= github.com/securego/gosec/v2 v2.21.4/go.mod h1:Jtb/MwRQfRxCXyCm1rfM1BEiiiTfUOdyzzAhlr6lUTA= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -951,42 +959,44 @@ go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY= go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo= go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= -go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= -go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= -go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= -go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= -go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= -go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= -go.etcd.io/etcd/pkg/v3 v3.6.5 h1:byxWB4AqIKI4SBmquZUG1WGtvMfMaorXFoCcFbVeoxM= -go.etcd.io/etcd/pkg/v3 v3.6.5/go.mod h1:uqrXrzmMIJDEy5j00bCqhVLzR5jEJIwDp5wTlLwPGOU= -go.etcd.io/etcd/server/v3 v3.6.5 h1:4RbUb1Bd4y1WkBHmuF+cZII83JNQMuNXzyjwigQ06y0= -go.etcd.io/etcd/server/v3 v3.6.5/go.mod h1:PLuhyVXz8WWRhzXDsl3A3zv/+aK9e4A9lpQkqawIaH0= +go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= +go.etcd.io/etcd/api/v3 v3.6.8/go.mod h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q= +go.etcd.io/etcd/client/pkg/v3 v3.6.8 h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50= +go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= +go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= +go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= +go.etcd.io/etcd/pkg/v3 v3.6.8 h1:Xe+LIL974spy8b4nEx3H0KMr1ofq3r0kh6FbU3aw4es= +go.etcd.io/etcd/pkg/v3 v3.6.8/go.mod h1:TRibVNe+FqJIe1abOAA1PsuQ4wqO87ZaOoprg09Tn8c= +go.etcd.io/etcd/server/v3 v3.6.8 h1:U2strdSEy1U8qcSzRIdkYpvOPtBy/9i/IfaaCI9flZ4= +go.etcd.io/etcd/server/v3 v3.6.8/go.mod h1:88dCtwUnSirkUoJbflQxxWXqtBSZa6lSG0Kuej+dois= go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0 h1:KemlMZlVwBSEGaO91WKgp41BBFsnWqqj9sKRwmOqC40= -go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0/go.mod h1:uq8DrRaen3suIWTpdR/JNHCGpurSvMv9D5Nr5CU5TXc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/contrib/propagators/b3 v1.19.0 h1:ulz44cpm6V5oAeg5Aw9HyqGFMS6XM7untlMEhD7YzzA= -go.opentelemetry.io/contrib/propagators/b3 v1.19.0/go.mod h1:OzCmE2IVS+asTI+odXQstRGVfXQ4bXv9nMBRK0nNyqQ= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.65.0 h1:kCBKHmfe+cFC7nrgJQdxpjveMD5hXqHToW7xuIMsTqU= +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.65.0/go.mod h1:JLdfEzERFdnjMGZPV3ceg4C+0s6uQalGoNWchryKO5I= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/contrib/propagators/b3 v1.40.0 h1:xariChe8OOVF3rNlfzGFgQc61npQmXhzZj/i82mxMfg= +go.opentelemetry.io/contrib/propagators/b3 v1.40.0/go.mod h1:72WvbdxbOfXaELEQfonFfOL6osvcVjI7uJEE8C2nkrs= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.podman.io/storage v1.62.0 h1:0QjX1XlzVmbiaulb+aR/CG6p9+pzaqwIeZPe3tEjHbY= @@ -1001,8 +1011,8 @@ 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.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= -go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20200104003542-c7e774b10ea0 h1:M6XsnQeLwG+rHQ+/rrGh3puBI3WZEy9TBWmf2H+enQA= @@ -1017,8 +1027,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f h1:WTyX8eCCyfdqiPYkRGm0MqElSfYFH3yR1+rl/mct9sA= @@ -1042,7 +1052,6 @@ golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1063,8 +1072,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= -golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= @@ -1137,9 +1146,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1190,7 +1198,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1: google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= -google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -1203,8 +1210,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1233,7 +1240,6 @@ gopkg.in/yaml.v3 v3.0.0-20191010095647-fc94e3f71652/go.mod h1:K4uyk7z7BCEPqu6E+C 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= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= @@ -1242,33 +1248,33 @@ k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYo k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kms v0.35.1 h1:kjv2r9g1mY7uL+l1RhyAZvWVZIA/4qIfBHXyjFGLRhU= -k8s.io/kms v0.35.1/go.mod h1:VT+4ekZAdrZDMgShK37vvlyHUVhwI9t/9tvh0AyCWmQ= -k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288 h1:A7Lby6ekC6nv+6oO38huCMFBRP0Os+tIeq1GkwxOQes= -k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/kms v0.36.2 h1:o0l8zMRecm38k5NyRnO/3+2YA/MR6TMGcc3KQZA76hI= +k8s.io/kms v0.36.2/go.mod h1:g91diTD9h0oJCCHkTb00krlF+Qm5HTnkWLi9Q/TpRoc= +k8s.io/kube-openapi v0.0.0-20260718133925-74c0ba7c0470 h1:BVDpOsFos+7pz64ZQ3g3mhfqFNKmBXW2a/BVXwbB7FI= +k8s.io/kube-openapi v0.0.0-20260718133925-74c0ba7c0470/go.mod h1:rcZ+P5cEvHQB+m154WBOatIGBgOEPjzmLkXjkHfg3ms= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.23.0 h1:Ubi7klJWiwEWqDY+odSVZiFA0aDSevOCXpa38yCSYu8= -sigs.k8s.io/controller-runtime v0.23.0/go.mod h1:DBOIr9NsprUqCZ1ZhsuJ0wAnQSIxY/C6VjZbmLgw0j0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240522175850-2e9781e9fc60 h1:ihaeBTCFuEYPL1T1/FqAavDY7z5UcKSnWpnb+I3DYeM= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240522175850-2e9781e9fc60/go.mod h1:4+4tM2Es0ycqPedATtzPer5RTrUq3Xab59BYogt0mCE= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96 h1:PFWFSkpArPNJxFX4ZKWAk9NSeRoZaXschn+ULa4xVek= sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96/go.mod h1:EOBQyBowOUsd7U4CJnMHNE0ri+zCXyouGdLwC/jZU+I= -sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= -sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= -sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= -sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po= +sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs= +sigs.k8s.io/kustomize/api v0.21.1/go.mod h1:f3wkKByTrgpgltLgySCntrYoq5d3q7aaxveSagwTlwI= +sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7fI= +sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/pkg/controller/drain/drain_controller.go b/pkg/controller/drain/drain_controller.go index 63af0fd5d4..466adb6922 100644 --- a/pkg/controller/drain/drain_controller.go +++ b/pkg/controller/drain/drain_controller.go @@ -418,7 +418,7 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro if duration > ctrl.cfg.DrainTimeoutDuration { logMessage := fmt.Sprintf("node %s: drain exceeded timeout: %v. Will continue to retry.", node.Name, ctrl.cfg.DrainTimeoutDuration) klog.Error(logMessage) - ctrl.eventRecorder.Eventf(node, corev1.EventTypeWarning, "DrainFailed", logMessage) + ctrl.eventRecorder.Eventf(node, corev1.EventTypeWarning, "DrainFailed", "%s", logMessage) ctrlcommon.MCCDrainErr.WithLabelValues(node.Name).Set(1) } break @@ -493,7 +493,7 @@ func (ctrl *Controller) drainNode(node *corev1.Node, drainer *drain.Helper) erro logMessage := fmt.Sprintf("Drain failed. Drain has been failing for more than %v minutes. Waiting %v minutes then retrying. "+ "Error message from drain: %v", ctrl.cfg.DrainRequeueFailingThreshold.Minutes(), ctrl.cfg.DrainRequeueFailingDelay.Minutes(), err) ctrl.logNode(node, "%s", logMessage) - ctrl.eventRecorder.Eventf(node, corev1.EventTypeWarning, "DrainThresholdExceeded", logMessage) + ctrl.eventRecorder.Eventf(node, corev1.EventTypeWarning, "DrainThresholdExceeded", "%s", logMessage) ctrl.enqueueAfter(node, ctrl.cfg.DrainRequeueFailingDelay) } else { ctrl.logNode(node, "Drain failed. Waiting %v minute then retrying. Error message from drain: %v", diff --git a/pkg/controller/kubelet-config/kubelet_config_nodes.go b/pkg/controller/kubelet-config/kubelet_config_nodes.go index 3d2a9e8182..30d4317ead 100644 --- a/pkg/controller/kubelet-config/kubelet_config_nodes.go +++ b/pkg/controller/kubelet-config/kubelet_config_nodes.go @@ -208,7 +208,7 @@ func (ctrl *Controller) updateNodeConfig(old, cur interface{}) { } if newNode.Name != ctrlcommon.ClusterNodeInstanceName { message := fmt.Sprintf("The node.config.openshift.io \"%v\" is invalid: metadata.name Invalid value: \"%v\" : must be \"%v\"", newNode.Name, newNode.Name, ctrlcommon.ClusterNodeInstanceName) - ctrl.eventRecorder.Eventf(oldNode, corev1.EventTypeNormal, "ActionProhibited", message) + ctrl.eventRecorder.Eventf(oldNode, corev1.EventTypeNormal, "ActionProhibited", "%s", message) klog.V(2).Infof("%s", message) return } @@ -228,7 +228,7 @@ func (ctrl *Controller) updateNodeConfig(old, cur interface{}) { } if !isValidWorkerLatencyProfleTransition { message := fmt.Sprintf("Skipping the Update Node event, name: %s, transition not allowed from old WorkerLatencyProfile: \"%s\" to new WorkerLatencyProfile: \"%s\"", newNode.Name, oldNode.Spec.WorkerLatencyProfile, newNode.Spec.WorkerLatencyProfile) - ctrl.eventRecorder.Eventf(newNode, corev1.EventTypeNormal, "ActionProhibited", message) + ctrl.eventRecorder.Eventf(newNode, corev1.EventTypeNormal, "ActionProhibited", "%s", message) klog.Info(message) return } @@ -246,7 +246,7 @@ func (ctrl *Controller) addNodeConfig(obj interface{}) { if nodeConfig.Name != ctrlcommon.ClusterNodeInstanceName { message := fmt.Sprintf("The node.config.openshift.io \"%v\" is invalid: metadata.name Invalid value: \"%v\" : must be \"%v\"", nodeConfig.Name, nodeConfig.Name, ctrlcommon.ClusterNodeInstanceName) klog.V(2).Info(message) - ctrl.eventRecorder.Eventf(nodeConfig, corev1.EventTypeNormal, "ActionProhibited", message) + ctrl.eventRecorder.Eventf(nodeConfig, corev1.EventTypeNormal, "ActionProhibited", "%s", message) return } klog.V(4).Infof("Adding the node config resource, name: %s", nodeConfig.Name) diff --git a/pkg/controller/node/node_controller.go b/pkg/controller/node/node_controller.go index c1d0df5ead..67ddefa52c 100644 --- a/pkg/controller/node/node_controller.go +++ b/pkg/controller/node/node_controller.go @@ -938,7 +938,7 @@ func (ctrl *Controller) updateNode(old, cur interface{}) { changed = true // For the control plane, emit events for these since they're important if pool.Name == ctrlcommon.MachineConfigPoolMaster { - ctrl.eventRecorder.Eventf(pool, corev1.EventTypeNormal, "AnnotationChange", controlPlaneChangedMsg) + ctrl.eventRecorder.Eventf(pool, corev1.EventTypeNormal, "AnnotationChange", "%s", controlPlaneChangedMsg) } } if !reflect.DeepEqual(oldNode.Labels, curNode.Labels) { diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index d238b25da2..2b2a53c5ed 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -938,7 +938,7 @@ func (dn *Daemon) runPreflightConfigDriftCheck() error { start := time.Now() if err := dn.validateOnDiskStateOrImage(currentOnDisk.currentConfig, currentOnDisk.currentImage); err != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "PreflightConfigDriftCheckFailed", err.Error()) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "PreflightConfigDriftCheckFailed", "%s", err.Error()) klog.Errorf("Preflight config drift check failed: %v", err) return &configDriftErr{err} } @@ -1456,7 +1456,7 @@ func (dn *Daemon) kubeletRebootstrap(ctx context.Context) error { // Called whenever the on-disk config has drifted from the current machineconfig. func (dn *Daemon) onConfigDrift(err error) { mcdConfigDrift.SetToCurrentTime() - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "ConfigDriftDetected", err.Error()) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "ConfigDriftDetected", "%s", err.Error()) klog.Error(err) if err := dn.updateErrorState(err); err != nil { klog.Errorf("Could not update annotation: %v", err) @@ -1545,9 +1545,7 @@ func (dn *Daemon) startConfigDriftMonitor() { return } - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ConfigDriftMonitorStarted", - "Config Drift Monitor started, watching against %s", odc.currentConfig.Name) - + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ConfigDriftMonitorStarted", "%s", fmt.Sprintf("Config Drift Monitor started, watching against %s", odc.currentConfig.Name)) go func() { // Common shutdown function shutdown := func() { @@ -1657,7 +1655,7 @@ func (dn *Daemon) syncFinalizationFailureAnnotation(finalizeError string) error // And let's emit this as an event if dn.previousFinalizationFailure != finalizeError { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedFinalization", finalizeError) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedFinalization", "%s", finalizeError) } annos := map[string]string{ @@ -2274,7 +2272,7 @@ func (dn *Daemon) checkStateOnFirstRun() error { } if err := dn.validateOnDiskStateOrImage(state.currentConfig, state.currentImage); err != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "OnDiskStateValidationFailed", err.Error()) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "OnDiskStateValidationFailed", "%s", err.Error()) // Start the config drift monitor even when there's pre-existing drift // so the metric gets initialized correctly on MCD restart dn.startConfigDriftMonitor() @@ -2293,7 +2291,7 @@ func (dn *Daemon) checkStateOnFirstRun() error { } if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "BootResync", fmt.Sprintf("Booting node %s, currentConfig %s, desiredConfig %s", dn.node.Name, state.currentConfig.GetName(), state.desiredConfig.GetName())) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "BootResync", "%s", fmt.Sprintf("Booting node %s, currentConfig %s, desiredConfig %s", dn.node.Name, state.currentConfig.GetName(), state.desiredConfig.GetName())) } // currentConfig != desiredConfig, and we're not booting up into the desiredConfig. @@ -2389,7 +2387,7 @@ func (dn *Daemon) updateConfigAndState(state *stateAndConfigs) (bool, bool, erro // We update the node annotation, and pop an event saying we're done. if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "NodeDone", fmt.Sprintf("Setting node %s, currentConfig %s to Done", dn.node.Name, state.currentConfig.GetName())) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "NodeDone", "%s", fmt.Sprintf("Setting node %s, currentConfig %s to Done", dn.node.Name, state.currentConfig.GetName())) } if err := dn.nodeWriter.SetDone(state); err != nil { @@ -2603,14 +2601,14 @@ func (dn *Daemon) completeUpdate(desiredConfigName string) error { }); err != nil { if wait.Interrupted(err) { failMsg := fmt.Sprintf("failed to uncordon node: %s after 10 minutes. Please see machine-config-controller logs for more information", dn.node.Name) - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToUncordon", failMsg) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToUncordon", "%s", failMsg) return errors.New(failMsg) } return fmt.Errorf("something went wrong while attempting to uncordon node: %w", err) } logSystem("Update completed for config %s and node has been successfully uncordoned", desiredConfigName) - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "Uncordon", fmt.Sprintf("Update completed for config %s and node has been uncordoned", desiredConfigName)) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "Uncordon", "%s", fmt.Sprintf("Update completed for config %s and node has been uncordoned", desiredConfigName)) return nil } diff --git a/pkg/daemon/drain.go b/pkg/daemon/drain.go index e34405abfb..d52891db74 100644 --- a/pkg/daemon/drain.go +++ b/pkg/daemon/drain.go @@ -111,7 +111,7 @@ func (dn *Daemon) performDrain() error { }); err != nil { if wait.Interrupted(err) { failMsg := fmt.Sprintf("failed to drain node: %s after 1 hour. Please see machine-config-controller logs for more information", dn.node.Name) - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToDrain", failMsg) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToDrain", "%s", failMsg) return errors.New(failMsg) diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go index 8f107bbec8..597da06110 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -126,7 +126,7 @@ func (dn *Daemon) finishRebootlessUpdate() error { func (dn *Daemon) executeReloadServiceNodeDisruptionAction(serviceName string, reloadErr error) error { if reloadErr != nil { if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", fmt.Sprintf("Reloading service %s failed. Error: %v", serviceName, reloadErr)) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", "%s", fmt.Sprintf("Reloading service %s failed. Error: %v", serviceName, reloadErr)) } return fmt.Errorf("could not apply update: reloading %s configuration failed. Error: %w", serviceName, reloadErr) } @@ -152,7 +152,7 @@ func (dn *Daemon) executeReloadServiceNodeDisruptionAction(serviceName string, r } if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ServiceReload", "Config changes do not require reboot. Service %s was reloaded.", serviceName) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ServiceReload", "%s", fmt.Sprintf("Config changes do not require reboot. Service %s was reloaded.", serviceName)) } logSystem("%s service reloaded successfully!", serviceName) return nil @@ -229,20 +229,20 @@ func (dn *Daemon) performPostConfigChangeNodeDisruptionAction(postConfigChangeAc cmd.Stderr = &stderr if err := cmd.Run(); err != nil { if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceRestart", fmt.Sprintf("Restarting %s service failed. Error: %v", serviceName, err)) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceRestart", "%s", fmt.Sprintf("Restarting %s service failed. Error: %v", serviceName, err)) } return fmt.Errorf("error running %s: %s: %w", constants.UpdateCATrustCommand, stderr.String(), err) } } else { if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceRestart", fmt.Sprintf("Restarting %s service failed. Error: %v", serviceName, err)) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceRestart", "%s", fmt.Sprintf("Restarting %s service failed. Error: %v", serviceName, err)) } return fmt.Errorf("could not apply update: restarting %s service failed. Error: %w", serviceName, err) } } // TODO: Add a new MCN Condition to the API for service restarts? if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ServiceRestart", "Config changes do not require reboot. Service %s was restarted.", serviceName) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "ServiceRestart", "%s", fmt.Sprintf("Config changes do not require reboot. Service %s was restarted.", serviceName)) } logSystem("%s service restarted successfully!", serviceName) @@ -325,7 +325,7 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string if err := reloadService(serviceName); err != nil { if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", fmt.Sprintf("Reloading %s service failed. Error: %v", serviceName, err)) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", "%s", fmt.Sprintf("Reloading %s service failed. Error: %v", serviceName, err)) } return fmt.Errorf("could not apply update: reloading %s configuration failed. Error: %w", serviceName, err) } @@ -363,7 +363,7 @@ func (dn *Daemon) performPostConfigChangeAction(postConfigChangeActions []string if err := restartService(serviceName); err != nil { if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", fmt.Sprintf("Reloading %s service failed. Error: %v", serviceName, err)) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedServiceReload", "%s", fmt.Sprintf("Reloading %s service failed. Error: %v", serviceName, err)) } return fmt.Errorf("could not apply update: reloading %s configuration failed. Error: %w", serviceName, err) } @@ -532,7 +532,7 @@ func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newC if mcDiff.osUpdate || mcDiff.extensions || mcDiff.kernelType || mcDiff.oclEnabled { // We emitted this event before, so keep it if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "InClusterUpgrade", fmt.Sprintf("Updating from oscontainer %s", newConfig.Spec.OSImageURL)) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "InClusterUpgrade", "%s", fmt.Sprintf("Updating from oscontainer %s", newConfig.Spec.OSImageURL)) } } @@ -558,7 +558,7 @@ func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newC // informative in such cases reason = fmt.Sprintf("Updating to a target config with %s kernel", helpers.CanonicalizeKernelType(newConfig.Spec.KernelType)) } - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpdateStarted", reason) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpdateStarted","%s", reason) } if err := dn.applyLayeredOSChanges(mcDiff, oldConfig, newConfig); err != nil { @@ -1007,7 +1007,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi } wrappedErr := fmt.Errorf("can't reconcile config %s with %s: %w", oldConfigName, newConfigName, reconcilableError) if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToReconcile", wrappedErr.Error()) + dn.nodeWriter.Eventf(corev1.EventTypeWarning, "FailedToReconcile", "%s", wrappedErr.Error()) } return &unreconcilableErr{wrappedErr} } @@ -3225,7 +3225,7 @@ func (dn *Daemon) reboot(rationale string) error { // We'll only have a recorder if we're cluster driven if dn.nodeWriter != nil { - dn.nodeWriter.Eventf(corev1.EventTypeNormal, "Reboot", rationale) + dn.nodeWriter.Eventf(corev1.EventTypeNormal, "Reboot", "%s", rationale) } logSystem("initiating reboot: %s", rationale) diff --git a/pkg/operator/status.go b/pkg/operator/status.go index 65f604209a..aaa7ae98a3 100644 --- a/pkg/operator/status.go +++ b/pkg/operator/status.go @@ -44,7 +44,7 @@ func (optr *Operator) syncVersion(co *configv1.ClusterOperator) { Namespace: co.Namespace, UID: co.GetUID(), } - optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", fmt.Sprintf("clusteroperator/machine-config version changed from %v to %v", co.Status.Versions, optr.vStore.GetAll())) + optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", "%s", fmt.Sprintf("clusteroperator/machine-config version changed from %v to %v", co.Status.Versions, optr.vStore.GetAll())) } co.Status.Versions = optr.vStore.GetAll() @@ -118,7 +118,7 @@ func (optr *Operator) syncProgressingStatus(co *configv1.ClusterOperator) { ) if optr.vStore.Equal(co.Status.Versions) { if optr.inClusterBringup { - optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", fmt.Sprintf("clusteroperator/machine-config is bootstrapping to %v", optr.vStore.GetAll())) + optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", "%s", fmt.Sprintf("clusteroperator/machine-config is bootstrapping to %v", optr.vStore.GetAll())) coStatusCondition.Message = fmt.Sprintf("Cluster is bootstrapping %s", optrVersion) coStatusCondition.Status = configv1.ConditionTrue } @@ -127,7 +127,7 @@ func (optr *Operator) syncProgressingStatus(co *configv1.ClusterOperator) { // but we want to fire the event only once when we're actually setting progressing and we // weren't progressing before. if !cov1helpers.IsStatusConditionTrue(co.Status.Conditions, configv1.OperatorProgressing) { - optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", fmt.Sprintf("clusteroperator/machine-config started a version change from %v to %v", co.Status.Versions, optr.vStore.GetAll())) + optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeNormal, "OperatorVersionChanged", "%s", fmt.Sprintf("clusteroperator/machine-config started a version change from %v to %v", co.Status.Versions, optr.vStore.GetAll())) } coStatusCondition.Message = fmt.Sprintf("Working towards %s", optrVersion) coStatusCondition.Status = configv1.ConditionTrue @@ -247,7 +247,7 @@ func (optr *Operator) syncDegradedStatus(co *configv1.ClusterOperator, ierr sync Namespace: co.Namespace, UID: co.GetUID(), } - optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeWarning, degradedReason, message) + optr.eventRecorder.Eventf(mcoObjectRef, corev1.EventTypeWarning, degradedReason, "%s", message) } cov1helpers.SetStatusCondition(&co.Status.Conditions, coDegradedCondition, clock.RealClock{}) diff --git a/vendor/cyphar.com/go-pathrs/handle_linux.go b/vendor/cyphar.com/go-pathrs/handle_linux.go index 3221ef6738..e8442b2b05 100644 --- a/vendor/cyphar.com/go-pathrs/handle_linux.go +++ b/vendor/cyphar.com/go-pathrs/handle_linux.go @@ -30,11 +30,9 @@ import ( // you can try to use [Root.Open] or [Root.OpenFile]. // // It is critical that perform all relevant operations through this [Handle] -// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]), +// (rather than fetching the underlying [os.File] yourself with [Handle.IntoFile]), // because the security properties of libpathrs depend on users doing all // relevant filesystem operations through libpathrs. -// -// [os.File]: https://pkg.go.dev/os#File type Handle struct { inner *os.File } @@ -43,7 +41,7 @@ type Handle struct { // handle will be copied by this method, so the original handle should still be // freed by the caller. // -// This is effectively the inverse operation of [Handle.IntoRaw], and is used +// This is effectively the inverse operation of [Handle.IntoFile], and is used // for "deserialising" pathrs root handles. func HandleFromFile(file *os.File) (*Handle, error) { newFile, err := fdutils.DupFile(file) @@ -92,8 +90,6 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) { // calling [Handle.Close] will also close any copies of the returned [os.File]. // If you want to get an independent copy, use [Handle.Clone] followed by // [Handle.IntoFile] on the cloned [Handle]. -// -// [os.File]: https://pkg.go.dev/os#File func (h *Handle) IntoFile() *os.File { // TODO: Figure out if we really don't want to make a copy. // TODO: We almost certainly want to clear r.inner here, but we can't do diff --git a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go index 5533c427cb..da97078f1f 100644 --- a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go +++ b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go @@ -64,8 +64,6 @@ func ProcPid(pid int) ProcBase { // ThreadCloser is a callback that needs to be called when you are done // operating on an [os.File] fetched using [Handle.OpenThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File type ThreadCloser func() // Handle is a wrapper around an *os.File handle to "/proc", which can be @@ -181,8 +179,6 @@ func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) { // Unlike [Handle.OpenThreadSelf], this method does not involve locking // the goroutine to the current OS thread and so is simpler to use and // theoretically has slightly less overhead. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) { file, closer, err := proc.open(ProcSelf, path, flags) if closer != nil { @@ -228,10 +224,6 @@ func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) { // callback MUST be called AFTER you have finished using the returned // [os.File]. This callback is completely separate to [os.File.Close], so it // must be called regardless of how you close the handle. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread -// [os.File]: https://pkg.go.dev/os#File -// [os.File.Close]: https://pkg.go.dev/os#File.Close func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) { return proc.open(ProcThreadSelf, path, flags) } diff --git a/vendor/cyphar.com/go-pathrs/root_linux.go b/vendor/cyphar.com/go-pathrs/root_linux.go index edc9e4c87f..b1cfd4e329 100644 --- a/vendor/cyphar.com/go-pathrs/root_linux.go +++ b/vendor/cyphar.com/go-pathrs/root_linux.go @@ -54,8 +54,6 @@ func OpenRoot(path string) (*Root, error) { // still be closed by the caller. // // This is effectively the inverse operation of [Root.IntoFile]. -// -// [os.File]: https://pkg.go.dev/os#File func RootFromFile(file *os.File) (*Root, error) { newFile, err := fdutils.DupFile(file) if err != nil { @@ -109,8 +107,6 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) { // ergonomic to use. // // This is effectively equivalent to [os.Open]. -// -// [os.Open]: https://pkg.go.dev/os#Open func (r *Root) Open(path string) (*os.File, error) { return r.OpenFile(path, os.O_RDONLY) } @@ -127,8 +123,6 @@ func (r *Root) Open(path string) (*os.File, error) { // // This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is // not supported. -// -// [os.OpenFile]: https://pkg.go.dev/os#OpenFile func (r *Root) OpenFile(path string, flags int) (*os.File, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { fd, err := libpathrs.InRootOpen(rootFd, path, flags) @@ -145,8 +139,6 @@ func (r *Root) OpenFile(path string, flags int) (*os.File, error) { // // Unlike [os.Create], if the file already exists an error is created rather // than the file being opened and truncated. -// -// [os.Create]: https://pkg.go.dev/os#Create func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) { unixMode, err := toUnixMode(mode, false) if err != nil { @@ -194,8 +186,6 @@ func (r *Root) RemoveFile(path string) error { // directory tree. // // This is effectively equivalent to [os.Remove]. -// -// [os.Remove]: https://pkg.go.dev/os#Remove func (r *Root) Remove(path string) error { // In order to match os.Remove's implementation we need to also do both // syscalls unconditionally and adjust the error based on whether @@ -219,8 +209,6 @@ func (r *Root) Remove(path string) error { // RemoveAll recursively deletes a path and all of its children. // // This is effectively equivalent to [os.RemoveAll]. -// -// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll func (r *Root) RemoveAll(path string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { err := libpathrs.InRootRemoveAll(rootFd, path) @@ -233,8 +221,6 @@ func (r *Root) RemoveAll(path string) error { // mode is used for the new directory (the process's umask applies). // // This is effectively equivalent to [os.Mkdir]. -// -// [os.Mkdir]: https://pkg.go.dev/os#Mkdir func (r *Root) Mkdir(path string, mode os.FileMode) error { unixMode, err := toUnixMode(mode, false) if err != nil { @@ -253,8 +239,6 @@ func (r *Root) Mkdir(path string, mode os.FileMode) error { // directories created by this function (the process's umask applies). // // This is effectively equivalent to [os.MkdirAll]. -// -// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { unixMode, err := toUnixMode(mode, false) if err != nil { @@ -278,9 +262,7 @@ func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { // directory tree. The provided mode is used for the new directory (the // process's umask applies). // -// This is effectively equivalent to [unix.Mknod]. -// -// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod +// This is effectively equivalent to [golang.org/x/sys/unix.Mknod]. func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { unixMode, err := toUnixMode(mode, true) if err != nil { @@ -298,8 +280,6 @@ func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { // created at path and is a link to target. // // This is effectively equivalent to [os.Symlink]. -// -// [os.Symlink]: https://pkg.go.dev/os#Symlink func (r *Root) Symlink(path, target string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { err := libpathrs.InRootSymlink(rootFd, path, target) @@ -314,8 +294,6 @@ func (r *Root) Symlink(path, target string) error { // host). // // This is effectively equivalent to [os.Link]. -// -// [os.Link]: https://pkg.go.dev/os#Link func (r *Root) Hardlink(path, target string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { err := libpathrs.InRootHardlink(rootFd, path, target) @@ -327,8 +305,6 @@ func (r *Root) Hardlink(path, target string) error { // Readlink returns the target of a symlink with a [Root]'s directory tree. // // This is effectively equivalent to [os.Readlink]. -// -// [os.Readlink]: https://pkg.go.dev/os#Readlink func (r *Root) Readlink(path string) (string, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) { return libpathrs.InRootReadlink(rootFd, path) @@ -345,8 +321,6 @@ func (r *Root) Readlink(path string) (string, error) { // calling [Root.Close] will also close any copies of the returned [os.File]. // If you want to get an independent copy, use [Root.Clone] followed by // [Root.IntoFile] on the cloned [Root]. -// -// [os.File]: https://pkg.go.dev/os#File func (r *Root) IntoFile() *os.File { // TODO: Figure out if we really don't want to make a copy. // TODO: We almost certainly want to clear r.inner here, but we can't do diff --git a/vendor/github.com/armon/circbuf/.gitignore b/vendor/github.com/armon/circbuf/.gitignore deleted file mode 100644 index 00268614f0..0000000000 --- a/vendor/github.com/armon/circbuf/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/vendor/github.com/armon/circbuf/LICENSE b/vendor/github.com/armon/circbuf/LICENSE deleted file mode 100644 index 106569e542..0000000000 --- a/vendor/github.com/armon/circbuf/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Armon Dadgar - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/armon/circbuf/README.md b/vendor/github.com/armon/circbuf/README.md deleted file mode 100644 index f2e356b8d7..0000000000 --- a/vendor/github.com/armon/circbuf/README.md +++ /dev/null @@ -1,28 +0,0 @@ -circbuf -======= - -This repository provides the `circbuf` package. This provides a `Buffer` object -which is a circular (or ring) buffer. It has a fixed size, but can be written -to infinitely. Only the last `size` bytes are ever retained. The buffer implements -the `io.Writer` interface. - -Documentation -============= - -Full documentation can be found on [Godoc](http://godoc.org/github.com/armon/circbuf) - -Usage -===== - -The `circbuf` package is very easy to use: - -```go -buf, _ := NewBuffer(6) -buf.Write([]byte("hello world")) - -if string(buf.Bytes()) != " world" { - panic("should only have last 6 bytes!") -} - -``` - diff --git a/vendor/github.com/armon/circbuf/circbuf.go b/vendor/github.com/armon/circbuf/circbuf.go deleted file mode 100644 index de3cb94a39..0000000000 --- a/vendor/github.com/armon/circbuf/circbuf.go +++ /dev/null @@ -1,92 +0,0 @@ -package circbuf - -import ( - "fmt" -) - -// Buffer implements a circular buffer. It is a fixed size, -// and new writes overwrite older data, such that for a buffer -// of size N, for any amount of writes, only the last N bytes -// are retained. -type Buffer struct { - data []byte - size int64 - writeCursor int64 - written int64 -} - -// NewBuffer creates a new buffer of a given size. The size -// must be greater than 0. -func NewBuffer(size int64) (*Buffer, error) { - if size <= 0 { - return nil, fmt.Errorf("Size must be positive") - } - - b := &Buffer{ - size: size, - data: make([]byte, size), - } - return b, nil -} - -// Write writes up to len(buf) bytes to the internal ring, -// overriding older data if necessary. -func (b *Buffer) Write(buf []byte) (int, error) { - // Account for total bytes written - n := len(buf) - b.written += int64(n) - - // If the buffer is larger than ours, then we only care - // about the last size bytes anyways - if int64(n) > b.size { - buf = buf[int64(n)-b.size:] - } - - // Copy in place - remain := b.size - b.writeCursor - copy(b.data[b.writeCursor:], buf) - if int64(len(buf)) > remain { - copy(b.data, buf[remain:]) - } - - // Update location of the cursor - b.writeCursor = ((b.writeCursor + int64(len(buf))) % b.size) - return n, nil -} - -// Size returns the size of the buffer -func (b *Buffer) Size() int64 { - return b.size -} - -// TotalWritten provides the total number of bytes written -func (b *Buffer) TotalWritten() int64 { - return b.written -} - -// Bytes provides a slice of the bytes written. This -// slice should not be written to. -func (b *Buffer) Bytes() []byte { - switch { - case b.written >= b.size && b.writeCursor == 0: - return b.data - case b.written > b.size: - out := make([]byte, b.size) - copy(out, b.data[b.writeCursor:]) - copy(out[b.size-b.writeCursor:], b.data[:b.writeCursor]) - return out - default: - return b.data[:b.writeCursor] - } -} - -// Reset resets the buffer so it has no content. -func (b *Buffer) Reset() { - b.writeCursor = 0 - b.written = 0 -} - -// String returns the contents of the buffer as a string -func (b *Buffer) String() string { - return string(b.Bytes()) -} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go similarity index 94% rename from vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go rename to vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go index 1c49674290..fe63fedadd 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go @@ -75,9 +75,8 @@ func Parse(arn string) (ARN, error) { }, nil } -// IsARN returns whether the given string is an ARN by looking for -// whether the string starts with "arn:" and contains the correct number -// of sections delimited by colons(:). +// IsARN returns whether the given string is an arn +// by looking for whether the string starts with arn: func IsARN(arn string) bool { return strings.HasPrefix(arn, arnPrefix) && strings.Count(arn, ":") >= arnSections-1 } diff --git a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt deleted file mode 100644 index 899129ecc4..0000000000 --- a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt +++ /dev/null @@ -1,3 +0,0 @@ -AWS SDK for Go -Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. -Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go b/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go index 13742ab01a..85d110112b 100644 --- a/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go +++ b/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go @@ -64,7 +64,7 @@ var ( ErrTangThumbprintRequired = errors.New("thumbprint is required") ErrInvalidTangAdvertisement = errors.New("advertisement is not valid JSON") ErrFileIllegalMode = errors.New("illegal file mode") - ErrModeSpecialBits = errors.New("setuid/setgid/sticky bits are not supported in spec versions older than 3.4.0") + ErrModeSpecialBits = errors.New("setuid/setgid/sticky bits are not supported or functional in spec versions older than 3.6.0") ErrBothIDAndNameSet = errors.New("cannot set both id and name") ErrLabelTooLong = errors.New("partition labels may not exceed 36 characters") ErrDoesntMatchGUIDRegex = errors.New("doesn't match the form \"01234567-89AB-CDEF-EDCB-A98765432101\"") diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_4/translate/translate.go b/vendor/github.com/coreos/ignition/v2/config/v3_4/translate/translate.go index 5d748d829e..5f6a23b88d 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_4/translate/translate.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_4/translate/translate.go @@ -16,7 +16,6 @@ package translate import ( "github.com/coreos/ignition/v2/config/translate" - "github.com/coreos/ignition/v2/config/util" old_types "github.com/coreos/ignition/v2/config/v3_3/types" "github.com/coreos/ignition/v2/config/v3_4/types" ) @@ -28,31 +27,6 @@ func translateIgnition(old old_types.Ignition) (ret types.Ignition) { return } -func translateFileEmbedded1(old old_types.FileEmbedded1) (ret types.FileEmbedded1) { - tr := translate.NewTranslator() - tr.Translate(&old.Append, &ret.Append) - tr.Translate(&old.Contents, &ret.Contents) - if old.Mode != nil { - // We support the special mode bits for specs >=3.4.0, so if - // the user provides special mode bits in an Ignition config - // with the version < 3.4.0, then we need to explicitly mask - // those bits out during translation. - ret.Mode = util.IntToPtr(*old.Mode & ^07000) - } - return -} - -func translateDirectoryEmbedded1(old old_types.DirectoryEmbedded1) (ret types.DirectoryEmbedded1) { - if old.Mode != nil { - // We support the special mode bits for specs >=3.4.0, so if - // the user provides special mode bits in an Ignition config - // with the version < 3.4.0, then we need to explicitly mask - // those bits out during translation. - ret.Mode = util.IntToPtr(*old.Mode & ^07000) - } - return -} - func translateLuks(old old_types.Luks) (ret types.Luks) { tr := translate.NewTranslator() tr.AddCustomTranslator(translateTang) @@ -77,8 +51,6 @@ func translateTang(old old_types.Tang) (ret types.Tang) { func Translate(old old_types.Config) (ret types.Config) { tr := translate.NewTranslator() tr.AddCustomTranslator(translateIgnition) - tr.AddCustomTranslator(translateDirectoryEmbedded1) - tr.AddCustomTranslator(translateFileEmbedded1) tr.AddCustomTranslator(translateLuks) tr.Translate(&old, &ret) return diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/directory.go b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/directory.go index f6f0684557..b01a6bf9d7 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/directory.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/directory.go @@ -22,5 +22,6 @@ import ( func (d Directory) Validate(c path.ContextPath) (r report.Report) { r.Merge(d.Node.Validate(c)) r.AddOnError(c.Append("mode"), validateMode(d.Mode)) + r.AddOnWarn(c.Append("mode"), validateModeSpecialBits(d.Mode)) return } diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/file.go b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/file.go index 9b71bb26aa..4e7566bd3b 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/file.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/file.go @@ -25,6 +25,7 @@ import ( func (f File) Validate(c path.ContextPath) (r report.Report) { r.Merge(f.Node.Validate(c)) r.AddOnError(c.Append("mode"), validateMode(f.Mode)) + r.AddOnWarn(c.Append("mode"), validateModeSpecialBits(f.Mode)) r.AddOnError(c.Append("overwrite"), f.validateOverwrite()) return } diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/mode.go b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/mode.go index 9eb7573d8b..ad3e51c22c 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/mode.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/mode.go @@ -24,3 +24,13 @@ func validateMode(m *int) error { } return nil } + +func validateModeSpecialBits(m *int) error { + if m != nil { + mode := uint32(*m) + if mode&07000 != 0 { + return errors.ErrModeSpecialBits + } + } + return nil +} diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/url.go b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/url.go index 3ca189dae3..97a4c9ae22 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_4/types/url.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_4/types/url.go @@ -18,7 +18,7 @@ import ( "net/url" "strings" - "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/vincent-petithory/dataurl" "github.com/coreos/ignition/v2/config/shared/errors" diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/directory.go b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/directory.go index f6f0684557..b01a6bf9d7 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/directory.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/directory.go @@ -22,5 +22,6 @@ import ( func (d Directory) Validate(c path.ContextPath) (r report.Report) { r.Merge(d.Node.Validate(c)) r.AddOnError(c.Append("mode"), validateMode(d.Mode)) + r.AddOnWarn(c.Append("mode"), validateModeSpecialBits(d.Mode)) return } diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/file.go b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/file.go index 9b71bb26aa..4e7566bd3b 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/file.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/file.go @@ -25,6 +25,7 @@ import ( func (f File) Validate(c path.ContextPath) (r report.Report) { r.Merge(f.Node.Validate(c)) r.AddOnError(c.Append("mode"), validateMode(f.Mode)) + r.AddOnWarn(c.Append("mode"), validateModeSpecialBits(f.Mode)) r.AddOnError(c.Append("overwrite"), f.validateOverwrite()) return } diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/mode.go b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/mode.go index 9eb7573d8b..ad3e51c22c 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/mode.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/mode.go @@ -24,3 +24,13 @@ func validateMode(m *int) error { } return nil } + +func validateModeSpecialBits(m *int) error { + if m != nil { + mode := uint32(*m) + if mode&07000 != 0 { + return errors.ErrModeSpecialBits + } + } + return nil +} diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/url.go b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/url.go index 3ca189dae3..97a4c9ae22 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5/types/url.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5/types/url.go @@ -18,7 +18,7 @@ import ( "net/url" "strings" - "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/vincent-petithory/dataurl" "github.com/coreos/ignition/v2/config/shared/errors" diff --git a/vendor/github.com/coreos/ignition/v2/config/validate/validate.go b/vendor/github.com/coreos/ignition/v2/config/validate/validate.go index 613c21e446..56ffcd0a76 100644 --- a/vendor/github.com/coreos/ignition/v2/config/validate/validate.go +++ b/vendor/github.com/coreos/ignition/v2/config/validate/validate.go @@ -83,7 +83,7 @@ func ValidateUnusedKeys(v reflect.Value, c path.ContextPath, root tree.Node) (r mapNode, ok := node.(tree.MapNode) if !ok { // Something is wrong, we won't be able to report unused keys here, so just warn about it and stop trying - r.AddOnWarn(c, fmt.Errorf("context tree does not match content tree at %s. Line and column reporting may be inconsistent. Unused keys may not be reported.", c.String())) + r.AddOnWarn(c, fmt.Errorf("context tree does not match content tree at %s. Line and column reporting may be inconsistent. Unused keys may not be reported", c.String())) return } @@ -94,7 +94,7 @@ func ValidateUnusedKeys(v reflect.Value, c path.ContextPath, root tree.Node) (r } for key := range mapNode.Keys { if _, ok := fieldMap[key]; !ok { - r.AddOnWarn(c.Append(tree.Key(key)), fmt.Errorf("Unused key %s", key)) + r.AddOnWarn(c.Append(tree.Key(key)), fmt.Errorf("unused key %s", key)) } } return diff --git a/vendor/github.com/docker/go-connections/tlsconfig/config.go b/vendor/github.com/docker/go-connections/tlsconfig/config.go index 606c98a38b..8b0264f68b 100644 --- a/vendor/github.com/docker/go-connections/tlsconfig/config.go +++ b/vendor/github.com/docker/go-connections/tlsconfig/config.go @@ -34,51 +34,37 @@ type Options struct { // the system pool will be used. ExclusiveRootPools bool MinVersion uint16 - // If Passphrase is set, it will be used to decrypt a TLS private key - // if the key is encrypted. - // - // Deprecated: Use of encrypted TLS private keys has been deprecated, and - // will be removed in a future release. Golang has deprecated support for - // legacy PEM encryption (as specified in RFC 1423), as it is insecure by - // design (see https://go-review.googlesource.com/c/go/+/264159). - Passphrase string -} - -// Extra (server-side) accepted CBC cipher suites - will phase out in the future -var acceptedCBCCiphers = []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, } // DefaultServerAcceptedCiphers should be uses by code which already has a crypto/tls // options struct but wants to use a commonly accepted set of TLS cipher suites, with // known weak algorithms removed. -var DefaultServerAcceptedCiphers = append(clientCipherSuites, acceptedCBCCiphers...) +var DefaultServerAcceptedCiphers = defaultCipherSuites + +// defaultCipherSuites is shared by both client and server as the default set. +var defaultCipherSuites = []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +} // ServerDefault returns a secure-enough TLS configuration for the server TLS configuration. func ServerDefault(ops ...func(*tls.Config)) *tls.Config { - tlsConfig := &tls.Config{ - // Avoid fallback by default to SSL protocols < TLS1.2 - MinVersion: tls.VersionTLS12, - PreferServerCipherSuites: true, - CipherSuites: DefaultServerAcceptedCiphers, - } - - for _, op := range ops { - op(tlsConfig) - } - - return tlsConfig + return defaultConfig(ops...) } // ClientDefault returns a secure-enough TLS configuration for the client TLS configuration. func ClientDefault(ops ...func(*tls.Config)) *tls.Config { + return defaultConfig(ops...) +} + +// defaultConfig is the default config used by both client and server TLS configuration. +func defaultConfig(ops ...func(*tls.Config)) *tls.Config { tlsConfig := &tls.Config{ - // Prefer TLS1.2 as the client minimum + // Avoid fallback by default to SSL protocols < TLS1.2 MinVersion: tls.VersionTLS12, - CipherSuites: clientCipherSuites, + CipherSuites: defaultCipherSuites, } for _, op := range ops { @@ -92,13 +78,13 @@ func ClientDefault(ops ...func(*tls.Config)) *tls.Config { func certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) { // If we should verify the server, we need to load a trusted ca var ( - certPool *x509.CertPool - err error + pool *x509.CertPool + err error ) if exclusivePool { - certPool = x509.NewCertPool() + pool = x509.NewCertPool() } else { - certPool, err = SystemCertPool() + pool, err = SystemCertPool() if err != nil { return nil, fmt.Errorf("failed to read system certificates: %v", err) } @@ -107,10 +93,10 @@ func certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) { if err != nil { return nil, fmt.Errorf("could not read CA certificate %q: %v", caFile, err) } - if !certPool.AppendCertsFromPEM(pemData) { + if !pool.AppendCertsFromPEM(pemData) { return nil, fmt.Errorf("failed to append certificates from PEM file: %q", caFile) } - return certPool, nil + return pool, nil } // allTLSVersions lists all the TLS versions and is used by the code that validates @@ -144,34 +130,32 @@ func adjustMinVersion(options Options, config *tls.Config) error { return nil } -// IsErrEncryptedKey returns true if the 'err' is an error of incorrect -// password when trying to decrypt a TLS private key. +// errEncryptedKeyDeprecated is produced when we encounter an encrypted +// (password-protected) key. From https://go-review.googlesource.com/c/go/+/264159; // -// Deprecated: Use of encrypted TLS private keys has been deprecated, and -// will be removed in a future release. Golang has deprecated support for -// legacy PEM encryption (as specified in RFC 1423), as it is insecure by -// design (see https://go-review.googlesource.com/c/go/+/264159). -func IsErrEncryptedKey(err error) bool { - return errors.Is(err, x509.IncorrectPasswordError) -} +// > Legacy PEM encryption as specified in RFC 1423 is insecure by design. Since +// > it does not authenticate the ciphertext, it is vulnerable to padding oracle +// > attacks that can let an attacker recover the plaintext +// > +// > It's unfortunate that we don't implement PKCS#8 encryption so we can't +// > recommend an alternative but PEM encryption is so broken that it's worth +// > deprecating outright. +// +// Also see https://docs.docker.com/go/deprecated/ +var errEncryptedKeyDeprecated = errors.New("private key is encrypted; encrypted private keys are obsolete, and not supported") // getPrivateKey returns the private key in 'keyBytes', in PEM-encoded format. -// If the private key is encrypted, 'passphrase' is used to decrypted the -// private key. -func getPrivateKey(keyBytes []byte, passphrase string) ([]byte, error) { +// It returns an error if the file could not be decoded or was protected by +// a passphrase. +func getPrivateKey(keyBytes []byte) ([]byte, error) { // this section makes some small changes to code from notary/tuf/utils/x509.go pemBlock, _ := pem.Decode(keyBytes) if pemBlock == nil { return nil, fmt.Errorf("no valid private key found") } - var err error if x509.IsEncryptedPEMBlock(pemBlock) { //nolint:staticcheck // Ignore SA1019 (IsEncryptedPEMBlock is deprecated) - keyBytes, err = x509.DecryptPEMBlock(pemBlock, []byte(passphrase)) //nolint:staticcheck // Ignore SA1019 (DecryptPEMBlock is deprecated) - if err != nil { - return nil, fmt.Errorf("private key is encrypted, but could not decrypt it: %w", err) - } - keyBytes = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyBytes}) + return nil, errEncryptedKeyDeprecated } return keyBytes, nil @@ -195,7 +179,7 @@ func getCert(options Options) ([]tls.Certificate, error) { return nil, err } - prKeyBytes, err = getPrivateKey(prKeyBytes, options.Passphrase) + prKeyBytes, err = getPrivateKey(prKeyBytes) if err != nil { return nil, err } @@ -210,7 +194,7 @@ func getCert(options Options) ([]tls.Certificate, error) { // Client returns a TLS configuration meant to be used by a client. func Client(options Options) (*tls.Config, error) { - tlsConfig := ClientDefault() + tlsConfig := defaultConfig() tlsConfig.InsecureSkipVerify = options.InsecureSkipVerify if !options.InsecureSkipVerify && options.CAFile != "" { CAs, err := certPool(options.CAFile, options.ExclusiveRootPools) @@ -235,7 +219,7 @@ func Client(options Options) (*tls.Config, error) { // Server returns a TLS configuration meant to be used by a server. func Server(options Options) (*tls.Config, error) { - tlsConfig := ServerDefault() + tlsConfig := defaultConfig() tlsConfig.ClientAuth = options.ClientAuth tlsCert, err := tls.LoadX509KeyPair(options.CertFile, options.KeyFile) if err != nil { diff --git a/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go b/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go deleted file mode 100644 index a82f9fa52e..0000000000 --- a/vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package tlsconfig provides primitives to retrieve secure-enough TLS configurations for both clients and servers. -package tlsconfig - -import ( - "crypto/tls" -) - -// Client TLS cipher suites (dropping CBC ciphers for client preferred suite set) -var clientCipherSuites = []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -} diff --git a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml index 38cb9ae101..08081fbde5 100644 --- a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml +++ b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml @@ -1,104 +1,116 @@ -# Do not delete linter settings. Linters like gocritic can be enabled on the command line. - -linters-settings: - depguard: - rules: - prevent_unmaintained_packages: - list-mode: strict - files: - - $all - - "!$test" - allow: - - $gostd - - github.com/x448/float16 - deny: - - pkg: io/ioutil - desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" - dupl: - threshold: 100 - funlen: - lines: 100 - statements: 50 - goconst: - ignore-tests: true - min-len: 2 - min-occurrences: 3 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - commentedOutCode - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - paramTypeCombine - - whyNoLint - gofmt: - simplify: false - goimports: - local-prefixes: github.com/fxamacker/cbor - golint: - min-confidence: 0 - govet: - check-shadowing: true - lll: - line-length: 140 - maligned: - suggest-new: true - misspell: - locale: US - staticcheck: - checks: ["all"] - +version: "2" linters: - disable-all: true + default: none enable: - asciicheck - bidichk - depguard - errcheck - - exportloopref + - forbidigo - goconst - gocritic - gocyclo - - gofmt - - goimports - goprintffuncname - gosec - - gosimple - govet - ineffassign - misspell - nilerr - revive - staticcheck - - stylecheck - - typecheck - unconvert - unused - + settings: + depguard: + rules: + prevent_unmaintained_packages: + list-mode: strict + files: + - $all + - '!$test' + allow: + - $gostd + - github.com/x448/float16 + deny: + - pkg: io/ioutil + desc: 'replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil' + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + goconst: + min-len: 2 + min-occurrences: 3 + gocritic: + disabled-checks: + - commentedOutCode + - dupImport + - ifElseChain + - octalLiteral + - paramTypeCombine + - whyNoLint + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + govet: + enable: + - shadow + lll: + line-length: 140 + misspell: + locale: US + staticcheck: + checks: + - all + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - path: decode.go + text: string ` overflows ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` \(range is \[` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `, ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` overflows Go's int64` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `\]\)` has (\d+) occurrences, make it a constant + - path: valid.go + text: string ` for type ` has (\d+) occurrences, make it a constant + - path: valid.go + text: 'string `cbor: ` has (\d+) occurrences, make it a constant' + - linters: + - goconst + path: (.+)_test\.go + paths: + - third_party$ + - builtin$ + - examples$ issues: - # max-issues-per-linter default is 50. Set to 0 to disable limit. max-issues-per-linter: 0 - # max-same-issues default is 3. Set to 0 to disable limit. max-same-issues: 0 - - exclude-rules: - - path: decode.go - text: "string ` overflows ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` \\(range is \\[` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `, ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` overflows Go's int64` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `\\]\\)` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string ` for type ` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string `cbor: ` has (\\d+) occurrences, make it a constant" +formatters: + enable: + - gofmt + - goimports + settings: + gofmt: + simplify: false + goimports: + local-prefixes: + - github.com/fxamacker/cbor + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md index d072b81c73..7aca561095 100644 --- a/vendor/github.com/fxamacker/cbor/v2/README.md +++ b/vendor/github.com/fxamacker/cbor/v2/README.md @@ -683,7 +683,7 @@ because RFC 8949 treats CBOR data item with remaining bytes as malformed. Other useful functions: - `Diagnose`, `DiagnoseFirst` produce human-readable [Extended Diagnostic Notation](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G) from CBOR data. - `UnmarshalFirst` decodes first CBOR data item and return any remaining bytes. -- `Wellformed` returns true if the CBOR data item is well-formed. +- `Wellformed` returns nil error if the CBOR data item is well-formed. Interfaces identical or comparable to Go `encoding` packages include: `Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`. @@ -702,28 +702,29 @@ Default limits may need to be increased for systems handling very large data (e. ## Status -[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. -- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string. -- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function. -- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR. +v2.9.2 (Sunday, May 3, 2026) refactors and hardens the streaming encoder by adding stricter checks for encoding to CBOR indefinite-length data. This prevents improper use of this library from producing malformed CBOR indefinite-length data that would be rejected by the decoder. -v2.9.0 passed fuzz tests and is production quality. +This release includes other bugfixes, defensive checks, and added more tests. -The minimum version of Go required to build: -- v2.8.0 and newer releases require go 1.20+. -- v2.7.1 and older releases require go 1.17+. +v2.9.2 passed fuzz tests (billions of executions) and is production quality. -For more details, see [release notes](https://github.com/fxamacker/cbor/releases). +For more details, see [v2.9.2 release notes](https://github.com/fxamacker/cbor/releases). ### Prior Releases -[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. +Releases and commits tend to be on Sundays because my work schedule didn't leave time to work on this during weekdays (sometimes consecutive weekends and consecutive Christmas breaks, too). Monday morning releases were to allow more fuzzing to run overnight before clicking the release button. -[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. +[v2.9.1](https://github.com/fxamacker/cbor/releases/tag/v2.9.1) (Monday, Mar 30, 2026) includes important bugfixes, defensive checks, improved code quality, and more tests. Although not public, the fuzzer was also improved by adding more fuzz tests. It passed fuzz tests (billions of executions) and is production quality. -[v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. +[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Sunday, Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. It passed fuzz tests (billions of executions) and is production quality. -[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). +[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (Sunday, March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. + +[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (Monday, June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. + +[v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (Sunday, Feb 11, 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. + +[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Sunday, August 13, 2023) adds new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). __IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading. diff --git a/vendor/github.com/fxamacker/cbor/v2/cache.go b/vendor/github.com/fxamacker/cbor/v2/cache.go index 5051f110fb..5743f3eb25 100644 --- a/vendor/github.com/fxamacker/cbor/v2/cache.go +++ b/vendor/github.com/fxamacker/cbor/v2/cache.go @@ -92,94 +92,126 @@ func newTypeInfo(t reflect.Type) *typeInfo { } type decodingStructType struct { - fields fields - fieldIndicesByName map[string]int - err error - toArray bool + fields decodingFields + fieldIndicesByName map[string]int // Only populated if toArray is false + fieldIndicesByIntKey map[int64]int // Only populated if toArray is false + err error + toArray bool } -// The stdlib errors.Join was introduced in Go 1.20, and we still support Go 1.17, so instead, -// here's a very basic implementation of an aggregated error. -type multierror []error - -func (m multierror) Error() string { - var sb strings.Builder - for i, err := range m { - sb.WriteString(err.Error()) - if i < len(m)-1 { - sb.WriteString(", ") - } - } - return sb.String() -} - -func getDecodingStructType(t reflect.Type) *decodingStructType { +func getDecodingStructType(t reflect.Type) (*decodingStructType, error) { if v, _ := decodingStructTypeCache.Load(t); v != nil { - return v.(*decodingStructType) + structType := v.(*decodingStructType) + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) toArray := hasToArrayOption(structOptions) - var errs []error - for i := 0; i < len(flds); i++ { - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - errs = append(errs, errors.New("cbor: failed to parse field name \""+flds[i].name+"\" to int ("+numErr.Error()+")")) - break + if toArray { + return getDecodingStructToArrayType(t, flds) + } + + fieldIndicesByName := make(map[string]int, len(flds)) + var fieldIndicesByIntKey map[int64]int + + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err } - flds[i].nameAsInt = int64(nameAsInt) } - flds[i].typInfo = getTypeInfo(flds[i].typ) - } + if f.keyAsInt { + if fieldIndicesByIntKey == nil { + fieldIndicesByIntKey = make(map[int64]int, len(flds)) + } + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByIntKey[f.nameAsInt]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same keyasint value %d", t, f.nameAsInt), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByIntKey[f.nameAsInt] = i + } else { + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByName[f.name]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, f.name), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByName[f.name] = i + } - fieldIndicesByName := make(map[string]int, len(flds)) - for i, fld := range flds { - if _, ok := fieldIndicesByName[fld.name]; ok { - errs = append(errs, fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, fld.name)) - continue + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), } - fieldIndicesByName[fld.name] = i } - var err error - { - var multi multierror - for _, each := range errs { - if each != nil { - multi = append(multi, each) + structType := &decodingStructType{ + fields: decFlds, + fieldIndicesByName: fieldIndicesByName, + fieldIndicesByIntKey: fieldIndicesByIntKey, + } + decodingStructTypeCache.Store(t, structType) + return structType, nil +} + +func getDecodingStructToArrayType(t reflect.Type, flds fields) (*decodingStructType, error) { + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err } } - if len(multi) == 1 { - err = multi[0] - } else if len(multi) > 1 { - err = multi + + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), } } structType := &decodingStructType{ - fields: flds, - fieldIndicesByName: fieldIndicesByName, - err: err, - toArray: toArray, + fields: decFlds, + toArray: true, } decodingStructTypeCache.Store(t, structType) - return structType + return structType, nil } type encodingStructType struct { - fields fields - bytewiseFields fields - lengthFirstFields fields - omitEmptyFieldsIdx []int + fields encodingFields + bytewiseFields encodingFields // Only populated if toArray is false + lengthFirstFields encodingFields // Only populated if toArray is false + omitEmptyFieldsIdx []int // Only populated if toArray is false err error toArray bool } -func (st *encodingStructType) getFields(em *encMode) fields { +func (st *encodingStructType) getFields(em *encMode) encodingFields { switch em.sort { case SortNone, SortFastShuffle: return st.fields @@ -191,7 +223,7 @@ func (st *encodingStructType) getFields(em *encMode) fields { } type bytewiseFieldSorter struct { - fields fields + fields encodingFields } func (x *bytewiseFieldSorter) Len() int { @@ -203,11 +235,11 @@ func (x *bytewiseFieldSorter) Swap(i, j int) { } func (x *bytewiseFieldSorter) Less(i, j int) bool { - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } type lengthFirstFieldSorter struct { - fields fields + fields encodingFields } func (x *lengthFirstFieldSorter) Len() int { @@ -222,13 +254,16 @@ func (x *lengthFirstFieldSorter) Less(i, j int) bool { if len(x.fields[i].cborName) != len(x.fields[j].cborName) { return len(x.fields[i].cborName) < len(x.fields[j].cborName) } - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { if v, _ := encodingStructTypeCache.Load(t); v != nil { structType := v.(*encodingStructType) - return structType, structType.err + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) @@ -237,111 +272,119 @@ func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { return getEncodingStructToArrayType(t, flds) } - var err error var hasKeyAsInt bool var hasKeyAsStr bool var omitEmptyIdx []int + + encFlds := make(encodingFields, len(flds)) + e := getEncodeBuffer() - for i := 0; i < len(flds); i++ { + defer putEncodeBuffer(e) + + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + ef := encFlds[i] + // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { - err = &UnsupportedTypeError{t} - break + ef.ef, ef.ief, ef.izf = getEncodeFunc(f.typ) + if ef.ef == nil { + structType := &encodingStructType{err: &UnsupportedTypeError{t}} + encodingStructTypeCache.Store(t, structType) + return nil, structType.err } // Encode field name - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - err = errors.New("cbor: failed to parse field name \"" + flds[i].name + "\" to int (" + numErr.Error() + ")") - break + if f.keyAsInt { + if f.nameAsInt == 0 { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &encodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + encodingStructTypeCache.Store(t, structType) + return nil, structType.err + } } - flds[i].nameAsInt = int64(nameAsInt) + nameAsInt := f.nameAsInt if nameAsInt >= 0 { - encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) + encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) //nolint:gosec } else { n := nameAsInt*(-1) - 1 - encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) + encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) //nolint:gosec } - flds[i].cborName = make([]byte, e.Len()) - copy(flds[i].cborName, e.Bytes()) + ef.cborName = make([]byte, e.Len()) + copy(ef.cborName, e.Bytes()) e.Reset() hasKeyAsInt = true } else { - encodeHead(e, byte(cborTypeTextString), uint64(len(flds[i].name))) - flds[i].cborName = make([]byte, e.Len()+len(flds[i].name)) - n := copy(flds[i].cborName, e.Bytes()) - copy(flds[i].cborName[n:], flds[i].name) + encodeHead(e, byte(cborTypeTextString), uint64(len(f.name))) + ef.cborName = make([]byte, e.Len()+len(f.name)) + n := copy(ef.cborName, e.Bytes()) + copy(ef.cborName[n:], f.name) e.Reset() // If cborName contains a text string, then cborNameByteString contains a // string that has the byte string major type but is otherwise identical to // cborName. - flds[i].cborNameByteString = make([]byte, len(flds[i].cborName)) - copy(flds[i].cborNameByteString, flds[i].cborName) + ef.cborNameByteString = make([]byte, len(ef.cborName)) + copy(ef.cborNameByteString, ef.cborName) // Reset encoded CBOR type to byte string, preserving the "additional // information" bits: - flds[i].cborNameByteString[0] = byte(cborTypeByteString) | - getAdditionalInformation(flds[i].cborNameByteString[0]) + ef.cborNameByteString[0] = byte(cborTypeByteString) | + getAdditionalInformation(ef.cborNameByteString[0]) hasKeyAsStr = true } // Check if field can be omitted when empty - if flds[i].omitEmpty { + if f.omitEmpty { omitEmptyIdx = append(omitEmptyIdx, i) } } - putEncodeBuffer(e) - - if err != nil { - structType := &encodingStructType{err: err} - encodingStructTypeCache.Store(t, structType) - return structType, structType.err - } // Sort fields by canonical order - bytewiseFields := make(fields, len(flds)) - copy(bytewiseFields, flds) + bytewiseFields := make(encodingFields, len(encFlds)) + copy(bytewiseFields, encFlds) sort.Sort(&bytewiseFieldSorter{bytewiseFields}) lengthFirstFields := bytewiseFields if hasKeyAsInt && hasKeyAsStr { - lengthFirstFields = make(fields, len(flds)) - copy(lengthFirstFields, flds) + lengthFirstFields = make(encodingFields, len(encFlds)) + copy(lengthFirstFields, encFlds) sort.Sort(&lengthFirstFieldSorter{lengthFirstFields}) } structType := &encodingStructType{ - fields: flds, + fields: encFlds, bytewiseFields: bytewiseFields, lengthFirstFields: lengthFirstFields, omitEmptyFieldsIdx: omitEmptyIdx, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodingStructToArrayType(t reflect.Type, flds fields) (*encodingStructType, error) { - for i := 0; i < len(flds); i++ { - // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { + encFlds := make(encodingFields, len(flds)) + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + encFlds[i].ef, encFlds[i].ief, encFlds[i].izf = getEncodeFunc(f.typ) + if encFlds[i].ef == nil { structType := &encodingStructType{err: &UnsupportedTypeError{t}} encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return nil, structType.err } } structType := &encodingStructType{ - fields: flds, + fields: encFlds, toArray: true, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodeFunc(t reflect.Type) (encodeFunc, isEmptyFunc, isZeroFunc) { diff --git a/vendor/github.com/fxamacker/cbor/v2/decode.go b/vendor/github.com/fxamacker/cbor/v2/decode.go index f0bdc3b38d..1d3e63d068 100644 --- a/vendor/github.com/fxamacker/cbor/v2/decode.go +++ b/vendor/github.com/fxamacker/cbor/v2/decode.go @@ -16,7 +16,6 @@ import ( "math/big" "reflect" "strconv" - "strings" "time" "unicode/utf8" @@ -326,14 +325,14 @@ func (dmkm DupMapKeyMode) valid() bool { return dmkm >= 0 && dmkm < maxDupMapKeyMode } -// IndefLengthMode specifies whether to allow indefinite length items. +// IndefLengthMode specifies whether to allow indefinite-length items. type IndefLengthMode int const ( - // IndefLengthAllowed allows indefinite length items. + // IndefLengthAllowed allows indefinite-length items. IndefLengthAllowed IndefLengthMode = iota - // IndefLengthForbidden disallows indefinite length items. + // IndefLengthForbidden disallows indefinite-length items. IndefLengthForbidden maxIndefLengthMode @@ -378,6 +377,7 @@ const ( // - int64 if value fits // - big.Int or *big.Int (see BigIntDecMode) if value < math.MinInt64 // - return UnmarshalTypeError if value > math.MaxInt64 + // // Deprecated: IntDecConvertSigned should not be used. // Please use other options, such as IntDecConvertSignedOrError, IntDecConvertSignedOrBigInt, IntDecConvertNone. IntDecConvertSigned @@ -811,7 +811,7 @@ type DecOptions struct { // Default is 128*1024=131072 and it can be set to [16, 2147483647] MaxMapPairs int - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // TagsMd specifies whether to allow CBOR tags (major type 6). @@ -1055,7 +1055,7 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore } if !opts.ExtraReturnErrors.valid() { - return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) + return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) //nolint:gosec } if opts.DefaultMapType != nil && opts.DefaultMapType.Kind() != reflect.Map { @@ -1149,8 +1149,8 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore unrecognizedTagToAny: opts.UnrecognizedTagToAny, timeTagToAny: opts.TimeTagToAny, simpleValues: simpleValues, - nanDec: opts.NaN, - infDec: opts.Inf, + nan: opts.NaN, + inf: opts.Inf, byteStringToTime: opts.ByteStringToTime, byteStringExpectedFormat: opts.ByteStringExpectedFormat, bignumTag: opts.BignumTag, @@ -1230,8 +1230,8 @@ type decMode struct { unrecognizedTagToAny UnrecognizedTagToAnyMode timeTagToAny TimeTagToAnyMode simpleValues *SimpleValueRegistry - nanDec NaNMode - infDec InfMode + nan NaNMode + inf InfMode byteStringToTime ByteStringToTimeMode byteStringExpectedFormat ByteStringExpectedFormatMode bignumTag BignumTagMode @@ -1272,8 +1272,8 @@ func (dm *decMode) DecOptions() DecOptions { UnrecognizedTagToAny: dm.unrecognizedTagToAny, TimeTagToAny: dm.timeTagToAny, SimpleValues: simpleValues, - NaN: dm.nanDec, - Inf: dm.infDec, + NaN: dm.nan, + Inf: dm.inf, ByteStringToTime: dm.byteStringToTime, ByteStringExpectedFormat: dm.byteStringExpectedFormat, BignumTag: dm.bignumTag, @@ -1583,11 +1583,11 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin _, ai, val := d.getHead() switch ai { case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat64: @@ -1595,10 +1595,10 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return fillFloat(t, f, v) default: // ai <= 24 - if d.dm.simpleValues.rejected[SimpleValue(val)] { + if d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } @@ -1677,20 +1677,23 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return d.parseToValue(v, tInfo) case cborTypeArray: - if tInfo.nonPtrKind == reflect.Slice { + switch tInfo.nonPtrKind { + case reflect.Slice: return d.parseArrayToSlice(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Array { + case reflect.Array: return d.parseArrayToArray(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Struct { + case reflect.Struct: return d.parseArrayToStruct(v, tInfo) } + d.skip() return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()} case cborTypeMap: - if tInfo.nonPtrKind == reflect.Struct { + switch tInfo.nonPtrKind { + case reflect.Struct: return d.parseMapToStruct(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Map { + case reflect.Map: return d.parseMapToMap(v, tInfo) } d.skip() @@ -1745,8 +1748,8 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { // Read tag number _, _, tagNum := d.getHead() if tagNum != 0 && tagNum != 1 { - d.skip() // skip tag content - return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") + d.skip() // skip tag content + return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") //nolint:gosec } } } else { @@ -1815,10 +1818,10 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { var f float64 switch ai { case additionalInformationAsFloat16: - f = float64(float16.Frombits(uint16(val)).Float32()) + f = float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec case additionalInformationAsFloat32: - f = float64(math.Float32frombits(uint32(val))) + f = float64(math.Float32frombits(uint32(val))) //nolint:gosec case additionalInformationAsFloat64: f = math.Float64frombits(val) @@ -1832,6 +1835,13 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { return time.Time{}, true, nil } seconds, fractional := math.Modf(f) + if seconds > math.MaxInt64 || seconds < math.MinInt64 { + return time.Time{}, false, &UnmarshalTypeError{ + CBORType: t.String(), + GoType: typeTime.String(), + errorMsg: fmt.Sprintf("%v overflows Go's int64", f), + } + } return time.Unix(int64(seconds), int64(fractional*1e9)), true, nil default: @@ -2145,14 +2155,14 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc case cborTypePrimitives: _, ai, val := d.getHead() - if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { + if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return nil, &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } if ai < 20 || ai == 24 { - return SimpleValue(val), nil + return SimpleValue(val), nil //nolint:gosec } switch ai { @@ -2165,11 +2175,11 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc return nil, nil case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return f, nil case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return f, nil case additionalInformationAsFloat64: @@ -2202,16 +2212,16 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc func (d *decoder) parseByteString() ([]byte, bool) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec return b, false } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - b = append(b, d.data[d.off:d.off+int(val)]...) - d.off += int(val) + b = append(b, d.data[d.off:d.off+int(val)]...) //nolint:gosec + d.off += int(val) //nolint:gosec } return b, true } @@ -2253,7 +2263,7 @@ func (d *decoder) applyByteStringTextConversion( default: // If this happens, there is a bug: the decoder has pushed an invalid // "expected later encoding" tag to the stack. - panic(fmt.Sprintf("unrecognized expected later encoding tag: %d", d.expectedLaterEncodingTags)) + panic(fmt.Sprintf("unrecognized expected later encoding tag: %d", d.expectedLaterEncodingTags[len(d.expectedLaterEncodingTags)-1])) } case reflect.Slice: @@ -2300,19 +2310,19 @@ func (d *decoder) applyByteStringTextConversion( func (d *decoder) parseTextString() ([]byte, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(b) { return nil, &SemanticError{"cbor: invalid UTF-8 string"} } return b, nil } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - x := d.data[d.off : d.off+int(val)] - d.off += int(val) + x := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(x) { for !d.foundBreak() { d.skip() // Skip remaining chunk on error @@ -2327,7 +2337,7 @@ func (d *decoder) parseTextString() ([]byte, error) { func (d *decoder) parseArray() ([]any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2349,7 +2359,7 @@ func (d *decoder) parseArray() ([]any, error) { func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2371,7 +2381,7 @@ func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec gi := 0 vLen := v.Len() var err error @@ -2400,7 +2410,7 @@ func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseMap() (any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec m := make(map[any]any) var k, e any var err, lastErr error @@ -2465,7 +2475,7 @@ func (d *decoder) parseMap() (any, error) { func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if v.IsNil() { mapsize := count if !hasSize { @@ -2566,9 +2576,9 @@ func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //noli } func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if !structType.toArray { @@ -2584,7 +2594,7 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { start := d.off _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size } @@ -2637,11 +2647,72 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { return err } -// parseMapToStruct needs to be fast so gocyclo can be ignored for now. +// skipMapEntriesFromIndex skips remaining map entries starting from index i. +func (d *decoder) skipMapEntriesFromIndex(i, count int, hasSize bool) { + for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { + d.skip() + d.skip() + } +} + +// skipMapForDupKey skips the current map value and all remaining map entries, +// then returns a DupMapKeyError for the given key at map index i. +func (d *decoder) skipMapForDupKey(dupKey any, i, count int, hasSize bool) error { + // Skip the value of the duplicate key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &DupMapKeyError{dupKey, i} +} + +// skipMapForUnknownField skips the current map value and all remaining map entries, +// then returns a UnknownFieldError for the given key at map index i. +func (d *decoder) skipMapForUnknownField(i, count int, hasSize bool) error { + // Skip the value of the unknown key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &UnknownFieldError{i} +} + +// decodeToStructField decodes the next CBOR value into the struct field f in v. +// If the field cannot be resolved, the CBOR value is skipped. +func (d *decoder) decodeToStructField(v reflect.Value, f *decodingField, tInfo *typeInfo) error { + var fv reflect.Value + + if len(f.idx) == 1 { + fv = v.Field(f.idx[0]) + } else { + var err error + fv, err = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { + // Return a new value for embedded field null pointer to point to, or return error. + if !v.CanSet() { + return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) + } + v.Set(reflect.New(v.Type().Elem())) + return v, nil + }) + if !fv.IsValid() { + d.skip() + return err + } + } + + err := d.parseToValue(fv, f.typInfo) + if err != nil { + if typeError, ok := err.(*UnmarshalTypeError); ok { + typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name + } + return err + } + + return nil +} + func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if structType.toArray { @@ -2654,14 +2725,12 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - var err, lastErr error - // Get CBOR map size _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec - // Keeps track of matched struct fields + // Keep track of matched struct fields to detect duplicate map keys. var foundFldIdx []bool { const maxStackFields = 128 @@ -2675,99 +2744,80 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - // Keeps track of CBOR map keys to detect duplicate map key - keyCount := 0 - var mapKeys map[any]struct{} - - errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + // Keep track of unmatched CBOR map keys to detect duplicate map keys. + var unmatchedMapKeys map[any]struct{} -MapEntryLoop: - for j := 0; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - var f *field + var err error - // If duplicate field detection is enabled and the key at index j did not match any - // field, k will hold the map key. - var k any + caseInsensitive := d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive + for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { t := d.nextCBORType() - if t == cborTypeTextString || (t == cborTypeByteString && d.dm.fieldNameByteString == FieldNameByteStringAllowed) { + + // Reclassify disallowed byte string keys so they fall to the default case. + // keyType is only used for branch control. + keyType := t + if t == cborTypeByteString && d.dm.fieldNameByteString != FieldNameByteStringAllowed { + keyType = 0xff + } + + switch keyType { + case cborTypeTextString, cborTypeByteString: var keyBytes []byte if t == cborTypeTextString { - keyBytes, lastErr = d.parseTextString() - if lastErr != nil { + var parseErr error + keyBytes, parseErr = d.parseTextString() + if parseErr != nil { if err == nil { - err = lastErr + err = parseErr } - d.skip() // skip value + d.skip() // Skip value continue } } else { // cborTypeByteString keyBytes, _ = d.parseByteString() } - // Check for exact match on field name. - if i, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { - fld := structType.fields[i] + // Find matching struct field (exact match, then case-insensitive fallback). + if fldIdx, ok := findStructFieldByKey(structType, keyBytes, caseInsensitive); ok { + fld := structType.fields[fldIdx] - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{fld.name, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - return err - } else { - // discard repeated match + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(string(keyBytes), i, count, hasSize) + case mapActionSkipValueAndContinue: d.skip() - continue MapEntryLoop + continue } } - // Find field with case-insensitive match - if f == nil && d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive { - keyLen := len(keyBytes) - keyString := string(keyBytes) - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if len(fld.name) == keyLen && strings.EqualFold(fld.name, keyString) { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{keyString, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop - } - break - } - } + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, string(keyBytes), i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = string(keyBytes) - } - } else if t <= cborTypeNegativeInt { // uint/int + case cborTypePositiveInt, cborTypeNegativeInt: var nameAsInt int64 if t == cborTypePositiveInt { _, _, val := d.getHead() - nameAsInt = int64(val) + if val > math.MaxInt64 { + if err == nil { + err = &UnmarshalTypeError{ + CBORType: t.String(), + GoType: reflect.TypeOf(int64(0)).String(), + errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64", + } + } + d.skip() // skip value + continue + } + nameAsInt = int64(val) //nolint:gosec } else { _, _, val := d.getHead() if val > math.MaxInt64 { @@ -2781,39 +2831,35 @@ MapEntryLoop: d.skip() // skip value continue } - nameAsInt = int64(-1) ^ int64(val) - } - - // Find field - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if fld.keyAsInt && fld.nameAsInt == nameAsInt { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{nameAsInt, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop + nameAsInt = int64(-1) ^ int64(val) //nolint:gosec + } + + // Find field by integer key + if fldIdx, ok := structType.fieldIndicesByIntKey[nameAsInt]; ok { + fld := structType.fields[fldIdx] + + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - break + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(nameAsInt, i, count, hasSize) + case mapActionSkipValueAndContinue: + d.skip() + continue } } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = nameAsInt + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, nameAsInt, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - } else { + + default: + // CBOR map keys that can't be matched to any struct field. + if err == nil { err = &UnmarshalTypeError{ CBORType: t.String(), @@ -2821,97 +2867,31 @@ MapEntryLoop: errorMsg: "map key is of type " + t.String() + " and cannot be used to match struct field name", } } + + var otherKey any if d.dm.dupMapKey == DupMapKeyEnforcedAPF { // parse key - k, lastErr = d.parse(true) - if lastErr != nil { + var parseErr error + otherKey, parseErr = d.parse(true) + if parseErr != nil { d.skip() // skip value continue } // Detect if CBOR map key can be used as Go map key. - if !isHashableValue(reflect.ValueOf(k)) { + if !isHashableValue(reflect.ValueOf(otherKey)) { d.skip() // skip value continue } } else { d.skip() // skip key } - } - - if f == nil { - if errOnUnknownField { - err = &UnknownFieldError{j} - d.skip() // Skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - - // Two map keys that match the same struct field are immediately considered - // duplicates. This check detects duplicates between two map keys that do - // not match a struct field. If unknown field errors are enabled, then this - // check is never reached. - if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - if mapKeys == nil { - mapKeys = make(map[any]struct{}, 1) - } - mapKeys[k] = struct{}{} - newKeyCount := len(mapKeys) - if newKeyCount == keyCount { - err = &DupMapKeyError{k, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - keyCount = newKeyCount - } - - d.skip() // Skip value - continue - } - - // Get field value by index - var fv reflect.Value - if len(f.idx) == 1 { - fv = v.Field(f.idx[0]) - } else { - fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { - // Return a new value for embedded field null pointer to point to, or return error. - if !v.CanSet() { - return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) - } - v.Set(reflect.New(v.Type().Elem())) - return v, nil - }) - if lastErr != nil && err == nil { - err = lastErr - } - if !fv.IsValid() { - d.skip() - continue - } - } - if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil { - if err == nil { - if typeError, ok := lastErr.(*UnmarshalTypeError); ok { - typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name - err = typeError - } else { - err = lastErr - } + if unmatchedErr := handleUnmatchedMapKey(d, otherKey, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } } } + return err } @@ -2958,15 +2938,15 @@ func (d *decoder) skip() { switch t { case cborTypeByteString, cborTypeTextString: - d.off += int(val) + d.off += int(val) //nolint:gosec case cborTypeArray: - for i := 0; i < int(val); i++ { + for i := 0; i < int(val); i++ { //nolint:gosec d.skip() } case cborTypeMap: - for i := 0; i < int(val)*2; i++ { + for i := 0; i < int(val)*2; i++ { //nolint:gosec d.skip() } diff --git a/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go new file mode 100644 index 0000000000..3c8c423ad1 --- /dev/null +++ b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go @@ -0,0 +1,98 @@ +// Copyright (c) Faye Amacker. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +package cbor + +import "strings" + +// mapAction represents the next action during decoding a CBOR map to a Go struct. +type mapAction int + +const ( + mapActionParseValueAndContinue mapAction = iota // The caller should process the map value. + mapActionSkipValueAndContinue // The caller should skip the map value. + mapActionSkipAllAndReturnError // The caller should skip the rest of the map and return an error. +) + +// checkDupField checks if a struct field at index i has already been matched and returns the next action. +// If not matched, it marks the field as matched and returns mapActionParseValueAndContinue. +// If matched and DupMapKeyEnforcedAPF is specified in the given dm, it returns mapActionSkipAllAndReturnError. +// If matched and DupMapKeyEnforcedAPF is not specified in the given dm, it returns mapActionSkipValueAndContinue. +func checkDupField(dm *decMode, foundFldIdx []bool, i int) mapAction { + if !foundFldIdx[i] { + foundFldIdx[i] = true + return mapActionParseValueAndContinue + } + if dm.dupMapKey == DupMapKeyEnforcedAPF { + return mapActionSkipAllAndReturnError + } + return mapActionSkipValueAndContinue +} + +// findStructFieldByKey finds a struct field matching keyBytes by name. +// It tries an exact match first. If no exact match is found and +// caseInsensitive is true, it falls back to a case-insensitive search. +// findStructFieldByKey returns the field index and true, or -1 and false. +func findStructFieldByKey( + structType *decodingStructType, + keyBytes []byte, + caseInsensitive bool, +) (int, bool) { + if fldIdx, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { + return fldIdx, true + } + if caseInsensitive { + return findFieldCaseInsensitive(structType.fields, string(keyBytes)) + } + return -1, false +} + +// findFieldCaseInsensitive returns the index of the first field whose name +// case-insensitively matches key, or -1 and false if no field matches. +func findFieldCaseInsensitive(flds decodingFields, key string) (int, bool) { + keyLen := len(key) + for i, f := range flds { + if f.keyAsInt { + continue + } + if len(f.name) == keyLen && strings.EqualFold(f.name, key) { + return i, true + } + } + return -1, false +} + +// handleUnmatchedMapKey handles a map entry whose key does not match any struct +// field. It can return UnknownFieldError or DupMapKeyError. +// handleUnmatchedMapKey consumes the CBOR value, so the caller doesn't need to skip any values. +// If an error is returned, the caller should abort parsing the map and return the error. +// If no error is returned, the caller should continue to process the next map pair. +func handleUnmatchedMapKey( + d *decoder, + key any, + i int, + count int, + hasSize bool, + // *map[any]struct{} is used here because we use lazy initialization for uks + uks *map[any]struct{}, //nolint:gocritic +) error { + errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + + if errOnUnknownField { + return d.skipMapForUnknownField(i, count, hasSize) + } + + if d.dm.dupMapKey == DupMapKeyEnforcedAPF { + if *uks == nil { + *uks = make(map[any]struct{}) + } + if _, dup := (*uks)[key]; dup { + return d.skipMapForDupKey(key, i, count, hasSize) + } + (*uks)[key] = struct{}{} + } + + // Skip value. + d.skip() + return nil +} diff --git a/vendor/github.com/fxamacker/cbor/v2/diagnose.go b/vendor/github.com/fxamacker/cbor/v2/diagnose.go index 44afb86608..42a67ad11f 100644 --- a/vendor/github.com/fxamacker/cbor/v2/diagnose.go +++ b/vendor/github.com/fxamacker/cbor/v2/diagnose.go @@ -51,11 +51,8 @@ const ( maxByteStringEncoding ) -func (bse ByteStringEncoding) valid() error { - if bse >= maxByteStringEncoding { - return errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(bse))) - } - return nil +func (bse ByteStringEncoding) valid() bool { + return bse < maxByteStringEncoding } // DiagOptions specifies Diag options. @@ -104,8 +101,8 @@ func (opts DiagOptions) DiagMode() (DiagMode, error) { } func (opts DiagOptions) diagMode() (*diagMode, error) { - if err := opts.ByteStringEncoding.valid(); err != nil { - return nil, err + if !opts.ByteStringEncoding.valid() { + return nil, errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(opts.ByteStringEncoding))) } decMode, err := DecOptions{ @@ -360,7 +357,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeArray: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('[') for i := 0; i < count; i++ { @@ -376,7 +373,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeMap: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('{') for i := 0; i < count; i++ { @@ -477,8 +474,8 @@ func (di *diagnose) item() error { //nolint:gocyclo func (di *diagnose) writeU16(val rune) { di.w.WriteString("\\u") var in [2]byte - in[0] = byte(val >> 8) - in[1] = byte(val) + in[0] = byte(val >> 8) //nolint:gosec + in[1] = byte(val) //nolint:gosec sz := hex.EncodedLen(len(in)) di.w.Grow(sz) dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz] @@ -608,7 +605,7 @@ func (di *diagnose) encodeTextString(val string, quote byte) error { c, size := utf8.DecodeRuneInString(val[i:]) switch { - case c == utf8.RuneError: + case c == utf8.RuneError && size == 1: return &SemanticError{"cbor: invalid UTF-8 string"} case c < utf16SurrSelf: @@ -631,7 +628,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { f64 := float64(0) switch ai { case additionalInformationAsFloat16: - f16 := float16.Frombits(uint16(val)) + f16 := float16.Frombits(uint16(val)) //nolint:gosec switch { case f16.IsNaN(): di.w.WriteString("NaN") @@ -647,7 +644,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { } case additionalInformationAsFloat32: - f32 := math.Float32frombits(uint32(val)) + f32 := math.Float32frombits(uint32(val)) //nolint:gosec switch { case f32 != f32: di.w.WriteString("NaN") diff --git a/vendor/github.com/fxamacker/cbor/v2/doc.go b/vendor/github.com/fxamacker/cbor/v2/doc.go index c758b73748..e4c1d27b8d 100644 --- a/vendor/github.com/fxamacker/cbor/v2/doc.go +++ b/vendor/github.com/fxamacker/cbor/v2/doc.go @@ -56,20 +56,30 @@ modes won't accidentally change at runtime after they're created. Modes are intended to be reused and are safe for concurrent use. -EncMode and DecMode Interfaces +EncMode, UserBufferEncMode, and DecMode Interfaces // EncMode interface uses immutable options and is safe for concurrent use. type EncMode interface { - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) NewEncoder(w io.Writer) *Encoder - EncOptions() EncOptions // returns copy of options + EncOptions() EncOptions + } + + // UserBufferEncMode extends EncMode with MarshalToBuffer, which supports + // user specified buffer rather than encoding into the built-in buffer pool. + type UserBufferEncMode interface { + EncMode + MarshalToBuffer(v any, buf *bytes.Buffer) error } // DecMode interface uses immutable options and is safe for concurrent use. type DecMode interface { - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error + UnmarshalFirst(data []byte, v any) (rest []byte, err error) + Valid(data []byte) error // Deprecated: use Wellformed instead. + Wellformed(data []byte) error NewDecoder(r io.Reader) *Decoder - DecOptions() DecOptions // returns copy of options + DecOptions() DecOptions } Using Default Encoding Mode diff --git a/vendor/github.com/fxamacker/cbor/v2/encode.go b/vendor/github.com/fxamacker/cbor/v2/encode.go index c550617c38..e65a29d8a6 100644 --- a/vendor/github.com/fxamacker/cbor/v2/encode.go +++ b/vendor/github.com/fxamacker/cbor/v2/encode.go @@ -30,7 +30,7 @@ import ( // If value implements the Marshaler interface, Marshal calls its // MarshalCBOR method. // -// If value implements encoding.BinaryMarshaler, Marhsal calls its +// If value implements encoding.BinaryMarshaler, Marshal calls its // MarshalBinary method and encode it as CBOR byte string. // // Boolean values encode as CBOR booleans (type 7). @@ -343,7 +343,7 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339 // TimeRFC3339Nano causes time.Time to encode to a CBOR time (tag 0) with a text string content @@ -351,9 +351,13 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339Nano. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339Nano + // TimeRFC3339NanoUTC causes time.Time to encode to a CBOR time (tag 0) with a text string content + // representing UTC time using nanosecond precision in RFC3339 format. + TimeRFC3339NanoUTC + maxTimeMode ) @@ -436,7 +440,7 @@ const ( // FieldNameToTextString encodes struct fields to CBOR text string (major type 3). FieldNameToTextString FieldNameMode = iota - // FieldNameToTextString encodes struct fields to CBOR byte string (major type 2). + // FieldNameToByteString encodes struct fields to CBOR byte string (major type 2). FieldNameToByteString maxFieldNameMode @@ -567,7 +571,7 @@ type EncOptions struct { // RFC3339 format gets tag number 0, and numeric epoch time tag number 1. TimeTag EncTagMode - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // NilContainers specifies how to encode nil slices and maps. @@ -1132,10 +1136,11 @@ func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error { if fopt == ShortestFloat16 { var f16 float16.Float16 p := float16.PrecisionFromfloat32(f32) - if p == float16.PrecisionExact { + switch p { + case float16.PrecisionExact: // Roundtrip float32->float16->float32 test isn't needed. f16 = float16.Fromfloat32(f32) - } else if p == float16.PrecisionUnknown { + case float16.PrecisionUnknown: // Try roundtrip float32->float16->float32 to determine if float32 can fit into float16. f16 = float16.Fromfloat32(f32) if f16.Float32() == f32 { @@ -1293,10 +1298,10 @@ func encodeByteString(e *bytes.Buffer, em *encMode, v reflect.Value) error { if slen == 0 { return e.WriteByte(byte(cborTypeByteString)) } - encodeHead(e, byte(cborTypeByteString), uint64(slen)) + encodeHead(e, byte(cborTypeByteString), uint64(slen)) //nolint:gosec if vk == reflect.Array { for i := 0; i < slen; i++ { - e.WriteByte(byte(v.Index(i).Uint())) + e.WriteByte(byte(v.Index(i).Uint())) //nolint:gosec } return nil } @@ -1333,7 +1338,7 @@ func (ae arrayEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) if alen == 0 { return e.WriteByte(byte(cborTypeArray)) } - encodeHead(e, byte(cborTypeArray), uint64(alen)) + encodeHead(e, byte(cborTypeArray), uint64(alen)) //nolint:gosec for i := 0; i < alen; i++ { if err := ae.f(e, em, v.Index(i)); err != nil { return err @@ -1364,7 +1369,7 @@ func (me mapEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) er return e.WriteByte(byte(cborTypeMap)) } - encodeHead(e, byte(cborTypeMap), uint64(mlen)) + encodeHead(e, byte(cborTypeMap), uint64(mlen)) //nolint:gosec if em.sort == SortNone || em.sort == SortFastShuffle || mlen <= 1 { return me.e(e, em, v, nil) } @@ -1427,7 +1432,7 @@ func (x *bytewiseKeyValueSorter) Swap(i, j int) { func (x *bytewiseKeyValueSorter) Less(i, j int) bool { kvi, kvj := x.kvs[i], x.kvs[j] - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } type lengthFirstKeyValueSorter struct { @@ -1448,7 +1453,7 @@ func (x *lengthFirstKeyValueSorter) Less(i, j int) bool { if keyLengthDifference := (kvi.valueOffset - kvi.offset) - (kvj.valueOffset - kvj.offset); keyLengthDifference != 0 { return keyLengthDifference < 0 } - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } var keyValuePool = sync.Pool{} @@ -1535,8 +1540,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Head is rewritten later if actual encoded field count is different from struct field count. encodedHeadLen := encodeHead(e, byte(cborTypeMap), uint64(len(flds))) - kvbegin := e.Len() - kvcount := 0 + kvBeginOffset := e.Len() + kvCount := 0 for offset := 0; offset < len(flds); offset++ { f := flds[(start+offset)%len(flds)] @@ -1582,10 +1587,10 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { return err } - kvcount++ + kvCount++ } - if len(flds) == kvcount { + if len(flds) == kvCount { // Encoded element count in head is the same as actual element count. return nil } @@ -1593,8 +1598,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Overwrite the bytes that were reserved for the head before encoding the map entries. var actualHeadLen int { - headbuf := *bytes.NewBuffer(e.Bytes()[kvbegin-encodedHeadLen : kvbegin-encodedHeadLen : kvbegin]) - actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvcount)) + headbuf := *bytes.NewBuffer(e.Bytes()[kvBeginOffset-encodedHeadLen : kvBeginOffset-encodedHeadLen : kvBeginOffset]) + actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvCount)) } if actualHeadLen == encodedHeadLen { @@ -1607,8 +1612,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // encoded. The encoded entries are offset to the right by the number of excess reserved // bytes. Shift the entries left to remove the gap. excessReservedBytes := encodedHeadLen - actualHeadLen - dst := e.Bytes()[kvbegin-excessReservedBytes : e.Len()-excessReservedBytes] - src := e.Bytes()[kvbegin:e.Len()] + dst := e.Bytes()[kvBeginOffset-excessReservedBytes : e.Len()-excessReservedBytes] + src := e.Bytes()[kvBeginOffset:e.Len()] copy(dst, src) // After shifting, the excess bytes are at the end of the output buffer and they are @@ -1633,7 +1638,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { } if em.timeTag == EncTagRequired { tagNumber := 1 - if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano { + if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano || em.time == TimeRFC3339NanoUTC { tagNumber = 0 } encodeHead(e, byte(cborTypeTag), uint64(tagNumber)) @@ -1650,7 +1655,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { case TimeUnixDynamic: t = t.UTC().Round(time.Microsecond) - secs, nsecs := t.Unix(), uint64(t.Nanosecond()) + secs, nsecs := t.Unix(), uint64(t.Nanosecond()) //nolint:gosec if nsecs == 0 { return encodeInt(e, em, reflect.ValueOf(secs)) } @@ -1661,6 +1666,10 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { s := t.Format(time.RFC3339) return encodeString(e, em, reflect.ValueOf(s)) + case TimeRFC3339NanoUTC: + s := t.UTC().Format(time.RFC3339Nano) + return encodeString(e, em, reflect.ValueOf(s)) + default: // TimeRFC3339Nano s := t.Format(time.RFC3339Nano) return encodeString(e, em, reflect.ValueOf(s)) diff --git a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go index 30f72814f6..9912e855c2 100644 --- a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go +++ b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go @@ -93,6 +93,6 @@ func (sv *SimpleValue) unmarshalCBOR(data []byte) error { // It is safe to cast val to uint8 here because // - data is already verified to be well-formed CBOR simple value and // - val is <= math.MaxUint8. - *sv = SimpleValue(val) + *sv = SimpleValue(val) //nolint:gosec return nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/stream.go b/vendor/github.com/fxamacker/cbor/v2/stream.go index 7ac6d7d671..282b3f7ddc 100644 --- a/vendor/github.com/fxamacker/cbor/v2/stream.go +++ b/vendor/github.com/fxamacker/cbor/v2/stream.go @@ -6,6 +6,7 @@ package cbor import ( "bytes" "errors" + "fmt" "io" "reflect" ) @@ -157,11 +158,32 @@ func (dec *Decoder) overwriteBuf(newBuf []byte) { dec.off = 0 } +// indefDataItem tracks open indefinite-length data item during encoding. +// typ is the CBOR type of the indefinite-length data item. +// count is the number of items written so far. +// For indefinite-length maps, count must be even (key/value pairs) when +// the container is closed. +type indefDataItem struct { + typ cborType + count int +} + +// IndefiniteLengthMapOddItemCountError indicates that EndIndefinite was +// called on an open indefinite-length map with an odd number of items. +type IndefiniteLengthMapOddItemCountError struct { + count int +} + +func (e *IndefiniteLengthMapOddItemCountError) Error() string { + return fmt.Sprintf("cbor: cannot end indefinite-length map with %d item(s)", e.count) +} + // Encoder writes CBOR values to io.Writer. type Encoder struct { - w io.Writer - em *encMode - indefTypes []cborType + w io.Writer + em *encMode + indefs []indefDataItem + scratch [1]byte // reused for single-byte writes (indefinite-length head and break code) } // NewEncoder returns a new encoder that writes to w using the default encoding options. @@ -171,89 +193,166 @@ func NewEncoder(w io.Writer) *Encoder { // Encode writes the CBOR encoding of v. func (enc *Encoder) Encode(v any) error { - if len(enc.indefTypes) > 0 && v != nil { - indefType := enc.indefTypes[len(enc.indefTypes)-1] - if indefType == cborTypeTextString { - k := reflect.TypeOf(v).Kind() - if k != reflect.String { - return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length text string") - } - } else if indefType == cborTypeByteString { - t := reflect.TypeOf(v) - k := t.Kind() - if (k != reflect.Array && k != reflect.Slice) || t.Elem().Kind() != reflect.Uint8 { - return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length byte string") - } + if len(enc.indefs) > 0 { + err := validateIndefiniteLengthChunkByType(enc.indefs[len(enc.indefs)-1].typ, v) + if err != nil { + return err } } buf := getEncodeBuffer() err := encode(buf, enc.em, reflect.ValueOf(v)) + + // Validate the encoded chunk against the indefinite-length data item using a byte-based check. + // This reliably detects chunks from cbor.Marshaler, registered tags, StringToByteString, etc., + // which may produce a chunk inconsistent with the parent's major type. + // Applies only to indefinite-length byte/text string parents (RFC 8949 Section 3.2.3). + if err == nil && len(enc.indefs) > 0 { + err = validateIndefiniteLengthChunkByData(enc.indefs[len(enc.indefs)-1].typ, buf.Bytes(), v) + } + if err == nil { _, err = enc.w.Write(buf.Bytes()) } putEncodeBuffer(buf) - return err + + if err != nil { + return err + } + + if len(enc.indefs) > 0 { + enc.indefs[len(enc.indefs)-1].count++ + } + + return nil } -// StartIndefiniteByteString starts byte string encoding of indefinite length. +// StartIndefiniteByteString starts indefinite-length byte string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length byte strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteByteString() error { return enc.startIndefinite(cborTypeByteString) } -// StartIndefiniteTextString starts text string encoding of indefinite length. +// StartIndefiniteTextString starts indefinite-length text string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length text strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteTextString() error { return enc.startIndefinite(cborTypeTextString) } -// StartIndefiniteArray starts array encoding of indefinite length. +// StartIndefiniteArray starts indefinite-length array encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the array // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteArray() error { return enc.startIndefinite(cborTypeArray) } -// StartIndefiniteMap starts array encoding of indefinite length. +// StartIndefiniteMap starts indefinite-length map encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the map // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteMap() error { return enc.startIndefinite(cborTypeMap) } -// EndIndefinite closes last opened indefinite length value. +// EndIndefinite closes last opened indefinite-length value. +// It returns *IndefiniteLengthMapOddItemCountError without writing the +// "break" code if the open indefinite-length map has an odd number of +// items; the encoder state is unchanged so the caller can write the +// missing value and retry. func (enc *Encoder) EndIndefinite() error { - if len(enc.indefTypes) == 0 { + if len(enc.indefs) == 0 { return errors.New("cbor: cannot encode \"break\" code outside indefinite length values") } - _, err := enc.w.Write([]byte{cborBreakFlag}) - if err == nil { - enc.indefTypes = enc.indefTypes[:len(enc.indefTypes)-1] + + // Verify that indefinite-length map has even number of elements + top := enc.indefs[len(enc.indefs)-1] + if top.typ == cborTypeMap && top.count%2 != 0 { + return &IndefiniteLengthMapOddItemCountError{count: top.count} } - return err -} -var cborIndefHeader = map[cborType][]byte{ - cborTypeByteString: {cborByteStringWithIndefiniteLengthHead}, - cborTypeTextString: {cborTextStringWithIndefiniteLengthHead}, - cborTypeArray: {cborArrayWithIndefiniteLengthHead}, - cborTypeMap: {cborMapWithIndefiniteLengthHead}, + // Write break code + enc.scratch[0] = cborBreakFlag + _, err := enc.w.Write(enc.scratch[:]) + if err != nil { + return err + } + + enc.indefs = enc.indefs[:len(enc.indefs)-1] + + // Increment parent container's item count because the child + // (indefinite-length data item) is fully written to the stream. + if len(enc.indefs) > 0 { + enc.indefs[len(enc.indefs)-1].count++ + } + + return nil } func (enc *Encoder) startIndefinite(typ cborType) error { if enc.em.indefLength == IndefLengthForbidden { return &IndefiniteLengthError{typ} } - _, err := enc.w.Write(cborIndefHeader[typ]) - if err == nil { - enc.indefTypes = append(enc.indefTypes, typ) + + // Verify that new indefinite-length data item is not a chunk in indefinite-length byte/text string. + if len(enc.indefs) > 0 { + parent := enc.indefs[len(enc.indefs)-1].typ + if parent == cborTypeByteString || parent == cborTypeTextString { + return errors.New("cbor: cannot encode indefinite-length " + typ.String() + + " as chunk of indefinite-length " + parent.String()) + } } - return err + + // Write indefinite-length head. + enc.scratch[0] = byte(typ) | additionalInformationAsIndefiniteLengthFlag + _, err := enc.w.Write(enc.scratch[:]) + if err != nil { + return err + } + + enc.indefs = append(enc.indefs, indefDataItem{typ: typ}) + return nil +} + +// validateIndefiniteLengthChunkByType rejects chunks based solely on their Go type. +func validateIndefiniteLengthChunkByType(indefiniteLengthCborType cborType, v any) error { + if indefiniteLengthCborType != cborTypeByteString && + indefiniteLengthCborType != cborTypeTextString { + return nil + } + if v == nil { + return errors.New("cbor: cannot encode nil for indefinite-length " + indefiniteLengthCborType.String()) + } + return nil +} + +// validateIndefiniteLengthChunkByData checks that chunk is a definite-length +// CBOR data item with a matching major type. +// No-op for indefinite-length array/map, where any data item is valid. +func validateIndefiniteLengthChunkByData(indefiniteLengthCborType cborType, chunk []byte, v any) error { + if indefiniteLengthCborType != cborTypeByteString && + indefiniteLengthCborType != cborTypeTextString { + return nil + } + + if len(chunk) == 0 { + return errors.New("cbor: cannot encode item type " + reflect.TypeOf(v).Kind().String() + + " for indefinite-length " + indefiniteLengthCborType.String()) + } + + t, ai := parseInitialByte(chunk[0]) + if t != indefiniteLengthCborType { + return errors.New("cbor: cannot encode item type " + reflect.TypeOf(v).Kind().String() + + " for indefinite-length " + indefiniteLengthCborType.String()) + } + + if ai == additionalInformationAsIndefiniteLengthFlag { + return errors.New("cbor: cannot encode indefinite-length " + indefiniteLengthCborType.String() + + " as chunk of indefinite-length " + indefiniteLengthCborType.String()) + } + return nil } // RawMessage is a raw encoded CBOR value. @@ -262,7 +361,9 @@ type RawMessage []byte // MarshalCBOR returns m or CBOR nil if m is nil. func (m RawMessage) MarshalCBOR() ([]byte, error) { if len(m) == 0 { - return cborNil, nil + b := make([]byte, len(cborNil)) + copy(b, cborNil) + return b, nil } return m, nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/structfields.go b/vendor/github.com/fxamacker/cbor/v2/structfields.go index cf0a922cd7..b2d71f2e9a 100644 --- a/vendor/github.com/fxamacker/cbor/v2/structfields.go +++ b/vendor/github.com/fxamacker/cbor/v2/structfields.go @@ -6,27 +6,43 @@ package cbor import ( "reflect" "sort" + "strconv" "strings" ) +// field holds shared struct field metadata returned by getFields(). type field struct { - name string - nameAsInt int64 // used to decoder to match field name with CBOR int + name string + nameAsInt int64 // used to match field name with CBOR int + idx []int + typ reflect.Type // used during cache building only + keyAsInt bool // used to encode/decode field name as int + tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) + omitEmpty bool // used to skip empty field + omitZero bool // used to skip zero field +} + +type fields []*field + +// encodingField extends field with encoding-specific data. +type encodingField struct { + field cborName []byte - cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3 - idx []int - typ reflect.Type + cborNameByteString []byte // major type 2 name encoding if cborName has major type 3 ef encodeFunc ief isEmptyFunc izf isZeroFunc - typInfo *typeInfo // used to decoder to reuse type info - tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) - omitEmpty bool // used to skip empty field - omitZero bool // used to skip zero field - keyAsInt bool // used to encode/decode field name as int } -type fields []*field +type encodingFields []*encodingField + +// decodingField extends field with decoding-specific data. +type decodingField struct { + field + typInfo *typeInfo // used by decoder to reuse type info +} + +type decodingFields []*decodingField // indexFieldSorter sorts fields by field idx at each level, breaking ties with idx depth. type indexFieldSorter struct { @@ -48,7 +64,7 @@ func (x *indexFieldSorter) Less(i, j int) bool { return iIdx[k] < jIdx[k] } } - return len(iIdx) <= len(jIdx) + return len(iIdx) < len(jIdx) } // nameLevelAndTagFieldSorter sorts fields by field name, idx depth, and presence of tag. @@ -69,6 +85,10 @@ func (x *nameLevelAndTagFieldSorter) Less(i, j int) bool { if fi.name != fj.name { return fi.name < fj.name } + // Fields with the same name but different keyAsInt are in separate namespaces. + if fi.keyAsInt != fj.keyAsInt { + return fi.keyAsInt + } if len(fi.idx) != len(fj.idx) { return len(fi.idx) < len(fj.idx) } @@ -117,22 +137,37 @@ func getFields(t reflect.Type) (flds fields, structOptions string) { } } + // Normalize keyasint field names to their canonical integer string form. + // This ensures that "01", "+1", and "1" are treated as the same key + // during deduplication. + for _, f := range flds { + if f.keyAsInt { + nameAsInt, err := strconv.Atoi(f.name) + if err != nil { + continue // Leave invalid names for callers to report. + } + f.nameAsInt = int64(nameAsInt) + f.name = strconv.Itoa(nameAsInt) + } + } + sort.Sort(&nameLevelAndTagFieldSorter{flds}) // Keep visible fields. j := 0 // index of next unique field for i := 0; i < len(flds); { name := flds[i].name + keyAsInt := flds[i].keyAsInt if i == len(flds)-1 || // last field - name != flds[i+1].name || // field i has unique field name + name != flds[i+1].name || flds[i+1].keyAsInt != keyAsInt || // field i has unique (name, keyAsInt) len(flds[i].idx) < len(flds[i+1].idx) || // field i is at a less nested level than field i+1 (flds[i].tagged && !flds[i+1].tagged) { // field i is tagged while field i+1 is not flds[j] = flds[i] j++ } - // Skip fields with the same field name. - for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive + // Skip fields with the same (name, keyAsInt). + for i++; i < len(flds) && name == flds[i].name && keyAsInt == flds[i].keyAsInt; i++ { //nolint:revive } } if j != len(flds) { diff --git a/vendor/github.com/fxamacker/cbor/v2/tag.go b/vendor/github.com/fxamacker/cbor/v2/tag.go index bd8b773f54..ee46e74213 100644 --- a/vendor/github.com/fxamacker/cbor/v2/tag.go +++ b/vendor/github.com/fxamacker/cbor/v2/tag.go @@ -155,6 +155,7 @@ type TagSet interface { Add(opts TagOptions, contentType reflect.Type, num uint64, nestedNum ...uint64) error // Remove removes given tag content type from TagSet. + // Remove is a no-op if contentType is nil. Remove(contentType reflect.Type) tagProvider @@ -245,7 +246,11 @@ func (t *syncTagSet) Add(opts TagOptions, contentType reflect.Type, num uint64, } // Remove removes given tag content type from TagSet. +// Remove is a no-op if contentType is nil. func (t *syncTagSet) Remove(contentType reflect.Type) { + if contentType == nil { + return + } for contentType.Kind() == reflect.Pointer { contentType = contentType.Elem() } diff --git a/vendor/github.com/fxamacker/cbor/v2/valid.go b/vendor/github.com/fxamacker/cbor/v2/valid.go index b40793b95e..850b95019c 100644 --- a/vendor/github.com/fxamacker/cbor/v2/valid.go +++ b/vendor/github.com/fxamacker/cbor/v2/valid.go @@ -54,7 +54,7 @@ func (e *MaxMapPairsError) Error() string { return "cbor: exceeded max number of key-value pairs " + strconv.Itoa(e.maxMapPairs) + " for CBOR map" } -// IndefiniteLengthError indicates found disallowed indefinite length items. +// IndefiniteLengthError indicates found disallowed indefinite-length items. type IndefiniteLengthError struct { t cborType } @@ -113,7 +113,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err } return d.wellformedIndefiniteString(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, causing integer overflow") @@ -136,7 +136,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return d.wellformedIndefiniteArrayOrMap(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, it would cause integer overflow") @@ -212,7 +212,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return depth, nil } -// wellformedIndefiniteString checks indefinite length byte/text string's well-formedness and returns max depth and error. +// wellformedIndefiniteString checks indefinite-length byte/text string's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error for { @@ -223,7 +223,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin d.off++ break } - // Peek ahead to get next type and indefinite length status. + // Peek ahead to get next type and indefinite-length status. nt, ai := parseInitialByte(d.data[d.off]) if t != nt { return 0, &SyntaxError{"cbor: wrong element type " + nt.String() + " for indefinite-length " + t.String()} @@ -238,7 +238,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin return depth, nil } -// wellformedIndefiniteArrayOrMap checks indefinite length array/map's well-formedness and returns max depth and error. +// wellformedIndefiniteArrayOrMap checks indefinite-length array/map's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteArrayOrMap(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error maxDepth := depth @@ -326,7 +326,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { + if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -341,7 +341,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { + if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -379,12 +379,12 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) func (d *decoder) acceptableFloat(f float64) error { switch { - case d.dm.nanDec == NaNDecodeForbidden && math.IsNaN(f): + case d.dm.nan == NaNDecodeForbidden && math.IsNaN(f): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point NaN", } - case d.dm.infDec == InfDecodeForbidden && math.IsInf(f, 0): + case d.dm.inf == InfDecodeForbidden && math.IsInf(f, 0): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point infinity", diff --git a/vendor/github.com/godbus/dbus/v5/.cirrus.yml b/vendor/github.com/godbus/dbus/v5/.cirrus.yml index 75a0d798ae..6e2090296e 100644 --- a/vendor/github.com/godbus/dbus/v5/.cirrus.yml +++ b/vendor/github.com/godbus/dbus/v5/.cirrus.yml @@ -1,10 +1,11 @@ +# See https://cirrus-ci.org/guide/FreeBSD/ freebsd_instance: - image_family: freebsd-14-0 + image_family: freebsd-14-3 task: name: Test on FreeBSD - install_script: pkg install -y go122 dbus + install_script: pkg install -y go125 dbus test_script: | /usr/local/etc/rc.d/dbus onestart && \ eval `dbus-launch --sh-syntax` && \ - go122 test -v ./... + go125 test -v ./... diff --git a/vendor/github.com/godbus/dbus/v5/.golangci.yml b/vendor/github.com/godbus/dbus/v5/.golangci.yml index f2d7910d4c..5bbdd9342b 100644 --- a/vendor/github.com/godbus/dbus/v5/.golangci.yml +++ b/vendor/github.com/godbus/dbus/v5/.golangci.yml @@ -1,7 +1,13 @@ -# For documentation, see https://golangci-lint.run/usage/configuration/ +version: "2" linters: enable: - - gofumpt - unconvert - unparam + exclusions: + presets: + - std-error-handling + +formatters: + enable: + - gofumpt diff --git a/vendor/github.com/godbus/dbus/v5/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go index 5fecbd3d41..c56dbaad3a 100644 --- a/vendor/github.com/godbus/dbus/v5/auth.go +++ b/vendor/github.com/godbus/dbus/v5/auth.go @@ -54,10 +54,10 @@ type Auth interface { func (conn *Conn) Auth(methods []Auth) error { if methods == nil { uid := strconv.Itoa(os.Geteuid()) - methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())} + methods = getDefaultAuthMethods(uid) } in := bufio.NewReader(conn.transport) - err := conn.transport.SendNullByte() + err := conn.SendNullByte() if err != nil { return err } diff --git a/vendor/github.com/godbus/dbus/v5/auth_default_other.go b/vendor/github.com/godbus/dbus/v5/auth_default_other.go new file mode 100644 index 0000000000..e112ccfe96 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/auth_default_other.go @@ -0,0 +1,7 @@ +//go:build !windows + +package dbus + +func getDefaultAuthMethods(user string) []Auth { + return []Auth{AuthExternal(user)} +} diff --git a/vendor/github.com/godbus/dbus/v5/auth_default_windows.go b/vendor/github.com/godbus/dbus/v5/auth_default_windows.go new file mode 100644 index 0000000000..2289850a8e --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/auth_default_windows.go @@ -0,0 +1,5 @@ +package dbus + +func getDefaultAuthMethods(user string) []Auth { + return []Auth{AuthCookieSha1(user, getHomeDir())} +} diff --git a/vendor/github.com/godbus/dbus/v5/auth_sha1.go b/vendor/github.com/godbus/dbus/v5/auth_sha1_windows.go similarity index 95% rename from vendor/github.com/godbus/dbus/v5/auth_sha1.go rename to vendor/github.com/godbus/dbus/v5/auth_sha1_windows.go index 80286700b6..0c5480eee1 100644 --- a/vendor/github.com/godbus/dbus/v5/auth_sha1.go +++ b/vendor/github.com/godbus/dbus/v5/auth_sha1_windows.go @@ -100,3 +100,10 @@ func (a authCookieSha1) generateChallenge() []byte { hex.Encode(enc, b) return enc } + +func getHomeDir() string { + if dir, err := os.UserHomeDir(); err == nil { + return dir + } + return "/" +} diff --git a/vendor/github.com/godbus/dbus/v5/call.go b/vendor/github.com/godbus/dbus/v5/call.go index ac01ec669f..d16171ab91 100644 --- a/vendor/github.com/godbus/dbus/v5/call.go +++ b/vendor/github.com/godbus/dbus/v5/call.go @@ -9,7 +9,7 @@ type Call struct { Destination string Path ObjectPath Method string - Args []interface{} + Args []any // Strobes when the call is complete. Done chan *Call @@ -19,7 +19,7 @@ type Call struct { Err error // Holds the response once the call is done. - Body []interface{} + Body []any // ResponseSequence stores the sequence number of the DBus message containing // the call response (or error). This can be compared to the sequence number @@ -52,7 +52,7 @@ func (c *Call) ContextCancel() { // Store stores the body of the reply into the provided pointers. It returns // an error if the signatures of the body and retvalues don't match, or if // the error status is not nil. -func (c *Call) Store(retvalues ...interface{}) error { +func (c *Call) Store(retvalues ...any) error { if c.Err != nil { return c.Err } diff --git a/vendor/github.com/godbus/dbus/v5/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go index bbe111b228..8a22acc98b 100644 --- a/vendor/github.com/godbus/dbus/v5/conn.go +++ b/vendor/github.com/godbus/dbus/v5/conn.go @@ -3,6 +3,7 @@ package dbus import ( "context" "errors" + "fmt" "io" "os" "strings" @@ -96,7 +97,7 @@ func SessionBusPrivate(opts ...ConnOption) (*Conn, error) { return Dial(address, opts...) } -// SessionBusPrivate returns a new private connection to the session bus. If +// SessionBusPrivateNoAutoStartup returns a new private connection to the session bus. If // the session bus is not already open, do not attempt to launch it. func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) { address, err := getSessionBusAddress(false) @@ -107,7 +108,7 @@ func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) { return Dial(address, opts...) } -// SessionBusPrivate returns a new private connection to the session bus. +// SessionBusPrivateHandler returns a new private connection to the session bus. // // Deprecated: use SessionBusPrivate with options instead. func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) { @@ -444,7 +445,8 @@ func (conn *Conn) handleSignal(sequence Sequence, msg *Message) { // sender is optional for signals. sender, _ := msg.Headers[FieldSender].value.(string) if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" { - if member == "NameLost" { + switch member { + case "NameLost": // If we lost the name on the bus, remove it from our // tracking list. name, ok := msg.Body[0].(string) @@ -452,7 +454,7 @@ func (conn *Conn) handleSignal(sequence Sequence, msg *Message) { panic("Unable to read the lost name") } conn.names.loseName(name) - } else if member == "NameAcquired" { + case "NameAcquired": // If we acquired the name on the bus, add it to our // tracking list. name, ok := msg.Body[0].(string) @@ -500,15 +502,27 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) error { return err } +func isEncodingError(err error) bool { + switch err.(type) { + case FormatError: + return true + case InvalidMessageError: + return true + } + return false +} + func (conn *Conn) handleSendError(msg *Message, err error) { - if msg.Type == TypeMethodCall { + switch msg.Type { + case TypeMethodCall: conn.calls.handleSendError(msg, err) - } else if msg.Type == TypeMethodReply { - if _, ok := err.(FormatError); ok { + case TypeMethodReply: + if isEncodingError(err) { // Make sure that the caller gets some kind of error response if // the application code tried to respond, but the resulting message // was malformed in the end - conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32)) + returnedErr := fmt.Errorf("destination tried to respond with invalid message (%w)", err) + conn.sendError(returnedErr, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32)) } } conn.serialGen.RetireSerial(msg.serial) @@ -613,7 +627,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) { // sendReply creates a method reply message corresponding to the parameters and // sends it to conn.out. -func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) { +func (conn *Conn) sendReply(dest string, serial uint32, values ...any) { msg := new(Message) msg.Type = TypeMethodReply msg.Headers = make(map[HeaderField]Variant) @@ -701,10 +715,10 @@ func (conn *Conn) SupportsUnixFDs() bool { // Error represents a D-Bus message of type Error. type Error struct { Name string - Body []interface{} + Body []any } -func NewError(name string, body []interface{}) *Error { +func NewError(name string, body []any) *Error { return &Error{name, body} } @@ -724,7 +738,7 @@ type Signal struct { Sender string Path ObjectPath Name string - Body []interface{} + Body []any Sequence Sequence } @@ -775,10 +789,10 @@ func getTransport(address string) (transport, error) { // getKey gets a key from a the list of keys. Returns "" on error / not found... func getKey(s, key string) string { - for _, keyEqualsValue := range strings.Split(s, ",") { - keyValue := strings.SplitN(keyEqualsValue, "=", 2) - if len(keyValue) == 2 && keyValue[0] == key { - val, err := UnescapeBusAddressValue(keyValue[1]) + keyEq := key + "=" + for _, kv := range strings.Split(s, ",") { + if v, ok := strings.CutPrefix(kv, keyEq); ok { + val, err := UnescapeBusAddressValue(v) if err != nil { // No way to return an error. return "" @@ -951,7 +965,7 @@ func (tracker *callTracker) handleSendError(msg *Message, err error) { } } -func (tracker *callTracker) finalizeWithBody(sn uint32, sequence Sequence, body []interface{}) { +func (tracker *callTracker) finalizeWithBody(sn uint32, sequence Sequence, body []any) { tracker.lck.Lock() c, ok := tracker.calls[sn] if ok { diff --git a/vendor/github.com/godbus/dbus/v5/conn_other.go b/vendor/github.com/godbus/dbus/v5/conn_other.go index 1e9959446a..4c6eb305d0 100644 --- a/vendor/github.com/godbus/dbus/v5/conn_other.go +++ b/vendor/github.com/godbus/dbus/v5/conn_other.go @@ -1,5 +1,4 @@ //go:build !darwin -// +build !darwin package dbus @@ -61,13 +60,8 @@ func tryDiscoverDbusSessionBusAddress() string { // DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-E1c73yNqrG if f, err := os.ReadFile(runUserSessionDbusFile); err == nil { - fileContent := string(f) - - prefix := "DBUS_SESSION_BUS_ADDRESS=" - - if strings.HasPrefix(fileContent, prefix) { - address := strings.TrimRight(strings.TrimPrefix(fileContent, prefix), "\n\r") - return address + if addr, ok := strings.CutPrefix(string(f), "DBUS_SESSION_BUS_ADDRESS="); ok { + return strings.TrimRight(addr, "\n\r") } } } diff --git a/vendor/github.com/godbus/dbus/v5/conn_unix.go b/vendor/github.com/godbus/dbus/v5/conn_unix.go index 1a0daa6566..77d6bf1a47 100644 --- a/vendor/github.com/godbus/dbus/v5/conn_unix.go +++ b/vendor/github.com/godbus/dbus/v5/conn_unix.go @@ -1,9 +1,9 @@ //go:build !windows && !solaris && !darwin -// +build !windows,!solaris,!darwin package dbus import ( + "net" "os" ) @@ -16,3 +16,25 @@ func getSystemBusPlatformAddress() string { } return defaultSystemBusAddress } + +// DialUnix establishes a new private connection to the message bus specified by UnixConn. +func DialUnix(conn *net.UnixConn, opts ...ConnOption) (*Conn, error) { + tr := newUnixTransportFromConn(conn) + return newConn(tr, opts...) +} + +func ConnectUnix(uconn *net.UnixConn, opts ...ConnOption) (*Conn, error) { + conn, err := DialUnix(uconn, opts...) + if err != nil { + return nil, err + } + if err = conn.Auth(conn.auth); err != nil { + _ = conn.Close() + return nil, err + } + if err = conn.Hello(); err != nil { + _ = conn.Close() + return nil, err + } + return conn, nil +} diff --git a/vendor/github.com/godbus/dbus/v5/dbus.go b/vendor/github.com/godbus/dbus/v5/dbus.go index 8f152dc2f3..d3622d8079 100644 --- a/vendor/github.com/godbus/dbus/v5/dbus.go +++ b/vendor/github.com/godbus/dbus/v5/dbus.go @@ -21,8 +21,8 @@ var ( signatureType = reflect.TypeOf(Signature{""}) objectPathType = reflect.TypeOf(ObjectPath("")) variantType = reflect.TypeOf(Variant{Signature{""}, nil}) - interfacesType = reflect.TypeOf([]interface{}{}) - interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() + interfacesType = reflect.TypeOf([]any{}) + interfaceType = reflect.TypeOf((*any)(nil)).Elem() unixFDType = reflect.TypeOf(UnixFD(0)) unixFDIndexType = reflect.TypeOf(UnixFDIndex(0)) errType = reflect.TypeOf((*error)(nil)).Elem() @@ -42,7 +42,7 @@ func (e InvalidTypeError) Error() string { // pointers. It converts slices of interfaces from src to corresponding structs // in dest. An error is returned if the lengths of src and dest or the types of // their elements don't match. -func Store(src []interface{}, dest ...interface{}) error { +func Store(src []any, dest ...any) error { if len(src) != len(dest) { return errors.New("dbus.Store: length mismatch") } @@ -55,7 +55,7 @@ func Store(src []interface{}, dest ...interface{}) error { return nil } -func storeInterfaces(src, dest interface{}) error { +func storeInterfaces(src, dest any) error { return store(reflect.ValueOf(dest), reflect.ValueOf(src)) } @@ -222,7 +222,7 @@ func storeStruct(dest, src reflect.Value) error { if isVariant(dest.Type()) { return storeBase(dest, src) } - dval := make([]interface{}, 0, dest.NumField()) + dval := make([]any, 0, dest.NumField()) dtype := dest.Type() for i := 0; i < dest.NumField(); i++ { field := dest.Field(i) @@ -242,7 +242,7 @@ func storeStruct(dest, src reflect.Value) error { "enough fields need: %d have: %d", src.Len(), len(dval)) } - return Store(src.Interface().([]interface{}), dval...) + return Store(src.Interface().([]any), dval...) } func storeSliceIntoVariant(dest, src reflect.Value) error { diff --git a/vendor/github.com/godbus/dbus/v5/decoder.go b/vendor/github.com/godbus/dbus/v5/decoder.go index d03bdd8e87..05af8cdd34 100644 --- a/vendor/github.com/godbus/dbus/v5/decoder.go +++ b/vendor/github.com/godbus/dbus/v5/decoder.go @@ -53,13 +53,13 @@ func (dec *decoder) align(n int) { } // Calls binary.Read(dec.in, dec.order, v) and panics on read errors. -func (dec *decoder) binread(v interface{}) { +func (dec *decoder) binread(v any) { if err := binary.Read(dec.in, dec.order, v); err != nil { panic(err) } } -func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) { +func (dec *decoder) Decode(sig Signature) (vs []any, err error) { defer func() { var ok bool v := recover() @@ -69,7 +69,7 @@ func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) { } } }() - vs = make([]interface{}, 0) + vs = make([]any, 0) s := sig.str for s != "" { err, rem := validSingle(s, &depthCounter{}) @@ -106,7 +106,7 @@ func (dec *decoder) decodeU() uint32 { return dec.order.Uint32(dec.buf) } -func (dec *decoder) decode(s string, depth int) interface{} { +func (dec *decoder) decode(s string, depth int) any { dec.align(alignment(typeFor(s))) switch s[0] { case 'y': @@ -249,7 +249,7 @@ func (dec *decoder) decode(s string, depth int) interface{} { panic(FormatError("input exceeds container depth limit")) } dec.align(8) - v := make([]interface{}, 0) + v := make([]any, 0) s = s[1 : len(s)-1] for s != "" { err, rem := validSingle(s, &depthCounter{}) @@ -291,9 +291,10 @@ func sigByteSize(sig string) int { i := 1 depth := 1 for i < len(sig[offset:]) && depth != 0 { - if sig[offset+i] == '(' { + switch sig[offset+i] { + case '(': depth++ - } else if sig[offset+i] == ')' { + case ')': depth-- } i++ diff --git a/vendor/github.com/godbus/dbus/v5/default_handler.go b/vendor/github.com/godbus/dbus/v5/default_handler.go index 3da16b1ecb..c17ab0b97d 100644 --- a/vendor/github.com/godbus/dbus/v5/default_handler.go +++ b/vendor/github.com/godbus/dbus/v5/default_handler.go @@ -52,9 +52,9 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string { if p != "/" { p += "/" } - if strings.HasPrefix(string(obj), p) { - node_name := strings.Split(string(obj[len(p):]), "/")[0] - subpath[node_name] = struct{}{} + if after, ok := strings.CutPrefix(string(obj), p); ok { + name, _, _ := strings.Cut(after, "/") + subpath[name] = struct{}{} } } for s := range subpath { @@ -117,7 +117,7 @@ type exportedMethod struct { reflect.Value } -func (m exportedMethod) Call(args ...interface{}) ([]interface{}, error) { +func (m exportedMethod) Call(args ...any) ([]any, error) { t := m.Type() params := make([]reflect.Value, len(args)) @@ -143,7 +143,7 @@ func (m exportedMethod) Call(args ...interface{}) ([]interface{}, error) { ret = ret[:t.NumOut()-1] } } - out := make([]interface{}, len(ret)) + out := make([]any, len(ret)) for i, val := range ret { out[i] = val.Interface() } @@ -158,7 +158,7 @@ func (m exportedMethod) NumArguments() int { return m.Value.Type().NumIn() } -func (m exportedMethod) ArgumentValue(i int) interface{} { +func (m exportedMethod) ArgumentValue(i int) any { return reflect.Zero(m.Type().In(i)).Interface() } @@ -166,7 +166,7 @@ func (m exportedMethod) NumReturns() int { return m.Value.Type().NumOut() } -func (m exportedMethod) ReturnValue(i int) interface{} { +func (m exportedMethod) ReturnValue(i int) any { return reflect.Zero(m.Type().Out(i)).Interface() } diff --git a/vendor/github.com/godbus/dbus/v5/encoder.go b/vendor/github.com/godbus/dbus/v5/encoder.go index 015b26cd5c..5901ab42a9 100644 --- a/vendor/github.com/godbus/dbus/v5/encoder.go +++ b/vendor/github.com/godbus/dbus/v5/encoder.go @@ -59,7 +59,7 @@ func (enc *encoder) padding(offset, algn int) int { } // Calls binary.Write(enc.out, enc.order, v) and panics on write errors. -func (enc *encoder) binwrite(v interface{}) { +func (enc *encoder) binwrite(v any) { if err := binary.Write(enc.out, enc.order, v); err != nil { panic(err) } @@ -67,7 +67,7 @@ func (enc *encoder) binwrite(v interface{}) { // Encode encodes the given values to the underlying reader. All written values // are aligned properly as required by the D-Bus spec. -func (enc *encoder) Encode(vs ...interface{}) (err error) { +func (enc *encoder) Encode(vs ...any) (err error) { defer func() { err, _ = recover().(error) }() diff --git a/vendor/github.com/godbus/dbus/v5/export.go b/vendor/github.com/godbus/dbus/v5/export.go index fa009d2ce4..20d8cb38fa 100644 --- a/vendor/github.com/godbus/dbus/v5/export.go +++ b/vendor/github.com/godbus/dbus/v5/export.go @@ -11,47 +11,47 @@ import ( var ( ErrMsgInvalidArg = Error{ "org.freedesktop.DBus.Error.InvalidArgs", - []interface{}{"Invalid type / number of args"}, + []any{"Invalid type / number of args"}, } ErrMsgNoObject = Error{ "org.freedesktop.DBus.Error.NoSuchObject", - []interface{}{"No such object"}, + []any{"No such object"}, } ErrMsgUnknownMethod = Error{ "org.freedesktop.DBus.Error.UnknownMethod", - []interface{}{"Unknown / invalid method"}, + []any{"Unknown / invalid method"}, } ErrMsgUnknownInterface = Error{ "org.freedesktop.DBus.Error.UnknownInterface", - []interface{}{"Object does not implement the interface"}, + []any{"Object does not implement the interface"}, } ) func MakeNoObjectError(path ObjectPath) Error { return Error{ "org.freedesktop.DBus.Error.NoSuchObject", - []interface{}{fmt.Sprintf("No such object '%s'", string(path))}, + []any{fmt.Sprintf("No such object '%s'", string(path))}, } } func MakeUnknownMethodError(methodName string) Error { return Error{ "org.freedesktop.DBus.Error.UnknownMethod", - []interface{}{fmt.Sprintf("Unknown / invalid method '%s'", methodName)}, + []any{fmt.Sprintf("Unknown / invalid method '%s'", methodName)}, } } func MakeUnknownInterfaceError(ifaceName string) Error { return Error{ "org.freedesktop.DBus.Error.UnknownInterface", - []interface{}{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)}, + []any{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)}, } } func MakeFailedError(err error) *Error { return &Error{ "org.freedesktop.DBus.Error.Failed", - []interface{}{err.Error()}, + []any{err.Error()}, } } @@ -67,7 +67,7 @@ func computeMethodName(name string, mapping map[string]string) string { return name } -func getMethods(in interface{}, mapping map[string]string) map[string]reflect.Value { +func getMethods(in any, mapping map[string]string) map[string]reflect.Value { if in == nil { return nil } @@ -91,7 +91,7 @@ func getMethods(in interface{}, mapping map[string]string) map[string]reflect.Va return methods } -func getAllMethods(in interface{}, mapping map[string]string) map[string]reflect.Value { +func getAllMethods(in any, mapping map[string]string) map[string]reflect.Value { if in == nil { return nil } @@ -107,9 +107,9 @@ func getAllMethods(in interface{}, mapping map[string]string) map[string]reflect return methods } -func standardMethodArgumentDecode(m Method, sender string, msg *Message, body []interface{}) ([]interface{}, error) { - pointers := make([]interface{}, m.NumArguments()) - decode := make([]interface{}, 0, len(body)) +func standardMethodArgumentDecode(m Method, sender string, msg *Message, body []any) ([]any, error) { + pointers := make([]any, m.NumArguments()) + decode := make([]any, 0, len(body)) for i := 0; i < m.NumArguments(); i++ { tp := reflect.TypeOf(m.ArgumentValue(i)) @@ -135,7 +135,7 @@ func standardMethodArgumentDecode(m Method, sender string, msg *Message, body [] return pointers, nil } -func (conn *Conn) decodeArguments(m Method, sender string, msg *Message) ([]interface{}, error) { +func (conn *Conn) decodeArguments(m Method, sender string, msg *Message) ([]any, error) { if decoder, ok := m.(ArgumentDecoder); ok { return decoder.DecodeArguments(conn, sender, msg, msg.Body) } @@ -204,7 +204,7 @@ func (conn *Conn) handleCall(msg *Message) { reply.Headers[FieldDestination] = msg.Headers[FieldSender] } reply.Headers[FieldReplySerial] = MakeVariant(msg.serial) - reply.Body = make([]interface{}, len(ret)) + reply.Body = make([]any, len(ret)) copy(reply.Body, ret) reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) @@ -218,7 +218,7 @@ func (conn *Conn) handleCall(msg *Message) { // Emit emits the given signal on the message bus. The name parameter must be // formatted as "interface.member", e.g., "org.freedesktop.DBus.NameLost". -func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) error { +func (conn *Conn) Emit(path ObjectPath, name string, values ...any) error { i := strings.LastIndex(name, ".") if i == -1 { return errors.New("dbus: invalid method name") @@ -274,7 +274,7 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro // the given combination of path and interface. // // Export returns an error if path is not a valid path name. -func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error { +func (conn *Conn) Export(v any, path ObjectPath, iface string) error { return conn.ExportWithMap(v, nil, path, iface) } @@ -286,7 +286,7 @@ func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error { // type parameter to your method signature. If the error returned is not nil, // it is sent back to the caller as an error. Otherwise, a method reply is // sent with the other return values as its body. -func (conn *Conn) ExportAll(v interface{}, path ObjectPath, iface string) error { +func (conn *Conn) ExportAll(v any, path ObjectPath, iface string) error { return conn.export(getAllMethods(v, nil), path, iface, false) } @@ -295,7 +295,7 @@ func (conn *Conn) ExportAll(v interface{}, path ObjectPath, iface string) error // // The keys in the map are the real method names (exported on the struct), and // the values are the method names to be exported on DBus. -func (conn *Conn) ExportWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error { +func (conn *Conn) ExportWithMap(v any, mapping map[string]string, path ObjectPath, iface string) error { return conn.export(getMethods(v, mapping), path, iface, false) } @@ -309,7 +309,7 @@ func (conn *Conn) ExportWithMap(v interface{}, mapping map[string]string, path O // Note that more specific export paths take precedence over less specific. For // example, a method call using the ObjectPath /foo/bar/baz will call a method // exported on /foo/bar before a method exported on /foo. -func (conn *Conn) ExportSubtree(v interface{}, path ObjectPath, iface string) error { +func (conn *Conn) ExportSubtree(v any, path ObjectPath, iface string) error { return conn.ExportSubtreeWithMap(v, nil, path, iface) } @@ -318,7 +318,7 @@ func (conn *Conn) ExportSubtree(v interface{}, path ObjectPath, iface string) er // // The keys in the map are the real method names (exported on the struct), and // the values are the method names to be exported on DBus. -func (conn *Conn) ExportSubtreeWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error { +func (conn *Conn) ExportSubtreeWithMap(v any, mapping map[string]string, path ObjectPath, iface string) error { return conn.export(getMethods(v, mapping), path, iface, true) } @@ -332,16 +332,16 @@ func (conn *Conn) ExportSubtreeWithMap(v interface{}, mapping map[string]string, // methods on the fly. // // Any non-function objects in the method table are ignored. -func (conn *Conn) ExportMethodTable(methods map[string]interface{}, path ObjectPath, iface string) error { +func (conn *Conn) ExportMethodTable(methods map[string]any, path ObjectPath, iface string) error { return conn.exportMethodTable(methods, path, iface, false) } // Like ExportSubtree, but with the same caveats as ExportMethodTable. -func (conn *Conn) ExportSubtreeMethodTable(methods map[string]interface{}, path ObjectPath, iface string) error { +func (conn *Conn) ExportSubtreeMethodTable(methods map[string]any, path ObjectPath, iface string) error { return conn.exportMethodTable(methods, path, iface, true) } -func (conn *Conn) exportMethodTable(methods map[string]interface{}, path ObjectPath, iface string, includeSubtree bool) error { +func (conn *Conn) exportMethodTable(methods map[string]any, path ObjectPath, iface string, includeSubtree bool) error { var out map[string]reflect.Value if methods != nil { out = make(map[string]reflect.Value) @@ -438,6 +438,18 @@ const ( ReleaseNameReplyNotOwner ) +func (rep ReleaseNameReply) String() string { + switch rep { + case ReleaseNameReplyReleased: + return "released" + case ReleaseNameReplyNonExistent: + return "non existent" + case ReleaseNameReplyNotOwner: + return "not owner" + } + return "unknown" +} + // RequestNameFlags represents the possible flags for a RequestName call. type RequestNameFlags uint32 @@ -456,3 +468,17 @@ const ( RequestNameReplyExists RequestNameReplyAlreadyOwner ) + +func (rep RequestNameReply) String() string { + switch rep { + case RequestNameReplyPrimaryOwner: + return "primary owner" + case RequestNameReplyInQueue: + return "in queue" + case RequestNameReplyExists: + return "exists" + case RequestNameReplyAlreadyOwner: + return "already owner" + } + return "unknown" +} diff --git a/vendor/github.com/godbus/dbus/v5/homedir.go b/vendor/github.com/godbus/dbus/v5/homedir.go deleted file mode 100644 index c44d9b5fc2..0000000000 --- a/vendor/github.com/godbus/dbus/v5/homedir.go +++ /dev/null @@ -1,25 +0,0 @@ -package dbus - -import ( - "os" - "os/user" -) - -// Get returns the home directory of the current user, which is usually the -// value of HOME environment variable. In case it is not set or empty, os/user -// package is used. -// -// If linking statically with cgo enabled against glibc, make sure the -// osusergo build tag is used. -// -// If needing to do nss lookups, do not disable cgo or set osusergo. -func getHomeDir() string { - homeDir := os.Getenv("HOME") - if homeDir != "" { - return homeDir - } - if u, err := user.Current(); err == nil { - return u.HomeDir - } - return "/" -} diff --git a/vendor/github.com/godbus/dbus/v5/message.go b/vendor/github.com/godbus/dbus/v5/message.go index 5ab6e9d9a1..097ca3a7fa 100644 --- a/vendor/github.com/godbus/dbus/v5/message.go +++ b/vendor/github.com/godbus/dbus/v5/message.go @@ -108,7 +108,7 @@ type Message struct { Type Flags Headers map[HeaderField]Variant - Body []interface{} + Body []any serial uint32 } @@ -232,7 +232,7 @@ func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds if err := msg.validateHeader(); err != nil { return nil, err } - var vs [7]interface{} + var vs [7]any switch order { case binary.LittleEndian: vs[0] = byte('l') diff --git a/vendor/github.com/godbus/dbus/v5/object.go b/vendor/github.com/godbus/dbus/v5/object.go index b4b1e939b3..954d380712 100644 --- a/vendor/github.com/godbus/dbus/v5/object.go +++ b/vendor/github.com/godbus/dbus/v5/object.go @@ -9,15 +9,15 @@ import ( // BusObject is the interface of a remote object on which methods can be // invoked. type BusObject interface { - Call(method string, flags Flags, args ...interface{}) *Call - CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call - Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call - GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call + Call(method string, flags Flags, args ...any) *Call + CallWithContext(ctx context.Context, method string, flags Flags, args ...any) *Call + Go(method string, flags Flags, ch chan *Call, args ...any) *Call + GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...any) *Call AddMatchSignal(iface, member string, options ...MatchOption) *Call RemoveMatchSignal(iface, member string, options ...MatchOption) *Call GetProperty(p string) (Variant, error) - StoreProperty(p string, value interface{}) error - SetProperty(p string, v interface{}) error + StoreProperty(p string, value any) error + SetProperty(p string, v any) error Destination() string Path() ObjectPath } @@ -30,12 +30,12 @@ type Object struct { } // Call calls a method with (*Object).Go and waits for its reply. -func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call { +func (o *Object) Call(method string, flags Flags, args ...any) *Call { return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done } // CallWithContext acts like Call but takes a context -func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call { +func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...any) *Call { return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done } @@ -89,16 +89,16 @@ func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) // // If the method parameter contains a dot ('.'), the part before the last dot // specifies the interface on which the method is called. -func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call { +func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...any) *Call { return o.createCall(context.Background(), method, flags, ch, args...) } // GoWithContext acts like Go but takes a context -func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call { +func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...any) *Call { return o.createCall(ctx, method, flags, ch, args...) } -func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call { +func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...any) *Call { if ctx == nil { panic("nil context") } @@ -136,7 +136,7 @@ func (o *Object) GetProperty(p string) (Variant, error) { // StoreProperty calls org.freedesktop.DBus.Properties.Get on the given // object. The property name must be given in interface.member notation. // It stores the returned property into the provided value. -func (o *Object) StoreProperty(p string, value interface{}) error { +func (o *Object) StoreProperty(p string, value any) error { idx := strings.LastIndex(p, ".") if idx == -1 || idx+1 == len(p) { return errors.New("dbus: invalid property " + p) @@ -152,7 +152,7 @@ func (o *Object) StoreProperty(p string, value interface{}) error { // SetProperty calls org.freedesktop.DBus.Properties.Set on the given // object. The property name must be given in interface.member notation. // Panics if v is not a valid Variant type. -func (o *Object) SetProperty(p string, v interface{}) error { +func (o *Object) SetProperty(p string, v any) error { // v might already be a variant... variant, ok := v.(Variant) if !ok { diff --git a/vendor/github.com/godbus/dbus/v5/server_interfaces.go b/vendor/github.com/godbus/dbus/v5/server_interfaces.go index aef3c772fa..24d4ad6329 100644 --- a/vendor/github.com/godbus/dbus/v5/server_interfaces.go +++ b/vendor/github.com/godbus/dbus/v5/server_interfaces.go @@ -38,17 +38,17 @@ type Interface interface { // A Method represents the exposed methods on D-Bus. type Method interface { // Call requires that all arguments are decoded before being passed to it. - Call(args ...interface{}) ([]interface{}, error) + Call(args ...any) ([]any, error) NumArguments() int NumReturns() int // ArgumentValue returns a representative value for the argument at position // it should be of the proper type. reflect.Zero would be a good mechanism // to use for this Value. - ArgumentValue(position int) interface{} + ArgumentValue(position int) any // ReturnValue returns a representative value for the return at position // it should be of the proper type. reflect.Zero would be a good mechanism // to use for this Value. - ReturnValue(position int) interface{} + ReturnValue(position int) any } // An Argument Decoder can decode arguments using the non-standard mechanism @@ -65,7 +65,7 @@ type ArgumentDecoder interface { // To decode the arguments of a method the sender and message are // provided in case the semantics of the implementer provides access // to these as part of the method invocation. - DecodeArguments(conn *Conn, sender string, msg *Message, args []interface{}) ([]interface{}, error) + DecodeArguments(conn *Conn, sender string, msg *Message, args []any) ([]any, error) } // A SignalHandler is responsible for delivering a signal. @@ -93,7 +93,7 @@ type SignalRegistrar interface { // "org.freedesktop.DBus.Error.Failed" error. By implementing this // interface as well a custom encoding may be provided. type DBusError interface { - DBusError() (string, []interface{}) + DBusError() (string, []any) } // SerialGenerator is responsible for serials generation. diff --git a/vendor/github.com/godbus/dbus/v5/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go index 5bd797b62f..de49f860de 100644 --- a/vendor/github.com/godbus/dbus/v5/sig.go +++ b/vendor/github.com/godbus/dbus/v5/sig.go @@ -31,7 +31,7 @@ type Signature struct { // SignatureOf returns the concatenation of all the signatures of the given // values. It panics if one of them is not representable in D-Bus. -func SignatureOf(vs ...interface{}) Signature { +func SignatureOf(vs ...any) Signature { var s string for _, v := range vs { s += getSignature(reflect.TypeOf(v), &depthCounter{}) @@ -89,9 +89,10 @@ func getSignature(t reflect.Type, depth *depthCounter) (sig string) { } return "s" case reflect.Struct: - if t == variantType { + switch t { + case variantType: return "v" - } else if t == signatureType { + case signatureType: return "g" } var s string @@ -183,26 +184,26 @@ func (cnt *depthCounter) Valid() bool { return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32 } -func (cnt *depthCounter) EnterArray() *depthCounter { +func (cnt depthCounter) EnterArray() *depthCounter { cnt.arrayDepth++ - return cnt + return &cnt } -func (cnt *depthCounter) EnterStruct() *depthCounter { +func (cnt depthCounter) EnterStruct() *depthCounter { cnt.structDepth++ - return cnt + return &cnt } -func (cnt *depthCounter) EnterDictEntry() *depthCounter { +func (cnt depthCounter) EnterDictEntry() *depthCounter { cnt.dictEntryDepth++ - return cnt + return &cnt } // Try to read a single type from this string. If it was successful, err is nil // and rem is the remaining unparsed part. Otherwise, err is a non-nil // SignatureError and rem is "". depth is the current recursion depth which may // not be greater than 64 and should be given as 0 on the first call. -func validSingle(s string, depth *depthCounter) (err error, rem string) { +func validSingle(s string, depth *depthCounter) (err error, rem string) { //nolint:staticcheck // Ignore "ST1008: error should be returned as the last argument". if s == "" { return SignatureError{Sig: s, Reason: "empty signature"}, "" } @@ -258,9 +259,10 @@ func validSingle(s string, depth *depthCounter) (err error, rem string) { func findMatching(s string, left, right rune) int { n := 0 for i, v := range s { - if v == left { + switch v { + case left: n++ - } else if v == right { + case right: n-- } if n == 0 { diff --git a/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go index a08d0891ce..9ffdeb0c0d 100644 --- a/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go +++ b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package dbus @@ -30,10 +29,12 @@ func newNonceTcpTransport(keys string) (transport, error) { } b, err := os.ReadFile(noncefile) if err != nil { + socket.Close() return nil, err } _, err = socket.Write(b) if err != nil { + socket.Close() return nil, err } return NewConn(socket) diff --git a/vendor/github.com/godbus/dbus/v5/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go index 6840387a5f..3baad2e9af 100644 --- a/vendor/github.com/godbus/dbus/v5/transport_unix.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go @@ -1,5 +1,4 @@ //go:build !windows && !solaris -// +build !windows,!solaris package dbus @@ -55,6 +54,14 @@ type unixTransport struct { hasUnixFDs bool } +func newUnixTransportFromConn(conn *net.UnixConn) transport { + t := new(unixTransport) + t.UnixConn = conn + t.hasUnixFDs = true + + return t +} + func newUnixTransport(keys string) (transport, error) { var err error @@ -134,16 +141,16 @@ func (t *unixTransport) ReadMessage() (*Message, error) { } msg := &Message{ - Type: t.rdr.msghead.Type, - Flags: t.rdr.msghead.Flags, - serial: t.rdr.msghead.Serial, + Type: t.rdr.Type, + Flags: t.rdr.Flags, + serial: t.rdr.Serial, } // Length of header fields (without alignment). - hlen := t.rdr.msghead.HeaderLen + hlen := t.rdr.HeaderLen if hlen%8 != 0 { hlen += 8 - (hlen % 8) } - if hlen+t.rdr.msghead.BodyLen+16 > 1<<27 { + if hlen+t.rdr.BodyLen+16 > 1<<27 { return nil, InvalidMessageError("message is too long") } @@ -167,7 +174,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) { var unixfds uint32 for _, v := range t.rdr.headers { if v.Field == byte(FieldUnixFDs) { - unixfds, _ = v.Variant.value.(uint32) + unixfds, _ = v.value.(uint32) } } @@ -264,7 +271,7 @@ func (t *unixTransport) SendMessage(msg *Message) error { return err } oob := syscall.UnixRights(fds...) - n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil) + n, oobn, err := t.WriteMsgUnix(buf.Bytes(), oob, nil) if err != nil { return err } diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go index d9dfdf6982..2d5d7f612f 100644 --- a/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go +++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go @@ -14,7 +14,7 @@ import ( func (t *unixTransport) SendNullByte() error { ucred := &syscall.Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())} b := syscall.UnixCredentials(ucred) - _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil) + _, oobn, err := t.WriteMsgUnix([]byte{0}, b, nil) if err != nil { return err } diff --git a/vendor/github.com/godbus/dbus/v5/variant.go b/vendor/github.com/godbus/dbus/v5/variant.go index ca3dbe16a4..bf98ddea73 100644 --- a/vendor/github.com/godbus/dbus/v5/variant.go +++ b/vendor/github.com/godbus/dbus/v5/variant.go @@ -11,17 +11,17 @@ import ( // Variant represents the D-Bus variant type. type Variant struct { sig Signature - value interface{} + value any } // MakeVariant converts the given value to a Variant. It panics if v cannot be // represented as a D-Bus type. -func MakeVariant(v interface{}) Variant { +func MakeVariant(v any) Variant { return MakeVariantWithSignature(v, SignatureOf(v)) } // MakeVariantWithSignature converts the given value to a Variant. -func MakeVariantWithSignature(v interface{}, s Signature) Variant { +func MakeVariantWithSignature(v any, s Signature) Variant { return Variant{s, v} } @@ -73,7 +73,7 @@ func (v Variant) format() (string, bool) { } rv := reflect.ValueOf(v.value) switch rv.Kind() { - case reflect.Slice: + case reflect.Slice, reflect.Array: if rv.Len() == 0 { return "[]", false } @@ -119,6 +119,25 @@ func (v Variant) format() (string, bool) { } buf.WriteByte('}') return buf.String(), unamb + case reflect.Struct: + if rv.NumField() == 0 { + return "()", false + } + unamb := true + var buf bytes.Buffer + buf.WriteByte('(') + for i := 0; i < rv.NumField(); i++ { + s, b := MakeVariant(rv.Field(i).Interface()).format() + unamb = unamb && b + buf.WriteString(s) + buf.WriteString(",") + if i != rv.NumField()-1 { + buf.WriteString(" ") + } + } + buf.WriteByte(')') + return buf.String(), unamb + } return `"INVALID"`, true } @@ -139,12 +158,12 @@ func (v Variant) String() string { } // Value returns the underlying value of v. -func (v Variant) Value() interface{} { +func (v Variant) Value() any { return v.value } // Store converts the variant into a native go type using the same // mechanism as the "Store" function. -func (v Variant) Store(value interface{}) error { +func (v Variant) Store(value any) error { return storeInterfaces(v.value, value) } diff --git a/vendor/github.com/godbus/dbus/v5/variant_lexer.go b/vendor/github.com/godbus/dbus/v5/variant_lexer.go index bf1398c8f0..a0649c5ca5 100644 --- a/vendor/github.com/godbus/dbus/v5/variant_lexer.go +++ b/vendor/github.com/godbus/dbus/v5/variant_lexer.go @@ -67,7 +67,7 @@ func (l *varLexer) emit(t varTokenType) { l.start = l.pos } -func (l *varLexer) errorf(format string, v ...interface{}) lexState { +func (l *varLexer) errorf(format string, v ...any) lexState { l.tokens = append(l.tokens, varToken{ tokError, fmt.Sprintf(format, v...), diff --git a/vendor/github.com/godbus/dbus/v5/variant_parser.go b/vendor/github.com/godbus/dbus/v5/variant_parser.go index 9532e36f3c..bc0bd945c8 100644 --- a/vendor/github.com/godbus/dbus/v5/variant_parser.go +++ b/vendor/github.com/godbus/dbus/v5/variant_parser.go @@ -33,7 +33,7 @@ type varNode interface { Infer() (Signature, error) String() string Sigs() sigSet - Value(Signature) (interface{}, error) + Value(Signature) (any, error) } func varMakeNode(p *varParser) (varNode, error) { @@ -134,7 +134,7 @@ func (s sigSet) ToArray() sigSet { type numNode struct { sig Signature str string - val interface{} + val any } var numSigSet = sigSet{ @@ -169,7 +169,7 @@ func (n numNode) Sigs() sigSet { return numSigSet } -func (n numNode) Value(sig Signature) (interface{}, error) { +func (n numNode) Value(sig Signature) (any, error) { if n.sig.str != "" && n.sig != sig { return nil, varTypeError{n.str, sig} } @@ -190,7 +190,7 @@ func varMakeNumNode(tok varToken, sig Signature) (varNode, error) { return numNode{sig: sig, val: num}, nil } -func varNumAs(s string, sig Signature) (interface{}, error) { +func varNumAs(s string, sig Signature) (any, error) { isUnsigned := false size := 32 switch sig.str { @@ -220,20 +220,20 @@ func varNumAs(s string, sig Signature) (interface{}, error) { return nil, varTypeError{s, sig} } base := 10 - if strings.HasPrefix(s, "0x") { + if after, ok := strings.CutPrefix(s, "0x"); ok { base = 16 - s = s[2:] + s = after } - if strings.HasPrefix(s, "0") && len(s) != 1 { + if after, ok := strings.CutPrefix(s, "0"); ok && len(s) != 1 { base = 8 - s = s[1:] + s = after } if isUnsigned { i, err := strconv.ParseUint(s, base, size) if err != nil { return nil, err } - var v interface{} = i + var v any = i switch sig.str { case "y": v = byte(i) @@ -248,7 +248,7 @@ func varNumAs(s string, sig Signature) (interface{}, error) { if err != nil { return nil, err } - var v interface{} = i + var v any = i switch sig.str { case "n": v = int16(i) @@ -260,8 +260,8 @@ func varNumAs(s string, sig Signature) (interface{}, error) { type stringNode struct { sig Signature - str string // parsed - val interface{} // has correct type + str string // parsed + val any // has correct type } var stringSigSet = sigSet{ @@ -285,19 +285,19 @@ func (n stringNode) Sigs() sigSet { return stringSigSet } -func (n stringNode) Value(sig Signature) (interface{}, error) { +func (n stringNode) Value(sig Signature) (any, error) { if n.sig.str != "" && n.sig != sig { return nil, varTypeError{n.str, sig} } if n.val != nil { return n.val, nil } - switch { - case sig.str == "g": + switch sig.str { + case "g": return Signature{n.str}, nil - case sig.str == "o": + case "o": return ObjectPath(n.str), nil - case sig.str == "s": + case "s": return n.str, nil default: return nil, varTypeError{n.str, sig} @@ -407,7 +407,7 @@ func (boolNode) Sigs() sigSet { return boolSigSet } -func (b boolNode) Value(sig Signature) (interface{}, error) { +func (b boolNode) Value(sig Signature) (any, error) { if sig.str != "b" { return nil, varTypeError{b.String(), sig} } @@ -445,7 +445,7 @@ func (n arrayNode) Sigs() sigSet { return n.set } -func (n arrayNode) Value(sig Signature) (interface{}, error) { +func (n arrayNode) Value(sig Signature) (any, error) { if n.set.Empty() { // no type information whatsoever, so this must be an empty slice return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil @@ -536,7 +536,7 @@ func (variantNode) Sigs() sigSet { return variantSet } -func (n variantNode) Value(sig Signature) (interface{}, error) { +func (n variantNode) Value(sig Signature) (any, error) { if sig.str != "v" { return nil, varTypeError{n.String(), sig} } @@ -612,7 +612,7 @@ func (n dictNode) Sigs() sigSet { return r } -func (n dictNode) Value(sig Signature) (interface{}, error) { +func (n dictNode) Value(sig Signature) (any, error) { set := n.Sigs() if set.Empty() { // no type information -> empty dict @@ -747,7 +747,7 @@ func (b byteStringNode) Sigs() sigSet { return byteStringSet } -func (b byteStringNode) Value(sig Signature) (interface{}, error) { +func (b byteStringNode) Value(sig Signature) (any, error) { if sig.str != "ay" { return nil, varTypeError{b.String(), sig} } diff --git a/vendor/github.com/google/cadvisor/cache/memory/memory.go b/vendor/github.com/google/cadvisor/cache/memory/memory.go index a43e1b442e..e30b30fc9e 100644 --- a/vendor/github.com/google/cadvisor/cache/memory/memory.go +++ b/vendor/github.com/google/cadvisor/cache/memory/memory.go @@ -29,6 +29,38 @@ import ( // ErrDataNotFound is the error resulting if failed to find a container in memory cache. var ErrDataNotFound = errors.New("unable to find data in memory cache") +// containerCacheMap is a typed wrapper around sync.Map that eliminates the need +// for type assertions at every call site. It stores container name strings +// mapped to *containerCache values. +type containerCacheMap struct { + m sync.Map +} + +// Load retrieves a container cache by name. Returns nil, false if not found. +func (c *containerCacheMap) Load(name string) (*containerCache, bool) { + v, ok := c.m.Load(name) + if !ok { + return nil, false + } + return v.(*containerCache), true +} + +// Store saves a container cache with the given name. +func (c *containerCacheMap) Store(name string, cache *containerCache) { + c.m.Store(name, cache) +} + +// LoadOrStore returns the existing cache if present, otherwise stores and returns the given one. +func (c *containerCacheMap) LoadOrStore(name string, cache *containerCache) (*containerCache, bool) { + v, loaded := c.m.LoadOrStore(name, cache) + return v.(*containerCache), loaded +} + +// Delete removes a container cache by name. +func (c *containerCacheMap) Delete(name string) { + c.m.Delete(name) +} + // TODO(vmarmol): See about refactoring this class, we have an unnecessary redirection of containerCache and InMemoryCache. // containerCache is used to store per-container information type containerCache struct { @@ -67,24 +99,18 @@ func newContainerStore(ref info.ContainerReference, maxAge time.Duration) *conta } type InMemoryCache struct { - lock sync.RWMutex - containerCacheMap map[string]*containerCache + containerCacheMap containerCacheMap maxAge time.Duration backend []storage.StorageDriver } func (c *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error { - var cstore *containerCache - var ok bool - - func() { - c.lock.Lock() - defer c.lock.Unlock() - if cstore, ok = c.containerCacheMap[cInfo.ContainerReference.Name]; !ok { - cstore = newContainerStore(cInfo.ContainerReference, c.maxAge) - c.containerCacheMap[cInfo.ContainerReference.Name] = cstore - } - }() + name := cInfo.ContainerReference.Name + cstore, ok := c.containerCacheMap.Load(name) + if !ok { + newStore := newContainerStore(cInfo.ContainerReference, c.maxAge) + cstore, _ = c.containerCacheMap.LoadOrStore(name, newStore) + } for _, backend := range c.backend { // TODO(monnand): To deal with long delay write operations, we @@ -98,34 +124,20 @@ func (c *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.Containe } func (c *InMemoryCache) RecentStats(name string, start, end time.Time, maxStats int) ([]*info.ContainerStats, error) { - var cstore *containerCache - var ok bool - err := func() error { - c.lock.RLock() - defer c.lock.RUnlock() - if cstore, ok = c.containerCacheMap[name]; !ok { - return ErrDataNotFound - } - return nil - }() - if err != nil { - return nil, err + cstore, ok := c.containerCacheMap.Load(name) + if !ok { + return nil, ErrDataNotFound } - return cstore.RecentStats(start, end, maxStats) } func (c *InMemoryCache) Close() error { - c.lock.Lock() - c.containerCacheMap = make(map[string]*containerCache, 32) - c.lock.Unlock() + c.containerCacheMap = containerCacheMap{} return nil } func (c *InMemoryCache) RemoveContainer(containerName string) error { - c.lock.Lock() - delete(c.containerCacheMap, containerName) - c.lock.Unlock() + c.containerCacheMap.Delete(containerName) return nil } @@ -133,10 +145,8 @@ func New( maxAge time.Duration, backend []storage.StorageDriver, ) *InMemoryCache { - ret := &InMemoryCache{ - containerCacheMap: make(map[string]*containerCache, 32), - maxAge: maxAge, - backend: backend, + return &InMemoryCache{ + maxAge: maxAge, + backend: backend, } - return ret } diff --git a/vendor/github.com/google/cadvisor/collector/generic_collector.go b/vendor/github.com/google/cadvisor/collector/generic_collector.go index 490f63e48b..b9702e25c2 100644 --- a/vendor/github.com/google/cadvisor/collector/generic_collector.go +++ b/vendor/github.com/google/cadvisor/collector/generic_collector.go @@ -67,7 +67,7 @@ func NewCollector(collectorName string, configFile []byte, metricCountLimit int, // TODO : Add checks for validity of config file (eg : Accurate JSON fields) if len(configInJSON.MetricsConfig) == 0 { - return nil, fmt.Errorf("No metrics provided in config") + return nil, fmt.Errorf("no metrics provided in config") } minPollFrequency := time.Duration(0) @@ -83,7 +83,7 @@ func NewCollector(collectorName string, configFile []byte, metricCountLimit int, regexprs[ind], err = regexp.Compile(metricConfig.Regex) if err != nil { - return nil, fmt.Errorf("Invalid regexp %v for metric %v", metricConfig.Regex, metricConfig.Name) + return nil, fmt.Errorf("invalid regexp %v for metric %v", metricConfig.Regex, metricConfig.Name) } } @@ -94,7 +94,7 @@ func NewCollector(collectorName string, configFile []byte, metricCountLimit int, } if len(configInJSON.MetricsConfig) > metricCountLimit { - return nil, fmt.Errorf("Too many metrics defined: %d limit: %d", len(configInJSON.MetricsConfig), metricCountLimit) + return nil, fmt.Errorf("too many metrics defined: %d limit: %d", len(configInJSON.MetricsConfig), metricCountLimit) } return &GenericCollector{ @@ -173,10 +173,10 @@ func (collector *GenericCollector) Collect(metrics map[string][]v1.MetricVal) (t } } else { - errorSlice = append(errorSlice, fmt.Errorf("Unexpected value of 'data_type' for metric '%v' in config ", metricConfig.Name)) + errorSlice = append(errorSlice, fmt.Errorf("unexpected value of 'data_type' for metric '%v' in config ", metricConfig.Name)) } } else { - errorSlice = append(errorSlice, fmt.Errorf("No match found for regexp: %v for metric '%v' in config", metricConfig.Regex, metricConfig.Name)) + errorSlice = append(errorSlice, fmt.Errorf("no match found for regexp: %v for metric '%v' in config", metricConfig.Regex, metricConfig.Name)) } } return nextCollectionTime, metrics, compileErrors(errorSlice) diff --git a/vendor/github.com/google/cadvisor/collector/prometheus_collector.go b/vendor/github.com/google/cadvisor/collector/prometheus_collector.go index cd653dd8f6..b8fb289193 100644 --- a/vendor/github.com/google/cadvisor/collector/prometheus_collector.go +++ b/vendor/github.com/google/cadvisor/collector/prometheus_collector.go @@ -72,7 +72,7 @@ func NewPrometheusCollector(collectorName string, configFile []byte, metricCount } if metricCountLimit < 0 { - return nil, fmt.Errorf("Metric count limit must be greater than or equal to 0") + return nil, fmt.Errorf("metric count limit must be greater than or equal to 0") } var metricsSet map[string]bool @@ -84,7 +84,7 @@ func NewPrometheusCollector(collectorName string, configFile []byte, metricCount } if len(configInJSON.MetricsConfig) > metricCountLimit { - return nil, fmt.Errorf("Too many metrics defined: %d limit %d", len(configInJSON.MetricsConfig), metricCountLimit) + return nil, fmt.Errorf("too many metrics defined: %d limit %d", len(configInJSON.MetricsConfig), metricCountLimit) } // TODO : Add checks for validity of config file (eg : Accurate JSON fields) diff --git a/vendor/github.com/google/cadvisor/collector/util.go b/vendor/github.com/google/cadvisor/collector/util.go index b8814d131f..742ff0c690 100644 --- a/vendor/github.com/google/cadvisor/collector/util.go +++ b/vendor/github.com/google/cadvisor/collector/util.go @@ -16,11 +16,10 @@ package collector import "github.com/google/cadvisor/container" -func (endpointConfig *EndpointConfig) configure(containerHandler container.ContainerHandler) { - //If the exact URL was not specified, generate it based on the ip address of the container. - endpoint := endpointConfig - if endpoint.URL == "" { +func (ec *EndpointConfig) configure(containerHandler container.ContainerHandler) { + // If the exact URL was not specified, generate it based on the ip address of the container. + if ec.URL == "" { ipAddress := containerHandler.GetContainerIPAddress() - endpointConfig.URL = endpoint.URLConfig.Protocol + "://" + ipAddress + ":" + endpoint.URLConfig.Port.String() + endpoint.URLConfig.Path + ec.URL = ec.URLConfig.Protocol + "://" + ipAddress + ":" + ec.URLConfig.Port.String() + ec.URLConfig.Path } } diff --git a/vendor/github.com/google/cadvisor/container/common/container_hints.go b/vendor/github.com/google/cadvisor/container/common/container_hints.go index 505f8c243d..a2af57b3cf 100644 --- a/vendor/github.com/google/cadvisor/container/common/container_hints.go +++ b/vendor/github.com/google/cadvisor/container/common/container_hints.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Unmarshal's a Containers description json file. The json file contains // an array of ContainerHint structs, each with a container's id and networkInterface // This allows collecting stats about network interfaces configured outside docker diff --git a/vendor/github.com/google/cadvisor/container/common/fsHandler.go b/vendor/github.com/google/cadvisor/container/common/fsHandler.go index f944b2277a..21d6ab017a 100644 --- a/vendor/github.com/google/cadvisor/container/common/fsHandler.go +++ b/vendor/github.com/google/cadvisor/container/common/fsHandler.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Handler for Docker containers. package common diff --git a/vendor/github.com/google/cadvisor/container/common/helpers.go b/vendor/github.com/google/cadvisor/container/common/helpers.go index ae8bb51622..3b3d27f300 100644 --- a/vendor/github.com/google/cadvisor/container/common/helpers.go +++ b/vendor/github.com/google/cadvisor/container/common/helpers.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package common import ( @@ -25,7 +27,6 @@ import ( "strings" "time" - "github.com/karrick/godirwalk" "github.com/opencontainers/cgroups" "golang.org/x/sys/unix" @@ -301,16 +302,11 @@ func readUInt64(dirpath string, file string) uint64 { // Lists all directories under "path" and outputs the results as children of "parent". func ListDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}) error { - buf := make([]byte, godirwalk.MinimumScratchBufferSize) - return listDirectories(dirpath, parent, recursive, output, buf) -} - -func listDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}, buf []byte) error { - dirents, err := godirwalk.ReadDirents(dirpath, buf) + dirents, err := os.ReadDir(dirpath) if err != nil { // Ignore if this hierarchy does not exist. if errors.Is(err, fs.ErrNotExist) { - err = nil + return nil } return err } @@ -326,8 +322,7 @@ func listDirectories(dirpath string, parent string, recursive bool, output map[s // List subcontainers if asked to. if recursive { - err := listDirectories(path.Join(dirpath, dirname), name, true, output, buf) - if err != nil { + if err := ListDirectories(path.Join(dirpath, dirname), name, true, output); err != nil { return err } } @@ -387,6 +382,10 @@ func AssignDeviceNamesToDiskStats(namer DeviceNamer, stats *info.DiskIoStats) { stats.IoTime, stats.IoWaitTime, stats.Sectors, + stats.IoCostUsage, + stats.IoCostWait, + stats.IoCostIndebt, + stats.IoCostIndelay, ) } diff --git a/vendor/github.com/google/cadvisor/container/common/inotify_watcher.go b/vendor/github.com/google/cadvisor/container/common/inotify_watcher.go index 7480dfc5fd..3453f1f20a 100644 --- a/vendor/github.com/google/cadvisor/container/common/inotify_watcher.go +++ b/vendor/github.com/google/cadvisor/container/common/inotify_watcher.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package common import ( diff --git a/vendor/github.com/google/cadvisor/container/container.go b/vendor/github.com/google/cadvisor/container/container.go index 4c435a0e81..faa21b04a5 100644 --- a/vendor/github.com/google/cadvisor/container/container.go +++ b/vendor/github.com/google/cadvisor/container/container.go @@ -34,7 +34,6 @@ const ( ContainerTypeDocker ContainerTypeCrio ContainerTypeContainerd - ContainerTypeMesos ContainerTypePodman ) @@ -64,6 +63,11 @@ type ContainerHandler interface { // Returns the container's ip address, if available GetContainerIPAddress() string + // GetExitCode returns the container's exit code if available. + // Returns an error if the container has not exited, exit codes are not supported + // for this handler type, or the container information is unavailable. + GetExitCode() (int, error) + // Returns whether the container still exists. Exists() bool diff --git a/vendor/github.com/google/cadvisor/container/containerd/client.go b/vendor/github.com/google/cadvisor/container/containerd/client.go index 34134baf3e..e568eb7f77 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/client.go +++ b/vendor/github.com/google/cadvisor/container/containerd/client.go @@ -45,6 +45,8 @@ type client struct { type ContainerdClient interface { LoadContainer(ctx context.Context, id string) (*containers.Container, error) TaskPid(ctx context.Context, id string) (uint32, error) + LoadTaskProcess(ctx context.Context, id string) (*tasktypes.Process, error) + TaskExitStatus(ctx context.Context, id string) (uint32, error) Version(ctx context.Context) (string, error) } @@ -54,6 +56,7 @@ var ( var once sync.Once var ctrdClient ContainerdClient = nil +var ctrdClientErr error = nil const ( maxBackoffDelay = 3 * time.Second @@ -64,11 +67,10 @@ const ( // Client creates a containerd client func Client(address, namespace string) (ContainerdClient, error) { - var retErr error once.Do(func() { tryConn, err := net.DialTimeout("unix", address, connectionTimeout) if err != nil { - retErr = fmt.Errorf("containerd: cannot unix dial containerd api service: %v", err) + ctrdClientErr = fmt.Errorf("containerd: cannot unix dial containerd api service: %v", err) return } tryConn.Close() @@ -97,7 +99,7 @@ func Client(address, namespace string) (ContainerdClient, error) { //nolint:staticcheck // SA1019 conn, err := grpc.DialContext(ctx, dialer.DialAddress(address), gopts...) if err != nil { - retErr = err + ctrdClientErr = err return } ctrdClient = &client{ @@ -106,7 +108,7 @@ func Client(address, namespace string) (ContainerdClient, error) { versionService: versionapi.NewVersionClient(conn), } }) - return ctrdClient, retErr + return ctrdClient, ctrdClientErr } func (c *client) LoadContainer(ctx context.Context, id string) (*containers.Container, error) { @@ -132,6 +134,30 @@ func (c *client) TaskPid(ctx context.Context, id string) (uint32, error) { return response.Process.Pid, nil } +func (c *client) LoadTaskProcess(ctx context.Context, id string) (*tasktypes.Process, error) { + response, err := c.taskService.Get(ctx, &tasksapi.GetRequest{ + ContainerID: id, + }) + if err != nil { + return nil, errgrpc.ToNative(err) + } + + return response.Process, nil +} + +func (c *client) TaskExitStatus(ctx context.Context, id string) (uint32, error) { + response, err := c.taskService.Get(ctx, &tasksapi.GetRequest{ + ContainerID: id, + }) + if err != nil { + return 0, errgrpc.ToNative(err) + } + if response.Process.Status != tasktypes.Status_STOPPED { + return 0, fmt.Errorf("container %s has not exited (status: %v)", id, response.Process.Status) + } + return response.Process.ExitStatus, nil +} + func (c *client) Version(ctx context.Context) (string, error) { response, err := c.versionService.Version(ctx, &emptypb.Empty{}) if err != nil { diff --git a/vendor/github.com/google/cadvisor/container/containerd/factory.go b/vendor/github.com/google/cadvisor/container/containerd/factory.go index 1688bd7845..0f64e945d3 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/factory.go +++ b/vendor/github.com/google/cadvisor/container/containerd/factory.go @@ -12,16 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package containerd import ( + "context" "flag" "fmt" "path" "regexp" "strings" - "golang.org/x/net/context" "k8s.io/klog/v2" "github.com/google/cadvisor/container" diff --git a/vendor/github.com/google/cadvisor/container/containerd/grpc.go b/vendor/github.com/google/cadvisor/container/containerd/grpc.go index 532104056b..e73a9a17ce 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/grpc.go +++ b/vendor/github.com/google/cadvisor/container/containerd/grpc.go @@ -16,9 +16,11 @@ package containerd import ( - "github.com/google/cadvisor/container/containerd/namespaces" - "golang.org/x/net/context" + "context" + "google.golang.org/grpc" + + "github.com/google/cadvisor/container/containerd/namespaces" ) type namespaceInterceptor struct { diff --git a/vendor/github.com/google/cadvisor/container/containerd/handler.go b/vendor/github.com/google/cadvisor/container/containerd/handler.go index d7f0864a63..0fd69e253f 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/handler.go +++ b/vendor/github.com/google/cadvisor/container/containerd/handler.go @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Handler for containerd containers. package containerd import ( + "context" "encoding/json" "errors" "fmt" @@ -25,7 +28,6 @@ import ( "github.com/containerd/errdefs" "github.com/opencontainers/cgroups" specs "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/net/context" "github.com/google/cadvisor/container" "github.com/google/cadvisor/container/common" @@ -50,6 +52,7 @@ type containerdContainerHandler struct { includedMetrics container.MetricSet libcontainerHandler *containerlibcontainer.Handler + client ContainerdClient } var _ container.ContainerHandler = &containerdContainerHandler{} @@ -143,6 +146,7 @@ func newContainerdContainerHandler( includedMetrics: metrics, reference: containerReference, libcontainerHandler: libcontainerHandler, + client: client, } // Add the name and bare ID as aliases of the container. handler.image = cntr.Image @@ -248,3 +252,12 @@ func (h *containerdContainerHandler) GetContainerIPAddress() string { // containerd doesnt take care of networking.So it doesnt maintain networking states return "" } + +func (h *containerdContainerHandler) GetExitCode() (int, error) { + ctx := context.Background() + exitStatus, err := h.client.TaskExitStatus(ctx, h.reference.Id) + if err != nil { + return -1, err + } + return int(exitStatus), nil +} diff --git a/vendor/github.com/google/cadvisor/container/containerd/install/install.go b/vendor/github.com/google/cadvisor/container/containerd/install/install.go index 274357cb0b..fd399fa467 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/install/install.go +++ b/vendor/github.com/google/cadvisor/container/containerd/install/install.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // The install package registers containerd.NewPlugin() as the "containerd" container provider when imported package install diff --git a/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go index f03945ba9a..69df91f2d7 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go +++ b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. //go:build !windows -// +build !windows /* Copyright The containerd Authors. diff --git a/vendor/github.com/google/cadvisor/container/containerd/plugin.go b/vendor/github.com/google/cadvisor/container/containerd/plugin.go index 9d42b5d46d..bfb676380f 100644 --- a/vendor/github.com/google/cadvisor/container/containerd/plugin.go +++ b/vendor/github.com/google/cadvisor/container/containerd/plugin.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package containerd import ( diff --git a/vendor/github.com/google/cadvisor/container/crio/client.go b/vendor/github.com/google/cadvisor/container/crio/client.go index fad9a5152c..9fed330e9c 100644 --- a/vendor/github.com/google/cadvisor/container/crio/client.go +++ b/vendor/github.com/google/cadvisor/container/crio/client.go @@ -72,7 +72,7 @@ type crioClientImpl struct { func configureUnixTransport(tr *http.Transport, proto, addr string) error { if len(addr) > maxUnixSocketPathSize { - return fmt.Errorf("Unix socket path %q is too long", addr) + return fmt.Errorf("unix socket path %q is too long", addr) } // No need for compression in local communications. tr.DisableCompression = true @@ -149,9 +149,9 @@ func (c *crioClientImpl) ContainerInfo(id string) (*ContainerInfo, error) { if resp.StatusCode != http.StatusOK { respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("Error finding container %s: Status %d", id, resp.StatusCode) + return nil, fmt.Errorf("error finding container %s: status %d", id, resp.StatusCode) } - return nil, fmt.Errorf("Error finding container %s: Status %d returned error %s", id, resp.StatusCode, string(respBody)) + return nil, fmt.Errorf("error finding container %s: status %d returned error %s", id, resp.StatusCode, string(respBody)) } if err := json.NewDecoder(resp.Body).Decode(&cInfo); err != nil { diff --git a/vendor/github.com/google/cadvisor/container/crio/factory.go b/vendor/github.com/google/cadvisor/container/crio/factory.go index e16b68a2a0..691e56f687 100644 --- a/vendor/github.com/google/cadvisor/container/crio/factory.go +++ b/vendor/github.com/google/cadvisor/container/crio/factory.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package crio import ( diff --git a/vendor/github.com/google/cadvisor/container/crio/handler.go b/vendor/github.com/google/cadvisor/container/crio/handler.go index f955732376..31349a08ee 100644 --- a/vendor/github.com/google/cadvisor/container/crio/handler.go +++ b/vendor/github.com/google/cadvisor/container/crio/handler.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Handler for CRI-O containers. package crio @@ -360,3 +362,7 @@ func (h *crioContainerHandler) Exists() bool { func (h *crioContainerHandler) Type() container.ContainerType { return container.ContainerTypeCrio } + +func (h *crioContainerHandler) GetExitCode() (int, error) { + return -1, fmt.Errorf("exit code not available from CRI-O API") +} diff --git a/vendor/github.com/google/cadvisor/container/crio/install/install.go b/vendor/github.com/google/cadvisor/container/crio/install/install.go index c49df71f60..0c9b17470b 100644 --- a/vendor/github.com/google/cadvisor/container/crio/install/install.go +++ b/vendor/github.com/google/cadvisor/container/crio/install/install.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // The install package registers crio.NewPlugin() as the "crio" container provider when imported package install diff --git a/vendor/github.com/google/cadvisor/container/crio/plugin.go b/vendor/github.com/google/cadvisor/container/crio/plugin.go index 9384de3f43..61630912b8 100644 --- a/vendor/github.com/google/cadvisor/container/crio/plugin.go +++ b/vendor/github.com/google/cadvisor/container/crio/plugin.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package crio import ( diff --git a/vendor/github.com/google/cadvisor/container/factory.go b/vendor/github.com/google/cadvisor/container/factory.go index dfe6de6437..f5a3c90ff0 100644 --- a/vendor/github.com/google/cadvisor/container/factory.go +++ b/vendor/github.com/google/cadvisor/container/factory.go @@ -192,7 +192,6 @@ func RegisterPlugin(name string, plugin Plugin) error { if _, found := plugins[name]; found { return fmt.Errorf("Plugin %q was registered twice", name) } - klog.V(4).Infof("Registered Plugin %q", name) plugins[name] = plugin return nil } diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go index cb34177cb9..4d6e8a40fc 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package libcontainer import ( @@ -311,7 +313,7 @@ func processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info. func (h *Handler) schedulerStatsFromProcs() (info.CpuSchedstat, error) { pids, err := h.cgroupManager.GetAllPids() if err != nil { - return info.CpuSchedstat{}, fmt.Errorf("Could not get PIDs for container %d: %w", h.pid, err) + return info.CpuSchedstat{}, fmt.Errorf("could not get PIDs for container %d: %w", h.pid, err) } alivePids := make(map[int]struct{}, len(pids)) for _, pid := range pids { @@ -771,6 +773,8 @@ func setCPUStats(s *cgroups.Stats, ret *info.ContainerStats, withPerCPU bool) { ret.Cpu.CFS.Periods = s.CpuStats.ThrottlingData.Periods ret.Cpu.CFS.ThrottledPeriods = s.CpuStats.ThrottlingData.ThrottledPeriods ret.Cpu.CFS.ThrottledTime = s.CpuStats.ThrottlingData.ThrottledTime + ret.Cpu.CFS.BurstsPeriods = s.CpuStats.BurstData.BurstsPeriods + ret.Cpu.CFS.BurstTime = s.CpuStats.BurstData.BurstTime setPSIStats(s.CpuStats.PSI, &ret.Cpu.PSI) if !withPerCPU { @@ -793,6 +797,10 @@ func setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.DiskIo.IoWaitTime = diskStatsCopy(s.BlkioStats.IoWaitTimeRecursive) ret.DiskIo.IoMerged = diskStatsCopy(s.BlkioStats.IoMergedRecursive) ret.DiskIo.IoTime = diskStatsCopy(s.BlkioStats.IoTimeRecursive) + ret.DiskIo.IoCostUsage = diskStatsCopy(s.BlkioStats.IoCostUsage) + ret.DiskIo.IoCostWait = diskStatsCopy(s.BlkioStats.IoCostWait) + ret.DiskIo.IoCostIndebt = diskStatsCopy(s.BlkioStats.IoCostIndebt) + ret.DiskIo.IoCostIndelay = diskStatsCopy(s.BlkioStats.IoCostIndelay) setPSIStats(s.BlkioStats.PSI, &ret.DiskIo.PSI) } diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go index de2387ee99..b8a337c0c1 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package libcontainer import ( diff --git a/vendor/github.com/google/cadvisor/container/raw/factory.go b/vendor/github.com/google/cadvisor/container/raw/factory.go index 0db2b995d3..0ab60829a8 100644 --- a/vendor/github.com/google/cadvisor/container/raw/factory.go +++ b/vendor/github.com/google/cadvisor/container/raw/factory.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package raw import ( diff --git a/vendor/github.com/google/cadvisor/container/raw/handler.go b/vendor/github.com/google/cadvisor/container/raw/handler.go index 9397fb6434..a53c018806 100644 --- a/vendor/github.com/google/cadvisor/container/raw/handler.go +++ b/vendor/github.com/google/cadvisor/container/raw/handler.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Handler for "raw" containers. package raw @@ -281,6 +283,10 @@ func (h *rawContainerHandler) Type() container.ContainerType { return container.ContainerTypeRaw } +func (h *rawContainerHandler) GetExitCode() (int, error) { + return -1, fmt.Errorf("exit codes not applicable for raw cgroup containers") +} + type fsNamer struct { fs []fs.Fs factory info.MachineInfoFactory diff --git a/vendor/github.com/google/cadvisor/container/raw/watcher.go b/vendor/github.com/google/cadvisor/container/raw/watcher.go index d71cc12065..dec1aeaea4 100644 --- a/vendor/github.com/google/cadvisor/container/raw/watcher.go +++ b/vendor/github.com/google/cadvisor/container/raw/watcher.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Package container defines types for sub-container events and also // defines an interface for container operation handlers. package raw diff --git a/vendor/github.com/google/cadvisor/container/systemd/factory.go b/vendor/github.com/google/cadvisor/container/systemd/factory.go index e33f698657..cef022a3d8 100644 --- a/vendor/github.com/google/cadvisor/container/systemd/factory.go +++ b/vendor/github.com/google/cadvisor/container/systemd/factory.go @@ -33,7 +33,7 @@ func (f *systemdFactory) String() string { } func (f *systemdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) { - return nil, fmt.Errorf("Not yet supported") + return nil, fmt.Errorf("not yet supported") } func (f *systemdFactory) CanHandleAndAccept(name string) (bool, bool, error) { diff --git a/vendor/github.com/google/cadvisor/devicemapper/thin_ls_client.go b/vendor/github.com/google/cadvisor/devicemapper/thin_ls_client.go index e8e8e7a614..afa5af8497 100644 --- a/vendor/github.com/google/cadvisor/devicemapper/thin_ls_client.go +++ b/vendor/github.com/google/cadvisor/devicemapper/thin_ls_client.go @@ -58,7 +58,7 @@ func (c *defaultThinLsClient) ThinLs(deviceName string) (map[string]uint64, erro output, err := exec.Command(c.thinLsPath, args...).Output() if err != nil { - return nil, fmt.Errorf("Error running command `thin_ls %v`: %v\noutput:\n\n%v", strings.Join(args, " "), err, string(output)) + return nil, fmt.Errorf("error running command `thin_ls %v`: %v\noutput:\n\n%v", strings.Join(args, " "), err, string(output)) } return parseThinLsOutput(output), nil diff --git a/vendor/github.com/google/cadvisor/devicemapper/thin_pool_watcher.go b/vendor/github.com/google/cadvisor/devicemapper/thin_pool_watcher.go index 39df156877..5619cb8374 100644 --- a/vendor/github.com/google/cadvisor/devicemapper/thin_pool_watcher.go +++ b/vendor/github.com/google/cadvisor/devicemapper/thin_pool_watcher.go @@ -17,19 +17,35 @@ package devicemapper import ( "fmt" "strings" - "sync" + "sync/atomic" "time" "k8s.io/klog/v2" ) +// usageCache is a typed wrapper around atomic.Value that eliminates the need +// for type assertions at every call site. It stores device ID strings mapped +// to usage values (uint64). +type usageCache struct { + v atomic.Value +} + +// Load retrieves the current cache map. +func (c *usageCache) Load() map[string]uint64 { + return c.v.Load().(map[string]uint64) +} + +// Store saves a new cache map. +func (c *usageCache) Store(m map[string]uint64) { + c.v.Store(m) +} + // ThinPoolWatcher maintains a cache of device name -> usage stats for a // devicemapper thin-pool using thin_ls. type ThinPoolWatcher struct { poolName string metadataDevice string - lock *sync.RWMutex - cache map[string]uint64 + cache usageCache period time.Duration stopChan chan struct{} dmsetup DmsetupClient @@ -44,15 +60,16 @@ func NewThinPoolWatcher(poolName, metadataDevice string) (*ThinPoolWatcher, erro return nil, fmt.Errorf("encountered error creating thin_ls client: %v", err) } - return &ThinPoolWatcher{poolName: poolName, + w := &ThinPoolWatcher{ + poolName: poolName, metadataDevice: metadataDevice, - lock: &sync.RWMutex{}, - cache: make(map[string]uint64), period: 15 * time.Second, stopChan: make(chan struct{}), dmsetup: NewDmsetupClient(), thinLsClient: thinLsClient, - }, nil + } + w.cache.Store(map[string]uint64{}) + return w, nil } // Start starts the ThinPoolWatcher. @@ -87,14 +104,11 @@ func (w *ThinPoolWatcher) Stop() { // GetUsage gets the cached usage value of the given device. func (w *ThinPoolWatcher) GetUsage(deviceID string) (uint64, error) { - w.lock.RLock() - defer w.lock.RUnlock() - - v, ok := w.cache[deviceID] + cache := w.cache.Load() + v, ok := cache[deviceID] if !ok { return 0, fmt.Errorf("no cached value for usage of device %v", deviceID) } - return v, nil } @@ -106,9 +120,6 @@ const ( // Refresh performs a `thin_ls` of the pool being watched and refreshes the // cached data with the result. func (w *ThinPoolWatcher) Refresh() error { - w.lock.Lock() - defer w.lock.Unlock() - currentlyReserved, err := w.checkReservation(w.poolName) if err != nil { err = fmt.Errorf("error determining whether snapshot is reserved: %v", err) @@ -148,7 +159,7 @@ func (w *ThinPoolWatcher) Refresh() error { return err } - w.cache = newCache + w.cache.Store(newCache) return nil } diff --git a/vendor/github.com/google/cadvisor/fs/btrfs/install/install.go b/vendor/github.com/google/cadvisor/fs/btrfs/install/install.go new file mode 100644 index 0000000000..8d9ff282be --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/btrfs/install/install.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/btrfs" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("btrfs", btrfs.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register btrfs fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/btrfs/mount.go b/vendor/github.com/google/cadvisor/fs/btrfs/mount.go new file mode 100644 index 0000000000..f92da92e5d --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/btrfs/mount.go @@ -0,0 +1,63 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package btrfs + +import ( + "fmt" + "syscall" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +// major extracts the major device number from a device number. +func major(devNumber uint64) uint { + return uint((devNumber >> 8) & 0xfff) +} + +// minor extracts the minor device number from a device number. +func minor(devNumber uint64) uint { + return uint((devNumber & 0xff) | ((devNumber >> 12) & 0xfff00)) +} + +// GetBtrfsMajorMinorIds gets the major and minor device IDs for a btrfs mount point. +// This is a workaround for wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. +// Instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point. +func GetBtrfsMajorMinorIds(mnt *mount.Info) (int, int, error) { + buf := new(syscall.Stat_t) + err := syscall.Stat(mnt.Source, buf) + if err != nil { + err = fmt.Errorf("stat failed on %s with error: %s", mnt.Source, err) + return 0, 0, err + } + + klog.V(4).Infof("btrfs mount %#v", mnt) + if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK { + err := syscall.Stat(mnt.Mountpoint, buf) + if err != nil { + err = fmt.Errorf("stat failed on %s with error: %s", mnt.Mountpoint, err) + return 0, 0, err + } + + // The type Dev and Rdev in Stat_t are 32bit on mips. + klog.V(4).Infof("btrfs dev major:minor %d:%d\n", int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev)))) // nolint: unconvert + klog.V(4).Infof("btrfs rdev major:minor %d:%d\n", int(major(uint64(buf.Rdev))), int(minor(uint64(buf.Rdev)))) // nolint: unconvert + + return int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))), nil // nolint: unconvert + } + return 0, 0, fmt.Errorf("%s is not a block device", mnt.Source) +} diff --git a/vendor/github.com/google/cadvisor/fs/btrfs/plugin.go b/vendor/github.com/google/cadvisor/fs/btrfs/plugin.go new file mode 100644 index 0000000000..eaca16a27b --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/btrfs/plugin.go @@ -0,0 +1,87 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package btrfs + +import ( + "strings" + + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/vfs" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +type btrfsPlugin struct{} + +// NewPlugin creates a new Btrfs filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &btrfsPlugin{} +} + +func (p *btrfsPlugin) Name() string { + return "btrfs" +} + +// CanHandle returns true if the filesystem type is btrfs. +func (p *btrfsPlugin) CanHandle(fsType string) bool { + return fsType == "btrfs" +} + +// Priority returns 100 - Btrfs has higher priority than VFS. +func (p *btrfsPlugin) Priority() int { + return 100 +} + +// GetStats returns filesystem statistics for Btrfs. +// Btrfs delegates to VFS for stats collection. +func (p *btrfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + // Btrfs uses VFS stats + capacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint) + if err != nil { + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Inodes: &inodes, + InodesFree: &inodesFree, + Type: fs.VFS, + }, nil +} + +// ProcessMount handles Btrfs mount processing. +// Btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. +// Instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point. +func (p *btrfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + // Only apply fix if Major is 0 and Source starts with /dev/ + if mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") { + major, minor, err := GetBtrfsMajorMinorIds(mnt) + if err != nil { + klog.Warningf("%s", err) + } else { + // Create a copy with corrected values + correctedMnt := *mnt + correctedMnt.Major = major + correctedMnt.Minor = minor + return true, &correctedMnt, nil + } + } + return true, mnt, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/devicemapper/install/install.go b/vendor/github.com/google/cadvisor/fs/devicemapper/install/install.go new file mode 100644 index 0000000000..57cfc7b62f --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/devicemapper/install/install.go @@ -0,0 +1,29 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/devicemapper" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("devicemapper", devicemapper.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register devicemapper fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/devicemapper/plugin.go b/vendor/github.com/google/cadvisor/fs/devicemapper/plugin.go new file mode 100644 index 0000000000..19704dc57f --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/devicemapper/plugin.go @@ -0,0 +1,66 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package devicemapper + +import ( + "github.com/google/cadvisor/fs" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +type dmPlugin struct{} + +// NewPlugin creates a new DeviceMapper filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &dmPlugin{} +} + +func (p *dmPlugin) Name() string { + return "devicemapper" +} + +// CanHandle returns true if the filesystem type is devicemapper. +func (p *dmPlugin) CanHandle(fsType string) bool { + return fsType == "devicemapper" +} + +// Priority returns 100 - DeviceMapper has higher priority than VFS. +func (p *dmPlugin) Priority() int { + return 100 +} + +// GetStats returns filesystem statistics for DeviceMapper thin provisioning. +func (p *dmPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + capacity, free, avail, err := GetDMStats(device, partition.BlockSize) + if err != nil { + return nil, err + } + + klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v", capacity, free, avail) + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Type: fs.DeviceMapper, + }, nil +} + +// ProcessMount handles DeviceMapper mount processing. +// For DeviceMapper, no special processing is needed. +func (p *dmPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + return true, mnt, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/devicemapper/stats.go b/vendor/github.com/google/cadvisor/fs/devicemapper/stats.go new file mode 100644 index 0000000000..afa652d75b --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/devicemapper/stats.go @@ -0,0 +1,113 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package devicemapper + +import ( + "fmt" + "os/exec" + "strconv" + "strings" + + dm "github.com/google/cadvisor/devicemapper" +) + +// GetDMStats returns devicemapper thin provisioning stats. +func GetDMStats(poolName string, dataBlkSize uint) (uint64, uint64, uint64, error) { + out, err := exec.Command("dmsetup", "status", poolName).Output() + if err != nil { + return 0, 0, 0, err + } + + used, total, err := parseDMStatus(string(out)) + if err != nil { + return 0, 0, 0, err + } + + used *= 512 * uint64(dataBlkSize) + total *= 512 * uint64(dataBlkSize) + free := total - used + + return total, free, free, nil +} + +// parseDMStatus parses the output of `dmsetup status`. +func parseDMStatus(dmStatus string) (uint64, uint64, error) { + dmStatus = strings.Replace(dmStatus, "/", " ", -1) + dmFields := strings.Fields(dmStatus) + + if len(dmFields) < 8 { + return 0, 0, fmt.Errorf("invalid dmsetup status output: %s", dmStatus) + } + + used, err := strconv.ParseUint(dmFields[6], 10, 64) + if err != nil { + return 0, 0, err + } + total, err := strconv.ParseUint(dmFields[7], 10, 64) + if err != nil { + return 0, 0, err + } + + return used, total, nil +} + +// parseDMTable parses a single line of `dmsetup table` output and returns the +// major device, minor device, block size, and an error. +func ParseDMTable(dmTable string) (uint, uint, uint, error) { + dmTable = strings.Replace(dmTable, ":", " ", -1) + dmFields := strings.Fields(dmTable) + + if len(dmFields) < 8 { + return 0, 0, 0, fmt.Errorf("invalid dmsetup status output: %s", dmTable) + } + + major, err := strconv.ParseUint(dmFields[5], 10, 32) + if err != nil { + return 0, 0, 0, err + } + minor, err := strconv.ParseUint(dmFields[6], 10, 32) + if err != nil { + return 0, 0, 0, err + } + dataBlkSize, err := strconv.ParseUint(dmFields[7], 10, 32) + if err != nil { + return 0, 0, 0, err + } + + return uint(major), uint(minor), uint(dataBlkSize), nil +} + +// DockerDMDevice returns information about the devicemapper device and "partition" if +// docker is using devicemapper for its storage driver. +func DockerDMDevice(driverStatus map[string]string, dmsetup dm.DmsetupClient) (string, uint, uint, uint, error) { + const driverStatusPoolName = "Pool Name" + + poolName, ok := driverStatus[driverStatusPoolName] + if !ok || len(poolName) == 0 { + return "", 0, 0, 0, fmt.Errorf("could not get dm pool name") + } + + out, err := dmsetup.Table(poolName) + if err != nil { + return "", 0, 0, 0, err + } + + major, minor, dataBlkSize, err := ParseDMTable(string(out)) + if err != nil { + return "", 0, 0, 0, err + } + + return poolName, major, minor, dataBlkSize, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/fs.go b/vendor/github.com/google/cadvisor/fs/fs.go index 4c4de51931..ec2c3b2ccd 100644 --- a/vendor/github.com/google/cadvisor/fs/fs.go +++ b/vendor/github.com/google/cadvisor/fs/fs.go @@ -13,30 +13,25 @@ // limitations under the License. //go:build linux -// +build linux // Provides Filesystem Stats package fs import ( "bufio" - "context" + "errors" "fmt" "os" - "os/exec" "path" "path/filepath" "regexp" "strconv" "strings" "syscall" - "time" - zfs "github.com/mistifyio/go-zfs" mount "github.com/moby/sys/mountinfo" "github.com/google/cadvisor/devicemapper" - "github.com/google/cadvisor/utils" "k8s.io/klog/v2" ) @@ -173,28 +168,21 @@ func getFsUUIDToDeviceNameMap() (map[string]string, error) { func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) map[string]partition { partitions := make(map[string]partition) - supportedFsType := map[string]bool{ - // all ext and nfs systems are checked through prefix - // because there are a number of families (e.g., ext3, ext4, nfs3, nfs4...) - "btrfs": true, - "overlay": true, - "tmpfs": true, - "xfs": true, - "zfs": true, - } - for _, mnt := range mounts { - if !strings.HasPrefix(mnt.FSType, "ext") && !strings.HasPrefix(mnt.FSType, "nfs") && - !supportedFsType[mnt.FSType] { + // Use plugin system to determine if filesystem is supported + plugin := GetPluginForFsType(mnt.FSType) + if plugin == nil { continue } - // Avoid bind mounts, exclude tmpfs. + + // Avoid bind mounts, but allow tmpfs duplicates (handled by plugin's ProcessMount) if _, ok := partitions[mnt.Source]; ok { if mnt.FSType != "tmpfs" { continue } } + // Check for excluded mountpoint prefixes hasPrefix := false for _, prefix := range excludedMountpointPrefixes { if strings.HasPrefix(mnt.Mountpoint, prefix) { @@ -206,32 +194,21 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma continue } - // using mountpoint to replace device once fstype it tmpfs - if mnt.FSType == "tmpfs" { - mnt.Source = mnt.Mountpoint - } - // btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. - // instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point - if mnt.FSType == "btrfs" && mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") { - major, minor, err := getBtrfsMajorMinorIds(mnt) - if err != nil { - klog.Warningf("%s", err) - } else { - mnt.Major = major - mnt.Minor = minor - } + // Let plugin process the mount (handles filesystem-specific modifications) + include, processedMnt, err := plugin.ProcessMount(mnt) + if err != nil { + klog.Warningf("error processing mount for %s: %v", mnt.FSType, err) + continue } - - // overlay fix: Making mount source unique for all overlay mounts, using the mount's major and minor ids. - if mnt.FSType == "overlay" { - mnt.Source = fmt.Sprintf("%s_%d-%d", mnt.Source, mnt.Major, mnt.Minor) + if !include { + continue } - partitions[mnt.Source] = partition{ - fsType: mnt.FSType, - mountpoint: mnt.Mountpoint, - major: uint(mnt.Major), - minor: uint(mnt.Minor), + partitions[processedMnt.Source] = partition{ + fsType: processedMnt.FSType, + mountpoint: processedMnt.Mountpoint, + major: uint(processedMnt.Major), + minor: uint(processedMnt.Minor), } } @@ -412,81 +389,112 @@ func (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error if err != nil { return nil, err } - nfsInfo := make(map[string]Fs, 0) + // statsCache stores cached filesystem stats by cache key for plugins that implement FsCachingPlugin + statsCache := make(map[string]Fs) for device, partition := range i.partitions { _, hasMount := mountSet[partition.mountpoint] _, hasDevice := deviceSet[device] if mountSet == nil || (hasMount && !hasDevice) { var ( - err error - fs Fs + statsErr error + fs Fs ) - fsType := partition.fsType - if strings.HasPrefix(partition.fsType, "nfs") { - fsType = "nfs" + + // Use plugin system to get filesystem stats + plugin := GetPluginForFsType(partition.fsType) + if plugin == nil { + klog.V(4).Infof("no plugin found for filesystem type: %v", partition.fsType) + continue } - switch fsType { - case DeviceMapper.String(): - fs.Capacity, fs.Free, fs.Available, err = getDMStats(device, partition.blockSize) - klog.V(5).Infof("got devicemapper fs capacity stats: capacity: %v free: %v available: %v:", fs.Capacity, fs.Free, fs.Available) - fs.Type = DeviceMapper - case ZFS.String(): - if _, devzfs := os.Stat("/dev/zfs"); os.IsExist(devzfs) { - fs.Capacity, fs.Free, fs.Available, err = getZfstats(device) - fs.Type = ZFS - break - } - // if /dev/zfs is not present default to VFS - fallthrough - case NFS.String(): - devId := fmt.Sprintf("%d:%d", partition.major, partition.minor) - if v, ok := nfsInfo[devId]; ok { - fs = v - break + + partInfo := PartitionInfo{ + Mountpoint: partition.mountpoint, + Major: partition.major, + Minor: partition.minor, + FsType: partition.fsType, + BlockSize: partition.blockSize, + } + + // Check if plugin supports caching and if we have a cached value + var cacheKey string + if cachingPlugin, ok := plugin.(FsCachingPlugin); ok { + cacheKey = cachingPlugin.CacheKey(partInfo) + if cacheKey != "" { + if cachedFs, found := statsCache[cacheKey]; found { + fs = cachedFs + // Skip stats fetching, use cached value + deviceSet[device] = struct{}{} + fs.DeviceInfo = DeviceInfo{ + Device: device, + Major: uint(partition.major), + Minor: uint(partition.minor), + } + if val, ok := diskStatsMap[device]; ok { + fs.DiskStats = val + } else { + for k, v := range diskStatsMap { + if v.MajorNum == uint64(partition.major) && v.MinorNum == uint64(partition.minor) { + fs.DiskStats = diskStatsMap[k] + break + } + } + } + filesystems = append(filesystems, fs) + continue + } } - var inodes, inodesFree uint64 - fs.Capacity, fs.Free, fs.Available, inodes, inodesFree, err = getVfsStats(partition.mountpoint) - if err != nil { - klog.V(4).Infof("the file system type is %s, partition mountpoint does not exist: %v, error: %v", partition.fsType, partition.mountpoint, err) - break + } + + stats, statsErr := plugin.GetStats(device, partInfo) + if statsErr != nil { + // Handle fallback to VFS for plugins that request it + if errors.Is(statsErr, ErrFallbackToVFS) { + vfsPlugin := GetPluginForFsType("ext4") // VFS handles ext* + if vfsPlugin != nil { + stats, statsErr = vfsPlugin.GetStats(device, partInfo) + } } - fs.Inodes = &inodes - fs.InodesFree = &inodesFree - fs.Type = VFS - nfsInfo[devId] = fs - default: - var inodes, inodesFree uint64 - if utils.FileExists(partition.mountpoint) { - fs.Capacity, fs.Free, fs.Available, inodes, inodesFree, err = getVfsStats(partition.mountpoint) - fs.Inodes = &inodes - fs.InodesFree = &inodesFree - fs.Type = VFS - } else { - klog.V(4).Infof("unable to determine file system type, partition mountpoint does not exist: %v", partition.mountpoint) + if statsErr != nil { + klog.V(4).Infof("Stat fs failed for %s. Error: %v", partition.fsType, statsErr) + continue } } - if err != nil { - klog.V(4).Infof("Stat fs failed. Error: %v", err) - } else { - deviceSet[device] = struct{}{} - fs.DeviceInfo = DeviceInfo{ - Device: device, - Major: uint(partition.major), - Minor: uint(partition.minor), - } - if val, ok := diskStatsMap[device]; ok { - fs.DiskStats = val - } else { - for k, v := range diskStatsMap { - if v.MajorNum == uint64(partition.major) && v.MinorNum == uint64(partition.minor) { - fs.DiskStats = diskStatsMap[k] - break - } + if stats == nil { + klog.V(4).Infof("no stats returned for %s at %s", partition.fsType, partition.mountpoint) + continue + } + + fs.Capacity = stats.Capacity + fs.Free = stats.Free + fs.Available = stats.Available + fs.Inodes = stats.Inodes + fs.InodesFree = stats.InodesFree + fs.Type = stats.Type + + // Store in cache if plugin supports caching + if cacheKey != "" { + statsCache[cacheKey] = fs + } + + deviceSet[device] = struct{}{} + fs.DeviceInfo = DeviceInfo{ + Device: device, + Major: uint(partition.major), + Minor: uint(partition.minor), + } + + if val, ok := diskStatsMap[device]; ok { + fs.DiskStats = val + } else { + for k, v := range diskStatsMap { + if v.MajorNum == uint64(partition.major) && v.MinorNum == uint64(partition.minor) { + fs.DiskStats = diskStatsMap[k] + break } } - filesystems = append(filesystems, fs) } + filesystems = append(filesystems, fs) } } return filesystems, nil @@ -717,50 +725,12 @@ func (i *RealFsInfo) GetDirUsage(dir string) (UsageInfo, error) { return GetDirUsage(dir) } -func getVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) { - // timeout the context with, default is 2sec - timeout := 2 - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) - defer cancel() - - type result struct { - total uint64 - free uint64 - avail uint64 - inodes uint64 - inodesFree uint64 - err error - } - - resultChan := make(chan result, 1) - - go func() { - var s syscall.Statfs_t - if err = syscall.Statfs(path, &s); err != nil { - total, free, avail, inodes, inodesFree = 0, 0, 0, 0, 0 - } - total = uint64(s.Frsize) * s.Blocks - free = uint64(s.Frsize) * s.Bfree - avail = uint64(s.Frsize) * s.Bavail - inodes = uint64(s.Files) - inodesFree = uint64(s.Ffree) - resultChan <- result{total: total, free: free, avail: avail, inodes: inodes, inodesFree: inodesFree, err: err} - }() - - select { - case <-ctx.Done(): - return 0, 0, 0, 0, 0, ctx.Err() - case res := <-resultChan: - return res.total, res.free, res.avail, res.inodes, res.inodesFree, res.err - } -} - // Devicemapper thin provisioning is detailed at // https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt func dockerDMDevice(driverStatus map[string]string, dmsetup devicemapper.DmsetupClient) (string, uint, uint, uint, error) { poolName, ok := driverStatus[DriverStatusPoolName] if !ok || len(poolName) == 0 { - return "", 0, 0, 0, fmt.Errorf("Could not get dm pool name") + return "", 0, 0, 0, fmt.Errorf("could not get dm pool name") } out, err := dmsetup.Table(poolName) @@ -783,7 +753,7 @@ func parseDMTable(dmTable string) (uint, uint, uint, error) { dmFields := strings.Fields(dmTable) if len(dmFields) < 8 { - return 0, 0, 0, fmt.Errorf("Invalid dmsetup status output: %s", dmTable) + return 0, 0, 0, fmt.Errorf("invalid dmsetup status output: %s", dmTable) } major, err := strconv.ParseUint(dmFields[5], 10, 32) @@ -802,56 +772,6 @@ func parseDMTable(dmTable string) (uint, uint, uint, error) { return uint(major), uint(minor), uint(dataBlkSize), nil } -func getDMStats(poolName string, dataBlkSize uint) (uint64, uint64, uint64, error) { - out, err := exec.Command("dmsetup", "status", poolName).Output() - if err != nil { - return 0, 0, 0, err - } - - used, total, err := parseDMStatus(string(out)) - if err != nil { - return 0, 0, 0, err - } - - used *= 512 * uint64(dataBlkSize) - total *= 512 * uint64(dataBlkSize) - free := total - used - - return total, free, free, nil -} - -func parseDMStatus(dmStatus string) (uint64, uint64, error) { - dmStatus = strings.Replace(dmStatus, "/", " ", -1) - dmFields := strings.Fields(dmStatus) - - if len(dmFields) < 8 { - return 0, 0, fmt.Errorf("Invalid dmsetup status output: %s", dmStatus) - } - - used, err := strconv.ParseUint(dmFields[6], 10, 64) - if err != nil { - return 0, 0, err - } - total, err := strconv.ParseUint(dmFields[7], 10, 64) - if err != nil { - return 0, 0, err - } - - return used, total, nil -} - -// getZfstats returns ZFS mount stats using zfsutils -func getZfstats(poolName string) (uint64, uint64, uint64, error) { - dataset, err := zfs.GetDataset(poolName) - if err != nil { - return 0, 0, 0, err - } - - total := dataset.Used + dataset.Avail + dataset.Usedbydataset - - return total, dataset.Avail, dataset.Avail, nil -} - // Get major and minor Ids for a mount point using btrfs as filesystem. func getBtrfsMajorMinorIds(mount *mount.Info) (int, int, error) { // btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. diff --git a/vendor/github.com/google/cadvisor/fs/nfs/install/install.go b/vendor/github.com/google/cadvisor/fs/nfs/install/install.go new file mode 100644 index 0000000000..61fa81aed1 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/nfs/install/install.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/nfs" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("nfs", nfs.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register nfs fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/nfs/plugin.go b/vendor/github.com/google/cadvisor/fs/nfs/plugin.go new file mode 100644 index 0000000000..002c3626bc --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/nfs/plugin.go @@ -0,0 +1,85 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package nfs + +import ( + "fmt" + "strings" + + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/vfs" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +type nfsPlugin struct{} + +// Ensure nfsPlugin implements FsCachingPlugin +var _ fs.FsCachingPlugin = &nfsPlugin{} + +// NewPlugin creates a new NFS filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &nfsPlugin{} +} + +func (p *nfsPlugin) Name() string { + return "nfs" +} + +// CanHandle returns true if the filesystem type is NFS (nfs, nfs3, nfs4, etc.). +func (p *nfsPlugin) CanHandle(fsType string) bool { + return strings.HasPrefix(fsType, "nfs") +} + +// Priority returns 50 - NFS has medium priority (higher than VFS but lower than specific plugins). +func (p *nfsPlugin) Priority() int { + return 50 +} + +// GetStats returns filesystem statistics for NFS. +// NFS uses VFS stats. +func (p *nfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + capacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint) + if err != nil { + klog.V(4).Infof("the file system type is %s, partition mountpoint does not exist: %v, error: %v", + partition.FsType, partition.Mountpoint, err) + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Inodes: &inodes, + InodesFree: &inodesFree, + Type: fs.VFS, + }, nil +} + +// ProcessMount handles NFS mount processing. +// For NFS, no special processing is needed. +func (p *nfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + return true, mnt, nil +} + +// CacheKey returns a cache key based on device ID (major:minor). +// NFS mounts with the same device ID share the same underlying filesystem, +// so we can cache stats to avoid redundant statfs calls. +func (p *nfsPlugin) CacheKey(partition fs.PartitionInfo) string { + return fmt.Sprintf("%d:%d", partition.Major, partition.Minor) +} diff --git a/vendor/github.com/google/cadvisor/fs/overlay/install/install.go b/vendor/github.com/google/cadvisor/fs/overlay/install/install.go new file mode 100644 index 0000000000..8f389ea13a --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/overlay/install/install.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/overlay" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("overlay", overlay.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register overlay fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/overlay/plugin.go b/vendor/github.com/google/cadvisor/fs/overlay/plugin.go new file mode 100644 index 0000000000..ed4b3a5be8 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/overlay/plugin.go @@ -0,0 +1,76 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package overlay + +import ( + "fmt" + + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/vfs" + + mount "github.com/moby/sys/mountinfo" +) + +type overlayPlugin struct{} + +// NewPlugin creates a new Overlay filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &overlayPlugin{} +} + +func (p *overlayPlugin) Name() string { + return "overlay" +} + +// CanHandle returns true if the filesystem type is overlay or overlay2. +func (p *overlayPlugin) CanHandle(fsType string) bool { + return fsType == "overlay" +} + +// Priority returns 100 - Overlay has higher priority than VFS. +func (p *overlayPlugin) Priority() int { + return 100 +} + +// GetStats returns filesystem statistics for Overlay. +// Overlay delegates to VFS for stats collection. +func (p *overlayPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + // Overlay uses VFS stats + capacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint) + if err != nil { + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Inodes: &inodes, + InodesFree: &inodesFree, + Type: fs.VFS, + }, nil +} + +// ProcessMount handles Overlay mount processing. +// Overlay fix: Making mount source unique for all overlay mounts, using the mount's major and minor ids. +// This is needed because multiple overlay mounts can have the same source. +func (p *overlayPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + // Create a copy with unique source + correctedMnt := *mnt + correctedMnt.Source = fmt.Sprintf("%s_%d-%d", mnt.Source, mnt.Major, mnt.Minor) + return true, &correctedMnt, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/plugin.go b/vendor/github.com/google/cadvisor/fs/plugin.go new file mode 100644 index 0000000000..bddbb76f6d --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/plugin.go @@ -0,0 +1,179 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fs + +import ( + "errors" + "fmt" + "sync" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +// FsPlugin provides filesystem-specific statistics collection. +type FsPlugin interface { + // Name returns the plugin identifier (e.g., "zfs", "devicemapper", "vfs"). + Name() string + + // CanHandle returns true if this plugin handles the given filesystem type. + CanHandle(fsType string) bool + + // Priority returns the plugin priority (higher = checked first). + // Allows specific plugins (zfs, btrfs) to override generic (vfs). + Priority() int + + // GetStats returns filesystem statistics for a partition. + GetStats(device string, partition PartitionInfo) (*FsStats, error) + + // ProcessMount optionally modifies mount info during processing. + // Returns (shouldInclude bool, modifiedMount *mount.Info, error). + ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) +} + +// FsCachingPlugin is an optional interface for plugins that want to cache +// stats by a key (e.g., device ID) to avoid redundant stat calls. +// This is useful for network filesystems like NFS where multiple mounts +// may point to the same underlying device. +type FsCachingPlugin interface { + FsPlugin + + // CacheKey returns a cache key for the given partition. + // Stats will be cached by this key and reused for partitions with the same key. + // Return empty string to disable caching for a specific partition. + CacheKey(partition PartitionInfo) string +} + +// FsWatcherPlugin is an optional interface for plugins that provide +// background monitoring (e.g., ZFS watcher, ThinPool watcher). +type FsWatcherPlugin interface { + FsPlugin + + // StartWatcher starts background monitoring. + // Returns a Watcher that can be used to get container-level usage. + StartWatcher() (FsWatcher, error) +} + +// FsWatcher provides container-level filesystem usage from background monitoring. +type FsWatcher interface { + // GetUsage returns filesystem usage for a specific container/path. + GetUsage(containerID string, deviceID string) (uint64, error) + + // Stop stops the background monitoring. + Stop() +} + +// PartitionInfo contains information needed for stats collection. +type PartitionInfo struct { + Mountpoint string + Major uint + Minor uint + FsType string + BlockSize uint +} + +// FsStats contains filesystem statistics returned by plugins. +type FsStats struct { + Capacity uint64 + Free uint64 + Available uint64 + Inodes *uint64 + InodesFree *uint64 + Type FsType +} + +// ErrFallbackToVFS signals that a specialized plugin cannot handle +// this filesystem and VFS should be used instead. +var ErrFallbackToVFS = errors.New("fallback to VFS") + +// Plugin registry (init-time registration only). +var ( + pluginsLock sync.RWMutex + plugins = make(map[string]FsPlugin) +) + +// RegisterPlugin registers a filesystem plugin. +// This should be called from init() functions. +func RegisterPlugin(name string, plugin FsPlugin) error { + pluginsLock.Lock() + defer pluginsLock.Unlock() + if _, found := plugins[name]; found { + return fmt.Errorf("FsPlugin %q was registered twice", name) + } + klog.V(4).Infof("Registered FsPlugin %q", name) + plugins[name] = plugin + return nil +} + +// GetPluginForFsType returns the appropriate plugin for the filesystem type. +// Returns nil if no plugin can handle the filesystem type. +func GetPluginForFsType(fsType string) FsPlugin { + pluginsLock.RLock() + defer pluginsLock.RUnlock() + + var best FsPlugin + for _, p := range plugins { + if p.CanHandle(fsType) { + if best == nil || p.Priority() > best.Priority() { + best = p + } + } + } + return best +} + +// GetAllPlugins returns all registered plugins. +func GetAllPlugins() []FsPlugin { + pluginsLock.RLock() + defer pluginsLock.RUnlock() + + result := make([]FsPlugin, 0, len(plugins)) + for _, p := range plugins { + result = append(result, p) + } + return result +} + +// InitializeWatchers starts all plugin watchers and returns them. +func InitializeWatchers() map[string]FsWatcher { + pluginsLock.RLock() + defer pluginsLock.RUnlock() + + watchers := make(map[string]FsWatcher) + for name, plugin := range plugins { + if wp, ok := plugin.(FsWatcherPlugin); ok { + watcher, err := wp.StartWatcher() + if err != nil { + klog.V(4).Infof("Failed to start watcher for plugin %s: %v", name, err) + continue + } + if watcher != nil { + watchers[name] = watcher + klog.V(4).Infof("Started watcher for FsPlugin %q", name) + } + } + } + return watchers +} + +// StopWatchers stops all provided watchers. +func StopWatchers(watchers map[string]FsWatcher) { + for name, watcher := range watchers { + if watcher != nil { + watcher.Stop() + klog.V(4).Infof("Stopped watcher for FsPlugin %q", name) + } + } +} diff --git a/vendor/github.com/google/cadvisor/fs/tmpfs/install/install.go b/vendor/github.com/google/cadvisor/fs/tmpfs/install/install.go new file mode 100644 index 0000000000..777e82be8c --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/tmpfs/install/install.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/tmpfs" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("tmpfs", tmpfs.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register tmpfs fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/tmpfs/plugin.go b/vendor/github.com/google/cadvisor/fs/tmpfs/plugin.go new file mode 100644 index 0000000000..da2acb9195 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/tmpfs/plugin.go @@ -0,0 +1,80 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package tmpfs + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/vfs" + + mount "github.com/moby/sys/mountinfo" +) + +type tmpfsPlugin struct{} + +// NewPlugin creates a new tmpfs filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &tmpfsPlugin{} +} + +func (p *tmpfsPlugin) Name() string { + return "tmpfs" +} + +// CanHandle returns true if the filesystem type is tmpfs. +func (p *tmpfsPlugin) CanHandle(fsType string) bool { + return fsType == "tmpfs" +} + +// Priority returns 100 - tmpfs has higher priority than VFS. +func (p *tmpfsPlugin) Priority() int { + return 100 +} + +// GetStats returns filesystem statistics for tmpfs. +// tmpfs delegates to VFS for stats collection. +func (p *tmpfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + // tmpfs uses VFS stats + capacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint) + if err != nil { + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Inodes: &inodes, + InodesFree: &inodesFree, + Type: fs.VFS, + }, nil +} + +// ProcessMount handles tmpfs mount processing. +// For tmpfs, we use the mountpoint as the source to make each mount unique. +// This allows multiple tmpfs mounts with the same "tmpfs" source to coexist. +func (p *tmpfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + // Use mountpoint as source to make each tmpfs mount unique + correctedMnt := *mnt + correctedMnt.Source = mnt.Mountpoint + return true, &correctedMnt, nil +} + +// AllowDuplicateSource returns true for tmpfs since multiple tmpfs mounts +// should be tracked separately even if they appear to have the same source. +func (p *tmpfsPlugin) AllowDuplicateSource() bool { + return true +} diff --git a/vendor/github.com/google/cadvisor/fs/vfs/install/install.go b/vendor/github.com/google/cadvisor/fs/vfs/install/install.go new file mode 100644 index 0000000000..0d5f66e9fc --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/vfs/install/install.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/vfs" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("vfs", vfs.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register vfs fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/vfs/plugin.go b/vendor/github.com/google/cadvisor/fs/vfs/plugin.go new file mode 100644 index 0000000000..af093df7f8 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/vfs/plugin.go @@ -0,0 +1,97 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package vfs + +import ( + "strings" + + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/utils" + + mount "github.com/moby/sys/mountinfo" + "k8s.io/klog/v2" +) + +type vfsPlugin struct{} + +// NewPlugin creates a new VFS filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &vfsPlugin{} +} + +func (p *vfsPlugin) Name() string { + return "vfs" +} + +// CanHandle returns true for standard filesystems that use VFS stats. +// This includes ext2/3/4, xfs, and similar block-based filesystems. +// Virtual/pseudo filesystems (proc, sysfs, cgroup, etc.) are excluded. +func (p *vfsPlugin) CanHandle(fsType string) bool { + // Exclude virtual/pseudo filesystems that don't have real disk backing + switch fsType { + case "cgroup", "cgroup2", "cpuset", "mqueue", "proc", "sysfs", + "devtmpfs", "devpts", "securityfs", "debugfs", "tracefs", + "pstore", "configfs", "fusectl", "hugetlbfs", "autofs", + "binfmt_misc", "efivarfs", "rpc_pipefs", "nsfs": + return false + } + + // VFS can handle most standard Linux filesystems + if strings.HasPrefix(fsType, "ext") { + return true + } + switch fsType { + case "xfs", "squashfs", "f2fs", "jfs", "reiserfs", "hfs", "hfsplus", + "ntfs", "vfat", "fat", "msdos", "exfat", "udf", "iso9660": + return true + } + // Don't act as a general fallback - only handle known filesystem types + return false +} + +// Priority returns 0 - VFS is the lowest priority fallback plugin. +func (p *vfsPlugin) Priority() int { + return 0 +} + +// GetStats returns filesystem statistics using the statfs syscall. +func (p *vfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + if !utils.FileExists(partition.Mountpoint) { + klog.V(4).Infof("VFS: mountpoint does not exist: %v", partition.Mountpoint) + return nil, nil + } + + capacity, free, avail, inodes, inodesFree, err := GetVfsStats(partition.Mountpoint) + if err != nil { + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Inodes: &inodes, + InodesFree: &inodesFree, + Type: fs.VFS, + }, nil +} + +// ProcessMount handles standard mount processing. +// For VFS, no special processing is needed. +func (p *vfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + return true, mnt, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/vfs/stats.go b/vendor/github.com/google/cadvisor/fs/vfs/stats.go new file mode 100644 index 0000000000..12c844ae54 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/vfs/stats.go @@ -0,0 +1,63 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package vfs + +import ( + "context" + "syscall" + "time" +) + +// GetVfsStats returns filesystem statistics using the statfs syscall. +// It has a timeout to prevent hanging on unresponsive filesystems. +func GetVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) { + // timeout the context with, default is 2sec + timeout := 2 + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + type result struct { + total uint64 + free uint64 + avail uint64 + inodes uint64 + inodesFree uint64 + err error + } + + resultChan := make(chan result, 1) + + go func() { + var s syscall.Statfs_t + if err = syscall.Statfs(path, &s); err != nil { + total, free, avail, inodes, inodesFree = 0, 0, 0, 0, 0 + } + total = uint64(s.Frsize) * s.Blocks + free = uint64(s.Frsize) * s.Bfree + avail = uint64(s.Frsize) * s.Bavail + inodes = uint64(s.Files) + inodesFree = uint64(s.Ffree) + resultChan <- result{total: total, free: free, avail: avail, inodes: inodes, inodesFree: inodesFree, err: err} + }() + + select { + case <-ctx.Done(): + return 0, 0, 0, 0, 0, ctx.Err() + case res := <-resultChan: + return res.total, res.free, res.avail, res.inodes, res.inodesFree, res.err + } +} diff --git a/vendor/github.com/google/cadvisor/fs/zfs/install/install.go b/vendor/github.com/google/cadvisor/fs/zfs/install/install.go new file mode 100644 index 0000000000..02d61646ec --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/zfs/install/install.go @@ -0,0 +1,29 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package install + +import ( + "github.com/google/cadvisor/fs" + "github.com/google/cadvisor/fs/zfs" + + "k8s.io/klog/v2" +) + +func init() { + err := fs.RegisterPlugin("zfs", zfs.NewPlugin()) + if err != nil { + klog.Fatalf("Failed to register zfs fs plugin: %v", err) + } +} diff --git a/vendor/github.com/google/cadvisor/fs/zfs/plugin.go b/vendor/github.com/google/cadvisor/fs/zfs/plugin.go new file mode 100644 index 0000000000..be4330b981 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/zfs/plugin.go @@ -0,0 +1,70 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zfs + +import ( + "os" + + "github.com/google/cadvisor/fs" + + mount "github.com/moby/sys/mountinfo" +) + +type zfsPlugin struct{} + +// NewPlugin creates a new ZFS filesystem plugin. +func NewPlugin() fs.FsPlugin { + return &zfsPlugin{} +} + +func (p *zfsPlugin) Name() string { + return "zfs" +} + +// CanHandle returns true if the filesystem type is zfs. +func (p *zfsPlugin) CanHandle(fsType string) bool { + return fsType == "zfs" +} + +// Priority returns 100 - ZFS has higher priority than VFS. +func (p *zfsPlugin) Priority() int { + return 100 +} + +// GetStats returns filesystem statistics for ZFS. +func (p *zfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) { + // Check if ZFS is available - if /dev/zfs doesn't exist, fall back to VFS + if _, err := os.Stat("/dev/zfs"); os.IsNotExist(err) { + return nil, fs.ErrFallbackToVFS + } + + capacity, free, avail, err := GetZfsStats(device) + if err != nil { + return nil, err + } + + return &fs.FsStats{ + Capacity: capacity, + Free: free, + Available: avail, + Type: fs.ZFS, + }, nil +} + +// ProcessMount handles ZFS mount processing. +// For ZFS, no special processing is needed. +func (p *zfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) { + return true, mnt, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/zfs/stats.go b/vendor/github.com/google/cadvisor/fs/zfs/stats.go new file mode 100644 index 0000000000..b41a9f82e7 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/zfs/stats.go @@ -0,0 +1,31 @@ +// Copyright 2014 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zfs + +import ( + zfslib "github.com/mistifyio/go-zfs" +) + +// GetZfsStats returns ZFS mount stats using zfsutils. +func GetZfsStats(poolName string) (uint64, uint64, uint64, error) { + dataset, err := zfslib.GetDataset(poolName) + if err != nil { + return 0, 0, 0, err + } + + total := dataset.Used + dataset.Avail + dataset.Usedbydataset + + return total, dataset.Avail, dataset.Avail, nil +} diff --git a/vendor/github.com/google/cadvisor/fs/zfs/watcher.go b/vendor/github.com/google/cadvisor/fs/zfs/watcher.go new file mode 100644 index 0000000000..13a681b493 --- /dev/null +++ b/vendor/github.com/google/cadvisor/fs/zfs/watcher.go @@ -0,0 +1,123 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zfs + +import ( + "fmt" + "sync/atomic" + "time" + + zfslib "github.com/mistifyio/go-zfs" + "k8s.io/klog/v2" +) + +// usageCache is a typed wrapper around atomic.Value that eliminates the need +// for type assertions at every call site. It stores filesystem name strings +// mapped to usage values (uint64). +type usageCache struct { + v atomic.Value +} + +// Load retrieves the current cache map. +func (c *usageCache) Load() map[string]uint64 { + return c.v.Load().(map[string]uint64) +} + +// Store saves a new cache map. +func (c *usageCache) Store(m map[string]uint64) { + c.v.Store(m) +} + +// ZfsWatcher maintains a cache of filesystem -> usage stats for a +// zfs filesystem +type ZfsWatcher struct { + filesystem string + cache usageCache + period time.Duration + stopChan chan struct{} +} + +// NewZfsWatcher returns a new ZfsWatcher for the given zfs filesystem. +func NewZfsWatcher(filesystem string) (*ZfsWatcher, error) { + w := &ZfsWatcher{ + filesystem: filesystem, + period: 15 * time.Second, + stopChan: make(chan struct{}), + } + w.cache.Store(map[string]uint64{}) + return w, nil +} + +// Start starts the ZfsWatcher. +func (w *ZfsWatcher) Start() { + err := w.Refresh() + if err != nil { + klog.Errorf("encountered error refreshing zfs watcher: %v", err) + } + + for { + select { + case <-w.stopChan: + return + case <-time.After(w.period): + start := time.Now() + err = w.Refresh() + if err != nil { + klog.Errorf("encountered error refreshing zfs watcher: %v", err) + } + + // print latency for refresh + duration := time.Since(start) + klog.V(5).Infof("zfs(%d) took %s", start.Unix(), duration) + } + } +} + +// Stop stops the ZfsWatcher. +func (w *ZfsWatcher) Stop() { + close(w.stopChan) +} + +// GetUsage gets the cached usage value of the given filesystem. +func (w *ZfsWatcher) GetUsage(filesystem string) (uint64, error) { + cache := w.cache.Load() + v, ok := cache[filesystem] + if !ok { + return 0, fmt.Errorf("no cached value for usage of filesystem %v", filesystem) + } + return v, nil +} + +// Refresh performs a zfs get +func (w *ZfsWatcher) Refresh() error { + parent, err := zfslib.GetDataset(w.filesystem) + if err != nil { + klog.Errorf("encountered error getting zfs filesystem: %s: %v", w.filesystem, err) + return err + } + children, err := parent.Children(0) + if err != nil { + klog.Errorf("encountered error getting children of zfs filesystem: %s: %v", w.filesystem, err) + return err + } + + newCache := make(map[string]uint64) + for _, ds := range children { + newCache[ds.Name] = ds.Used + } + + w.cache.Store(newCache) + return nil +} diff --git a/vendor/github.com/google/cadvisor/info/v1/container.go b/vendor/github.com/google/cadvisor/info/v1/container.go index 5921783165..3d2d282135 100644 --- a/vendor/github.com/google/cadvisor/info/v1/container.go +++ b/vendor/github.com/google/cadvisor/info/v1/container.go @@ -329,6 +329,13 @@ type CpuCFS struct { // Total time duration for which tasks in the cgroup have been throttled. // Unit: nanoseconds. ThrottledTime uint64 `json:"throttled_time"` + + // Total number of periods when CPU burst occurs. + BurstsPeriods uint64 `json:"bursts_periods"` + + // Total time duration when CPU burst occurs. + // Unit: nanoseconds. + BurstTime uint64 `json:"burst_time"` } // Cpu Aggregated scheduler statistics @@ -374,6 +381,10 @@ type DiskIoStats struct { IoWaitTime []PerDiskStats `json:"io_wait_time,omitempty"` IoMerged []PerDiskStats `json:"io_merged,omitempty"` IoTime []PerDiskStats `json:"io_time,omitempty"` + IoCostUsage []PerDiskStats `json:"io_cost_usage,omitempty"` + IoCostWait []PerDiskStats `json:"io_cost_wait,omitempty"` + IoCostIndebt []PerDiskStats `json:"io_cost_indebt,omitempty"` + IoCostIndelay []PerDiskStats `json:"io_cost_indelay,omitempty"` PSI PSIStats `json:"psi"` } @@ -964,6 +975,11 @@ type ProcessStats struct { Ulimits []UlimitSpec `json:"ulimits,omitempty"` } +type Health struct { + // Health status of the container + Status string `json:"status"` +} + type ContainerStats struct { // The time of this stat point. Timestamp time.Time `json:"timestamp"` @@ -1003,6 +1019,8 @@ type ContainerStats struct { CpuSet CPUSetStats `json:"cpuset,omitempty"` OOMEvents uint64 `json:"oom_events,omitempty"` + + Health Health `json:"health,omitempty"` } func timeEq(t1, t2 time.Time, tolerance time.Duration) bool { @@ -1097,6 +1115,9 @@ const ( type EventData struct { // Information about an OOM kill event. OomKill *OomKillEventData `json:"oom,omitempty"` + + // Information about a container deletion event. + ContainerDeletion *ContainerDeletionEventData `json:"container_deletion,omitempty"` } // Information related to an OOM kill instance @@ -1107,3 +1128,10 @@ type OomKillEventData struct { // The name of the killed process ProcessName string `json:"process_name"` } + +// Information related to a container deletion event +type ContainerDeletionEventData struct { + // ExitCode is the exit code of the container. + // A value of -1 indicates the exit code was not available or not applicable. + ExitCode int `json:"exit_code"` +} diff --git a/vendor/github.com/google/cadvisor/info/v1/machine.go b/vendor/github.com/google/cadvisor/info/v1/machine.go index 4fa4b0e554..6df86a266e 100644 --- a/vendor/github.com/google/cadvisor/info/v1/machine.go +++ b/vendor/github.com/google/cadvisor/info/v1/machine.go @@ -193,6 +193,12 @@ type MachineInfo struct { // The number of cpu sockets in this machine. NumSockets int `json:"num_sockets"` + // The number of cpu books in this machine. + NumBooks int `json:"num_books,omitempty"` + + // The number of cpu drawers in this machine. + NumDrawers int `json:"num_drawers,omitempty"` + // Maximum clock speed for the cores, in KHz. CpuFrequency uint64 `json:"cpu_frequency_khz"` @@ -263,6 +269,8 @@ func (m *MachineInfo) Clone() *MachineInfo { NumCores: m.NumCores, NumPhysicalCores: m.NumPhysicalCores, NumSockets: m.NumSockets, + NumBooks: m.NumBooks, + NumDrawers: m.NumDrawers, CpuFrequency: m.CpuFrequency, MemoryCapacity: m.MemoryCapacity, SwapCapacity: m.SwapCapacity, diff --git a/vendor/github.com/google/cadvisor/info/v2/container.go b/vendor/github.com/google/cadvisor/info/v2/container.go index f0824027a3..7f9c1c1891 100644 --- a/vendor/github.com/google/cadvisor/info/v2/container.go +++ b/vendor/github.com/google/cadvisor/info/v2/container.go @@ -192,6 +192,8 @@ type Percentiles struct { Present bool `json:"present"` // Average over the collected sample. Mean uint64 `json:"mean"` + // Standard deviation of the collected sample. + Std uint64 `json:"std"` // Max seen over the collected sample. Max uint64 `json:"max"` // 50th percentile over the collected sample. @@ -200,6 +202,8 @@ type Percentiles struct { Ninety uint64 `json:"ninety"` // 95th percentile over the collected sample. NinetyFive uint64 `json:"ninetyfive"` + // Number of samples used to calculate these percentiles. + Count uint64 `json:"count"` } type Usage struct { diff --git a/vendor/github.com/google/cadvisor/machine/info.go b/vendor/github.com/google/cadvisor/machine/info.go index 76d2272f6a..a3cc59e61e 100644 --- a/vendor/github.com/google/cadvisor/machine/info.go +++ b/vendor/github.com/google/cadvisor/machine/info.go @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package machine import ( - "bytes" "flag" "os" "path/filepath" @@ -130,6 +131,8 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach NumCores: numCores, NumPhysicalCores: GetPhysicalCores(cpuinfo), NumSockets: GetSockets(cpuinfo), + NumBooks: GetBooks(cpuinfo), + NumDrawers: GetDrawers(cpuinfo), CpuFrequency: clockSpeed, MemoryCapacity: memoryCapacity, MemoryByType: memoryByType, @@ -169,10 +172,8 @@ func ContainerOsVersion() string { func KernelVersion() string { uname := &unix.Utsname{} - if err := unix.Uname(uname); err != nil { return "Unknown" } - - return string(uname.Release[:bytes.IndexByte(uname.Release[:], 0)]) + return unix.ByteSliceToString(uname.Release[:]) } diff --git a/vendor/github.com/google/cadvisor/machine/machine.go b/vendor/github.com/google/cadvisor/machine/machine.go index 0ba161614f..fed9fd6fce 100644 --- a/vendor/github.com/google/cadvisor/machine/machine.go +++ b/vendor/github.com/google/cadvisor/machine/machine.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // The machine package contains functions that extract machine-level specs. package machine @@ -20,6 +22,7 @@ import ( "os" "path" "regexp" + "runtime" "strconv" "strings" @@ -35,8 +38,10 @@ import ( ) var ( - coreRegExp = regexp.MustCompile(`(?m)^core id\s*:\s*([0-9]+)$`) - nodeRegExp = regexp.MustCompile(`(?m)^physical id\s*:\s*([0-9]+)$`) + coreRegExp = regexp.MustCompile(`(?m)^core id\s*:\s*([0-9]+)$`) + nodeRegExp = regexp.MustCompile(`(?m)^physical id\s*:\s*([0-9]+)$`) + bookRegExp = regexp.MustCompile(`(?m)^book id\s*:\s*([0-9]+)$`) + drawerRegExp = regexp.MustCompile(`(?m)^drawer id\s*:\s*([0-9]+)$`) // Power systems have a different format so cater for both cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|CPU MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`) memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`) @@ -96,6 +101,41 @@ func GetSockets(procInfo []byte) int { return numSocket } +// GetBooks returns number of CPU books reading from sysfs cpu path +func GetBooks(procInfo []byte) int { + if runtime.GOARCH != "s390x" { + return 0 + } + numBook := getUniqueMatchesCount(string(procInfo), bookRegExp) + if numBook == 0 { + // read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors + // for which 'book id' is not available in /proc/cpuinfo + numBook = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUBookID) + } + if numBook == 0 { + klog.Errorf("Cannot read number of books correctly, number of books set to %d", numBook) + } + return numBook +} + +// GetDrawer returns number of CPU drawerss reading from sysfs cpu path +func GetDrawers(procInfo []byte) int { + if runtime.GOARCH != "s390x" { + return 0 + } + numDrawer := getUniqueMatchesCount(string(procInfo), drawerRegExp) + if numDrawer == 0 { + // read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors + // read number of drawers from /sys/bus/cpu/devices/cpu*/topology/drawer_id to deal with processors + // for which 'drawer id' is not available in /proc/cpuinfo + numDrawer = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUDrawerID) + } + if numDrawer == 0 { + klog.Errorf("Cannot read number of drawers correctly, number of drawers set to %d", numDrawer) + } + return numDrawer +} + // GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file. func GetClockSpeed(procInfo []byte) (uint64, error) { // First look through sys to find a max supported cpu frequency. @@ -257,7 +297,7 @@ func getMachineArch() string { klog.Errorf("Cannot get machine architecture, err: %v", err) return "" } - return string(uname.Machine[:]) + return unix.ByteSliceToString(uname.Machine[:]) } // arm32 changes diff --git a/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go b/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go index 00db2d6b1a..92e409d82f 100644 --- a/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go +++ b/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go @@ -13,17 +13,17 @@ // limitations under the License. //go:build freebsd || darwin || linux -// +build freebsd darwin linux package machine import ( "fmt" "os" - "os/exec" "regexp" "runtime" "strings" + + "golang.org/x/sys/unix" ) var rex = regexp.MustCompile("(PRETTY_NAME)=(.*)") @@ -31,12 +31,12 @@ var rex = regexp.MustCompile("(PRETTY_NAME)=(.*)") // getOperatingSystem gets the name of the current operating system. func getOperatingSystem() (string, error) { if runtime.GOOS == "darwin" || runtime.GOOS == "freebsd" { - cmd := exec.Command("uname", "-s") - osName, err := cmd.Output() + uname := unix.Utsname{} + err := unix.Uname(&uname) if err != nil { return "", err } - return string(osName), nil + return unix.ByteSliceToString(uname.Sysname[:]), nil } bytes, err := os.ReadFile("/etc/os-release") if err != nil && os.IsNotExist(err) { diff --git a/vendor/github.com/google/cadvisor/manager/container.go b/vendor/github.com/google/cadvisor/manager/container.go index 9160aebae0..5020e945b2 100644 --- a/vendor/github.com/google/cadvisor/manager/container.go +++ b/vendor/github.com/google/cadvisor/manager/container.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package manager import ( @@ -64,6 +66,18 @@ type containerInfo struct { Spec info.ContainerSpec } +// atomicTime is a lock-free wrapper for storing and retrieving time values. +// It stores time as Unix nanoseconds in an atomic.Int64, enabling concurrent +// reads and writes without mutex contention. +type atomicTime struct { + atomic.Int64 +} + +// Time returns the stored time value as a time.Time. +func (t *atomicTime) Time() time.Time { + return time.Unix(0, t.Load()) +} + type containerData struct { oomEvents uint64 handler container.ContainerHandler @@ -77,8 +91,8 @@ type containerData struct { housekeepingInterval time.Duration maxHousekeepingInterval time.Duration allowDynamicHousekeeping bool - infoLastUpdatedTime time.Time - statsLastUpdatedTime time.Time + infoLastUpdatedTime atomicTime // Unix nano + statsLastUpdatedTime atomicTime // Unix nano lastErrorTime time.Time // used to track time clock clock.Clock @@ -90,7 +104,8 @@ type containerData struct { logUsage bool // Tells the container to stop. - stop chan struct{} + stop chan struct{} + stopOnce sync.Once // Tells the container to immediately collect stats onDemandChan chan chan struct{} @@ -126,7 +141,12 @@ func (cd *containerData) Stop() error { if err != nil { return err } - close(cd.stop) + // Use sync.Once to ensure the channel is only closed once, preventing + // panic from concurrent calls to Stop() when multiple goroutines try + // to destroy the same container simultaneously. + cd.stopOnce.Do(func() { + close(cd.stop) + }) cd.perfCollector.Destroy() cd.resctrlCollector.Destroy() return nil @@ -145,9 +165,7 @@ func (cd *containerData) allowErrorLogging() bool { // periodic housekeeping to reset. This should be used sparingly, as calling OnDemandHousekeeping frequently // can have serious performance costs. func (cd *containerData) OnDemandHousekeeping(maxAge time.Duration) { - cd.lock.Lock() - timeSinceStatsLastUpdate := cd.clock.Since(cd.statsLastUpdatedTime) - cd.lock.Unlock() + timeSinceStatsLastUpdate := cd.clock.Since(cd.statsLastUpdatedTime.Time()) if timeSinceStatsLastUpdate > maxAge { housekeepingFinishedChan := make(chan struct{}) cd.onDemandChan <- housekeepingFinishedChan @@ -172,7 +190,7 @@ func (cd *containerData) notifyOnDemand() { func (cd *containerData) GetInfo(shouldUpdateSubcontainers bool) (*containerInfo, error) { // Get spec and subcontainers. - if cd.clock.Since(cd.infoLastUpdatedTime) > 5*time.Second || shouldUpdateSubcontainers { + if cd.clock.Since(cd.infoLastUpdatedTime.Time()) > 5*time.Second || shouldUpdateSubcontainers { err := cd.updateSpec() if err != nil { return nil, err @@ -183,7 +201,7 @@ func (cd *containerData) GetInfo(shouldUpdateSubcontainers bool) (*containerInfo return nil, err } } - cd.infoLastUpdatedTime = cd.clock.Now() + cd.infoLastUpdatedTime.Store(cd.clock.Now().UnixNano()) } cd.lock.Lock() defer cd.lock.Unlock() @@ -594,9 +612,7 @@ func (cd *containerData) housekeepingTick(timer <-chan time.Time, longHousekeepi klog.V(3).Infof("[%s] Housekeeping took %s", cd.info.Name, duration) } cd.notifyOnDemand() - cd.lock.Lock() - defer cd.lock.Unlock() - cd.statsLastUpdatedTime = cd.clock.Now() + cd.statsLastUpdatedTime.Store(cd.clock.Now().UnixNano()) return true } diff --git a/vendor/github.com/google/cadvisor/manager/manager.go b/vendor/github.com/google/cadvisor/manager/manager.go index e5f69e7c44..0ea1f297d8 100644 --- a/vendor/github.com/google/cadvisor/manager/manager.go +++ b/vendor/github.com/google/cadvisor/manager/manager.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Manager of cAdvisor-monitored containers. package manager @@ -191,7 +193,6 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, HousekeepingConfi eventsChannel := make(chan watcher.ContainerEvent, 16) newManager := &manager{ - containers: make(map[namespacedContainerName]*containerData), quitChannels: make([]chan error, 0, 2), memoryCache: memoryCache, fsInfo: fsInfo, @@ -245,9 +246,40 @@ type namespacedContainerName struct { Name string } +// containerMap is a type-safe wrapper around sync.Map for storing containerData +// keyed by namespacedContainerName. +type containerMap struct { + m sync.Map +} + +// Load returns the containerData for the given name, or nil if not found. +func (c *containerMap) Load(name namespacedContainerName) (*containerData, bool) { + v, ok := c.m.Load(name) + if !ok { + return nil, false + } + return v.(*containerData), true +} + +// Store stores the containerData for the given name. +func (c *containerMap) Store(name namespacedContainerName, data *containerData) { + c.m.Store(name, data) +} + +// Delete removes the containerData for the given name. +func (c *containerMap) Delete(name namespacedContainerName) { + c.m.Delete(name) +} + +// Range calls f for each container in the map. If f returns false, iteration stops. +func (c *containerMap) Range(f func(name namespacedContainerName, data *containerData) bool) { + c.m.Range(func(key, value any) bool { + return f(key.(namespacedContainerName), value.(*containerData)) + }) +} + type manager struct { - containers map[namespacedContainerName]*containerData - containersLock sync.RWMutex + containers containerMap memoryCache *memory.InMemoryCache fsInfo fs.FsInfo sysFs sysfs.SysFs @@ -363,10 +395,14 @@ func (m *manager) Stop() error { } func (m *manager) destroyCollectors() { - for _, container := range m.containers { + m.containers.Range(func(_ namespacedContainerName, container *containerData) bool { + if container == nil { + return true + } container.perfCollector.Destroy() container.resctrlCollector.Destroy() - } + return true + }) } func (m *manager) updateMachineInfo(quit chan error) { @@ -425,17 +461,8 @@ func (m *manager) globalHousekeeping(quit chan error) { } func (m *manager) getContainerData(containerName string) (*containerData, error) { - var cont *containerData - var ok bool - func() { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - - // Ensure we have the container. - cont, ok = m.containers[namespacedContainerName{ - Name: containerName, - }] - }() + // Ensure we have the container. + cont, ok := m.containers.Load(namespacedContainerName{Name: containerName}) if !ok { return nil, fmt.Errorf("unknown container %q", containerName) } @@ -563,9 +590,7 @@ func (m *manager) containerDataToContainerInfo(cont *containerData, query *info. } func (m *manager) getContainer(containerName string) (*containerData, error) { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - cont, ok := m.containers[namespacedContainerName{Name: containerName}] + cont, ok := m.containers.Load(namespacedContainerName{Name: containerName}) if !ok { return nil, fmt.Errorf("unknown container %q", containerName) } @@ -573,21 +598,20 @@ func (m *manager) getContainer(containerName string) (*containerData, error) { } func (m *manager) getSubcontainers(containerName string) map[string]*containerData { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - containersMap := make(map[string]*containerData, len(m.containers)) + matchedName := path.Join(containerName, "/") + containersMap := make(map[string]*containerData) // Get all the unique subcontainers of the specified container - matchedName := path.Join(containerName, "/") - for i := range m.containers { - if m.containers[i] == nil { - continue + m.containers.Range(func(_ namespacedContainerName, cont *containerData) bool { + if cont == nil { + return true } - name := m.containers[i].info.Name + name := cont.info.Name if name == containerName || strings.HasPrefix(name, matchedName) { - containersMap[m.containers[i].info.Name] = m.containers[i] + containersMap[name] = cont } - } + return true + }) return containersMap } @@ -602,16 +626,18 @@ func (m *manager) SubcontainersInfo(containerName string, query *info.ContainerI } func (m *manager) getAllNamespacedContainers(ns string) map[string]*containerData { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - containers := make(map[string]*containerData, len(m.containers)) + containers := make(map[string]*containerData) // Get containers in a namespace. - for name, cont := range m.containers { + m.containers.Range(func(name namespacedContainerName, cont *containerData) bool { + if cont == nil { + return true + } if name.Namespace == ns { containers[cont.info.Name] = cont } - } + return true + }) return containers } @@ -621,30 +647,32 @@ func (m *manager) AllDockerContainers(query *info.ContainerInfoRequest) (map[str } func (m *manager) namespacedContainer(containerName string, ns string) (*containerData, error) { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - // Check for the container in the namespace. - cont, ok := m.containers[namespacedContainerName{ - Namespace: ns, - Name: containerName, - }] + if cont, ok := m.containers.Load(namespacedContainerName{Namespace: ns, Name: containerName}); ok { + return cont, nil + } // Look for container by short prefix name if no exact match found. - if !ok { - for contName, c := range m.containers { - if contName.Namespace == ns && strings.HasPrefix(contName.Name, containerName) { - if cont == nil { - cont = c - } else { - return nil, fmt.Errorf("unable to find container in %q namespace. Container %q is not unique", ns, containerName) - } + var cont *containerData + var err error + m.containers.Range(func(name namespacedContainerName, c *containerData) bool { + if name.Namespace == ns && strings.HasPrefix(name.Name, containerName) { + if cont == nil { + cont = c + } else { + err = fmt.Errorf("unable to find container in %q namespace. Container %q is not unique", ns, containerName) + return false // stop iteration } } + return true + }) - if cont == nil { - return nil, fmt.Errorf("unable to find container %q in %q namespace", containerName, ns) - } + if err != nil { + return nil, err + } + + if cont == nil { + return nil, fmt.Errorf("unable to find container %q in %q namespace", containerName, ns) } return cont, nil @@ -837,14 +865,7 @@ func (m *manager) GetVersionInfo() (*info.VersionInfo, error) { } func (m *manager) Exists(containerName string) bool { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - - namespacedName := namespacedContainerName{ - Name: containerName, - } - - _, ok := m.containers[namespacedName] + _, ok := m.containers.Load(namespacedContainerName{Name: containerName}) return ok } @@ -858,7 +879,7 @@ func (m *manager) GetProcessList(containerName string, options v2.RequestOptions return nil, err } if len(conts) != 1 { - return nil, fmt.Errorf("Expected the request to match only one container") + return nil, fmt.Errorf("expected the request to match only one container") } // TODO(rjnagal): handle count? Only if we can do count by type (eg. top 5 cpu users) ps := []v2.ProcessInfo{} @@ -904,19 +925,12 @@ func (m *manager) registerCollectors(collectorConfigs map[string]string, cont *c // Create a container. func (m *manager) createContainer(containerName string, watchSource watcher.ContainerWatchSource) error { - m.containersLock.Lock() - defer m.containersLock.Unlock() - - return m.createContainerLocked(containerName, watchSource) -} - -func (m *manager) createContainerLocked(containerName string, watchSource watcher.ContainerWatchSource) error { namespacedName := namespacedContainerName{ Name: containerName, } // Check that the container didn't already exist. - if _, ok := m.containers[namespacedName]; ok { + if _, ok := m.containers.Load(namespacedName); ok { return nil } @@ -973,12 +987,12 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche } // Add the container name and all its aliases. The aliases must be within the namespace of the factory. - m.containers[namespacedName] = cont + m.containers.Store(namespacedName, cont) for _, alias := range cont.info.Aliases { - m.containers[namespacedContainerName{ + m.containers.Store(namespacedContainerName{ Namespace: cont.info.Namespace, Name: alias, - }] = cont + }, cont) } klog.V(3).Infof("Added container: %q (aliases: %v, namespace: %q)", containerName, cont.info.Aliases, cont.info.Namespace) @@ -1007,37 +1021,35 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche } func (m *manager) destroyContainer(containerName string) error { - m.containersLock.Lock() - defer m.containersLock.Unlock() - - return m.destroyContainerLocked(containerName) -} - -func (m *manager) destroyContainerLocked(containerName string) error { namespacedName := namespacedContainerName{ Name: containerName, } - cont, ok := m.containers[namespacedName] + cont, ok := m.containers.Load(namespacedName) if !ok { // Already destroyed, done. return nil } - // Tell the container to stop. - err := cont.Stop() + exitCode, err := cont.handler.GetExitCode() + if err != nil { + klog.V(4).Infof("Could not retrieve exit code for container %q: %v (using -1)", containerName, err) + exitCode = -1 + } + + err = cont.Stop() if err != nil { return err } // Remove the container from our records (and all its aliases). - delete(m.containers, namespacedName) + m.containers.Delete(namespacedName) for _, alias := range cont.info.Aliases { - delete(m.containers, namespacedContainerName{ + m.containers.Delete(namespacedContainerName{ Namespace: cont.info.Namespace, Name: alias, }) } - klog.V(3).Infof("Destroyed container: %q (aliases: %v, namespace: %q)", containerName, cont.info.Aliases, cont.info.Namespace) + klog.V(3).Infof("Destroyed container: %q (aliases: %v, namespace: %q, exit_code: %d)", containerName, cont.info.Aliases, cont.info.Namespace, exitCode) contRef, err := cont.handler.ContainerReference() if err != nil { @@ -1048,6 +1060,11 @@ func (m *manager) destroyContainerLocked(containerName string) error { ContainerName: contRef.Name, Timestamp: time.Now(), EventType: info.EventContainerDeletion, + EventData: info.EventData{ + ContainerDeletion: &info.ContainerDeletionEventData{ + ExitCode: exitCode, + }, + }, } err = m.eventHandler.AddEvent(newEvent) if err != nil { @@ -1059,11 +1076,7 @@ func (m *manager) destroyContainerLocked(containerName string) error { // Detect all containers that have been added or deleted from the specified container. func (m *manager) getContainersDiff(containerName string) (added []info.ContainerReference, removed []info.ContainerReference, err error) { // Get all subcontainers recursively. - m.containersLock.RLock() - cont, ok := m.containers[namespacedContainerName{ - Name: containerName, - }] - m.containersLock.RUnlock() + cont, ok := m.containers.Load(namespacedContainerName{Name: containerName}) if !ok { return nil, nil, fmt.Errorf("failed to find container %q while checking for new containers", containerName) } @@ -1074,24 +1087,23 @@ func (m *manager) getContainersDiff(containerName string) (added []info.Containe } allContainers = append(allContainers, info.ContainerReference{Name: containerName}) - m.containersLock.RLock() - defer m.containersLock.RUnlock() - // Determine which were added and which were removed. allContainersSet := make(map[string]*containerData) - for name, d := range m.containers { + m.containers.Range(func(name namespacedContainerName, cont *containerData) bool { + if cont == nil { + return true + } // Only add the canonical name. - if d.info.Name == name.Name { - allContainersSet[name.Name] = d + if cont.info.Name == name.Name { + allContainersSet[name.Name] = cont } - } + return true + }) // Added containers for _, c := range allContainers { delete(allContainersSet, c.Name) - _, ok := m.containers[namespacedContainerName{ - Name: c.Name, - }] + _, ok := m.containers.Load(namespacedContainerName{Name: c.Name}) if !ok { added = append(added, c) } @@ -1322,16 +1334,13 @@ func (m *manager) DebugInfo() map[string][]string { debugInfo := container.DebugInfo() // Get unique containers. - var conts map[*containerData]struct{} - func() { - m.containersLock.RLock() - defer m.containersLock.RUnlock() - - conts = make(map[*containerData]struct{}, len(m.containers)) - for _, c := range m.containers { - conts[c] = struct{}{} + conts := make(map[*containerData]struct{}) + m.containers.Range(func(_ namespacedContainerName, cont *containerData) bool { + if cont != nil { + conts[cont] = struct{}{} } - }() + return true + }) // List containers. lines := make([]string, 0, len(conts)) diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus.go b/vendor/github.com/google/cadvisor/metrics/prometheus.go index aa6d53ceeb..3702dd79cb 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus.go @@ -135,6 +135,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }} }, }, + { + name: "container_health_state", + help: "The result of the container's health check", + valueType: prometheus.GaugeValue, + getValues: getContainerHealthState, + }, }, includedMetrics: includedMetrics, opts: opts, @@ -228,6 +234,30 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri timestamp: s.Timestamp, }} }, + }, { + name: "container_cpu_cfs_burst_periods_total", + help: "Number of periods when burst occurs.", + valueType: prometheus.CounterValue, + condition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 }, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{ + { + value: float64(s.Cpu.CFS.BurstsPeriods), + timestamp: s.Timestamp, + }} + }, + }, { + name: "container_cpu_cfs_burst_seconds_total", + help: "Total time duration the container has been bursted.", + valueType: prometheus.CounterValue, + condition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 }, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{ + { + value: float64(s.Cpu.CFS.BurstTime) / float64(time.Second), + timestamp: s.Timestamp, + }} + }, }, }...) } @@ -749,6 +779,54 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri return float64(fs.WeightedIoTime) / float64(time.Second) }, s.Timestamp) }, + }, { + name: "container_fs_io_cost_usage_seconds_total", + help: "Cumulative IOCost usage in seconds", + valueType: prometheus.CounterValue, + extraLabels: []string{"device"}, + getValues: func(s *info.ContainerStats) metricValues { + return ioValues( + s.DiskIo.IoCostUsage, "Count", asMicrosecondsToSeconds, + []info.FsStats{}, nil, + s.Timestamp, + ) + }, + }, { + name: "container_fs_io_cost_wait_seconds_total", + help: "Cumulative IOCost wait in seconds", + valueType: prometheus.CounterValue, + extraLabels: []string{"device"}, + getValues: func(s *info.ContainerStats) metricValues { + return ioValues( + s.DiskIo.IoCostWait, "Count", asMicrosecondsToSeconds, + []info.FsStats{}, nil, + s.Timestamp, + ) + }, + }, { + name: "container_fs_io_cost_indebt_seconds_total", + help: "Cumulative IOCost debt in seconds", + valueType: prometheus.CounterValue, + extraLabels: []string{"device"}, + getValues: func(s *info.ContainerStats) metricValues { + return ioValues( + s.DiskIo.IoCostIndebt, "Count", asMicrosecondsToSeconds, + []info.FsStats{}, nil, + s.Timestamp, + ) + }, + }, { + name: "container_fs_io_cost_indelay_seconds_total", + help: "Cumulative IOCost delay in seconds", + valueType: prometheus.CounterValue, + extraLabels: []string{"device"}, + getValues: func(s *info.ContainerStats) metricValues { + return ioValues( + s.DiskIo.IoCostIndelay, "Count", asMicrosecondsToSeconds, + []info.FsStats{}, nil, + s.Timestamp, + ) + }, }, { name: "container_blkio_device_usage_total", @@ -2091,3 +2169,18 @@ func getMinCoreScalingRatio(s *info.ContainerStats) metricValues { } return values } + +func getContainerHealthState(s *info.ContainerStats) metricValues { + value := float64(0) + switch s.Health.Status { + case "healthy": + value = 1 + case "": // if container has no health check defined + value = -1 + default: // starting or unhealthy + } + return metricValues{{ + value: value, + timestamp: s.Timestamp, + }} +} diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go b/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go index 5e53a8d6de..ab48cce860 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go @@ -320,6 +320,8 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req Periods: 723, ThrottledPeriods: 18, ThrottledTime: 1724314000, + BurstsPeriods: 25, + BurstTime: 500000000, }, Schedstat: info.CpuSchedstat{ RunTime: 53643567, @@ -578,6 +580,30 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req "Write": 6, }, }}, + IoCostUsage: []info.PerDiskStats{{ + Device: "sda1", + Major: 8, + Minor: 1, + Stats: map[string]uint64{"Count": 1500000}, + }}, + IoCostWait: []info.PerDiskStats{{ + Device: "sda1", + Major: 8, + Minor: 1, + Stats: map[string]uint64{"Count": 2500000}, + }}, + IoCostIndebt: []info.PerDiskStats{{ + Device: "sda1", + Major: 8, + Minor: 1, + Stats: map[string]uint64{"Count": 500000}, + }}, + IoCostIndelay: []info.PerDiskStats{{ + Device: "sda1", + Major: 8, + Minor: 1, + Stats: map[string]uint64{"Count": 750000}, + }}, PSI: info.PSIStats{ Full: info.PSIData{ Avg10: 0.3, @@ -778,6 +804,7 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req }, }, CpuSet: info.CPUSetStats{MemoryMigrate: 1}, + Health: info.Health{Status: "healthy"}, }, }, }, @@ -791,14 +818,14 @@ type erroringSubcontainersInfoProvider struct { func (p *erroringSubcontainersInfoProvider) GetVersionInfo() (*info.VersionInfo, error) { if p.shouldFail { - return nil, errors.New("Oops 1") + return nil, errors.New("oops 1") } return p.successfulProvider.GetVersionInfo() } func (p *erroringSubcontainersInfoProvider) GetMachineInfo() (*info.MachineInfo, error) { if p.shouldFail { - return nil, errors.New("Oops 2") + return nil, errors.New("oops 2") } return p.successfulProvider.GetMachineInfo() } @@ -806,7 +833,7 @@ func (p *erroringSubcontainersInfoProvider) GetMachineInfo() (*info.MachineInfo, func (p *erroringSubcontainersInfoProvider) GetRequestedContainersInfo( a string, opt v2.RequestOptions) (map[string]*info.ContainerInfo, error) { if p.shouldFail { - return map[string]*info.ContainerInfo{}, errors.New("Oops 3") + return map[string]*info.ContainerInfo{}, errors.New("oops 3") } return p.successfulProvider.GetRequestedContainersInfo(a, opt) } diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go b/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go index 67e5c13d74..2c3e96a12d 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go @@ -103,6 +103,22 @@ func NewPrometheusMachineCollector(i infoProvider, includedMetrics container.Met return metricValues{{value: float64(machineInfo.NumSockets), timestamp: machineInfo.Timestamp}} }, }, + { + name: "machine_cpu_books", + help: "Number of CPU books.", + valueType: prometheus.GaugeValue, + getValues: func(machineInfo *info.MachineInfo) metricValues { + return metricValues{{value: float64(machineInfo.NumBooks), timestamp: machineInfo.Timestamp}} + }, + }, + { + name: "machine_cpu_drawers", + help: "Number of CPU drawers.", + valueType: prometheus.GaugeValue, + getValues: func(machineInfo *info.MachineInfo) metricValues { + return metricValues{{value: float64(machineInfo.NumDrawers), timestamp: machineInfo.Timestamp}} + }, + }, { name: "machine_memory_bytes", help: "Amount of memory installed on the machine.", diff --git a/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go b/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go index 949d417def..46c146a727 100644 --- a/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go +++ b/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go @@ -1,5 +1,4 @@ //go:build libipmctl && cgo -// +build libipmctl,cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go b/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go index 886dd1bf44..701586b29a 100644 --- a/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go +++ b/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go @@ -1,5 +1,4 @@ //go:build !libipmctl || !cgo -// +build !libipmctl !cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/collector_libpfm.go b/vendor/github.com/google/cadvisor/perf/collector_libpfm.go index 3c8edf867b..3ff1079f58 100644 --- a/vendor/github.com/google/cadvisor/perf/collector_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/collector_libpfm.go @@ -1,5 +1,4 @@ //go:build libpfm && cgo -// +build libpfm,cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go b/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go index 57c1a20595..360c9d1d70 100644 --- a/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go @@ -1,5 +1,4 @@ //go:build !libpfm || !cgo -// +build !libpfm !cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/manager_libpfm.go b/vendor/github.com/google/cadvisor/perf/manager_libpfm.go index 9be47e372c..a54edf89c2 100644 --- a/vendor/github.com/google/cadvisor/perf/manager_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/manager_libpfm.go @@ -1,5 +1,4 @@ //go:build libpfm && cgo -// +build libpfm,cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go b/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go index 135d778eea..49711efde2 100644 --- a/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go @@ -1,5 +1,4 @@ //go:build !libpfm || !cgo -// +build !libpfm !cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/types_libpfm.go b/vendor/github.com/google/cadvisor/perf/types_libpfm.go index 89cf7be10b..9f6ae0cccb 100644 --- a/vendor/github.com/google/cadvisor/perf/types_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/types_libpfm.go @@ -1,5 +1,4 @@ //go:build libpfm && cgo -// +build libpfm,cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go b/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go index 431bd6839c..b40eb655a7 100644 --- a/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go +++ b/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go @@ -1,5 +1,4 @@ //go:build libpfm && cgo -// +build libpfm,cgo // Copyright 2020 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/summary/percentiles.go b/vendor/github.com/google/cadvisor/summary/percentiles.go index 8ce706ad9e..6d610cf919 100644 --- a/vendor/github.com/google/cadvisor/summary/percentiles.go +++ b/vendor/github.com/google/cadvisor/summary/percentiles.go @@ -105,10 +105,12 @@ func (r *resource) AddSample(val uint64) { sample := info.Percentiles{ Present: true, Mean: val, + Std: 0, Max: val, Fifty: val, Ninety: val, NinetyFive: val, + Count: 1, } r.Add(sample) } @@ -117,10 +119,13 @@ func (r *resource) AddSample(val uint64) { func (r *resource) GetAllPercentiles() info.Percentiles { p := info.Percentiles{} p.Mean = uint64(r.mean.Mean) + p.Std = uint64(r.samples.getStandardDeviation(r.mean.Mean)) p.Max = r.max p.Fifty = r.samples.GetPercentile(0.5) p.Ninety = r.samples.GetPercentile(0.9) p.NinetyFive = r.samples.GetPercentile(0.95) + // len(samples) is equal to count stored in mean. + p.Count = r.mean.count p.Present = true return p } @@ -160,6 +165,21 @@ func getPercentComplete(stats []*secondSample) (percent int32) { return } +func (s Uint64Slice) getStandardDeviation(mean float64) float64 { + n := len(s) + if n <= 1 { + return 0 + } + var ss float64 + for _, v := range s { + d := float64(v) - mean + ss += d * d + } + // Use Bessel's correction (n-1) to calculate sample standard deviation. + // This provides an unbiased estimate of population variance from sample data. + return math.Sqrt(ss / float64(n-1)) +} + // Calculate cpurate from two consecutive total cpu usage samples. func getCPURate(latest, previous secondSample) (uint64, error) { elapsed := latest.Timestamp.Sub(previous.Timestamp).Nanoseconds() diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go index 926c67034a..b8a9224d5e 100644 --- a/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go +++ b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package cpuload import ( diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/cpuload_unsupported.go b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload_unsupported.go new file mode 100644 index 0000000000..3c6e834bd0 --- /dev/null +++ b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload_unsupported.go @@ -0,0 +1,40 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !linux + +package cpuload + +import ( + "fmt" + + info "github.com/google/cadvisor/info/v1" +) + +type CpuLoadReader interface { + // Start the reader. + Start() error + + // Stop the reader and clean up internal state. + Stop() + + // Retrieve Cpu load for a given group. + // name is the full hierarchical name of the container. + // Path is an absolute filesystem path for a container under CPU cgroup hierarchy. + GetCpuLoad(name string, path string) (info.LoadStats, error) +} + +func New() (CpuLoadReader, error) { + return nil, fmt.Errorf("cpuload is not supported on this platform") +} diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/conn.go b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/conn.go index 5ddfef8d4c..5f2879d00c 100644 --- a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/conn.go +++ b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/conn.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package netlink import ( diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go index 8af275f9b2..1fd565ff7e 100644 --- a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go +++ b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package netlink import ( diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/reader.go b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/reader.go index ba478bb6ab..6591f31be7 100644 --- a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/reader.go +++ b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/reader.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package netlink import ( diff --git a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go index 32dc838fb9..f5909032aa 100644 --- a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go +++ b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package oomparser import ( diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go index f2aedfc757..a42876e80a 100644 --- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go @@ -49,6 +49,12 @@ const ( // (rather than the kernel's). The actual value is architecture and platform dependent. CPUCoreID = "core_id" + // On some architecture there exists additional level of book and drawer id + // CPUBookID is the book ID of cpu#. Typically corresponds to a physical book number. + CPUBookID = "book_id" + // CPUDrawerID is the drawer ID of cpu#. Typically corresponds to a physical drawer number. + CPUDrawerID = "drawer_id" + coreIDFilePath = "/" + sysFsCPUTopology + "/core_id" packageIDFilePath = "/" + sysFsCPUTopology + "/physical_package_id" bookIDFilePath = "/" + sysFsCPUTopology + "/book_id" diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go index e22dc20c3e..3ed7621838 100644 --- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go @@ -1,5 +1,4 @@ //go:build !x86 -// +build !x86 // Copyright 2021 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go index f0c7b1ae1d..d1fadd1f42 100644 --- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go @@ -1,5 +1,4 @@ //go:build x86 -// +build x86 // Copyright 2021 Google Inc. All Rights Reserved. // diff --git a/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go b/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go index 4084da1a5b..d2e8b6c943 100644 --- a/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go +++ b/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go @@ -274,7 +274,7 @@ func getCPUTopology(sysFs sysfs.SysFs) ([]info.Node, int, error) { cpusCount := len(cpusPaths) if cpusCount == 0 { - err = fmt.Errorf("Any CPU is not available, cpusPath: %s", cpusPath) + err = fmt.Errorf("no CPU is available, cpusPath: %s", cpusPath) return nil, 0, err } diff --git a/vendor/github.com/google/pprof/profile/profile.go b/vendor/github.com/google/pprof/profile/profile.go index 43f561d445..18df65a8df 100644 --- a/vendor/github.com/google/pprof/profile/profile.go +++ b/vendor/github.com/google/pprof/profile/profile.go @@ -278,7 +278,7 @@ func (p *Profile) massageMappings() { // Use heuristics to identify main binary and move it to the top of the list of mappings for i, m := range p.Mapping { - file := strings.TrimSpace(strings.Replace(m.File, "(deleted)", "", -1)) + file := strings.TrimSpace(strings.ReplaceAll(m.File, "(deleted)", "")) if len(file) == 0 { continue } diff --git a/vendor/github.com/google/pprof/profile/proto.go b/vendor/github.com/google/pprof/profile/proto.go index a15696ba16..31bf6bca63 100644 --- a/vendor/github.com/google/pprof/profile/proto.go +++ b/vendor/github.com/google/pprof/profile/proto.go @@ -36,6 +36,7 @@ package profile import ( "errors" "fmt" + "slices" ) type buffer struct { @@ -187,6 +188,16 @@ func le32(p []byte) uint32 { return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 } +func peekNumVarints(data []byte) (numVarints int) { + for ; len(data) > 0; numVarints++ { + var err error + if _, data, err = decodeVarint(data); err != nil { + break + } + } + return numVarints +} + func decodeVarint(data []byte) (uint64, []byte, error) { var u uint64 for i := 0; ; i++ { @@ -286,6 +297,9 @@ func decodeInt64(b *buffer, x *int64) error { func decodeInt64s(b *buffer, x *[]int64) error { if b.typ == 2 { // Packed encoding + dataLen := peekNumVarints(b.data) + *x = slices.Grow(*x, dataLen) + data := b.data for len(data) > 0 { var u uint64 @@ -316,8 +330,11 @@ func decodeUint64(b *buffer, x *uint64) error { func decodeUint64s(b *buffer, x *[]uint64) error { if b.typ == 2 { - data := b.data // Packed encoding + dataLen := peekNumVarints(b.data) + *x = slices.Grow(*x, dataLen) + + data := b.data for len(data) > 0 { var u uint64 var err error diff --git a/vendor/github.com/gregjones/httpcache/.travis.yml b/vendor/github.com/gregjones/httpcache/.travis.yml deleted file mode 100644 index 597bc9996f..0000000000 --- a/vendor/github.com/gregjones/httpcache/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -sudo: false -language: go -matrix: - allow_failures: - - go: master - fast_finish: true - include: - - go: 1.10.x - - go: 1.11.x - env: GOFMT=1 - - go: master -install: - - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). -script: - - go get -t -v ./... - - if test -n "${GOFMT}"; then gofmt -w -s . && git diff --exit-code; fi - - go tool vet . - - go test -v -race ./... diff --git a/vendor/github.com/gregjones/httpcache/README.md b/vendor/github.com/gregjones/httpcache/README.md deleted file mode 100644 index 51e7d23d09..0000000000 --- a/vendor/github.com/gregjones/httpcache/README.md +++ /dev/null @@ -1,29 +0,0 @@ -httpcache -========= - -[![Build Status](https://travis-ci.org/gregjones/httpcache.svg?branch=master)](https://travis-ci.org/gregjones/httpcache) [![GoDoc](https://godoc.org/github.com/gregjones/httpcache?status.svg)](https://godoc.org/github.com/gregjones/httpcache) - -Package httpcache provides a http.RoundTripper implementation that works as a mostly [RFC 7234](https://tools.ietf.org/html/rfc7234) compliant cache for http responses. - -It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy). - -This project isn't actively maintained; it works for what I, and seemingly others, want to do with it, and I consider it "done". That said, if you find any issues, please open a Pull Request and I will try to review it. Any changes now that change the public API won't be considered. - -Cache Backends --------------- - -- The built-in 'memory' cache stores responses in an in-memory map. -- [`github.com/gregjones/httpcache/diskcache`](https://github.com/gregjones/httpcache/tree/master/diskcache) provides a filesystem-backed cache using the [diskv](https://github.com/peterbourgon/diskv) library. -- [`github.com/gregjones/httpcache/memcache`](https://github.com/gregjones/httpcache/tree/master/memcache) provides memcache implementations, for both App Engine and 'normal' memcache servers. -- [`sourcegraph.com/sourcegraph/s3cache`](https://sourcegraph.com/github.com/sourcegraph/s3cache) uses Amazon S3 for storage. -- [`github.com/gregjones/httpcache/leveldbcache`](https://github.com/gregjones/httpcache/tree/master/leveldbcache) provides a filesystem-backed cache using [leveldb](https://github.com/syndtr/goleveldb/leveldb). -- [`github.com/die-net/lrucache`](https://github.com/die-net/lrucache) provides an in-memory cache that will evict least-recently used entries. -- [`github.com/die-net/lrucache/twotier`](https://github.com/die-net/lrucache/tree/master/twotier) allows caches to be combined, for example to use lrucache above with a persistent disk-cache. -- [`github.com/birkelund/boltdbcache`](https://github.com/birkelund/boltdbcache) provides a BoltDB implementation (based on the [bbolt](https://github.com/coreos/bbolt) fork). - -If you implement any other backend and wish it to be linked here, please send a PR editing this file. - -License -------- - -- [MIT License](LICENSE.txt) diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/LICENSE similarity index 100% rename from vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE rename to vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/LICENSE diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go new file mode 100644 index 0000000000..5c8ba20765 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go @@ -0,0 +1,117 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" +) + +// ClientMetrics represents a collection of metrics to be registered on a +// Prometheus metrics registry for a gRPC client. +type ClientMetrics struct { + clientStartedCounter *prometheus.CounterVec + clientHandledCounter *prometheus.CounterVec + clientStreamMsgReceived *prometheus.CounterVec + clientStreamMsgSent *prometheus.CounterVec + + // clientHandledHistogram can be nil + clientHandledHistogram *prometheus.HistogramVec + // clientStreamRecvHistogram can be nil + clientStreamRecvHistogram *prometheus.HistogramVec + // clientStreamSendHistogram can be nil + clientStreamSendHistogram *prometheus.HistogramVec +} + +// NewClientMetrics returns a new ClientMetrics object. +// NOTE: Remember to register ClientMetrics object using prometheus registry +// e.g. prometheus.MustRegister(myClientMetrics). +func NewClientMetrics(opts ...ClientMetricsOption) *ClientMetrics { + var config clientMetricsConfig + config.apply(opts) + return &ClientMetrics{ + clientStartedCounter: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_client_started_total", + Help: "Total number of RPCs started on the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientHandledCounter: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_client_handled_total", + Help: "Total number of RPCs completed by the client, regardless of success or failure.", + }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), + + clientStreamMsgReceived: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_client_msg_received_total", + Help: "Total number of RPC stream messages received by the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientStreamMsgSent: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_client_msg_sent_total", + Help: "Total number of gRPC stream messages sent by the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientHandledHistogram: config.clientHandledHistogram, + clientStreamRecvHistogram: config.clientStreamRecvHistogram, + clientStreamSendHistogram: config.clientStreamSendHistogram, + } +} + +// Describe sends the super-set of all possible descriptors of metrics +// collected by this Collector to the provided channel and returns once +// the last descriptor has been sent. +func (m *ClientMetrics) Describe(ch chan<- *prometheus.Desc) { + m.clientStartedCounter.Describe(ch) + m.clientHandledCounter.Describe(ch) + m.clientStreamMsgReceived.Describe(ch) + m.clientStreamMsgSent.Describe(ch) + if m.clientHandledHistogram != nil { + m.clientHandledHistogram.Describe(ch) + } + if m.clientStreamRecvHistogram != nil { + m.clientStreamRecvHistogram.Describe(ch) + } + if m.clientStreamSendHistogram != nil { + m.clientStreamSendHistogram.Describe(ch) + } +} + +// Collect is called by the Prometheus registry when collecting +// metrics. The implementation sends each collected metric via the +// provided channel and returns once the last metric has been sent. +func (m *ClientMetrics) Collect(ch chan<- prometheus.Metric) { + m.clientStartedCounter.Collect(ch) + m.clientHandledCounter.Collect(ch) + m.clientStreamMsgReceived.Collect(ch) + m.clientStreamMsgSent.Collect(ch) + if m.clientHandledHistogram != nil { + m.clientHandledHistogram.Collect(ch) + } + if m.clientStreamRecvHistogram != nil { + m.clientStreamRecvHistogram.Collect(ch) + } + if m.clientStreamSendHistogram != nil { + m.clientStreamSendHistogram.Collect(ch) + } +} + +// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. +func (m *ClientMetrics) UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor { + return interceptors.UnaryClientInterceptor(&reportable{ + opts: opts, + clientMetrics: m, + }) +} + +// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func (m *ClientMetrics) StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { + return interceptors.StreamClientInterceptor(&reportable{ + opts: opts, + clientMetrics: m, + }) +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go new file mode 100644 index 0000000000..c2671679c6 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go @@ -0,0 +1,77 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +type clientMetricsConfig struct { + counterOpts counterOptions + // clientHandledHistogram can be nil. + clientHandledHistogram *prometheus.HistogramVec + // clientStreamRecvHistogram can be nil. + clientStreamRecvHistogram *prometheus.HistogramVec + // clientStreamSendHistogram can be nil. + clientStreamSendHistogram *prometheus.HistogramVec +} + +type ClientMetricsOption func(*clientMetricsConfig) + +func (c *clientMetricsConfig) apply(opts []ClientMetricsOption) { + for _, o := range opts { + o(c) + } +} + +func WithClientCounterOptions(opts ...CounterOption) ClientMetricsOption { + return func(o *clientMetricsConfig) { + o.counterOpts = opts + } +} + +// WithClientHandlingTimeHistogram turns on recording of handling time of RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func WithClientHandlingTimeHistogram(opts ...HistogramOption) ClientMetricsOption { + return func(o *clientMetricsConfig) { + o.clientHandledHistogram = prometheus.NewHistogramVec( + histogramOptions(opts).apply(prometheus.HistogramOpts{ + Name: "grpc_client_handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + Buckets: prometheus.DefBuckets, + }), + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + } +} + +// WithClientStreamRecvHistogram turns on recording of single message receive time of streaming RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func WithClientStreamRecvHistogram(opts ...HistogramOption) ClientMetricsOption { + return func(o *clientMetricsConfig) { + o.clientStreamRecvHistogram = prometheus.NewHistogramVec( + histogramOptions(opts).apply(prometheus.HistogramOpts{ + Name: "grpc_client_msg_recv_handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC single message receive.", + Buckets: prometheus.DefBuckets, + }), + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + } +} + +// WithClientStreamSendHistogram turns on recording of single message send time of streaming RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func WithClientStreamSendHistogram(opts ...HistogramOption) ClientMetricsOption { + return func(o *clientMetricsConfig) { + o.clientStreamSendHistogram = prometheus.NewHistogramVec( + histogramOptions(opts).apply(prometheus.HistogramOpts{ + Name: "grpc_client_msg_send_handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC single message send.", + Buckets: prometheus.DefBuckets, + }), + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go new file mode 100644 index 0000000000..5c36923f7e --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go @@ -0,0 +1,23 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +type grpcType string + +// grpcType describes all types of grpc connection. +const ( + Unary grpcType = "unary" + ClientStream grpcType = "client_stream" + ServerStream grpcType = "server_stream" + BidiStream grpcType = "bidi_stream" +) + +// Kind describes whether interceptor is a client or server type. +type Kind string + +// Enum for Client and Server Kind. +const ( + KindClient Kind = "client" + KindServer Kind = "server" +) diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go new file mode 100644 index 0000000000..b62f17efb7 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go @@ -0,0 +1,8 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +/* +Package prometheus provides a standalone interceptor for metrics. It's next iteration of deprecated https://github.com/grpc-ecosystem/go-grpc-prometheus. +See https://github.com/grpc-ecosystem/go-grpc-middleware/tree/main/examples for example. +*/ +package prometheus diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go new file mode 100644 index 0000000000..2047b5fe41 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go @@ -0,0 +1,152 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" + "google.golang.org/grpc/status" +) + +// FromError returns a grpc status. If the error code is neither a valid grpc status nor a context error, codes.Unknown +// will be set. +func FromError(err error) *status.Status { + s, ok := status.FromError(err) + // Mirror what the grpc server itself does, i.e. also convert context errors to status + if !ok { + s = status.FromContextError(err) + } + return s +} + +// A CounterOption lets you add options to Counter metrics using With* funcs. +type CounterOption func(*prometheus.CounterOpts) + +type counterOptions []CounterOption + +func (co counterOptions) apply(o prometheus.CounterOpts) prometheus.CounterOpts { + for _, f := range co { + f(&o) + } + return o +} + +// WithConstLabels allows you to add ConstLabels to Counter metrics. +func WithConstLabels(labels prometheus.Labels) CounterOption { + return func(o *prometheus.CounterOpts) { + o.ConstLabels = labels + } +} + +// WithSubsystem allows you to add a Subsystem to Counter metrics. +func WithSubsystem(subsystem string) CounterOption { + return func(o *prometheus.CounterOpts) { + o.Subsystem = subsystem + } +} + +// WithNamespace allows you to add a Namespace to Counter metrics. +func WithNamespace(namespace string) CounterOption { + return func(o *prometheus.CounterOpts) { + o.Namespace = namespace + } +} + +// A HistogramOption lets you add options to Histogram metrics using With* +// funcs. +type HistogramOption func(*prometheus.HistogramOpts) + +type histogramOptions []HistogramOption + +func (ho histogramOptions) apply(o prometheus.HistogramOpts) prometheus.HistogramOpts { + for _, f := range ho { + f(&o) + } + return o +} + +// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. +func WithHistogramBuckets(buckets []float64) HistogramOption { + return func(o *prometheus.HistogramOpts) { o.Buckets = buckets } +} + +// WithHistogramOpts allows you to specify HistogramOpts but makes sure the correct name and label is used. +// This function is helpful when specifying more than just the buckets, like using NativeHistograms. +func WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption { + // TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts. + // Maybe we can change the interface to accept arbitrary HistogramOpts and + // only make sure to overwrite the necessary fields (name, labels). + return func(o *prometheus.HistogramOpts) { + o.Buckets = opts.Buckets + o.NativeHistogramBucketFactor = opts.NativeHistogramBucketFactor + o.NativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold + o.NativeHistogramMaxBucketNumber = opts.NativeHistogramMaxBucketNumber + o.NativeHistogramMinResetDuration = opts.NativeHistogramMinResetDuration + o.NativeHistogramMaxZeroThreshold = opts.NativeHistogramMaxZeroThreshold + } +} + +// WithHistogramConstLabels allows you to add custom ConstLabels to +// histograms metrics. +func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.ConstLabels = labels + } +} + +// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics. +func WithHistogramSubsystem(subsystem string) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.Subsystem = subsystem + } +} + +// WithHistogramNamespace allows you to add a Namespace to histograms metrics. +func WithHistogramNamespace(namespace string) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.Namespace = namespace + } +} + +func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { + if !mInfo.IsClientStream && !mInfo.IsServerStream { + return Unary + } + if mInfo.IsClientStream && !mInfo.IsServerStream { + return ClientStream + } + if !mInfo.IsClientStream && mInfo.IsServerStream { + return ServerStream + } + return BidiStream +} + +// An Option lets you add options to prometheus interceptors using With* funcs. +type Option func(*config) + +type config struct { + exemplarFn exemplarFromCtxFn + labelsFn labelsFromCtxFn +} + +func (c *config) apply(opts []Option) { + for _, o := range opts { + o(c) + } +} + +// WithExemplarFromContext sets function that will be used to deduce exemplar for all counter and histogram metrics. +func WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option { + return func(o *config) { + o.exemplarFn = exemplarFn + } +} + +// WithLabelsFromContext sets function that will be used to extract labels from context for metrics. +// This should be used in conjunction with WithContextLabels to define which labels to extract. +func WithLabelsFromContext(labelsFn labelsFromCtxFn) Option { + return func(o *config) { + o.labelsFn = labelsFn + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go new file mode 100644 index 0000000000..268beb3e61 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go @@ -0,0 +1,139 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "context" + "time" + + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/prometheus/client_golang/prometheus" +) + +type reporter struct { + clientMetrics *ClientMetrics + serverMetrics *ServerMetrics + typ interceptors.GRPCType + service, method string + kind Kind + exemplar prometheus.Labels + contextLabels []string +} + +func (r *reporter) PostCall(err error, rpcDuration time.Duration) { + // get status code from error + status := FromError(err) + code := status.Code() + + // perform handling of metrics from code + switch r.kind { + case KindServer: + baseLabels := []string{string(r.typ), r.service, r.method, code.String()} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverHandledCounter, allLabels...) + if r.serverMetrics.serverHandledHistogram != nil { + histLabels := []string{string(r.typ), r.service, r.method} + allHistLabels := append(histLabels, r.contextLabels...) + r.observeWithExemplar(r.serverMetrics.serverHandledHistogram, rpcDuration.Seconds(), allHistLabels...) + } + + case KindClient: + r.incrementWithExemplar(r.clientMetrics.clientHandledCounter, string(r.typ), r.service, r.method, code.String()) + if r.clientMetrics.clientHandledHistogram != nil { + r.observeWithExemplar(r.clientMetrics.clientHandledHistogram, rpcDuration.Seconds(), string(r.typ), r.service, r.method) + } + } +} + +func (r *reporter) PostMsgSend(_ any, _ error, sendDuration time.Duration) { + switch r.kind { + case KindServer: + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStreamMsgSent, allLabels...) + case KindClient: + r.incrementWithExemplar(r.clientMetrics.clientStreamMsgSent, string(r.typ), r.service, r.method) + if r.clientMetrics.clientStreamSendHistogram != nil { + r.observeWithExemplar(r.clientMetrics.clientStreamSendHistogram, sendDuration.Seconds(), string(r.typ), r.service, r.method) + } + } +} + +func (r *reporter) PostMsgReceive(_ any, _ error, recvDuration time.Duration) { + switch r.kind { + case KindServer: + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStreamMsgReceived, allLabels...) + case KindClient: + r.incrementWithExemplar(r.clientMetrics.clientStreamMsgReceived, string(r.typ), r.service, r.method) + if r.clientMetrics.clientStreamRecvHistogram != nil { + r.observeWithExemplar(r.clientMetrics.clientStreamRecvHistogram, recvDuration.Seconds(), string(r.typ), r.service, r.method) + } + } +} + +type reportable struct { + clientMetrics *ClientMetrics + serverMetrics *ServerMetrics + + opts []Option +} + +func (rep *reportable) ServerReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) { + return rep.reporter(ctx, rep.serverMetrics, nil, meta, KindServer) +} + +func (rep *reportable) ClientReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) { + return rep.reporter(ctx, nil, rep.clientMetrics, meta, KindClient) +} + +func (rep *reportable) reporter(ctx context.Context, sm *ServerMetrics, cm *ClientMetrics, meta interceptors.CallMeta, kind Kind) (interceptors.Reporter, context.Context) { + var c config + c.apply(rep.opts) + r := &reporter{ + clientMetrics: cm, + serverMetrics: sm, + typ: meta.Typ, + service: meta.Service, + method: meta.Method, + kind: kind, + } + if c.exemplarFn != nil { + r.exemplar = c.exemplarFn(ctx) + } + + // Extract context labels if labelsFn is configured and we're on server side + if c.labelsFn != nil && kind == KindServer && sm != nil { + contextLabelMap := c.labelsFn(ctx) + // Extract context label values in the order defined by the server metrics + r.contextLabels = make([]string, len(sm.contextLabelNames)) + for i, labelName := range sm.contextLabelNames { + if value, exists := contextLabelMap[labelName]; exists { + r.contextLabels[i] = value + } else { + // Use empty string if label not found in context + r.contextLabels[i] = "" + } + } + } + + switch kind { + case KindClient: + r.incrementWithExemplar(r.clientMetrics.clientStartedCounter, string(r.typ), r.service, r.method) + case KindServer: + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStartedCounter, allLabels...) + } + return r, ctx +} + +func (r *reporter) incrementWithExemplar(c *prometheus.CounterVec, lvals ...string) { + c.WithLabelValues(lvals...).(prometheus.ExemplarAdder).AddWithExemplar(1, r.exemplar) +} + +func (r *reporter) observeWithExemplar(h *prometheus.HistogramVec, value float64, lvals ...string) { + h.WithLabelValues(lvals...).(prometheus.ExemplarObserver).ObserveWithExemplar(value, r.exemplar) +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go new file mode 100644 index 0000000000..358d574caf --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go @@ -0,0 +1,163 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" + "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +// ServerMetrics represents a collection of metrics to be registered on a +// Prometheus metrics registry for a gRPC server. +type ServerMetrics struct { + serverStartedCounter *prometheus.CounterVec + serverHandledCounter *prometheus.CounterVec + serverStreamMsgReceived *prometheus.CounterVec + serverStreamMsgSent *prometheus.CounterVec + // serverHandledHistogram can be nil. + serverHandledHistogram *prometheus.HistogramVec + // contextLabelNames stores the names of context labels + contextLabelNames []string +} + +// NewServerMetrics returns a new ServerMetrics object that has server interceptor methods. +// NOTE: Remember to register ServerMetrics object by using prometheus registry +// e.g. prometheus.MustRegister(myServerMetrics). +func NewServerMetrics(opts ...ServerMetricsOption) *ServerMetrics { + var config serverMetricsConfig + config.apply(opts) + + // Build label names by combining default labels with context labels + defaultLabels := []string{"grpc_type", "grpc_service", "grpc_method"} + defaultLabelsWithCode := []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"} + + startedLabels := append(defaultLabels, config.contextLabels...) + handledLabels := append(defaultLabelsWithCode, config.contextLabels...) + streamLabels := append(defaultLabels, config.contextLabels...) + + // Create histogram if enabled + var serverHandledHistogram *prometheus.HistogramVec + if config.enableHistogram { + histogramLabels := append(defaultLabels, config.contextLabels...) + serverHandledHistogram = prometheus.NewHistogramVec( + histogramOptions(config.histogramOpts).apply(prometheus.HistogramOpts{ + Name: "grpc_server_handling_seconds", + Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", + Buckets: prometheus.DefBuckets, + }), + histogramLabels, + ) + } + + return &ServerMetrics{ + serverStartedCounter: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_server_started_total", + Help: "Total number of RPCs started on the server.", + }), startedLabels), + serverHandledCounter: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_server_handled_total", + Help: "Total number of RPCs completed on the server, regardless of success or failure.", + }), handledLabels), + serverStreamMsgReceived: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_server_msg_received_total", + Help: "Total number of RPC stream messages received on the server.", + }), streamLabels), + serverStreamMsgSent: prometheus.NewCounterVec( + config.counterOpts.apply(prometheus.CounterOpts{ + Name: "grpc_server_msg_sent_total", + Help: "Total number of gRPC stream messages sent by the server.", + }), streamLabels), + serverHandledHistogram: serverHandledHistogram, + contextLabelNames: config.contextLabels, + } +} + +// Describe sends the super-set of all possible descriptors of metrics +// collected by this Collector to the provided channel and returns once +// the last descriptor has been sent. +func (m *ServerMetrics) Describe(ch chan<- *prometheus.Desc) { + m.serverStartedCounter.Describe(ch) + m.serverHandledCounter.Describe(ch) + m.serverStreamMsgReceived.Describe(ch) + m.serverStreamMsgSent.Describe(ch) + if m.serverHandledHistogram != nil { + m.serverHandledHistogram.Describe(ch) + } +} + +// Collect is called by the Prometheus registry when collecting +// metrics. The implementation sends each collected metric via the +// provided channel and returns once the last metric has been sent. +func (m *ServerMetrics) Collect(ch chan<- prometheus.Metric) { + m.serverStartedCounter.Collect(ch) + m.serverHandledCounter.Collect(ch) + m.serverStreamMsgReceived.Collect(ch) + m.serverStreamMsgSent.Collect(ch) + if m.serverHandledHistogram != nil { + m.serverHandledHistogram.Collect(ch) + } +} + +// InitializeMetrics initializes all metrics, with their appropriate null +// value, for all gRPC methods registered on a gRPC server. This is useful, to +// ensure that all metrics exist when collecting and querying. +// NOTE: This might add significant cardinality and might not be needed in future version of Prometheus (created timestamp). +func (m *ServerMetrics) InitializeMetrics(server reflection.ServiceInfoProvider) { + serviceInfo := server.GetServiceInfo() + for serviceName, info := range serviceInfo { + for _, mInfo := range info.Methods { + m.preRegisterMethod(serviceName, &mInfo) + } + } +} + +// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated. +func (m *ServerMetrics) preRegisterMethod(serviceName string, mInfo *grpc.MethodInfo) { + methodName := mInfo.Name + methodType := string(typeFromMethodInfo(mInfo)) + + // Create empty context label values for pre-registration + contextLabels := make([]string, len(m.contextLabelNames)) + for i := range contextLabels { + contextLabels[i] = "" + } + + // Build complete label value arrays + startedLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + handledLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + streamLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + + // These are just references (no increments), as just referencing will create the labels but not set values. + _, _ = m.serverStartedCounter.GetMetricWithLabelValues(startedLabels...) + _, _ = m.serverStreamMsgReceived.GetMetricWithLabelValues(streamLabels...) + _, _ = m.serverStreamMsgSent.GetMetricWithLabelValues(streamLabels...) + if m.serverHandledHistogram != nil { + _, _ = m.serverHandledHistogram.GetMetricWithLabelValues(streamLabels...) + } + for _, code := range interceptors.AllCodes { + handledLabelsWithCode := append(handledLabels, code.String()) + _, _ = m.serverHandledCounter.GetMetricWithLabelValues(handledLabelsWithCode...) + } +} + +// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. +func (m *ServerMetrics) UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { + return interceptors.UnaryServerInterceptor(&reportable{ + opts: opts, + serverMetrics: m, + }) +} + +// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func (m *ServerMetrics) StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { + return interceptors.StreamServerInterceptor(&reportable{ + opts: opts, + serverMetrics: m, + }) +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go new file mode 100644 index 0000000000..14340637d1 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go @@ -0,0 +1,56 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package prometheus + +import ( + "context" + + "github.com/prometheus/client_golang/prometheus" +) + +type exemplarFromCtxFn func(ctx context.Context) prometheus.Labels +type labelsFromCtxFn func(metadata context.Context) prometheus.Labels + +type serverMetricsConfig struct { + counterOpts counterOptions + // histogramOpts stores the options for creating the histogram with dynamic labels + histogramOpts histogramOptions + // enableHistogram indicates whether histogram should be created + enableHistogram bool + // contextLabels defines the names of dynamic labels to be extracted from context + contextLabels []string +} + +type ServerMetricsOption func(*serverMetricsConfig) + +func (c *serverMetricsConfig) apply(opts []ServerMetricsOption) { + for _, o := range opts { + o(c) + } +} + +// WithServerCounterOptions sets counter options. +func WithServerCounterOptions(opts ...CounterOption) ServerMetricsOption { + return func(o *serverMetricsConfig) { + o.counterOpts = opts + } +} + +// WithServerHandlingTimeHistogram turns on recording of handling time of RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func WithServerHandlingTimeHistogram(opts ...HistogramOption) ServerMetricsOption { + return func(o *serverMetricsConfig) { + o.histogramOpts = opts + o.enableHistogram = true + } +} + +// WithContextLabels configures the server metrics to include dynamic labels extracted from context. +// The provided label names will be added to all server metrics as dynamic labels. +// Use WithLabelsFromContext in the interceptor options to specify how to extract these labels from context. +func WithContextLabels(labelNames ...string) ServerMetricsOption { + return func(o *serverMetricsConfig) { + o.contextLabels = labelNames + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT new file mode 100644 index 0000000000..3b13627cdb --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT @@ -0,0 +1,2 @@ +Copyright (c) The go-grpc-middleware Authors. +Licensed under the Apache License 2.0. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE new file mode 100644 index 0000000000..b2b065037f --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/callmeta.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/callmeta.go new file mode 100644 index 0000000000..df3f5d11a8 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/callmeta.go @@ -0,0 +1,67 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package interceptors + +import ( + "fmt" + "strings" + + "google.golang.org/grpc" +) + +func splitFullMethodName(fullMethod string) (string, string) { + fullMethod = strings.TrimPrefix(fullMethod, "/") // remove leading slash + if i := strings.Index(fullMethod, "/"); i >= 0 { + return fullMethod[:i], fullMethod[i+1:] + } + return "unknown", "unknown" +} + +type CallMeta struct { + ReqOrNil any + Typ GRPCType + Service string + Method string + IsClient bool +} + +func NewClientCallMeta(fullMethod string, streamDesc *grpc.StreamDesc, reqOrNil any) CallMeta { + c := CallMeta{IsClient: true, ReqOrNil: reqOrNil, Typ: Unary} + if streamDesc != nil { + c.Typ = clientStreamType(streamDesc) + } + c.Service, c.Method = splitFullMethodName(fullMethod) + return c +} + +func NewServerCallMeta(fullMethod string, streamInfo *grpc.StreamServerInfo, reqOrNil any) CallMeta { + c := CallMeta{IsClient: false, ReqOrNil: reqOrNil, Typ: Unary} + if streamInfo != nil { + c.Typ = serverStreamType(streamInfo) + } + c.Service, c.Method = splitFullMethodName(fullMethod) + return c +} + +func (c CallMeta) FullMethod() string { + return fmt.Sprintf("/%s/%s", c.Service, c.Method) +} + +func clientStreamType(desc *grpc.StreamDesc) GRPCType { + if desc.ClientStreams && !desc.ServerStreams { + return ClientStream + } else if !desc.ClientStreams && desc.ServerStreams { + return ServerStream + } + return BidiStream +} + +func serverStreamType(info *grpc.StreamServerInfo) GRPCType { + if info.IsClientStream && !info.IsServerStream { + return ClientStream + } else if !info.IsClientStream && info.IsServerStream { + return ServerStream + } + return BidiStream +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go new file mode 100644 index 0000000000..7b4460e21e --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go @@ -0,0 +1,80 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +// Go gRPC Middleware monitoring interceptors for client-side gRPC. + +package interceptors + +import ( + "context" + "errors" + "io" + "time" + + "google.golang.org/grpc" +) + +// UnaryClientInterceptor is a gRPC client-side interceptor that provides reporting for Unary RPCs. +func UnaryClientInterceptor(reportable ClientReportable) grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + r := newReport(NewClientCallMeta(method, nil, req)) + reporter, newCtx := reportable.ClientReporter(ctx, r.callMeta) + + reporter.PostMsgSend(req, nil, time.Since(r.startTime)) + err := invoker(newCtx, method, req, reply, cc, opts...) + reporter.PostMsgReceive(reply, err, time.Since(r.startTime)) + reporter.PostCall(err, time.Since(r.startTime)) + return err + } +} + +// StreamClientInterceptor is a gRPC client-side interceptor that provides reporting for Stream RPCs. +func StreamClientInterceptor(reportable ClientReportable) grpc.StreamClientInterceptor { + return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + r := newReport(NewClientCallMeta(method, desc, nil)) + reporter, newCtx := reportable.ClientReporter(ctx, r.callMeta) + + clientStream, err := streamer(newCtx, desc, cc, method, opts...) + if err != nil { + reporter.PostCall(err, time.Since(r.startTime)) + return nil, err + } + return &monitoredClientStream{ClientStream: clientStream, startTime: r.startTime, hasServerStream: desc.ServerStreams, reporter: reporter}, nil + } +} + +// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to report. +type monitoredClientStream struct { + grpc.ClientStream + + startTime time.Time + hasServerStream bool + reporter Reporter +} + +func (s *monitoredClientStream) SendMsg(m any) error { + start := time.Now() + err := s.ClientStream.SendMsg(m) + s.reporter.PostMsgSend(m, err, time.Since(start)) + return err +} + +func (s *monitoredClientStream) RecvMsg(m any) error { + start := time.Now() + err := s.ClientStream.RecvMsg(m) + s.reporter.PostMsgReceive(m, err, time.Since(start)) + + if s.hasServerStream { + if err == nil { + return nil + } + var postErr error + if !errors.Is(err, io.EOF) { + postErr = err + } + s.reporter.PostCall(postErr, time.Since(s.startTime)) + } else { + s.reporter.PostCall(err, time.Since(s.startTime)) + } + return err +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go new file mode 100644 index 0000000000..2608b9a4f8 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go @@ -0,0 +1,12 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +// +/* +interceptor is an internal package used by higher level middlewares. It allows injecting custom code in various +places of the gRPC lifecycle. + +This particular package is intended for use by other middleware, metric, logging or otherwise. +This allows code to be shared between different implementations. +*/ +package interceptors diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go new file mode 100644 index 0000000000..c1731962a0 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go @@ -0,0 +1,73 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +package interceptors + +import ( + "context" + "time" + + "google.golang.org/grpc/codes" +) + +type GRPCType string + +const ( + Unary GRPCType = "unary" + ClientStream GRPCType = "client_stream" + ServerStream GRPCType = "server_stream" + BidiStream GRPCType = "bidi_stream" +) + +var AllCodes = []codes.Code{ + codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, + codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, + codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, + codes.Unavailable, codes.DataLoss, +} + +type ClientReportable interface { + ClientReporter(context.Context, CallMeta) (Reporter, context.Context) +} + +type ServerReportable interface { + ServerReporter(context.Context, CallMeta) (Reporter, context.Context) +} + +// CommonReportableFunc helper allows an easy way to implement reporter with common client and server logic. +type CommonReportableFunc func(ctx context.Context, c CallMeta) (Reporter, context.Context) + +func (f CommonReportableFunc) ClientReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) { + return f(ctx, c) +} + +func (f CommonReportableFunc) ServerReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) { + return f(ctx, c) +} + +type Reporter interface { + PostCall(err error, rpcDuration time.Duration) + PostMsgSend(reqProto any, err error, sendDuration time.Duration) + PostMsgReceive(replyProto any, err error, recvDuration time.Duration) +} + +var _ Reporter = NoopReporter{} + +type NoopReporter struct{} + +func (NoopReporter) PostCall(error, time.Duration) {} +func (NoopReporter) PostMsgSend(any, error, time.Duration) {} +func (NoopReporter) PostMsgReceive(any, error, time.Duration) {} + +type report struct { + callMeta CallMeta + startTime time.Time +} + +func newReport(callMeta CallMeta) report { + r := report{ + startTime: time.Now(), + callMeta: callMeta, + } + return r +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go new file mode 100644 index 0000000000..0484109069 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go @@ -0,0 +1,65 @@ +// Copyright (c) The go-grpc-middleware Authors. +// Licensed under the Apache License 2.0. + +// Go gRPC Middleware monitoring interceptors for server-side gRPC. + +package interceptors + +import ( + "context" + "time" + + "google.golang.org/grpc" +) + +// UnaryServerInterceptor is a gRPC server-side interceptor that provides reporting for Unary RPCs. +func UnaryServerInterceptor(reportable ServerReportable) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { + r := newReport(NewServerCallMeta(info.FullMethod, nil, req)) + reporter, newCtx := reportable.ServerReporter(ctx, r.callMeta) + + reporter.PostMsgReceive(req, nil, time.Since(r.startTime)) + resp, err := handler(newCtx, req) + reporter.PostMsgSend(resp, err, time.Since(r.startTime)) + + reporter.PostCall(err, time.Since(r.startTime)) + return resp, err + } +} + +// StreamServerInterceptor is a gRPC server-side interceptor that provides reporting for Streaming RPCs. +func StreamServerInterceptor(reportable ServerReportable) grpc.StreamServerInterceptor { + return func(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + r := newReport(NewServerCallMeta(info.FullMethod, info, nil)) + reporter, newCtx := reportable.ServerReporter(ss.Context(), r.callMeta) + err := handler(srv, &monitoredServerStream{ServerStream: ss, newCtx: newCtx, reporter: reporter}) + reporter.PostCall(err, time.Since(r.startTime)) + return err + } +} + +// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to report. +type monitoredServerStream struct { + grpc.ServerStream + + newCtx context.Context + reporter Reporter +} + +func (s *monitoredServerStream) Context() context.Context { + return s.newCtx +} + +func (s *monitoredServerStream) SendMsg(m any) error { + start := time.Now() + err := s.ServerStream.SendMsg(m) + s.reporter.PostMsgSend(m, err, time.Since(start)) + return err +} + +func (s *monitoredServerStream) RecvMsg(m any) error { + start := time.Now() + err := s.ServerStream.RecvMsg(m) + s.reporter.PostMsgReceive(m, err, time.Since(start)) + return err +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore deleted file mode 100644 index 2233cff9d1..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore +++ /dev/null @@ -1,201 +0,0 @@ -#vendor -vendor/ - -# Created by .ignore support plugin (hsz.mobi) -coverage.txt -### Go template -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof -### Windows template -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk -### Kate template -# Swap Files # -.*.kate-swp -.swp.* -### SublimeText template -# cache files for sublime text -*.tmlanguage.cache -*.tmPreferences.cache -*.stTheme.cache - -# workspace files are user-specific -*.sublime-workspace - -# project files should be checked into the repository, unless a significant -# proportion of contributors will probably not be using SublimeText -# *.sublime-project - -# sftp configuration file -sftp-config.json -### Linux template -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -.idea -.idea/tasks.xml -.idea/dictionaries -.idea/vcs.xml -.idea/jsLibraryMappings.xml - -# Sensitive or high-churn files: -.idea/dataSources.ids -.idea/dataSources.xml -.idea/dataSources.local.xml -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml - -# Gradle: -.idea/gradle.xml -.idea/libraries - -# Mongo Explorer plugin: -.idea/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties -### Xcode template -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint -### Eclipse template - -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.settings/ -.loadpath -.recommenders - -# Eclipse Core -.project - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# PyDev specific (Python IDE for Eclipse) -*.pydevproject - -# CDT-specific (C/C++ Development Tooling) -.cproject - -# JDT-specific (Eclipse Java Development Tools) -.classpath - -# Java annotation processor (APT) -.factorypath - -# PDT-specific (PHP Development Tools) -.buildpath - -# sbteclipse plugin -.target - -# Tern plugin -.tern-project - -# TeXlipse plugin -.texlipse - -# STS (Spring Tool Suite) -.springBeans - -# Code Recommenders -.recommenders/ - diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml deleted file mode 100644 index ac037f5573..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -sudo: false -language: go -go: - - 1.9.x - - 1.10.x - - 1.11.x - - 1.12.x - - master - -env: -- GO111MODULE=on - -install: -# With Go modules (eg Go >= 1.11), it isn't necessary anymore to 'go get' the dependencies before running the tests. -- if [[ $TRAVIS_GO_VERSION =~ ^1\.(7|8|9|10)\. ]]; then go get github.com/prometheus/client_golang/prometheus; fi -- if [[ $TRAVIS_GO_VERSION =~ ^1\.(7|8|9|10)\. ]]; then go get google.golang.org/grpc; fi -- if [[ $TRAVIS_GO_VERSION =~ ^1\.(7|8|9|10)\. ]]; then go get github.com/stretchr/testify; fi - -script: -- make test - -after_success: -- bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md deleted file mode 100644 index 14e8869cb9..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md +++ /dev/null @@ -1,28 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added -* Support for error unwrapping. (Supported for `github.com/pkg/errors` and native wrapping added in go1.13) - -## [1.2.0](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases/tag/v1.2.0) - 2018-06-04 - -### Added - -* Require go 1.9 or later and test against these versions in CI. -* Provide metrics object as `prometheus.Collector`, for conventional metric registration. -* Support non-default/global Prometheus registry. -* Allow configuring counters with `prometheus.CounterOpts`. - -### Changed - -* Remove usage of deprecated `grpc.Code()`. -* Remove usage of deprecated `grpc.Errorf` and replace with `status.Errorf`. - ---- - -This changelog was started with version `v1.2.0`, for earlier versions refer to the respective [GitHub releases](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases). diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md deleted file mode 100644 index 2b2824028c..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md +++ /dev/null @@ -1,256 +0,0 @@ -# Go gRPC Interceptors for Prometheus monitoring - -[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus.svg)](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus) -[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-prometheus)](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus) -[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus) -[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge) -[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus) -[![Slack](https://img.shields.io/badge/join%20slack-%23go--grpc--prometheus-brightgreen.svg)](https://join.slack.com/t/improbable-eng/shared_invite/enQtMzQ1ODcyMzQ5MjM4LWY5ZWZmNGM2ODc5MmViNmQ3ZTA3ZTY3NzQwOTBlMTkzZmIxZTIxODk0OWU3YjZhNWVlNDU3MDlkZGViZjhkMjc) -[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) - -> :warning: We consolidating projects and moving to single repo where we have more control and awareness. We are moving this codebase for longterm to https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2. Existing state of Prometheus middleware was moved to https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2/providers/openmetrics -If you want to change something effectively long term, I would suggest proposing PR against https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2/providers/openmetrics instead (notice `v2 `branch, not master!). - - - - -[Prometheus](https://prometheus.io/) monitoring for your [gRPC Go](https://github.com/grpc/grpc-go) servers and clients. - -A sister implementation for [gRPC Java](https://github.com/grpc/grpc-java) (same metrics, same semantics) is in [grpc-ecosystem/java-grpc-prometheus](https://github.com/grpc-ecosystem/java-grpc-prometheus). - -## Interceptors - -[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for Interceptors, i.e. middleware that is executed -by a gRPC Server before the request is passed onto the user's application logic. It is a perfect way to implement -common patterns: auth, logging and... monitoring. - -To use Interceptors in chains, please see [`go-grpc-middleware`](https://github.com/mwitkow/go-grpc-middleware). - -This library requires Go 1.9 or later. - -## Usage - -There are two types of interceptors: client-side and server-side. This package provides monitoring Interceptors for both. - -### Server-side - -```go -import "github.com/grpc-ecosystem/go-grpc-prometheus" -... - // Initialize your gRPC server's interceptor. - myServer := grpc.NewServer( - grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor), - grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor), - ) - // Register your gRPC service implementations. - myservice.RegisterMyServiceServer(s.server, &myServiceImpl{}) - // After all your registrations, make sure all of the Prometheus metrics are initialized. - grpc_prometheus.Register(myServer) - // Register Prometheus metrics handler. - http.Handle("/metrics", promhttp.Handler()) -... -``` - -### Client-side - -```go -import "github.com/grpc-ecosystem/go-grpc-prometheus" -... - clientConn, err = grpc.Dial( - address, - grpc.WithUnaryInterceptor(grpc_prometheus.UnaryClientInterceptor), - grpc.WithStreamInterceptor(grpc_prometheus.StreamClientInterceptor) - ) - client = pb_testproto.NewTestServiceClient(clientConn) - resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"}) -... -``` - -# Metrics - -## Labels - -All server-side metrics start with `grpc_server` as Prometheus subsystem name. All client-side metrics start with `grpc_client`. Both of them have mirror-concepts. Similarly all methods -contain the same rich labels: - - * `grpc_service` - the [gRPC service](http://www.grpc.io/docs/#defining-a-service) name, which is the combination of protobuf `package` and - the `grpc_service` section name. E.g. for `package = mwitkow.testproto` and - `service TestService` the label will be `grpc_service="mwitkow.testproto.TestService"` - * `grpc_method` - the name of the method called on the gRPC service. E.g. - `grpc_method="Ping"` - * `grpc_type` - the gRPC [type of request](http://www.grpc.io/docs/guides/concepts.html#rpc-life-cycle). - Differentiating between the two is important especially for latency measurements. - - - `unary` is single request, single response RPC - - `client_stream` is a multi-request, single response RPC - - `server_stream` is a single request, multi-response RPC - - `bidi_stream` is a multi-request, multi-response RPC - - -Additionally for completed RPCs, the following labels are used: - - * `grpc_code` - the human-readable [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go). - The list of all statuses is to long, but here are some common ones: - - - `OK` - means the RPC was successful - - `IllegalArgument` - RPC contained bad values - - `Internal` - server-side error not disclosed to the clients - -## Counters - -The counters and their up to date documentation is in [server_reporter.go](server_reporter.go) and [client_reporter.go](client_reporter.go) -the respective Prometheus handler (usually `/metrics`). - -For the purpose of this documentation we will only discuss `grpc_server` metrics. The `grpc_client` ones contain mirror concepts. - -For simplicity, let's assume we're tracking a single server-side RPC call of [`mwitkow.testproto.TestService`](examples/testproto/test.proto), -calling the method `PingList`. The call succeeds and returns 20 messages in the stream. - -First, immediately after the server receives the call it will increment the -`grpc_server_started_total` and start the handling time clock (if histograms are enabled). - -```jsoniq -grpc_server_started_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 -``` - -Then the user logic gets invoked. It receives one message from the client containing the request -(it's a `server_stream`): - -```jsoniq -grpc_server_msg_received_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 -``` - -The user logic may return an error, or send multiple messages back to the client. In this case, on -each of the 20 messages sent back, a counter will be incremented: - -```jsoniq -grpc_server_msg_sent_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 20 -``` - -After the call completes, its status (`OK` or other [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go)) -and the relevant call labels increment the `grpc_server_handled_total` counter. - -```jsoniq -grpc_server_handled_total{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 -``` - -## Histograms - -[Prometheus histograms](https://prometheus.io/docs/concepts/metric_types/#histogram) are a great way -to measure latency distributions of your RPCs. However, since it is bad practice to have metrics -of [high cardinality](https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels) -the latency monitoring metrics are disabled by default. To enable them please call the following -in your server initialization code: - -```jsoniq -grpc_prometheus.EnableHandlingTimeHistogram() -``` - -After the call completes, its handling time will be recorded in a [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) -variable `grpc_server_handling_seconds`. The histogram variable contains three sub-metrics: - - * `grpc_server_handling_seconds_count` - the count of all completed RPCs by status and method - * `grpc_server_handling_seconds_sum` - cumulative time of RPCs by status and method, useful for - calculating average handling times - * `grpc_server_handling_seconds_bucket` - contains the counts of RPCs by status and method in respective - handling-time buckets. These buckets can be used by Prometheus to estimate SLAs (see [here](https://prometheus.io/docs/practices/histograms/)) - -The counter values will look as follows: - -```jsoniq -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.005"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.01"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.025"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.05"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.1"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.25"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.5"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="1"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="2.5"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="5"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="10"} 1 -grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="+Inf"} 1 -grpc_server_handling_seconds_sum{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 0.0003866430000000001 -grpc_server_handling_seconds_count{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 -``` - - -## Useful query examples - -Prometheus philosophy is to provide raw metrics to the monitoring system, and -let the aggregations be handled there. The verbosity of above metrics make it possible to have that -flexibility. Here's a couple of useful monitoring queries: - - -### request inbound rate -```jsoniq -sum(rate(grpc_server_started_total{job="foo"}[1m])) by (grpc_service) -``` -For `job="foo"` (common label to differentiate between Prometheus monitoring targets), calculate the -rate of requests per second (1 minute window) for each gRPC `grpc_service` that the job has. Please note -how the `grpc_method` is being omitted here: all methods of a given gRPC service will be summed together. - -### unary request error rate -```jsoniq -sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) -``` -For `job="foo"`, calculate the per-`grpc_service` rate of `unary` (1:1) RPCs that failed, i.e. the -ones that didn't finish with `OK` code. - -### unary request error percentage -```jsoniq -sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) - / -sum(rate(grpc_server_started_total{job="foo",grpc_type="unary"}[1m])) by (grpc_service) - * 100.0 -``` -For `job="foo"`, calculate the percentage of failed requests by service. It's easy to notice that -this is a combination of the two above examples. This is an example of a query you would like to -[alert on](https://prometheus.io/docs/alerting/rules/) in your system for SLA violations, e.g. -"no more than 1% requests should fail". - -### average response stream size -```jsoniq -sum(rate(grpc_server_msg_sent_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) - / -sum(rate(grpc_server_started_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) -``` -For `job="foo"` what is the `grpc_service`-wide `10m` average of messages returned for all ` -server_stream` RPCs. This allows you to track the stream sizes returned by your system, e.g. allows -you to track when clients started to send "wide" queries that ret -Note the divisor is the number of started RPCs, in order to account for in-flight requests. - -### 99%-tile latency of unary requests -```jsoniq -histogram_quantile(0.99, - sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary"}[5m])) by (grpc_service,le) -) -``` -For `job="foo"`, returns an 99%-tile [quantile estimation](https://prometheus.io/docs/practices/histograms/#quantiles) -of the handling time of RPCs per service. Please note the `5m` rate, this means that the quantile -estimation will take samples in a rolling `5m` window. When combined with other quantiles -(e.g. 50%, 90%), this query gives you tremendous insight into the responsiveness of your system -(e.g. impact of caching). - -### percentage of slow unary queries (>250ms) -```jsoniq -100.0 - ( -sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary",le="0.25"}[5m])) by (grpc_service) - / -sum(rate(grpc_server_handling_seconds_count{job="foo",grpc_type="unary"}[5m])) by (grpc_service) -) * 100.0 -``` -For `job="foo"` calculate the by-`grpc_service` fraction of slow requests that took longer than `0.25` -seconds. This query is relatively complex, since the Prometheus aggregations use `le` (less or equal) -buckets, meaning that counting "fast" requests fractions is easier. However, simple maths helps. -This is an example of a query you would like to alert on in your system for SLA violations, -e.g. "less than 1% of requests are slower than 250ms". - - -## Status - -This code has been used since August 2015 as the basis for monitoring of *production* gRPC micro services at [Improbable](https://improbable.io). - -## License - -`go-grpc-prometheus` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go deleted file mode 100644 index dc1a6e6f66..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -// gRPC Prometheus monitoring interceptors for client-side gRPC. - -package grpc_prometheus - -import ( - prom "github.com/prometheus/client_golang/prometheus" -) - -var ( - // DefaultClientMetrics is the default instance of ClientMetrics. It is - // intended to be used in conjunction the default Prometheus metrics - // registry. - DefaultClientMetrics = NewClientMetrics() - - // UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. - UnaryClientInterceptor = DefaultClientMetrics.UnaryClientInterceptor() - - // StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. - StreamClientInterceptor = DefaultClientMetrics.StreamClientInterceptor() -) - -func init() { - prom.MustRegister(DefaultClientMetrics.clientStartedCounter) - prom.MustRegister(DefaultClientMetrics.clientHandledCounter) - prom.MustRegister(DefaultClientMetrics.clientStreamMsgReceived) - prom.MustRegister(DefaultClientMetrics.clientStreamMsgSent) -} - -// EnableClientHandlingTimeHistogram turns on recording of handling time of -// RPCs. Histogram metrics can be very expensive for Prometheus to retain and -// query. This function acts on the DefaultClientMetrics variable and the -// default Prometheus metrics registry. -func EnableClientHandlingTimeHistogram(opts ...HistogramOption) { - DefaultClientMetrics.EnableClientHandlingTimeHistogram(opts...) - prom.Register(DefaultClientMetrics.clientHandledHistogram) -} - -// EnableClientStreamReceiveTimeHistogram turns on recording of -// single message receive time of streaming RPCs. -// This function acts on the DefaultClientMetrics variable and the -// default Prometheus metrics registry. -func EnableClientStreamReceiveTimeHistogram(opts ...HistogramOption) { - DefaultClientMetrics.EnableClientStreamReceiveTimeHistogram(opts...) - prom.Register(DefaultClientMetrics.clientStreamRecvHistogram) -} - -// EnableClientStreamSendTimeHistogram turns on recording of -// single message send time of streaming RPCs. -// This function acts on the DefaultClientMetrics variable and the -// default Prometheus metrics registry. -func EnableClientStreamSendTimeHistogram(opts ...HistogramOption) { - DefaultClientMetrics.EnableClientStreamSendTimeHistogram(opts...) - prom.Register(DefaultClientMetrics.clientStreamSendHistogram) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go deleted file mode 100644 index a344084262..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go +++ /dev/null @@ -1,244 +0,0 @@ -package grpc_prometheus - -import ( - "context" - "io" - - prom "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -// ClientMetrics represents a collection of metrics to be registered on a -// Prometheus metrics registry for a gRPC client. -type ClientMetrics struct { - clientStartedCounter *prom.CounterVec - clientHandledCounter *prom.CounterVec - clientStreamMsgReceived *prom.CounterVec - clientStreamMsgSent *prom.CounterVec - - clientHandledHistogramEnabled bool - clientHandledHistogramOpts prom.HistogramOpts - clientHandledHistogram *prom.HistogramVec - - clientStreamRecvHistogramEnabled bool - clientStreamRecvHistogramOpts prom.HistogramOpts - clientStreamRecvHistogram *prom.HistogramVec - - clientStreamSendHistogramEnabled bool - clientStreamSendHistogramOpts prom.HistogramOpts - clientStreamSendHistogram *prom.HistogramVec -} - -// NewClientMetrics returns a ClientMetrics object. Use a new instance of -// ClientMetrics when not using the default Prometheus metrics registry, for -// example when wanting to control which metrics are added to a registry as -// opposed to automatically adding metrics via init functions. -func NewClientMetrics(counterOpts ...CounterOption) *ClientMetrics { - opts := counterOptions(counterOpts) - return &ClientMetrics{ - clientStartedCounter: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_client_started_total", - Help: "Total number of RPCs started on the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientHandledCounter: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_client_handled_total", - Help: "Total number of RPCs completed by the client, regardless of success or failure.", - }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), - - clientStreamMsgReceived: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_client_msg_received_total", - Help: "Total number of RPC stream messages received by the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientStreamMsgSent: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_client_msg_sent_total", - Help: "Total number of gRPC stream messages sent by the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientHandledHistogramEnabled: false, - clientHandledHistogramOpts: prom.HistogramOpts{ - Name: "grpc_client_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", - Buckets: prom.DefBuckets, - }, - clientHandledHistogram: nil, - clientStreamRecvHistogramEnabled: false, - clientStreamRecvHistogramOpts: prom.HistogramOpts{ - Name: "grpc_client_msg_recv_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC single message receive.", - Buckets: prom.DefBuckets, - }, - clientStreamRecvHistogram: nil, - clientStreamSendHistogramEnabled: false, - clientStreamSendHistogramOpts: prom.HistogramOpts{ - Name: "grpc_client_msg_send_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC single message send.", - Buckets: prom.DefBuckets, - }, - clientStreamSendHistogram: nil, - } -} - -// Describe sends the super-set of all possible descriptors of metrics -// collected by this Collector to the provided channel and returns once -// the last descriptor has been sent. -func (m *ClientMetrics) Describe(ch chan<- *prom.Desc) { - m.clientStartedCounter.Describe(ch) - m.clientHandledCounter.Describe(ch) - m.clientStreamMsgReceived.Describe(ch) - m.clientStreamMsgSent.Describe(ch) - if m.clientHandledHistogramEnabled { - m.clientHandledHistogram.Describe(ch) - } - if m.clientStreamRecvHistogramEnabled { - m.clientStreamRecvHistogram.Describe(ch) - } - if m.clientStreamSendHistogramEnabled { - m.clientStreamSendHistogram.Describe(ch) - } -} - -// Collect is called by the Prometheus registry when collecting -// metrics. The implementation sends each collected metric via the -// provided channel and returns once the last metric has been sent. -func (m *ClientMetrics) Collect(ch chan<- prom.Metric) { - m.clientStartedCounter.Collect(ch) - m.clientHandledCounter.Collect(ch) - m.clientStreamMsgReceived.Collect(ch) - m.clientStreamMsgSent.Collect(ch) - if m.clientHandledHistogramEnabled { - m.clientHandledHistogram.Collect(ch) - } - if m.clientStreamRecvHistogramEnabled { - m.clientStreamRecvHistogram.Collect(ch) - } - if m.clientStreamSendHistogramEnabled { - m.clientStreamSendHistogram.Collect(ch) - } -} - -// EnableClientHandlingTimeHistogram turns on recording of handling time of RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func (m *ClientMetrics) EnableClientHandlingTimeHistogram(opts ...HistogramOption) { - for _, o := range opts { - o(&m.clientHandledHistogramOpts) - } - if !m.clientHandledHistogramEnabled { - m.clientHandledHistogram = prom.NewHistogramVec( - m.clientHandledHistogramOpts, - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } - m.clientHandledHistogramEnabled = true -} - -// EnableClientStreamReceiveTimeHistogram turns on recording of single message receive time of streaming RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func (m *ClientMetrics) EnableClientStreamReceiveTimeHistogram(opts ...HistogramOption) { - for _, o := range opts { - o(&m.clientStreamRecvHistogramOpts) - } - - if !m.clientStreamRecvHistogramEnabled { - m.clientStreamRecvHistogram = prom.NewHistogramVec( - m.clientStreamRecvHistogramOpts, - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } - - m.clientStreamRecvHistogramEnabled = true -} - -// EnableClientStreamSendTimeHistogram turns on recording of single message send time of streaming RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func (m *ClientMetrics) EnableClientStreamSendTimeHistogram(opts ...HistogramOption) { - for _, o := range opts { - o(&m.clientStreamSendHistogramOpts) - } - - if !m.clientStreamSendHistogramEnabled { - m.clientStreamSendHistogram = prom.NewHistogramVec( - m.clientStreamSendHistogramOpts, - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } - - m.clientStreamSendHistogramEnabled = true -} - -// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. -func (m *ClientMetrics) UnaryClientInterceptor() func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - monitor := newClientReporter(m, Unary, method) - monitor.SentMessage() - err := invoker(ctx, method, req, reply, cc, opts...) - if err == nil { - monitor.ReceivedMessage() - } - st, _ := status.FromError(err) - monitor.Handled(st.Code()) - return err - } -} - -// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. -func (m *ClientMetrics) StreamClientInterceptor() func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - monitor := newClientReporter(m, clientStreamType(desc), method) - clientStream, err := streamer(ctx, desc, cc, method, opts...) - if err != nil { - st, _ := status.FromError(err) - monitor.Handled(st.Code()) - return nil, err - } - return &monitoredClientStream{clientStream, monitor}, nil - } -} - -func clientStreamType(desc *grpc.StreamDesc) grpcType { - if desc.ClientStreams && !desc.ServerStreams { - return ClientStream - } else if !desc.ClientStreams && desc.ServerStreams { - return ServerStream - } - return BidiStream -} - -// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to increment counters. -type monitoredClientStream struct { - grpc.ClientStream - monitor *clientReporter -} - -func (s *monitoredClientStream) SendMsg(m interface{}) error { - timer := s.monitor.SendMessageTimer() - err := s.ClientStream.SendMsg(m) - timer.ObserveDuration() - if err == nil { - s.monitor.SentMessage() - } - return err -} - -func (s *monitoredClientStream) RecvMsg(m interface{}) error { - timer := s.monitor.ReceiveMessageTimer() - err := s.ClientStream.RecvMsg(m) - timer.ObserveDuration() - - if err == nil { - s.monitor.ReceivedMessage() - } else if err == io.EOF { - s.monitor.Handled(codes.OK) - } else { - st, _ := status.FromError(err) - s.monitor.Handled(st.Code()) - } - return err -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go deleted file mode 100644 index 286d6571ca..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_prometheus - -import ( - "time" - - "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc/codes" -) - -type clientReporter struct { - metrics *ClientMetrics - rpcType grpcType - serviceName string - methodName string - startTime time.Time -} - -func newClientReporter(m *ClientMetrics, rpcType grpcType, fullMethod string) *clientReporter { - r := &clientReporter{ - metrics: m, - rpcType: rpcType, - } - if r.metrics.clientHandledHistogramEnabled { - r.startTime = time.Now() - } - r.serviceName, r.methodName = splitMethodName(fullMethod) - r.metrics.clientStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() - return r -} - -// timer is a helper interface to time functions. -type timer interface { - ObserveDuration() time.Duration -} - -type noOpTimer struct { -} - -func (noOpTimer) ObserveDuration() time.Duration { - return 0 -} - -var emptyTimer = noOpTimer{} - -func (r *clientReporter) ReceiveMessageTimer() timer { - if r.metrics.clientStreamRecvHistogramEnabled { - hist := r.metrics.clientStreamRecvHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName) - return prometheus.NewTimer(hist) - } - - return emptyTimer -} - -func (r *clientReporter) ReceivedMessage() { - r.metrics.clientStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() -} - -func (r *clientReporter) SendMessageTimer() timer { - if r.metrics.clientStreamSendHistogramEnabled { - hist := r.metrics.clientStreamSendHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName) - return prometheus.NewTimer(hist) - } - - return emptyTimer -} - -func (r *clientReporter) SentMessage() { - r.metrics.clientStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() -} - -func (r *clientReporter) Handled(code codes.Code) { - r.metrics.clientHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() - if r.metrics.clientHandledHistogramEnabled { - r.metrics.clientHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile deleted file mode 100644 index 6cfc8d27fe..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile +++ /dev/null @@ -1,14 +0,0 @@ -GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/) - -all: vet fmt test - -fmt: - go fmt $(GOFILES_NOVENDOR) - -vet: - go vet $(GOFILES_NOVENDOR) - -test: vet - ./scripts/test_all.sh - -.PHONY: all vet test diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go deleted file mode 100644 index 9d51aec981..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go +++ /dev/null @@ -1,41 +0,0 @@ -package grpc_prometheus - -import ( - prom "github.com/prometheus/client_golang/prometheus" -) - -// A CounterOption lets you add options to Counter metrics using With* funcs. -type CounterOption func(*prom.CounterOpts) - -type counterOptions []CounterOption - -func (co counterOptions) apply(o prom.CounterOpts) prom.CounterOpts { - for _, f := range co { - f(&o) - } - return o -} - -// WithConstLabels allows you to add ConstLabels to Counter metrics. -func WithConstLabels(labels prom.Labels) CounterOption { - return func(o *prom.CounterOpts) { - o.ConstLabels = labels - } -} - -// A HistogramOption lets you add options to Histogram metrics using With* -// funcs. -type HistogramOption func(*prom.HistogramOpts) - -// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. -func WithHistogramBuckets(buckets []float64) HistogramOption { - return func(o *prom.HistogramOpts) { o.Buckets = buckets } -} - -// WithHistogramConstLabels allows you to add custom ConstLabels to -// histograms metrics. -func WithHistogramConstLabels(labels prom.Labels) HistogramOption { - return func(o *prom.HistogramOpts) { - o.ConstLabels = labels - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/grpcstatus.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/grpcstatus.go deleted file mode 100644 index 6c0f285f15..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/grpcstatus.go +++ /dev/null @@ -1,57 +0,0 @@ -package grpcstatus - -import ( - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type gRPCStatus interface { - GRPCStatus() *status.Status -} - -func unwrapPkgErrorsGRPCStatus(err error) (*status.Status, bool) { - type causer interface { - Cause() error - } - - // Unwrapping the github.com/pkg/errors causer interface, using `Cause` directly could miss some error implementing - // the `GRPCStatus` function so we have to check it on our selves. - unwrappedCauser := err - for unwrappedCauser != nil { - if s, ok := unwrappedCauser.(gRPCStatus); ok { - return s.GRPCStatus(), true - } - cause, ok := unwrappedCauser.(causer) - if !ok { - break - } - unwrappedCauser = cause.Cause() - } - return nil, false -} - -// Since error can be wrapped and the `FromError` function only checks for `GRPCStatus` function -// and as a fallback uses the `Unknown` gRPC status we need to unwrap the error if possible to get the original status. -// pkg/errors and Go native errors packages have two different approaches so we try to unwrap both types. -// Eventually should be implemented in the go-grpc status function `FromError`. See https://github.com/grpc/grpc-go/issues/2934 -func FromError(err error) (s *status.Status, ok bool) { - s, ok = status.FromError(err) - if ok { - return s, true - } - - // Try to unwrap `github.com/pkg/errors` wrapped error - s, ok = unwrapPkgErrorsGRPCStatus(err) - if ok { - return s, true - } - - // Try to unwrap native wrapped errors using `fmt.Errorf` and `%w` - s, ok = unwrapNativeWrappedGRPCStatus(err) - if ok { - return s, true - } - - // We failed to unwrap any GRPSStatus so return default `Unknown` - return status.New(codes.Unknown, err.Error()), false -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.12-.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.12-.go deleted file mode 100644 index 0f575fe294..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.12-.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !go1.13 - -package grpcstatus - -import ( - "google.golang.org/grpc/status" -) - -func unwrapNativeWrappedGRPCStatus(err error) (*status.Status, bool) { - return nil, false -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.13+.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.13+.go deleted file mode 100644 index 216d057e89..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus/native_unwrap1.13+.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build go1.13 - -package grpcstatus - -import ( - "errors" - "google.golang.org/grpc/status" -) - -func unwrapNativeWrappedGRPCStatus(err error) (*status.Status, bool) { - // Unwrapping the native Go unwrap interface - var unwrappedStatus gRPCStatus - if ok := errors.As(err, &unwrappedStatus); ok { - return unwrappedStatus.GRPCStatus(), true - } - return nil, false -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go deleted file mode 100644 index 322f99046f..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -// gRPC Prometheus monitoring interceptors for server-side gRPC. - -package grpc_prometheus - -import ( - prom "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" -) - -var ( - // DefaultServerMetrics is the default instance of ServerMetrics. It is - // intended to be used in conjunction the default Prometheus metrics - // registry. - DefaultServerMetrics = NewServerMetrics() - - // UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. - UnaryServerInterceptor = DefaultServerMetrics.UnaryServerInterceptor() - - // StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. - StreamServerInterceptor = DefaultServerMetrics.StreamServerInterceptor() -) - -func init() { - prom.MustRegister(DefaultServerMetrics.serverStartedCounter) - prom.MustRegister(DefaultServerMetrics.serverHandledCounter) - prom.MustRegister(DefaultServerMetrics.serverStreamMsgReceived) - prom.MustRegister(DefaultServerMetrics.serverStreamMsgSent) -} - -// Register takes a gRPC server and pre-initializes all counters to 0. This -// allows for easier monitoring in Prometheus (no missing metrics), and should -// be called *after* all services have been registered with the server. This -// function acts on the DefaultServerMetrics variable. -func Register(server *grpc.Server) { - DefaultServerMetrics.InitializeMetrics(server) -} - -// EnableHandlingTimeHistogram turns on recording of handling time -// of RPCs. Histogram metrics can be very expensive for Prometheus -// to retain and query. This function acts on the DefaultServerMetrics -// variable and the default Prometheus metrics registry. -func EnableHandlingTimeHistogram(opts ...HistogramOption) { - DefaultServerMetrics.EnableHandlingTimeHistogram(opts...) - prom.Register(DefaultServerMetrics.serverHandledHistogram) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go deleted file mode 100644 index d28a46e89b..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go +++ /dev/null @@ -1,186 +0,0 @@ -package grpc_prometheus - -import ( - "context" - "github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus" - prom "github.com/prometheus/client_golang/prometheus" - - "google.golang.org/grpc" -) - -// ServerMetrics represents a collection of metrics to be registered on a -// Prometheus metrics registry for a gRPC server. -type ServerMetrics struct { - serverStartedCounter *prom.CounterVec - serverHandledCounter *prom.CounterVec - serverStreamMsgReceived *prom.CounterVec - serverStreamMsgSent *prom.CounterVec - serverHandledHistogramEnabled bool - serverHandledHistogramOpts prom.HistogramOpts - serverHandledHistogram *prom.HistogramVec -} - -// NewServerMetrics returns a ServerMetrics object. Use a new instance of -// ServerMetrics when not using the default Prometheus metrics registry, for -// example when wanting to control which metrics are added to a registry as -// opposed to automatically adding metrics via init functions. -func NewServerMetrics(counterOpts ...CounterOption) *ServerMetrics { - opts := counterOptions(counterOpts) - return &ServerMetrics{ - serverStartedCounter: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_server_started_total", - Help: "Total number of RPCs started on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverHandledCounter: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_server_handled_total", - Help: "Total number of RPCs completed on the server, regardless of success or failure.", - }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), - serverStreamMsgReceived: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_server_msg_received_total", - Help: "Total number of RPC stream messages received on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverStreamMsgSent: prom.NewCounterVec( - opts.apply(prom.CounterOpts{ - Name: "grpc_server_msg_sent_total", - Help: "Total number of gRPC stream messages sent by the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverHandledHistogramEnabled: false, - serverHandledHistogramOpts: prom.HistogramOpts{ - Name: "grpc_server_handling_seconds", - Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", - Buckets: prom.DefBuckets, - }, - serverHandledHistogram: nil, - } -} - -// EnableHandlingTimeHistogram enables histograms being registered when -// registering the ServerMetrics on a Prometheus registry. Histograms can be -// expensive on Prometheus servers. It takes options to configure histogram -// options such as the defined buckets. -func (m *ServerMetrics) EnableHandlingTimeHistogram(opts ...HistogramOption) { - for _, o := range opts { - o(&m.serverHandledHistogramOpts) - } - if !m.serverHandledHistogramEnabled { - m.serverHandledHistogram = prom.NewHistogramVec( - m.serverHandledHistogramOpts, - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } - m.serverHandledHistogramEnabled = true -} - -// Describe sends the super-set of all possible descriptors of metrics -// collected by this Collector to the provided channel and returns once -// the last descriptor has been sent. -func (m *ServerMetrics) Describe(ch chan<- *prom.Desc) { - m.serverStartedCounter.Describe(ch) - m.serverHandledCounter.Describe(ch) - m.serverStreamMsgReceived.Describe(ch) - m.serverStreamMsgSent.Describe(ch) - if m.serverHandledHistogramEnabled { - m.serverHandledHistogram.Describe(ch) - } -} - -// Collect is called by the Prometheus registry when collecting -// metrics. The implementation sends each collected metric via the -// provided channel and returns once the last metric has been sent. -func (m *ServerMetrics) Collect(ch chan<- prom.Metric) { - m.serverStartedCounter.Collect(ch) - m.serverHandledCounter.Collect(ch) - m.serverStreamMsgReceived.Collect(ch) - m.serverStreamMsgSent.Collect(ch) - if m.serverHandledHistogramEnabled { - m.serverHandledHistogram.Collect(ch) - } -} - -// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. -func (m *ServerMetrics) UnaryServerInterceptor() func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - monitor := newServerReporter(m, Unary, info.FullMethod) - monitor.ReceivedMessage() - resp, err := handler(ctx, req) - st, _ := grpcstatus.FromError(err) - monitor.Handled(st.Code()) - if err == nil { - monitor.SentMessage() - } - return resp, err - } -} - -// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. -func (m *ServerMetrics) StreamServerInterceptor() func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - monitor := newServerReporter(m, streamRPCType(info), info.FullMethod) - err := handler(srv, &monitoredServerStream{ss, monitor}) - st, _ := grpcstatus.FromError(err) - monitor.Handled(st.Code()) - return err - } -} - -// InitializeMetrics initializes all metrics, with their appropriate null -// value, for all gRPC methods registered on a gRPC server. This is useful, to -// ensure that all metrics exist when collecting and querying. -func (m *ServerMetrics) InitializeMetrics(server *grpc.Server) { - serviceInfo := server.GetServiceInfo() - for serviceName, info := range serviceInfo { - for _, mInfo := range info.Methods { - preRegisterMethod(m, serviceName, &mInfo) - } - } -} - -func streamRPCType(info *grpc.StreamServerInfo) grpcType { - if info.IsClientStream && !info.IsServerStream { - return ClientStream - } else if !info.IsClientStream && info.IsServerStream { - return ServerStream - } - return BidiStream -} - -// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to increment counters. -type monitoredServerStream struct { - grpc.ServerStream - monitor *serverReporter -} - -func (s *monitoredServerStream) SendMsg(m interface{}) error { - err := s.ServerStream.SendMsg(m) - if err == nil { - s.monitor.SentMessage() - } - return err -} - -func (s *monitoredServerStream) RecvMsg(m interface{}) error { - err := s.ServerStream.RecvMsg(m) - if err == nil { - s.monitor.ReceivedMessage() - } - return err -} - -// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated. -func preRegisterMethod(metrics *ServerMetrics, serviceName string, mInfo *grpc.MethodInfo) { - methodName := mInfo.Name - methodType := string(typeFromMethodInfo(mInfo)) - // These are just references (no increments), as just referencing will create the labels but not set values. - metrics.serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName) - metrics.serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName) - metrics.serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName) - if metrics.serverHandledHistogramEnabled { - metrics.serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName) - } - for _, code := range allCodes { - metrics.serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String()) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go deleted file mode 100644 index aa9db5401a..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_prometheus - -import ( - "time" - - "google.golang.org/grpc/codes" -) - -type serverReporter struct { - metrics *ServerMetrics - rpcType grpcType - serviceName string - methodName string - startTime time.Time -} - -func newServerReporter(m *ServerMetrics, rpcType grpcType, fullMethod string) *serverReporter { - r := &serverReporter{ - metrics: m, - rpcType: rpcType, - } - if r.metrics.serverHandledHistogramEnabled { - r.startTime = time.Now() - } - r.serviceName, r.methodName = splitMethodName(fullMethod) - r.metrics.serverStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() - return r -} - -func (r *serverReporter) ReceivedMessage() { - r.metrics.serverStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() -} - -func (r *serverReporter) SentMessage() { - r.metrics.serverStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() -} - -func (r *serverReporter) Handled(code codes.Code) { - r.metrics.serverHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() - if r.metrics.serverHandledHistogramEnabled { - r.metrics.serverHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go deleted file mode 100644 index 7987de35f4..0000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_prometheus - -import ( - "strings" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" -) - -type grpcType string - -const ( - Unary grpcType = "unary" - ClientStream grpcType = "client_stream" - ServerStream grpcType = "server_stream" - BidiStream grpcType = "bidi_stream" -) - -var ( - allCodes = []codes.Code{ - codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, - codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, - codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, - codes.Unavailable, codes.DataLoss, - } -) - -func splitMethodName(fullMethodName string) (string, string) { - fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash - if i := strings.Index(fullMethodName, "/"); i >= 0 { - return fullMethodName[:i], fullMethodName[i+1:] - } - return "unknown", "unknown" -} - -func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { - if !mInfo.IsClientStream && !mInfo.IsServerStream { - return Unary - } - if mInfo.IsClientStream && !mInfo.IsServerStream { - return ClientStream - } - if !mInfo.IsClientStream && mInfo.IsServerStream { - return ServerStream - } - return BidiStream -} diff --git a/vendor/github.com/karrick/godirwalk/.gitignore b/vendor/github.com/karrick/godirwalk/.gitignore deleted file mode 100644 index ea2d9ece60..0000000000 --- a/vendor/github.com/karrick/godirwalk/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -examples/remove-empty-directories/remove-empty-directories -examples/sizes/sizes -examples/walk-fast/walk-fast -examples/walk-stdlib/walk-stdlib diff --git a/vendor/github.com/karrick/godirwalk/LICENSE b/vendor/github.com/karrick/godirwalk/LICENSE deleted file mode 100644 index 01ce194c80..0000000000 --- a/vendor/github.com/karrick/godirwalk/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -BSD 2-Clause License - -Copyright (c) 2017, Karrick McDermott -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/karrick/godirwalk/README.md b/vendor/github.com/karrick/godirwalk/README.md deleted file mode 100644 index ccfb2cbaf2..0000000000 --- a/vendor/github.com/karrick/godirwalk/README.md +++ /dev/null @@ -1,324 +0,0 @@ -# godirwalk - -`godirwalk` is a library for traversing a directory tree on a file -system. - -[![GoDoc](https://godoc.org/github.com/karrick/godirwalk?status.svg)](https://godoc.org/github.com/karrick/godirwalk) [![Build Status](https://dev.azure.com/microsoft0235/microsoft/_apis/build/status/karrick.godirwalk?branchName=master)](https://dev.azure.com/microsoft0235/microsoft/_build/latest?definitionId=1&branchName=master) - -In short, why did I create this library? - -1. It's faster than `filepath.Walk`. -1. It's more correct on Windows than `filepath.Walk`. -1. It's more easy to use than `filepath.Walk`. -1. It's more flexible than `filepath.Walk`. - -Depending on your specific circumstances, [you might no longer need a -library for file walking in -Go](https://engineering.kablamo.com.au/posts/2021/quick-comparison-between-go-file-walk-implementations). - -## Usage Example - -Additional examples are provided in the `examples/` subdirectory. - -This library will normalize the provided top level directory name -based on the os-specific path separator by calling `filepath.Clean` on -its first argument. However it always provides the pathname created by -using the correct os-specific path separator when invoking the -provided callback function. - -```Go - dirname := "some/directory/root" - err := godirwalk.Walk(dirname, &godirwalk.Options{ - Callback: func(osPathname string, de *godirwalk.Dirent) error { - // Following string operation is not most performant way - // of doing this, but common enough to warrant a simple - // example here: - if strings.Contains(osPathname, ".git") { - return godirwalk.SkipThis - } - fmt.Printf("%s %s\n", de.ModeType(), osPathname) - return nil - }, - Unsorted: true, // (optional) set true for faster yet non-deterministic enumeration (see godoc) - }) -``` - -This library not only provides functions for traversing a file system -directory tree, but also for obtaining a list of immediate descendants -of a particular directory, typically much more quickly than using -`os.ReadDir` or `os.ReadDirnames`. - -## Description - -Here's why I use `godirwalk` in preference to `filepath.Walk`, -`os.ReadDir`, and `os.ReadDirnames`. - -### It's faster than `filepath.Walk` - -When compared against `filepath.Walk` in benchmarks, it has been -observed to run between five and ten times the speed on darwin, at -speeds comparable to the that of the unix `find` utility; and about -twice the speed on linux; and about four times the speed on Windows. - -How does it obtain this performance boost? It does less work to give -you nearly the same output. This library calls the same `syscall` -functions to do the work, but it makes fewer calls, does not throw -away information that it might need, and creates less memory churn -along the way by reusing the same scratch buffer for reading from a -directory rather than reallocating a new buffer every time it reads -file system entry data from the operating system. - -While traversing a file system directory tree, `filepath.Walk` obtains -the list of immediate descendants of a directory, and throws away the -node type information for the file system entry that is provided by -the operating system that comes with the node's name. Then, -immediately prior to invoking the callback function, `filepath.Walk` -invokes `os.Stat` for each node, and passes the returned `os.FileInfo` -information to the callback. - -While the `os.FileInfo` information provided by `os.Stat` is extremely -helpful--and even includes the `os.FileMode` data--providing it -requires an additional system call for each node. - -Because most callbacks only care about what the node type is, this -library does not throw the type information away, but rather provides -that information to the callback function in the form of a -`os.FileMode` value. Note that the provided `os.FileMode` value that -this library provides only has the node type information, and does not -have the permission bits, sticky bits, or other information from the -file's mode. If the callback does care about a particular node's -entire `os.FileInfo` data structure, the callback can easiy invoke -`os.Stat` when needed, and only when needed. - -#### Benchmarks - -##### macOS - -```Bash -$ go test -bench=. -benchmem -goos: darwin -goarch: amd64 -pkg: github.com/karrick/godirwalk -BenchmarkReadDirnamesStandardLibrary-12 50000 26250 ns/op 10360 B/op 16 allocs/op -BenchmarkReadDirnamesThisLibrary-12 50000 24372 ns/op 5064 B/op 20 allocs/op -BenchmarkFilepathWalk-12 1 1099524875 ns/op 228415912 B/op 416952 allocs/op -BenchmarkGodirwalk-12 2 526754589 ns/op 103110464 B/op 451442 allocs/op -BenchmarkGodirwalkUnsorted-12 3 509219296 ns/op 100751400 B/op 378800 allocs/op -BenchmarkFlameGraphFilepathWalk-12 1 7478618820 ns/op 2284138176 B/op 4169453 allocs/op -BenchmarkFlameGraphGodirwalk-12 1 4977264058 ns/op 1031105328 B/op 4514423 allocs/op -PASS -ok github.com/karrick/godirwalk 21.219s -``` - -##### Linux - -```Bash -$ go test -bench=. -benchmem -goos: linux -goarch: amd64 -pkg: github.com/karrick/godirwalk -BenchmarkReadDirnamesStandardLibrary-12 100000 15458 ns/op 10360 B/op 16 allocs/op -BenchmarkReadDirnamesThisLibrary-12 100000 14646 ns/op 5064 B/op 20 allocs/op -BenchmarkFilepathWalk-12 2 631034745 ns/op 228210216 B/op 416939 allocs/op -BenchmarkGodirwalk-12 3 358714883 ns/op 102988664 B/op 451437 allocs/op -BenchmarkGodirwalkUnsorted-12 3 355363915 ns/op 100629234 B/op 378796 allocs/op -BenchmarkFlameGraphFilepathWalk-12 1 6086913991 ns/op 2282104720 B/op 4169417 allocs/op -BenchmarkFlameGraphGodirwalk-12 1 3456398824 ns/op 1029886400 B/op 4514373 allocs/op -PASS -ok github.com/karrick/godirwalk 19.179s -``` - -### It's more correct on Windows than `filepath.Walk` - -I did not previously care about this either, but humor me. We all love -how we can write once and run everywhere. It is essential for the -language's adoption, growth, and success, that the software we create -can run unmodified on all architectures and operating systems -supported by Go. - -When the traversed file system has a logical loop caused by symbolic -links to directories, on unix `filepath.Walk` ignores symbolic links -and traverses the entire directory tree without error. On Windows -however, `filepath.Walk` will continue following directory symbolic -links, even though it is not supposed to, eventually causing -`filepath.Walk` to terminate early and return an error when the -pathname gets too long from concatenating endless loops of symbolic -links onto the pathname. This error comes from Windows, passes through -`filepath.Walk`, and to the upstream client running `filepath.Walk`. - -The takeaway is that behavior is different based on which platform -`filepath.Walk` is running. While this is clearly not intentional, -until it is fixed in the standard library, it presents a compatibility -problem. - -This library fixes the above problem such that it will never follow -logical file sytem loops on either unix or Windows. Furthermore, it -will only follow symbolic links when `FollowSymbolicLinks` is set to -true. Behavior on Windows and other operating systems is identical. - -### It's more easy to use than `filepath.Walk` - -While this library strives to mimic the behavior of the incredibly -well-written `filepath.Walk` standard library, there are places where -it deviates a bit in order to provide a more easy or intuitive caller -interface. - -#### Callback interface does not send you an error to check - -Since this library does not invoke `os.Stat` on every file system node -it encounters, there is no possible error event for the callback -function to filter on. The third argument in the `filepath.WalkFunc` -function signature to pass the error from `os.Stat` to the callback -function is no longer necessary, and thus eliminated from signature of -the callback function from this library. - -Furthermore, this slight interface difference between -`filepath.WalkFunc` and this library's `WalkFunc` eliminates the -boilerplate code that callback handlers must write when they use -`filepath.Walk`. Rather than every callback function needing to check -the error value passed into it and branch accordingly, users of this -library do not even have an error value to check immediately upon -entry into the callback function. This is an improvement both in -runtime performance and code clarity. - -#### Callback function is invoked with OS specific file system path separator - -On every OS platform `filepath.Walk` invokes the callback function -with a solidus (`/`) delimited pathname. By contrast this library -invokes the callback with the os-specific pathname separator, -obviating a call to `filepath.Clean` in the callback function for each -node prior to actually using the provided pathname. - -In other words, even on Windows, `filepath.Walk` will invoke the -callback with `some/path/to/foo.txt`, requiring well written clients -to perform pathname normalization for every file prior to working with -the specified file. This is a hidden boilerplate requirement to create -truly os agnostic callback functions. In truth, many clients developed -on unix and not tested on Windows neglect this subtlety, and will -result in software bugs when someone tries to run that software on -Windows. - -This library invokes the callback function with `some\path\to\foo.txt` -for the same file when running on Windows, eliminating the need to -normalize the pathname by the client, and lessen the likelyhood that a -client will work on unix but not on Windows. - -This enhancement eliminates necessity for some more boilerplate code -in callback functions while improving the runtime performance of this -library. - -#### `godirwalk.SkipThis` is more intuitive to use than `filepath.SkipDir` - -One arguably confusing aspect of the `filepath.WalkFunc` interface -that this library must emulate is how a caller tells the `Walk` -function to skip file system entries. With both `filepath.Walk` and -this library's `Walk`, when a callback function wants to skip a -directory and not descend into its children, it returns -`filepath.SkipDir`. If the callback function returns -`filepath.SkipDir` for a non-directory, `filepath.Walk` and this -library will stop processing any more entries in the current -directory. This is not necessarily what most developers want or -expect. If you want to simply skip a particular non-directory entry -but continue processing entries in the directory, the callback -function must return nil. - -The implications of this interface design is when you want to walk a -file system hierarchy and skip an entry, you have to return a -different value based on what type of file system entry that node -is. To skip an entry, if the entry is a directory, you must return -`filepath.SkipDir`, and if entry is not a directory, you must return -`nil`. This is an unfortunate hurdle I have observed many developers -struggling with, simply because it is not an intuitive interface. - -Here is an example callback function that adheres to -`filepath.WalkFunc` interface to have it skip any file system entry -whose full pathname includes a particular substring, `optSkip`. Note -that this library still supports identical behavior of `filepath.Walk` -when the callback function returns `filepath.SkipDir`. - -```Go - func callback1(osPathname string, de *godirwalk.Dirent) error { - if optSkip != "" && strings.Contains(osPathname, optSkip) { - if b, err := de.IsDirOrSymlinkToDir(); b == true && err == nil { - return filepath.SkipDir - } - return nil - } - // Process file like normal... - return nil - } -``` - -This library attempts to eliminate some of that logic boilerplate -required in callback functions by providing a new token error value, -`SkipThis`, which a callback function may return to skip the current -file system entry regardless of what type of entry it is. If the -current entry is a directory, its children will not be enumerated, -exactly as if the callback had returned `filepath.SkipDir`. If the -current entry is a non-directory, the next file system entry in the -current directory will be enumerated, exactly as if the callback -returned `nil`. The following example callback function has identical -behavior as the previous, but has less boilerplate, and admittedly -logic that I find more simple to follow. - -```Go - func callback2(osPathname string, de *godirwalk.Dirent) error { - if optSkip != "" && strings.Contains(osPathname, optSkip) { - return godirwalk.SkipThis - } - // Process file like normal... - return nil - } -``` - -### It's more flexible than `filepath.Walk` - -#### Configurable Handling of Symbolic Links - -The default behavior of this library is to ignore symbolic links to -directories when walking a directory tree, just like `filepath.Walk` -does. However, it does invoke the callback function with each node it -finds, including symbolic links. If a particular use case exists to -follow symbolic links when traversing a directory tree, this library -can be invoked in manner to do so, by setting the -`FollowSymbolicLinks` config parameter to `true`. - -#### Configurable Sorting of Directory Children - -The default behavior of this library is to always sort the immediate -descendants of a directory prior to visiting each node, just like -`filepath.Walk` does. This is usually the desired behavior. However, -this does come at slight performance and memory penalties required to -sort the names when a directory node has many entries. Additionally if -caller specifies `Unsorted` enumeration in the configuration -parameter, reading directories is lazily performed as the caller -consumes entries. If a particular use case exists that does not -require sorting the directory's immediate descendants prior to -visiting its nodes, this library will skip the sorting step when the -`Unsorted` parameter is set to `true`. - -Here's an interesting read of the potential hazzards of traversing a -file system hierarchy in a non-deterministic order. If you know the -problem you are solving is not affected by the order files are -visited, then I encourage you to use `Unsorted`. Otherwise skip -setting this option. - -[Researchers find bug in Python script may have affected hundreds of studies](https://arstechnica.com/information-technology/2019/10/chemists-discover-cross-platform-python-scripts-not-so-cross-platform/) - -#### Configurable Post Children Callback - -This library provides upstream code with the ability to specify a -callback function to be invoked for each directory after its children -are processed. This has been used to recursively delete empty -directories after traversing the file system in a more efficient -manner. See the `examples/clean-empties` directory for an example of -this usage. - -#### Configurable Error Callback - -This library provides upstream code with the ability to specify a -callback to be invoked for errors that the operating system returns, -allowing the upstream code to determine the next course of action to -take, whether to halt walking the hierarchy, as it would do were no -error callback provided, or skip the node that caused the error. See -the `examples/walk-fast` directory for an example of this usage. diff --git a/vendor/github.com/karrick/godirwalk/azure-pipelines.yml b/vendor/github.com/karrick/godirwalk/azure-pipelines.yml deleted file mode 100644 index d56f2484d6..0000000000 --- a/vendor/github.com/karrick/godirwalk/azure-pipelines.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Go -# Build your Go project. -# Add steps that test, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/go - -trigger: -- master - -variables: - GOVERSION: 1.13 - -jobs: - - job: Linux - pool: - vmImage: 'ubuntu-latest' - steps: - - task: GoTool@0 - displayName: 'Use Go $(GOVERSION)' - inputs: - version: $(GOVERSION) - - task: Go@0 - inputs: - command: test - arguments: -race -v ./... - displayName: 'Execute Tests' - - - job: Mac - pool: - vmImage: 'macos-latest' - steps: - - task: GoTool@0 - displayName: 'Use Go $(GOVERSION)' - inputs: - version: $(GOVERSION) - - task: Go@0 - inputs: - command: test - arguments: -race -v ./... - displayName: 'Execute Tests' - - - job: Windows - pool: - vmImage: 'windows-latest' - steps: - - task: GoTool@0 - displayName: 'Use Go $(GOVERSION)' - inputs: - version: $(GOVERSION) - - task: Go@0 - inputs: - command: test - arguments: -race -v ./... - displayName: 'Execute Tests' diff --git a/vendor/github.com/karrick/godirwalk/bench.sh b/vendor/github.com/karrick/godirwalk/bench.sh deleted file mode 100644 index b2ba374cf2..0000000000 --- a/vendor/github.com/karrick/godirwalk/bench.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# for version in v1.9.1 v1.10.0 v1.10.3 v1.10.12 v1.11.2 v1.11.3 v1.12.0 v1.13.1 v1.14.0 v1.14.1 ; do -for version in v1.10.12 v1.14.1 v1.15.2 ; do - echo "### $version" > $version.txt - git checkout -- go.mod && git checkout $version && go test -run=NONE -bench=Benchmark2 >> $version.txt || exit 1 -done diff --git a/vendor/github.com/karrick/godirwalk/debug_development.go b/vendor/github.com/karrick/godirwalk/debug_development.go deleted file mode 100644 index 6e1cb0bf7e..0000000000 --- a/vendor/github.com/karrick/godirwalk/debug_development.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build godirwalk_debug - -package godirwalk - -import ( - "fmt" - "os" -) - -// debug formats and prints arguments to stderr for development builds -func debug(f string, a ...interface{}) { - // fmt.Fprintf(os.Stderr, f, a...) - os.Stderr.Write([]byte("godirwalk: " + fmt.Sprintf(f, a...))) -} diff --git a/vendor/github.com/karrick/godirwalk/debug_release.go b/vendor/github.com/karrick/godirwalk/debug_release.go deleted file mode 100644 index 986178731f..0000000000 --- a/vendor/github.com/karrick/godirwalk/debug_release.go +++ /dev/null @@ -1,6 +0,0 @@ -// +build !godirwalk_debug - -package godirwalk - -// debug is a no-op for release builds -func debug(_ string, _ ...interface{}) {} diff --git a/vendor/github.com/karrick/godirwalk/dirent.go b/vendor/github.com/karrick/godirwalk/dirent.go deleted file mode 100644 index 38e141ba6b..0000000000 --- a/vendor/github.com/karrick/godirwalk/dirent.go +++ /dev/null @@ -1,104 +0,0 @@ -package godirwalk - -import ( - "os" - "path/filepath" -) - -// Dirent stores the name and file system mode type of discovered file system -// entries. -type Dirent struct { - name string // base name of the file system entry. - path string // path name of the file system entry. - modeType os.FileMode // modeType is the type of file system entry. -} - -// NewDirent returns a newly initialized Dirent structure, or an error. This -// function does not follow symbolic links. -// -// This function is rarely used, as Dirent structures are provided by other -// functions in this library that read and walk directories, but is provided, -// however, for the occasion when a program needs to create a Dirent. -func NewDirent(osPathname string) (*Dirent, error) { - modeType, err := modeType(osPathname) - if err != nil { - return nil, err - } - return &Dirent{ - name: filepath.Base(osPathname), - path: filepath.Dir(osPathname), - modeType: modeType, - }, nil -} - -// IsDir returns true if and only if the Dirent represents a file system -// directory. Note that on some operating systems, more than one file mode bit -// may be set for a node. For instance, on Windows, a symbolic link that points -// to a directory will have both the directory and the symbolic link bits set. -func (de Dirent) IsDir() bool { return de.modeType&os.ModeDir != 0 } - -// IsDirOrSymlinkToDir returns true if and only if the Dirent represents a file -// system directory, or a symbolic link to a directory. Note that if the Dirent -// is not a directory but is a symbolic link, this method will resolve by -// sending a request to the operating system to follow the symbolic link. -func (de Dirent) IsDirOrSymlinkToDir() (bool, error) { - if de.IsDir() { - return true, nil - } - if !de.IsSymlink() { - return false, nil - } - // Does this symlink point to a directory? - info, err := os.Stat(filepath.Join(de.path, de.name)) - if err != nil { - return false, err - } - return info.IsDir(), nil -} - -// IsRegular returns true if and only if the Dirent represents a regular file. -// That is, it ensures that no mode type bits are set. -func (de Dirent) IsRegular() bool { return de.modeType&os.ModeType == 0 } - -// IsSymlink returns true if and only if the Dirent represents a file system -// symbolic link. Note that on some operating systems, more than one file mode -// bit may be set for a node. For instance, on Windows, a symbolic link that -// points to a directory will have both the directory and the symbolic link bits -// set. -func (de Dirent) IsSymlink() bool { return de.modeType&os.ModeSymlink != 0 } - -// IsDevice returns true if and only if the Dirent represents a device file. -func (de Dirent) IsDevice() bool { return de.modeType&os.ModeDevice != 0 } - -// ModeType returns the mode bits that specify the file system node type. We -// could make our own enum-like data type for encoding the file type, but Go's -// runtime already gives us architecture independent file modes, as discussed in -// `os/types.go`: -// -// Go's runtime FileMode type has same definition on all systems, so that -// information about files can be moved from one system to another portably. -func (de Dirent) ModeType() os.FileMode { return de.modeType } - -// Name returns the base name of the file system entry. -func (de Dirent) Name() string { return de.name } - -// reset releases memory held by entry err and name, and resets mode type to 0. -func (de *Dirent) reset() { - de.name = "" - de.path = "" - de.modeType = 0 -} - -// Dirents represents a slice of Dirent pointers, which are sortable by base -// name. This type satisfies the `sort.Interface` interface. -type Dirents []*Dirent - -// Len returns the count of Dirent structures in the slice. -func (l Dirents) Len() int { return len(l) } - -// Less returns true if and only if the base name of the element specified by -// the first index is lexicographically less than that of the second index. -func (l Dirents) Less(i, j int) bool { return l[i].name < l[j].name } - -// Swap exchanges the two Dirent entries specified by the two provided indexes. -func (l Dirents) Swap(i, j int) { l[i], l[j] = l[j], l[i] } diff --git a/vendor/github.com/karrick/godirwalk/doc.go b/vendor/github.com/karrick/godirwalk/doc.go deleted file mode 100644 index 440aa82a3a..0000000000 --- a/vendor/github.com/karrick/godirwalk/doc.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Package godirwalk provides functions to read and traverse directory trees. - -In short, why do I use this library? - -* It's faster than `filepath.Walk`. - -* It's more correct on Windows than `filepath.Walk`. - -* It's more easy to use than `filepath.Walk`. - -* It's more flexible than `filepath.Walk`. - -USAGE - -This library will normalize the provided top level directory name based on the -os-specific path separator by calling `filepath.Clean` on its first -argument. However it always provides the pathname created by using the correct -os-specific path separator when invoking the provided callback function. - - dirname := "some/directory/root" - err := godirwalk.Walk(dirname, &godirwalk.Options{ - Callback: func(osPathname string, de *godirwalk.Dirent) error { - fmt.Printf("%s %s\n", de.ModeType(), osPathname) - return nil - }, - }) - -This library not only provides functions for traversing a file system directory -tree, but also for obtaining a list of immediate descendants of a particular -directory, typically much more quickly than using `os.ReadDir` or -`os.ReadDirnames`. - - scratchBuffer := make([]byte, godirwalk.MinimumScratchBufferSize) - - names, err := godirwalk.ReadDirnames("some/directory", scratchBuffer) - // ... - - entries, err := godirwalk.ReadDirents("another/directory", scratchBuffer) - // ... -*/ -package godirwalk diff --git a/vendor/github.com/karrick/godirwalk/inoWithFileno.go b/vendor/github.com/karrick/godirwalk/inoWithFileno.go deleted file mode 100644 index 1dc04a717a..0000000000 --- a/vendor/github.com/karrick/godirwalk/inoWithFileno.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build dragonfly freebsd openbsd netbsd - -package godirwalk - -import "syscall" - -func inoFromDirent(de *syscall.Dirent) uint64 { - return uint64(de.Fileno) -} diff --git a/vendor/github.com/karrick/godirwalk/inoWithIno.go b/vendor/github.com/karrick/godirwalk/inoWithIno.go deleted file mode 100644 index 842a6662d8..0000000000 --- a/vendor/github.com/karrick/godirwalk/inoWithIno.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build aix darwin linux nacl solaris - -package godirwalk - -import "syscall" - -func inoFromDirent(de *syscall.Dirent) uint64 { - return uint64(de.Ino) -} diff --git a/vendor/github.com/karrick/godirwalk/modeType.go b/vendor/github.com/karrick/godirwalk/modeType.go deleted file mode 100644 index 6427a6852c..0000000000 --- a/vendor/github.com/karrick/godirwalk/modeType.go +++ /dev/null @@ -1,22 +0,0 @@ -package godirwalk - -import ( - "os" -) - -// modeType returns the mode type of the file system entry identified by -// osPathname by calling os.LStat function, to intentionally not follow symbolic -// links. -// -// Even though os.LStat provides all file mode bits, we want to ensure same -// values returned to caller regardless of whether we obtained file mode bits -// from syscall or stat call. Therefore mask out the additional file mode bits -// that are provided by stat but not by the syscall, so users can rely on their -// values. -func modeType(osPathname string) (os.FileMode, error) { - fi, err := os.Lstat(osPathname) - if err == nil { - return fi.Mode() & os.ModeType, nil - } - return 0, err -} diff --git a/vendor/github.com/karrick/godirwalk/modeTypeWithType.go b/vendor/github.com/karrick/godirwalk/modeTypeWithType.go deleted file mode 100644 index 7890e7761b..0000000000 --- a/vendor/github.com/karrick/godirwalk/modeTypeWithType.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build darwin dragonfly freebsd linux netbsd openbsd - -package godirwalk - -import ( - "os" - "path/filepath" - "syscall" -) - -// modeTypeFromDirent converts a syscall defined constant, which is in purview -// of OS, to a constant defined by Go, assumed by this project to be stable. -// -// When the syscall constant is not recognized, this function falls back to a -// Stat on the file system. -func modeTypeFromDirent(de *syscall.Dirent, osDirname, osBasename string) (os.FileMode, error) { - switch de.Type { - case syscall.DT_REG: - return 0, nil - case syscall.DT_DIR: - return os.ModeDir, nil - case syscall.DT_LNK: - return os.ModeSymlink, nil - case syscall.DT_CHR: - return os.ModeDevice | os.ModeCharDevice, nil - case syscall.DT_BLK: - return os.ModeDevice, nil - case syscall.DT_FIFO: - return os.ModeNamedPipe, nil - case syscall.DT_SOCK: - return os.ModeSocket, nil - default: - // If syscall returned unknown type (e.g., DT_UNKNOWN, DT_WHT), then - // resolve actual mode by reading file information. - return modeType(filepath.Join(osDirname, osBasename)) - } -} diff --git a/vendor/github.com/karrick/godirwalk/modeTypeWithoutType.go b/vendor/github.com/karrick/godirwalk/modeTypeWithoutType.go deleted file mode 100644 index 5299392ee9..0000000000 --- a/vendor/github.com/karrick/godirwalk/modeTypeWithoutType.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build aix js nacl solaris - -package godirwalk - -import ( - "os" - "path/filepath" - "syscall" -) - -// modeTypeFromDirent converts a syscall defined constant, which is in purview -// of OS, to a constant defined by Go, assumed by this project to be stable. -// -// Because some operating system syscall.Dirent structures do not include a Type -// field, fall back on Stat of the file system. -func modeTypeFromDirent(_ *syscall.Dirent, osDirname, osBasename string) (os.FileMode, error) { - return modeType(filepath.Join(osDirname, osBasename)) -} diff --git a/vendor/github.com/karrick/godirwalk/nameWithNamlen.go b/vendor/github.com/karrick/godirwalk/nameWithNamlen.go deleted file mode 100644 index 2c0231eea7..0000000000 --- a/vendor/github.com/karrick/godirwalk/nameWithNamlen.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build aix darwin dragonfly freebsd netbsd openbsd - -package godirwalk - -import ( - "reflect" - "syscall" - "unsafe" -) - -func nameFromDirent(de *syscall.Dirent) []byte { - // Because this GOOS' syscall.Dirent provides a Namlen field that says how - // long the name is, this function does not need to search for the NULL - // byte. - ml := int(de.Namlen) - - // Convert syscall.Dirent.Name, which is array of int8, to []byte, by - // overwriting Cap, Len, and Data slice header fields to values from - // syscall.Dirent fields. Setting the Cap, Len, and Data field values for - // the slice header modifies what the slice header points to, and in this - // case, the name buffer. - var name []byte - sh := (*reflect.SliceHeader)(unsafe.Pointer(&name)) - sh.Cap = ml - sh.Len = ml - sh.Data = uintptr(unsafe.Pointer(&de.Name[0])) - - return name -} diff --git a/vendor/github.com/karrick/godirwalk/nameWithoutNamlen.go b/vendor/github.com/karrick/godirwalk/nameWithoutNamlen.go deleted file mode 100644 index f776fbc760..0000000000 --- a/vendor/github.com/karrick/godirwalk/nameWithoutNamlen.go +++ /dev/null @@ -1,42 +0,0 @@ -// +build nacl linux js solaris - -package godirwalk - -import ( - "bytes" - "reflect" - "syscall" - "unsafe" -) - -// nameOffset is a compile time constant -const nameOffset = int(unsafe.Offsetof(syscall.Dirent{}.Name)) - -func nameFromDirent(de *syscall.Dirent) (name []byte) { - // Because this GOOS' syscall.Dirent does not provide a field that specifies - // the name length, this function must first calculate the max possible name - // length, and then search for the NULL byte. - ml := int(de.Reclen) - nameOffset - - // Convert syscall.Dirent.Name, which is array of int8, to []byte, by - // overwriting Cap, Len, and Data slice header fields to the max possible - // name length computed above, and finding the terminating NULL byte. - sh := (*reflect.SliceHeader)(unsafe.Pointer(&name)) - sh.Cap = ml - sh.Len = ml - sh.Data = uintptr(unsafe.Pointer(&de.Name[0])) - - if index := bytes.IndexByte(name, 0); index >= 0 { - // Found NULL byte; set slice's cap and len accordingly. - sh.Cap = index - sh.Len = index - return - } - - // NOTE: This branch is not expected, but included for defensive - // programming, and provides a hard stop on the name based on the structure - // field array size. - sh.Cap = len(de.Name) - sh.Len = sh.Cap - return -} diff --git a/vendor/github.com/karrick/godirwalk/readdir.go b/vendor/github.com/karrick/godirwalk/readdir.go deleted file mode 100644 index c8fa8155e3..0000000000 --- a/vendor/github.com/karrick/godirwalk/readdir.go +++ /dev/null @@ -1,53 +0,0 @@ -package godirwalk - -// ReadDirents returns a sortable slice of pointers to Dirent structures, each -// representing the file system name and mode type for one of the immediate -// descendant of the specified directory. If the specified directory is a -// symbolic link, it will be resolved. -// -// If an optional scratch buffer is provided that is at least one page of -// memory, it will be used when reading directory entries from the file -// system. If you plan on calling this function in a loop, you will have -// significantly better performance if you allocate a scratch buffer and use it -// each time you call this function. -// -// children, err := godirwalk.ReadDirents(osDirname, nil) -// if err != nil { -// return nil, errors.Wrap(err, "cannot get list of directory children") -// } -// sort.Sort(children) -// for _, child := range children { -// fmt.Printf("%s %s\n", child.ModeType, child.Name) -// } -func ReadDirents(osDirname string, scratchBuffer []byte) (Dirents, error) { - return readDirents(osDirname, scratchBuffer) -} - -// ReadDirnames returns a slice of strings, representing the immediate -// descendants of the specified directory. If the specified directory is a -// symbolic link, it will be resolved. -// -// If an optional scratch buffer is provided that is at least one page of -// memory, it will be used when reading directory entries from the file -// system. If you plan on calling this function in a loop, you will have -// significantly better performance if you allocate a scratch buffer and use it -// each time you call this function. -// -// Note that this function, depending on operating system, may or may not invoke -// the ReadDirents function, in order to prepare the list of immediate -// descendants. Therefore, if your program needs both the names and the file -// system mode types of descendants, it will always be faster to invoke -// ReadDirents directly, rather than calling this function, then looping over -// the results and calling os.Stat or os.LStat for each entry. -// -// children, err := godirwalk.ReadDirnames(osDirname, nil) -// if err != nil { -// return nil, errors.Wrap(err, "cannot get list of directory children") -// } -// sort.Strings(children) -// for _, child := range children { -// fmt.Printf("%s\n", child) -// } -func ReadDirnames(osDirname string, scratchBuffer []byte) ([]string, error) { - return readDirnames(osDirname, scratchBuffer) -} diff --git a/vendor/github.com/karrick/godirwalk/readdir_unix.go b/vendor/github.com/karrick/godirwalk/readdir_unix.go deleted file mode 100644 index a993038ba2..0000000000 --- a/vendor/github.com/karrick/godirwalk/readdir_unix.go +++ /dev/null @@ -1,131 +0,0 @@ -// +build !windows - -package godirwalk - -import ( - "os" - "syscall" - "unsafe" -) - -// MinimumScratchBufferSize specifies the minimum size of the scratch buffer -// that ReadDirents, ReadDirnames, Scanner, and Walk will use when reading file -// entries from the operating system. During program startup it is initialized -// to the result from calling `os.Getpagesize()` for non Windows environments, -// and 0 for Windows. -var MinimumScratchBufferSize = os.Getpagesize() - -func newScratchBuffer() []byte { return make([]byte, MinimumScratchBufferSize) } - -func readDirents(osDirname string, scratchBuffer []byte) ([]*Dirent, error) { - var entries []*Dirent - var workBuffer []byte - - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - fd := int(dh.Fd()) - - if len(scratchBuffer) < MinimumScratchBufferSize { - scratchBuffer = newScratchBuffer() - } - - var sde syscall.Dirent - for { - if len(workBuffer) == 0 { - n, err := syscall.ReadDirent(fd, scratchBuffer) - // n, err := unix.ReadDirent(fd, scratchBuffer) - if err != nil { - if err == syscall.EINTR /* || err == unix.EINTR */ { - continue - } - _ = dh.Close() - return nil, err - } - if n <= 0 { // end of directory: normal exit - if err = dh.Close(); err != nil { - return nil, err - } - return entries, nil - } - workBuffer = scratchBuffer[:n] // trim work buffer to number of bytes read - } - - copy((*[unsafe.Sizeof(syscall.Dirent{})]byte)(unsafe.Pointer(&sde))[:], workBuffer) - workBuffer = workBuffer[reclen(&sde):] // advance buffer for next iteration through loop - - if inoFromDirent(&sde) == 0 { - continue // inode set to 0 indicates an entry that was marked as deleted - } - - nameSlice := nameFromDirent(&sde) - nameLength := len(nameSlice) - - if nameLength == 0 || (nameSlice[0] == '.' && (nameLength == 1 || (nameLength == 2 && nameSlice[1] == '.'))) { - continue - } - - childName := string(nameSlice) - mt, err := modeTypeFromDirent(&sde, osDirname, childName) - if err != nil { - _ = dh.Close() - return nil, err - } - entries = append(entries, &Dirent{name: childName, path: osDirname, modeType: mt}) - } -} - -func readDirnames(osDirname string, scratchBuffer []byte) ([]string, error) { - var entries []string - var workBuffer []byte - var sde *syscall.Dirent - - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - fd := int(dh.Fd()) - - if len(scratchBuffer) < MinimumScratchBufferSize { - scratchBuffer = newScratchBuffer() - } - - for { - if len(workBuffer) == 0 { - n, err := syscall.ReadDirent(fd, scratchBuffer) - // n, err := unix.ReadDirent(fd, scratchBuffer) - if err != nil { - if err == syscall.EINTR /* || err == unix.EINTR */ { - continue - } - _ = dh.Close() - return nil, err - } - if n <= 0 { // end of directory: normal exit - if err = dh.Close(); err != nil { - return nil, err - } - return entries, nil - } - workBuffer = scratchBuffer[:n] // trim work buffer to number of bytes read - } - - sde = (*syscall.Dirent)(unsafe.Pointer(&workBuffer[0])) // point entry to first syscall.Dirent in buffer - // Handle first entry in the work buffer. - workBuffer = workBuffer[reclen(sde):] // advance buffer for next iteration through loop - - if inoFromDirent(sde) == 0 { - continue // inode set to 0 indicates an entry that was marked as deleted - } - - nameSlice := nameFromDirent(sde) - nameLength := len(nameSlice) - - if nameLength == 0 || (nameSlice[0] == '.' && (nameLength == 1 || (nameLength == 2 && nameSlice[1] == '.'))) { - continue - } - - entries = append(entries, string(nameSlice)) - } -} diff --git a/vendor/github.com/karrick/godirwalk/readdir_windows.go b/vendor/github.com/karrick/godirwalk/readdir_windows.go deleted file mode 100644 index 7dd76cbc35..0000000000 --- a/vendor/github.com/karrick/godirwalk/readdir_windows.go +++ /dev/null @@ -1,66 +0,0 @@ -// +build windows - -package godirwalk - -import "os" - -// MinimumScratchBufferSize specifies the minimum size of the scratch buffer -// that ReadDirents, ReadDirnames, Scanner, and Walk will use when reading file -// entries from the operating system. During program startup it is initialized -// to the result from calling `os.Getpagesize()` for non Windows environments, -// and 0 for Windows. -var MinimumScratchBufferSize = 0 - -func newScratchBuffer() []byte { return nil } - -func readDirents(osDirname string, _ []byte) ([]*Dirent, error) { - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - - fileinfos, err := dh.Readdir(-1) - if err != nil { - _ = dh.Close() - return nil, err - } - - entries := make([]*Dirent, len(fileinfos)) - - for i, fi := range fileinfos { - entries[i] = &Dirent{ - name: fi.Name(), - path: osDirname, - modeType: fi.Mode() & os.ModeType, - } - } - - if err = dh.Close(); err != nil { - return nil, err - } - return entries, nil -} - -func readDirnames(osDirname string, _ []byte) ([]string, error) { - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - - fileinfos, err := dh.Readdir(-1) - if err != nil { - _ = dh.Close() - return nil, err - } - - entries := make([]string, len(fileinfos)) - - for i, fi := range fileinfos { - entries[i] = fi.Name() - } - - if err = dh.Close(); err != nil { - return nil, err - } - return entries, nil -} diff --git a/vendor/github.com/karrick/godirwalk/reclenFromNamlen.go b/vendor/github.com/karrick/godirwalk/reclenFromNamlen.go deleted file mode 100644 index baeefcee3a..0000000000 --- a/vendor/github.com/karrick/godirwalk/reclenFromNamlen.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build dragonfly - -package godirwalk - -import "syscall" - -func reclen(de *syscall.Dirent) uint64 { - return (16 + uint64(de.Namlen) + 1 + 7) &^ 7 -} diff --git a/vendor/github.com/karrick/godirwalk/reclenFromReclen.go b/vendor/github.com/karrick/godirwalk/reclenFromReclen.go deleted file mode 100644 index 99be34d871..0000000000 --- a/vendor/github.com/karrick/godirwalk/reclenFromReclen.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build nacl linux js solaris aix darwin freebsd netbsd openbsd - -package godirwalk - -import "syscall" - -func reclen(de *syscall.Dirent) uint64 { - return uint64(de.Reclen) -} diff --git a/vendor/github.com/karrick/godirwalk/scandir_unix.go b/vendor/github.com/karrick/godirwalk/scandir_unix.go deleted file mode 100644 index 654039bd2b..0000000000 --- a/vendor/github.com/karrick/godirwalk/scandir_unix.go +++ /dev/null @@ -1,181 +0,0 @@ -//go:build !windows -// +build !windows - -package godirwalk - -import ( - "os" - "syscall" - "unsafe" -) - -// Scanner is an iterator to enumerate the contents of a directory. -type Scanner struct { - scratchBuffer []byte // read directory bytes from file system into this buffer - workBuffer []byte // points into scratchBuffer, from which we chunk out directory entries - osDirname string - childName string - err error // err is the error associated with scanning directory - statErr error // statErr is any error return while attempting to stat an entry - dh *os.File // used to close directory after done reading - de *Dirent // most recently decoded directory entry - sde syscall.Dirent - fd int // file descriptor used to read entries from directory -} - -// NewScanner returns a new directory Scanner that lazily enumerates -// the contents of a single directory. To prevent resource leaks, -// caller must invoke either the Scanner's Close or Err method after -// it has completed scanning a directory. -// -// scanner, err := godirwalk.NewScanner(dirname) -// if err != nil { -// fatal("cannot scan directory: %s", err) -// } -// -// for scanner.Scan() { -// dirent, err := scanner.Dirent() -// if err != nil { -// warning("cannot get dirent: %s", err) -// continue -// } -// name := dirent.Name() -// if name == "break" { -// break -// } -// if name == "continue" { -// continue -// } -// fmt.Printf("%v %v\n", dirent.ModeType(), dirent.Name()) -// } -// if err := scanner.Err(); err != nil { -// fatal("cannot scan directory: %s", err) -// } -func NewScanner(osDirname string) (*Scanner, error) { - return NewScannerWithScratchBuffer(osDirname, nil) -} - -// NewScannerWithScratchBuffer returns a new directory Scanner that -// lazily enumerates the contents of a single directory. On platforms -// other than Windows it uses the provided scratch buffer to read from -// the file system. On Windows the scratch buffer is ignored. To -// prevent resource leaks, caller must invoke either the Scanner's -// Close or Err method after it has completed scanning a directory. -func NewScannerWithScratchBuffer(osDirname string, scratchBuffer []byte) (*Scanner, error) { - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - if len(scratchBuffer) < MinimumScratchBufferSize { - scratchBuffer = newScratchBuffer() - } - scanner := &Scanner{ - scratchBuffer: scratchBuffer, - osDirname: osDirname, - dh: dh, - fd: int(dh.Fd()), - } - return scanner, nil -} - -// Close releases resources associated with scanning a directory. Call -// either this or the Err method when the directory no longer needs to -// be scanned. -func (s *Scanner) Close() error { - return s.Err() -} - -// Dirent returns the current directory entry while scanning a directory. -func (s *Scanner) Dirent() (*Dirent, error) { - if s.de == nil { - s.de = &Dirent{name: s.childName, path: s.osDirname} - s.de.modeType, s.statErr = modeTypeFromDirent(&s.sde, s.osDirname, s.childName) - } - return s.de, s.statErr -} - -// done is called when directory scanner unable to continue, with either the -// triggering error, or nil when there are simply no more entries to read from -// the directory. -func (s *Scanner) done(err error) { - if s.dh == nil { - return - } - - s.err = err - - if err = s.dh.Close(); s.err == nil { - s.err = err - } - - s.osDirname, s.childName = "", "" - s.scratchBuffer, s.workBuffer = nil, nil - s.dh, s.de, s.statErr = nil, nil, nil - s.sde = syscall.Dirent{} - s.fd = 0 -} - -// Err returns any error associated with scanning a directory. It is -// normal to call Err after Scan returns false, even though they both -// ensure Scanner resources are released. Call either this or the -// Close method when the directory no longer needs to be scanned. -func (s *Scanner) Err() error { - s.done(nil) - return s.err -} - -// Name returns the base name of the current directory entry while scanning a -// directory. -func (s *Scanner) Name() string { return s.childName } - -// Scan potentially reads and then decodes the next directory entry from the -// file system. -// -// When it returns false, this releases resources used by the Scanner then -// returns any error associated with closing the file system directory resource. -func (s *Scanner) Scan() bool { - if s.dh == nil { - return false - } - - s.de = nil - - for { - // When the work buffer has nothing remaining to decode, we need to load - // more data from disk. - if len(s.workBuffer) == 0 { - n, err := syscall.ReadDirent(s.fd, s.scratchBuffer) - // n, err := unix.ReadDirent(s.fd, s.scratchBuffer) - if err != nil { - if err == syscall.EINTR /* || err == unix.EINTR */ { - continue - } - s.done(err) // any other error forces a stop - return false - } - if n <= 0 { // end of directory: normal exit - s.done(nil) - return false - } - s.workBuffer = s.scratchBuffer[:n] // trim work buffer to number of bytes read - } - - // point entry to first syscall.Dirent in buffer - copy((*[unsafe.Sizeof(syscall.Dirent{})]byte)(unsafe.Pointer(&s.sde))[:], s.workBuffer) - s.workBuffer = s.workBuffer[reclen(&s.sde):] // advance buffer for next iteration through loop - - if inoFromDirent(&s.sde) == 0 { - continue // inode set to 0 indicates an entry that was marked as deleted - } - - nameSlice := nameFromDirent(&s.sde) - nameLength := len(nameSlice) - - if nameLength == 0 || (nameSlice[0] == '.' && (nameLength == 1 || (nameLength == 2 && nameSlice[1] == '.'))) { - continue - } - - s.childName = string(nameSlice) - return true - } -} diff --git a/vendor/github.com/karrick/godirwalk/scandir_windows.go b/vendor/github.com/karrick/godirwalk/scandir_windows.go deleted file mode 100644 index 338e3236ed..0000000000 --- a/vendor/github.com/karrick/godirwalk/scandir_windows.go +++ /dev/null @@ -1,149 +0,0 @@ -//go:build windows -// +build windows - -package godirwalk - -import ( - "fmt" - "os" -) - -// Scanner is an iterator to enumerate the contents of a directory. -type Scanner struct { - osDirname string - childName string - dh *os.File // dh is handle to open directory - de *Dirent - err error // err is the error associated with scanning directory - childMode os.FileMode -} - -// NewScanner returns a new directory Scanner that lazily enumerates -// the contents of a single directory. To prevent resource leaks, -// caller must invoke either the Scanner's Close or Err method after -// it has completed scanning a directory. -// -// scanner, err := godirwalk.NewScanner(dirname) -// if err != nil { -// fatal("cannot scan directory: %s", err) -// } -// -// for scanner.Scan() { -// dirent, err := scanner.Dirent() -// if err != nil { -// warning("cannot get dirent: %s", err) -// continue -// } -// name := dirent.Name() -// if name == "break" { -// break -// } -// if name == "continue" { -// continue -// } -// fmt.Printf("%v %v\n", dirent.ModeType(), dirent.Name()) -// } -// if err := scanner.Err(); err != nil { -// fatal("cannot scan directory: %s", err) -// } -func NewScanner(osDirname string) (*Scanner, error) { - dh, err := os.Open(osDirname) - if err != nil { - return nil, err - } - scanner := &Scanner{ - osDirname: osDirname, - dh: dh, - } - return scanner, nil -} - -// NewScannerWithScratchBuffer returns a new directory Scanner that -// lazily enumerates the contents of a single directory. On platforms -// other than Windows it uses the provided scratch buffer to read from -// the file system. On Windows the scratch buffer parameter is -// ignored. To prevent resource leaks, caller must invoke either the -// Scanner's Close or Err method after it has completed scanning a -// directory. -func NewScannerWithScratchBuffer(osDirname string, scratchBuffer []byte) (*Scanner, error) { - return NewScanner(osDirname) -} - -// Close releases resources associated with scanning a directory. Call -// either this or the Err method when the directory no longer needs to -// be scanned. -func (s *Scanner) Close() error { - return s.Err() -} - -// Dirent returns the current directory entry while scanning a directory. -func (s *Scanner) Dirent() (*Dirent, error) { - if s.de == nil { - s.de = &Dirent{ - name: s.childName, - path: s.osDirname, - modeType: s.childMode, - } - } - return s.de, nil -} - -// done is called when directory scanner unable to continue, with either the -// triggering error, or nil when there are simply no more entries to read from -// the directory. -func (s *Scanner) done(err error) { - if s.dh == nil { - return - } - - s.err = err - - if err = s.dh.Close(); s.err == nil { - s.err = err - } - - s.childName, s.osDirname = "", "" - s.de, s.dh = nil, nil -} - -// Err returns any error associated with scanning a directory. It is -// normal to call Err after Scan returns false, even though they both -// ensure Scanner resources are released. Call either this or the -// Close method when the directory no longer needs to be scanned. -func (s *Scanner) Err() error { - s.done(nil) - return s.err -} - -// Name returns the base name of the current directory entry while scanning a -// directory. -func (s *Scanner) Name() string { return s.childName } - -// Scan potentially reads and then decodes the next directory entry from the -// file system. -// -// When it returns false, this releases resources used by the Scanner then -// returns any error associated with closing the file system directory resource. -func (s *Scanner) Scan() bool { - if s.dh == nil { - return false - } - - s.de = nil - - fileinfos, err := s.dh.Readdir(1) - if err != nil { - s.done(err) - return false - } - - if l := len(fileinfos); l != 1 { - s.done(fmt.Errorf("expected a single entry rather than %d", l)) - return false - } - - fi := fileinfos[0] - s.childMode = fi.Mode() & os.ModeType - s.childName = fi.Name() - return true -} diff --git a/vendor/github.com/karrick/godirwalk/scanner.go b/vendor/github.com/karrick/godirwalk/scanner.go deleted file mode 100644 index c08179e1ed..0000000000 --- a/vendor/github.com/karrick/godirwalk/scanner.go +++ /dev/null @@ -1,44 +0,0 @@ -package godirwalk - -import "sort" - -type scanner interface { - Dirent() (*Dirent, error) - Err() error - Name() string - Scan() bool -} - -// sortedScanner enumerates through a directory's contents after reading the -// entire directory and sorting the entries by name. Used by walk to simplify -// its implementation. -type sortedScanner struct { - dd []*Dirent - de *Dirent -} - -func newSortedScanner(osPathname string, scratchBuffer []byte) (*sortedScanner, error) { - deChildren, err := ReadDirents(osPathname, scratchBuffer) - if err != nil { - return nil, err - } - sort.Sort(deChildren) - return &sortedScanner{dd: deChildren}, nil -} - -func (d *sortedScanner) Err() error { - d.dd, d.de = nil, nil - return nil -} - -func (d *sortedScanner) Dirent() (*Dirent, error) { return d.de, nil } - -func (d *sortedScanner) Name() string { return d.de.name } - -func (d *sortedScanner) Scan() bool { - if len(d.dd) > 0 { - d.de, d.dd = d.dd[0], d.dd[1:] - return true - } - return false -} diff --git a/vendor/github.com/karrick/godirwalk/walk.go b/vendor/github.com/karrick/godirwalk/walk.go deleted file mode 100644 index 9d0235dfb8..0000000000 --- a/vendor/github.com/karrick/godirwalk/walk.go +++ /dev/null @@ -1,379 +0,0 @@ -package godirwalk - -import ( - "errors" - "fmt" - "os" - "path/filepath" -) - -// Options provide parameters for how the Walk function operates. -type Options struct { - // ErrorCallback specifies a function to be invoked in the case of an error - // that could potentially be ignored while walking a file system - // hierarchy. When set to nil or left as its zero-value, any error condition - // causes Walk to immediately return the error describing what took - // place. When non-nil, this user supplied function is invoked with the OS - // pathname of the file system object that caused the error along with the - // error that took place. The return value of the supplied ErrorCallback - // function determines whether the error will cause Walk to halt immediately - // as it would were no ErrorCallback value provided, or skip this file - // system node yet continue on with the remaining nodes in the file system - // hierarchy. - // - // ErrorCallback is invoked both for errors that are returned by the - // runtime, and for errors returned by other user supplied callback - // functions. - ErrorCallback func(string, error) ErrorAction - - // FollowSymbolicLinks specifies whether Walk will follow symbolic links - // that refer to directories. When set to false or left as its zero-value, - // Walk will still invoke the callback function with symbolic link nodes, - // but if the symbolic link refers to a directory, it will not recurse on - // that directory. When set to true, Walk will recurse on symbolic links - // that refer to a directory. - FollowSymbolicLinks bool - - // Unsorted controls whether or not Walk will sort the immediate descendants - // of a directory by their relative names prior to visiting each of those - // entries. - // - // When set to false or left at its zero-value, Walk will get the list of - // immediate descendants of a particular directory, sort that list by - // lexical order of their names, and then visit each node in the list in - // sorted order. This will cause Walk to always traverse the same directory - // tree in the same order, however may be inefficient for directories with - // many immediate descendants. - // - // When set to true, Walk skips sorting the list of immediate descendants - // for a directory, and simply visits each node in the order the operating - // system enumerated them. This will be more fast, but with the side effect - // that the traversal order may be different from one invocation to the - // next. - Unsorted bool - - // Callback is a required function that Walk will invoke for every file - // system node it encounters. - Callback WalkFunc - - // PostChildrenCallback is an option function that Walk will invoke for - // every file system directory it encounters after its children have been - // processed. - PostChildrenCallback WalkFunc - - // ScratchBuffer is an optional byte slice to use as a scratch buffer for - // Walk to use when reading directory entries, to reduce amount of garbage - // generation. Not all architectures take advantage of the scratch - // buffer. If omitted or the provided buffer has fewer bytes than - // MinimumScratchBufferSize, then a buffer with MinimumScratchBufferSize - // bytes will be created and used once per Walk invocation. - ScratchBuffer []byte - - // AllowNonDirectory causes Walk to bypass the check that ensures it is - // being called on a directory node, or when FollowSymbolicLinks is true, a - // symbolic link that points to a directory. Leave this value false to have - // Walk return an error when called on a non-directory. Set this true to - // have Walk run even when called on a non-directory node. - AllowNonDirectory bool -} - -// ErrorAction defines a set of actions the Walk function could take based on -// the occurrence of an error while walking the file system. See the -// documentation for the ErrorCallback field of the Options structure for more -// information. -type ErrorAction int - -const ( - // Halt is the ErrorAction return value when the upstream code wants to halt - // the walk process when a runtime error takes place. It matches the default - // action the Walk function would take were no ErrorCallback provided. - Halt ErrorAction = iota - - // SkipNode is the ErrorAction return value when the upstream code wants to - // ignore the runtime error for the current file system node, skip - // processing of the node that caused the error, and continue walking the - // file system hierarchy with the remaining nodes. - SkipNode -) - -// SkipThis is used as a return value from WalkFuncs to indicate that the file -// system entry named in the call is to be skipped. It is not returned as an -// error by any function. -var SkipThis = errors.New("skip this directory entry") - -// WalkFunc is the type of the function called for each file system node visited -// by Walk. The pathname argument will contain the argument to Walk as a prefix; -// that is, if Walk is called with "dir", which is a directory containing the -// file "a", the provided WalkFunc will be invoked with the argument "dir/a", -// using the correct os.PathSeparator for the Go Operating System architecture, -// GOOS. The directory entry argument is a pointer to a Dirent for the node, -// providing access to both the basename and the mode type of the file system -// node. -// -// If an error is returned by the Callback or PostChildrenCallback functions, -// and no ErrorCallback function is provided, processing stops. If an -// ErrorCallback function is provided, then it is invoked with the OS pathname -// of the node that caused the error along along with the error. The return -// value of the ErrorCallback function determines whether to halt processing, or -// skip this node and continue processing remaining file system nodes. -// -// The exception is when the function returns the special value -// filepath.SkipDir. If the function returns filepath.SkipDir when invoked on a -// directory, Walk skips the directory's contents entirely. If the function -// returns filepath.SkipDir when invoked on a non-directory file system node, -// Walk skips the remaining files in the containing directory. Note that any -// supplied ErrorCallback function is not invoked with filepath.SkipDir when the -// Callback or PostChildrenCallback functions return that special value. -// -// One arguably confusing aspect of the filepath.WalkFunc API that this library -// must emulate is how a caller tells Walk to skip file system entries or -// directories. With both filepath.Walk and this Walk, when a callback function -// wants to skip a directory and not descend into its children, it returns -// filepath.SkipDir. If the callback function returns filepath.SkipDir for a -// non-directory, filepath.Walk and this library will stop processing any more -// entries in the current directory, which is what many people do not want. If -// you want to simply skip a particular non-directory entry but continue -// processing entries in the directory, a callback function must return nil. The -// implications of this API is when you want to walk a file system hierarchy and -// skip an entry, when the entry is a directory, you must return one value, -// namely filepath.SkipDir, but when the entry is a non-directory, you must -// return a different value, namely nil. In other words, to get identical -// behavior for two file system entry types you need to send different token -// values. -// -// Here is an example callback function that adheres to filepath.Walk API to -// have it skip any file system entry whose full pathname includes a particular -// substring, optSkip: -// -// func callback1(osPathname string, de *godirwalk.Dirent) error { -// if optSkip != "" && strings.Contains(osPathname, optSkip) { -// if b, err := de.IsDirOrSymlinkToDir(); b == true && err == nil { -// return filepath.SkipDir -// } -// return nil -// } -// // Process file like normal... -// return nil -// } -// -// This library attempts to eliminate some of that logic boilerplate by -// providing a new token error value, SkipThis, which a callback function may -// return to skip the current file system entry regardless of what type of entry -// it is. If the current entry is a directory, its children will not be -// enumerated, exactly as if the callback returned filepath.SkipDir. If the -// current entry is a non-directory, the next file system entry in the current -// directory will be enumerated, exactly as if the callback returned nil. The -// following example callback function has identical behavior as the previous, -// but has less boilerplate, and admittedly more simple logic. -// -// func callback2(osPathname string, de *godirwalk.Dirent) error { -// if optSkip != "" && strings.Contains(osPathname, optSkip) { -// return godirwalk.SkipThis -// } -// // Process file like normal... -// return nil -// } -type WalkFunc func(osPathname string, directoryEntry *Dirent) error - -// Walk walks the file tree rooted at the specified directory, calling the -// specified callback function for each file system node in the tree, including -// root, symbolic links, and other node types. -// -// This function is often much faster than filepath.Walk because it does not -// invoke os.Stat for every node it encounters, but rather obtains the file -// system node type when it reads the parent directory. -// -// If a runtime error occurs, either from the operating system or from the -// upstream Callback or PostChildrenCallback functions, processing typically -// halts. However, when an ErrorCallback function is provided in the provided -// Options structure, that function is invoked with the error along with the OS -// pathname of the file system node that caused the error. The ErrorCallback -// function's return value determines the action that Walk will then take. -// -// func main() { -// dirname := "." -// if len(os.Args) > 1 { -// dirname = os.Args[1] -// } -// err := godirwalk.Walk(dirname, &godirwalk.Options{ -// Callback: func(osPathname string, de *godirwalk.Dirent) error { -// fmt.Printf("%s %s\n", de.ModeType(), osPathname) -// return nil -// }, -// ErrorCallback: func(osPathname string, err error) godirwalk.ErrorAction { -// // Your program may want to log the error somehow. -// fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) -// -// // For the purposes of this example, a simple SkipNode will suffice, -// // although in reality perhaps additional logic might be called for. -// return godirwalk.SkipNode -// }, -// }) -// if err != nil { -// fmt.Fprintf(os.Stderr, "%s\n", err) -// os.Exit(1) -// } -// } -func Walk(pathname string, options *Options) error { - if options == nil || options.Callback == nil { - return errors.New("cannot walk without non-nil options and Callback function") - } - - pathname = filepath.Clean(pathname) - - var fi os.FileInfo - var err error - - if options.FollowSymbolicLinks { - fi, err = os.Stat(pathname) - } else { - fi, err = os.Lstat(pathname) - } - if err != nil { - return err - } - - mode := fi.Mode() - if !options.AllowNonDirectory && mode&os.ModeDir == 0 { - return fmt.Errorf("cannot Walk non-directory: %s", pathname) - } - - dirent := &Dirent{ - name: filepath.Base(pathname), - path: filepath.Dir(pathname), - modeType: mode & os.ModeType, - } - - if len(options.ScratchBuffer) < MinimumScratchBufferSize { - options.ScratchBuffer = newScratchBuffer() - } - - // If ErrorCallback is nil, set to a default value that halts the walk - // process on all operating system errors. This is done to allow error - // handling to be more succinct in the walk code. - if options.ErrorCallback == nil { - options.ErrorCallback = defaultErrorCallback - } - - err = walk(pathname, dirent, options) - switch err { - case nil, SkipThis, filepath.SkipDir: - // silence SkipThis and filepath.SkipDir for top level - debug("no error of significance: %v\n", err) - return nil - default: - return err - } -} - -// defaultErrorCallback always returns Halt because if the upstream code did not -// provide an ErrorCallback function, walking the file system hierarchy ought to -// halt upon any operating system error. -func defaultErrorCallback(_ string, _ error) ErrorAction { return Halt } - -// walk recursively traverses the file system node specified by pathname and the -// Dirent. -func walk(osPathname string, dirent *Dirent, options *Options) error { - err := options.Callback(osPathname, dirent) - if err != nil { - if err == SkipThis || err == filepath.SkipDir { - return err - } - if action := options.ErrorCallback(osPathname, err); action == SkipNode { - return nil - } - return err - } - - if dirent.IsSymlink() { - if !options.FollowSymbolicLinks { - return nil - } - // Does this symlink point to a directory? - info, err := os.Stat(osPathname) - if err != nil { - if action := options.ErrorCallback(osPathname, err); action == SkipNode { - return nil - } - return err - } - if !info.IsDir() { - return nil - } - } else if !dirent.IsDir() { - return nil - } - - // If get here, then specified pathname refers to a directory or a - // symbolic link to a directory. - - var ds scanner - - if options.Unsorted { - // When upstream does not request a sorted iteration, it's more memory - // efficient to read a single child at a time from the file system. - ds, err = NewScanner(osPathname) - } else { - // When upstream wants a sorted iteration, we must read the entire - // directory and sort through the child names, and then iterate on each - // child. - ds, err = newSortedScanner(osPathname, options.ScratchBuffer) - } - if err != nil { - if action := options.ErrorCallback(osPathname, err); action == SkipNode { - return nil - } - return err - } - - for ds.Scan() { - deChild, err := ds.Dirent() - osChildname := filepath.Join(osPathname, deChild.name) - if err != nil { - if action := options.ErrorCallback(osChildname, err); action == SkipNode { - return nil - } - return err - } - err = walk(osChildname, deChild, options) - debug("osChildname: %q; error: %v\n", osChildname, err) - if err == nil || err == SkipThis { - continue - } - if err != filepath.SkipDir { - return err - } - // When received SkipDir on a directory or a symbolic link to a - // directory, stop processing that directory but continue processing - // siblings. When received on a non-directory, stop processing - // remaining siblings. - isDir, err := deChild.IsDirOrSymlinkToDir() - if err != nil { - if action := options.ErrorCallback(osChildname, err); action == SkipNode { - continue // ignore and continue with next sibling - } - return err // caller does not approve of this error - } - if !isDir { - break // stop processing remaining siblings, but allow post children callback - } - // continue processing remaining siblings - } - if err = ds.Err(); err != nil { - return err - } - - if options.PostChildrenCallback == nil { - return nil - } - - err = options.PostChildrenCallback(osPathname, dirent) - if err == nil || err == filepath.SkipDir { - return err - } - - if action := options.ErrorCallback(osPathname, err); action == SkipNode { - return nil - } - return err -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/README.md b/vendor/github.com/libopenstorage/openstorage/api/README.md deleted file mode 100644 index 2b2a5ec54d..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# OpenStorage API usage - -Any storage product that uses the openstorage API can be managed via this API. Below are some examples of using this API. - -### Enumerate nodes in a cluster -```go - -import ( - ... - - "github.com/libopenstorage/gossip/types" - "github.com/libopenstorage/openstorage/api" - "github.com/libopenstorage/openstorage/api/client/cluster" -) - -type myapp struct { - manager cluster.Cluster -} - -func (c *myapp) init() { - // Choose the default version. - // Leave the host blank to use the local UNIX socket, or pass in an IP and a port at which the server is listening on. - clnt, err := cluster.NewClusterClient("", cluster.APIVersion) - if err != nil { - fmt.Printf("Failed to initialize client library: %v\n", err) - os.Exit(1) - } - c.manager = cluster.ClusterManager(clnt) -} - -func (c *myapp) listNodes() { - cluster, err := c.manager.Enumerate() - if err != nil { - cmdError(context, fn, err) - return - } - - // cluster is now a hashmap of nodes... do something useful with it: - for _, n := range cluster.Nodes { - - } -} -``` - -### Inspect a volume in a cluster -```go - -import ( - ... - - "github.com/libopenstorage/openstorage/api" - volumeclient "github.com/libopenstorage/openstorage/api/client/volume" - "github.com/libopenstorage/openstorage/volume" -) - -type myapp struct { - volDriver volume.VolumeDriver -} - -func (c *myapp) init() { - // Choose the default version. - // Leave the host blank to use the local UNIX socket, or pass in an IP and a port at which the server is listening on. - clnt, err := volumeclient.NewDriverClient("", v.name, volume.APIVersion) - if err != nil { - fmt.Printf("Failed to initialize client library: %v\n", err) - os.Exit(1) - } - v.volDriver = volumeclient.VolumeDriver(clnt) -} - -func (c *myapp) inspect(id string) { - stats, err := v.volDriver.Stats(id, true) - if err != nil { - return - } - - // stats is an object that has various volume properties and statistics. -} -``` diff --git a/vendor/github.com/libopenstorage/openstorage/api/api.go b/vendor/github.com/libopenstorage/openstorage/api/api.go deleted file mode 100644 index 4ce931447d..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/api.go +++ /dev/null @@ -1,365 +0,0 @@ -package api - -import ( - "fmt" - "math" - "strconv" - "strings" - "time" - - "github.com/mohae/deepcopy" -) - -// Strings for VolumeSpec -const ( - Name = "name" - SpecNodes = "nodes" - SpecParent = "parent" - SpecEphemeral = "ephemeral" - SpecShared = "shared" - SpecSticky = "sticky" - SpecSecure = "secure" - SpecCompressed = "compressed" - SpecSize = "size" - SpecScale = "scale" - SpecFilesystem = "fs" - SpecBlockSize = "block_size" - SpecHaLevel = "repl" - SpecPriority = "io_priority" - SpecSnapshotInterval = "snap_interval" - SpecSnapshotSchedule = "snap_schedule" - SpecAggregationLevel = "aggregation_level" - SpecDedupe = "dedupe" - SpecPassphrase = "secret_key" - SpecAutoAggregationValue = "auto" - SpecGroup = "group" - SpecGroupEnforce = "fg" - SpecZones = "zones" - SpecRacks = "racks" - SpecRegions = "regions" - SpecLabels = "labels" - SpecPriorityAlias = "priority_io" - SpecIoProfile = "io_profile" -) - -// OptionKey specifies a set of recognized query params. -const ( - // OptName query parameter used to lookup volume by name. - OptName = "Name" - // OptVolumeID query parameter used to lookup volume by ID. - OptVolumeID = "VolumeID" - // OptSnapID query parameter used to lookup snapshot by ID. - OptSnapID = "SnapID" - // OptLabel query parameter used to lookup volume by set of labels. - OptLabel = "Label" - // OptConfigLabel query parameter used to lookup volume by set of labels. - OptConfigLabel = "ConfigLabel" - // OptCumulative query parameter used to request cumulative stats. - OptCumulative = "Cumulative" -) - -// Api client-server Constants -const ( - OsdVolumePath = "osd-volumes" - OsdSnapshotPath = "osd-snapshot" - TimeLayout = "Jan 2 15:04:05 UTC 2006" -) - -const ( - // AutoAggregation value indicates driver to select aggregation level. - AutoAggregation = math.MaxUint32 -) - -// Node describes the state of a node. -// It includes the current physical state (CPU, memory, storage, network usage) as -// well as the containers running on the system. -type Node struct { - Id string - Cpu float64 // percentage. - MemTotal uint64 - MemUsed uint64 - MemFree uint64 - Avgload int - Status Status - GenNumber uint64 - Disks map[string]StorageResource - Pools []StoragePool - MgmtIp string - DataIp string - Timestamp time.Time - StartTime time.Time - Hostname string - NodeData map[string]interface{} - // User defined labels for node. Key Value pairs - NodeLabels map[string]string -} - -type FluentDConfig struct { - IP string `json:"ip"` - Port string `json:"port"` -} - -type TunnelConfig struct { - Key string `json:"key"` - Cert string `json:"cert"` - Endpoint string `json:"tunnel_endpoint"` -} - -// Cluster represents the state of the cluster. -type Cluster struct { - Status Status - - // Id is the ID of the cluster. - Id string - - // NodeId is the ID of the node on which this cluster object - // is initialized - NodeId string - - // Nodes is an array of all the nodes in the cluster. - Nodes []Node - - // Logging url for the cluster. - LoggingURL string - - // Management url for the cluster - ManagementURL string - - // FluentD Host for the cluster - FluentDConfig FluentDConfig - - // TunnelConfig for the cluster [key, cert, endpoint] - TunnelConfig TunnelConfig -} - -// StatPoint represents the basic structure of a single Stat reported -// TODO: This is the first step to introduce stats in openstorage. -// Follow up task is to introduce an API for logging stats -type StatPoint struct { - // Name of the Stat - Name string - // Tags for the Stat - Tags map[string]string - // Fields and values of the stat - Fields map[string]interface{} - // Timestamp in Unix format - Timestamp int64 -} - -// DriverTypeSimpleValueOf returns the string format of DriverType -func DriverTypeSimpleValueOf(s string) (DriverType, error) { - obj, err := simpleValueOf("driver_type", DriverType_value, s) - return DriverType(obj), err -} - -// SimpleString returns the string format of DriverType -func (x DriverType) SimpleString() string { - return simpleString("driver_type", DriverType_name, int32(x)) -} - -// FSTypeSimpleValueOf returns the string format of FSType -func FSTypeSimpleValueOf(s string) (FSType, error) { - obj, err := simpleValueOf("fs_type", FSType_value, s) - return FSType(obj), err -} - -// SimpleString returns the string format of DriverType -func (x FSType) SimpleString() string { - return simpleString("fs_type", FSType_name, int32(x)) -} - -// CosTypeSimpleValueOf returns the string format of CosType -func CosTypeSimpleValueOf(s string) (CosType, error) { - obj, exists := CosType_value[strings.ToUpper(s)] - if !exists { - return -1, fmt.Errorf("Invalid cos value: %s", s) - } - return CosType(obj), nil -} - -// SimpleString returns the string format of CosType -func (x CosType) SimpleString() string { - return simpleString("cos_type", CosType_name, int32(x)) -} - -// GraphDriverChangeTypeSimpleValueOf returns the string format of GraphDriverChangeType -func GraphDriverChangeTypeSimpleValueOf(s string) (GraphDriverChangeType, error) { - obj, err := simpleValueOf("graph_driver_change_type", GraphDriverChangeType_value, s) - return GraphDriverChangeType(obj), err -} - -// SimpleString returns the string format of GraphDriverChangeType -func (x GraphDriverChangeType) SimpleString() string { - return simpleString("graph_driver_change_type", GraphDriverChangeType_name, int32(x)) -} - -// VolumeActionParamSimpleValueOf returns the string format of VolumeAction -func VolumeActionParamSimpleValueOf(s string) (VolumeActionParam, error) { - obj, err := simpleValueOf("volume_action_param", VolumeActionParam_value, s) - return VolumeActionParam(obj), err -} - -// SimpleString returns the string format of VolumeAction -func (x VolumeActionParam) SimpleString() string { - return simpleString("volume_action_param", VolumeActionParam_name, int32(x)) -} - -// VolumeStateSimpleValueOf returns the string format of VolumeState -func VolumeStateSimpleValueOf(s string) (VolumeState, error) { - obj, err := simpleValueOf("volume_state", VolumeState_value, s) - return VolumeState(obj), err -} - -// SimpleString returns the string format of VolumeState -func (x VolumeState) SimpleString() string { - return simpleString("volume_state", VolumeState_name, int32(x)) -} - -// VolumeStatusSimpleValueOf returns the string format of VolumeStatus -func VolumeStatusSimpleValueOf(s string) (VolumeStatus, error) { - obj, err := simpleValueOf("volume_status", VolumeStatus_value, s) - return VolumeStatus(obj), err -} - -// SimpleString returns the string format of VolumeStatus -func (x VolumeStatus) SimpleString() string { - return simpleString("volume_status", VolumeStatus_name, int32(x)) -} - -// IoProfileSimpleValueOf returns the string format of IoProfile -func IoProfileSimpleValueOf(s string) (IoProfile, error) { - obj, err := simpleValueOf("io_profile", IoProfile_value, s) - return IoProfile(obj), err -} - -// SimpleString returns the string format of IoProfile -func (x IoProfile) SimpleString() string { - return simpleString("io_profile", IoProfile_name, int32(x)) -} - -func simpleValueOf(typeString string, valueMap map[string]int32, s string) (int32, error) { - obj, ok := valueMap[strings.ToUpper(fmt.Sprintf("%s_%s", typeString, s))] - if !ok { - return 0, fmt.Errorf("no openstorage.%s for %s", strings.ToUpper(typeString), s) - } - return obj, nil -} - -func simpleString(typeString string, nameMap map[int32]string, v int32) string { - s, ok := nameMap[v] - if !ok { - return strconv.Itoa(int(v)) - } - return strings.TrimPrefix(strings.ToLower(s), fmt.Sprintf("%s_", strings.ToLower(typeString))) -} - -func toSec(ms uint64) uint64 { - return ms / 1000 -} - -// WriteThroughput returns the write throughput -func (v *Stats) WriteThroughput() uint64 { - if v.IntervalMs == 0 { - return 0 - } - return (v.WriteBytes) / toSec(v.IntervalMs) -} - -// ReadThroughput returns the read throughput -func (v *Stats) ReadThroughput() uint64 { - if v.IntervalMs == 0 { - return 0 - } - return (v.ReadBytes) / toSec(v.IntervalMs) -} - -// Latency returns latency -func (v *Stats) Latency() uint64 { - ops := v.Writes + v.Reads - if ops == 0 { - return 0 - } - return (uint64)((v.IoMs * 1000) / ops) -} - -// Read latency returns avg. time required for read operation to complete -func (v *Stats) ReadLatency() uint64 { - if v.Reads == 0 { - return 0 - } - return (uint64)((v.ReadMs * 1000) / v.Reads) -} - -// Write latency returns avg. time required for write operation to complete -func (v *Stats) WriteLatency() uint64 { - if v.Writes == 0 { - return 0 - } - return (uint64)((v.WriteMs * 1000) / v.Writes) -} - -// Iops returns iops -func (v *Stats) Iops() uint64 { - if v.IntervalMs == 0 { - return 0 - } - return (v.Writes + v.Reads) / toSec(v.IntervalMs) -} - -// Scaled returns true if the volume is scaled. -func (v *Volume) Scaled() bool { - return v.Spec.Scale > 1 -} - -// Contains returns true if mid is a member of volume's replication set. -func (m *Volume) Contains(mid string) bool { - rsets := m.GetReplicaSets() - for _, rset := range rsets { - for _, node := range rset.Nodes { - if node == mid { - return true - } - } - } - return false -} - -// Copy makes a deep copy of VolumeSpec -func (s *VolumeSpec) Copy() *VolumeSpec { - spec := *s - if s.VolumeLabels != nil { - spec.VolumeLabels = make(map[string]string) - for k, v := range s.VolumeLabels { - spec.VolumeLabels[k] = v - } - } - if s.ReplicaSet != nil { - spec.ReplicaSet = &ReplicaSet{Nodes: make([]string, len(s.ReplicaSet.Nodes))} - copy(spec.ReplicaSet.Nodes, s.ReplicaSet.Nodes) - } - return &spec -} - -// Copy makes a deep copy of Node -func (s *Node) Copy() *Node { - localCopy := deepcopy.Copy(*s) - nodeCopy := localCopy.(Node) - return &nodeCopy -} - -func (v Volume) IsClone() bool { - return v.Source != nil && len(v.Source.Parent) != 0 && !v.Readonly -} - -func (v Volume) IsSnapshot() bool { - return v.Source != nil && len(v.Source.Parent) != 0 && v.Readonly -} - -func (v Volume) DisplayId() string { - if v.Locator != nil { - return fmt.Sprintf("%s (%s)", v.Locator.Name, v.Id) - } else { - return v.Id - } - return "" -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/api.pb.go b/vendor/github.com/libopenstorage/openstorage/api/api.pb.go deleted file mode 100644 index 3a01d0ee3d..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/api.pb.go +++ /dev/null @@ -1,2042 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: api/api.proto - -/* -Package api is a generated protocol buffer package. - -It is generated from these files: - api/api.proto - -It has these top-level messages: - StorageResource - StoragePool - VolumeLocator - Source - Group - VolumeSpec - ReplicaSet - RuntimeStateMap - Volume - Stats - Alert - Alerts - VolumeCreateRequest - VolumeResponse - VolumeCreateResponse - VolumeStateAction - VolumeSetRequest - VolumeSetResponse - SnapCreateRequest - SnapCreateResponse - VolumeInfo - GraphDriverChanges - ClusterResponse - ActiveRequest - ActiveRequests -*/ -package api - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type Status int32 - -const ( - Status_STATUS_NONE Status = 0 - Status_STATUS_INIT Status = 1 - Status_STATUS_OK Status = 2 - Status_STATUS_OFFLINE Status = 3 - Status_STATUS_ERROR Status = 4 - Status_STATUS_NOT_IN_QUORUM Status = 5 - Status_STATUS_DECOMMISSION Status = 6 - Status_STATUS_MAINTENANCE Status = 7 - Status_STATUS_STORAGE_DOWN Status = 8 - Status_STATUS_STORAGE_DEGRADED Status = 9 - Status_STATUS_NEEDS_REBOOT Status = 10 - Status_STATUS_STORAGE_REBALANCE Status = 11 - Status_STATUS_STORAGE_DRIVE_REPLACE Status = 12 - // Add statuses before MAX and update the number for MAX - Status_STATUS_MAX Status = 13 -) - -var Status_name = map[int32]string{ - 0: "STATUS_NONE", - 1: "STATUS_INIT", - 2: "STATUS_OK", - 3: "STATUS_OFFLINE", - 4: "STATUS_ERROR", - 5: "STATUS_NOT_IN_QUORUM", - 6: "STATUS_DECOMMISSION", - 7: "STATUS_MAINTENANCE", - 8: "STATUS_STORAGE_DOWN", - 9: "STATUS_STORAGE_DEGRADED", - 10: "STATUS_NEEDS_REBOOT", - 11: "STATUS_STORAGE_REBALANCE", - 12: "STATUS_STORAGE_DRIVE_REPLACE", - 13: "STATUS_MAX", -} -var Status_value = map[string]int32{ - "STATUS_NONE": 0, - "STATUS_INIT": 1, - "STATUS_OK": 2, - "STATUS_OFFLINE": 3, - "STATUS_ERROR": 4, - "STATUS_NOT_IN_QUORUM": 5, - "STATUS_DECOMMISSION": 6, - "STATUS_MAINTENANCE": 7, - "STATUS_STORAGE_DOWN": 8, - "STATUS_STORAGE_DEGRADED": 9, - "STATUS_NEEDS_REBOOT": 10, - "STATUS_STORAGE_REBALANCE": 11, - "STATUS_STORAGE_DRIVE_REPLACE": 12, - "STATUS_MAX": 13, -} - -func (x Status) String() string { - return proto.EnumName(Status_name, int32(x)) -} -func (Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -type DriverType int32 - -const ( - DriverType_DRIVER_TYPE_NONE DriverType = 0 - DriverType_DRIVER_TYPE_FILE DriverType = 1 - DriverType_DRIVER_TYPE_BLOCK DriverType = 2 - DriverType_DRIVER_TYPE_OBJECT DriverType = 3 - DriverType_DRIVER_TYPE_CLUSTERED DriverType = 4 - DriverType_DRIVER_TYPE_GRAPH DriverType = 5 -) - -var DriverType_name = map[int32]string{ - 0: "DRIVER_TYPE_NONE", - 1: "DRIVER_TYPE_FILE", - 2: "DRIVER_TYPE_BLOCK", - 3: "DRIVER_TYPE_OBJECT", - 4: "DRIVER_TYPE_CLUSTERED", - 5: "DRIVER_TYPE_GRAPH", -} -var DriverType_value = map[string]int32{ - "DRIVER_TYPE_NONE": 0, - "DRIVER_TYPE_FILE": 1, - "DRIVER_TYPE_BLOCK": 2, - "DRIVER_TYPE_OBJECT": 3, - "DRIVER_TYPE_CLUSTERED": 4, - "DRIVER_TYPE_GRAPH": 5, -} - -func (x DriverType) String() string { - return proto.EnumName(DriverType_name, int32(x)) -} -func (DriverType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type FSType int32 - -const ( - FSType_FS_TYPE_NONE FSType = 0 - FSType_FS_TYPE_BTRFS FSType = 1 - FSType_FS_TYPE_EXT4 FSType = 2 - FSType_FS_TYPE_FUSE FSType = 3 - FSType_FS_TYPE_NFS FSType = 4 - FSType_FS_TYPE_VFS FSType = 5 - FSType_FS_TYPE_XFS FSType = 6 - FSType_FS_TYPE_ZFS FSType = 7 -) - -var FSType_name = map[int32]string{ - 0: "FS_TYPE_NONE", - 1: "FS_TYPE_BTRFS", - 2: "FS_TYPE_EXT4", - 3: "FS_TYPE_FUSE", - 4: "FS_TYPE_NFS", - 5: "FS_TYPE_VFS", - 6: "FS_TYPE_XFS", - 7: "FS_TYPE_ZFS", -} -var FSType_value = map[string]int32{ - "FS_TYPE_NONE": 0, - "FS_TYPE_BTRFS": 1, - "FS_TYPE_EXT4": 2, - "FS_TYPE_FUSE": 3, - "FS_TYPE_NFS": 4, - "FS_TYPE_VFS": 5, - "FS_TYPE_XFS": 6, - "FS_TYPE_ZFS": 7, -} - -func (x FSType) String() string { - return proto.EnumName(FSType_name, int32(x)) -} -func (FSType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -type GraphDriverChangeType int32 - -const ( - GraphDriverChangeType_GRAPH_DRIVER_CHANGE_TYPE_NONE GraphDriverChangeType = 0 - GraphDriverChangeType_GRAPH_DRIVER_CHANGE_TYPE_MODIFIED GraphDriverChangeType = 1 - GraphDriverChangeType_GRAPH_DRIVER_CHANGE_TYPE_ADDED GraphDriverChangeType = 2 - GraphDriverChangeType_GRAPH_DRIVER_CHANGE_TYPE_DELETED GraphDriverChangeType = 3 -) - -var GraphDriverChangeType_name = map[int32]string{ - 0: "GRAPH_DRIVER_CHANGE_TYPE_NONE", - 1: "GRAPH_DRIVER_CHANGE_TYPE_MODIFIED", - 2: "GRAPH_DRIVER_CHANGE_TYPE_ADDED", - 3: "GRAPH_DRIVER_CHANGE_TYPE_DELETED", -} -var GraphDriverChangeType_value = map[string]int32{ - "GRAPH_DRIVER_CHANGE_TYPE_NONE": 0, - "GRAPH_DRIVER_CHANGE_TYPE_MODIFIED": 1, - "GRAPH_DRIVER_CHANGE_TYPE_ADDED": 2, - "GRAPH_DRIVER_CHANGE_TYPE_DELETED": 3, -} - -func (x GraphDriverChangeType) String() string { - return proto.EnumName(GraphDriverChangeType_name, int32(x)) -} -func (GraphDriverChangeType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -type SeverityType int32 - -const ( - SeverityType_SEVERITY_TYPE_NONE SeverityType = 0 - SeverityType_SEVERITY_TYPE_ALARM SeverityType = 1 - SeverityType_SEVERITY_TYPE_WARNING SeverityType = 2 - SeverityType_SEVERITY_TYPE_NOTIFY SeverityType = 3 -) - -var SeverityType_name = map[int32]string{ - 0: "SEVERITY_TYPE_NONE", - 1: "SEVERITY_TYPE_ALARM", - 2: "SEVERITY_TYPE_WARNING", - 3: "SEVERITY_TYPE_NOTIFY", -} -var SeverityType_value = map[string]int32{ - "SEVERITY_TYPE_NONE": 0, - "SEVERITY_TYPE_ALARM": 1, - "SEVERITY_TYPE_WARNING": 2, - "SEVERITY_TYPE_NOTIFY": 3, -} - -func (x SeverityType) String() string { - return proto.EnumName(SeverityType_name, int32(x)) -} -func (SeverityType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -type ResourceType int32 - -const ( - ResourceType_RESOURCE_TYPE_NONE ResourceType = 0 - ResourceType_RESOURCE_TYPE_VOLUME ResourceType = 1 - ResourceType_RESOURCE_TYPE_NODE ResourceType = 2 - ResourceType_RESOURCE_TYPE_CLUSTER ResourceType = 3 - ResourceType_RESOURCE_TYPE_DRIVE ResourceType = 4 -) - -var ResourceType_name = map[int32]string{ - 0: "RESOURCE_TYPE_NONE", - 1: "RESOURCE_TYPE_VOLUME", - 2: "RESOURCE_TYPE_NODE", - 3: "RESOURCE_TYPE_CLUSTER", - 4: "RESOURCE_TYPE_DRIVE", -} -var ResourceType_value = map[string]int32{ - "RESOURCE_TYPE_NONE": 0, - "RESOURCE_TYPE_VOLUME": 1, - "RESOURCE_TYPE_NODE": 2, - "RESOURCE_TYPE_CLUSTER": 3, - "RESOURCE_TYPE_DRIVE": 4, -} - -func (x ResourceType) String() string { - return proto.EnumName(ResourceType_name, int32(x)) -} -func (ResourceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -type AlertActionType int32 - -const ( - AlertActionType_ALERT_ACTION_TYPE_NONE AlertActionType = 0 - AlertActionType_ALERT_ACTION_TYPE_DELETE AlertActionType = 1 - AlertActionType_ALERT_ACTION_TYPE_CREATE AlertActionType = 2 - AlertActionType_ALERT_ACTION_TYPE_UPDATE AlertActionType = 3 -) - -var AlertActionType_name = map[int32]string{ - 0: "ALERT_ACTION_TYPE_NONE", - 1: "ALERT_ACTION_TYPE_DELETE", - 2: "ALERT_ACTION_TYPE_CREATE", - 3: "ALERT_ACTION_TYPE_UPDATE", -} -var AlertActionType_value = map[string]int32{ - "ALERT_ACTION_TYPE_NONE": 0, - "ALERT_ACTION_TYPE_DELETE": 1, - "ALERT_ACTION_TYPE_CREATE": 2, - "ALERT_ACTION_TYPE_UPDATE": 3, -} - -func (x AlertActionType) String() string { - return proto.EnumName(AlertActionType_name, int32(x)) -} -func (AlertActionType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -type VolumeActionParam int32 - -const ( - VolumeActionParam_VOLUME_ACTION_PARAM_NONE VolumeActionParam = 0 - // Maps to the boolean value false - VolumeActionParam_VOLUME_ACTION_PARAM_OFF VolumeActionParam = 1 - // Maps to the boolean value true. - VolumeActionParam_VOLUME_ACTION_PARAM_ON VolumeActionParam = 2 -) - -var VolumeActionParam_name = map[int32]string{ - 0: "VOLUME_ACTION_PARAM_NONE", - 1: "VOLUME_ACTION_PARAM_OFF", - 2: "VOLUME_ACTION_PARAM_ON", -} -var VolumeActionParam_value = map[string]int32{ - "VOLUME_ACTION_PARAM_NONE": 0, - "VOLUME_ACTION_PARAM_OFF": 1, - "VOLUME_ACTION_PARAM_ON": 2, -} - -func (x VolumeActionParam) String() string { - return proto.EnumName(VolumeActionParam_name, int32(x)) -} -func (VolumeActionParam) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -type CosType int32 - -const ( - CosType_NONE CosType = 0 - CosType_LOW CosType = 1 - CosType_MEDIUM CosType = 2 - CosType_HIGH CosType = 3 -) - -var CosType_name = map[int32]string{ - 0: "NONE", - 1: "LOW", - 2: "MEDIUM", - 3: "HIGH", -} -var CosType_value = map[string]int32{ - "NONE": 0, - "LOW": 1, - "MEDIUM": 2, - "HIGH": 3, -} - -func (x CosType) String() string { - return proto.EnumName(CosType_name, int32(x)) -} -func (CosType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -type IoProfile int32 - -const ( - IoProfile_IO_PROFILE_SEQUENTIAL IoProfile = 0 - IoProfile_IO_PROFILE_RANDOM IoProfile = 1 - IoProfile_IO_PROFILE_DB IoProfile = 2 - IoProfile_IO_PROFILE_DB_REMOTE IoProfile = 3 -) - -var IoProfile_name = map[int32]string{ - 0: "IO_PROFILE_SEQUENTIAL", - 1: "IO_PROFILE_RANDOM", - 2: "IO_PROFILE_DB", - 3: "IO_PROFILE_DB_REMOTE", -} -var IoProfile_value = map[string]int32{ - "IO_PROFILE_SEQUENTIAL": 0, - "IO_PROFILE_RANDOM": 1, - "IO_PROFILE_DB": 2, - "IO_PROFILE_DB_REMOTE": 3, -} - -func (x IoProfile) String() string { - return proto.EnumName(IoProfile_name, int32(x)) -} -func (IoProfile) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -// VolumeState represents the state of a volume. -type VolumeState int32 - -const ( - VolumeState_VOLUME_STATE_NONE VolumeState = 0 - // Volume is transitioning to new state - VolumeState_VOLUME_STATE_PENDING VolumeState = 1 - // Volume is ready to be assigned to a container - VolumeState_VOLUME_STATE_AVAILABLE VolumeState = 2 - // Volume is attached to container - VolumeState_VOLUME_STATE_ATTACHED VolumeState = 3 - // Volume is detached but associated with a container - VolumeState_VOLUME_STATE_DETACHED VolumeState = 4 - // Volume detach is in progress - VolumeState_VOLUME_STATE_DETATCHING VolumeState = 5 - // Volume is in error state - VolumeState_VOLUME_STATE_ERROR VolumeState = 6 - // Volume is deleted, it will remain in this state - // while resources are asynchronously reclaimed - VolumeState_VOLUME_STATE_DELETED VolumeState = 7 - // Volume is trying to be detached - VolumeState_VOLUME_STATE_TRY_DETACHING VolumeState = 8 - // Volume is undergoing restore - VolumeState_VOLUME_STATE_RESTORE VolumeState = 9 -) - -var VolumeState_name = map[int32]string{ - 0: "VOLUME_STATE_NONE", - 1: "VOLUME_STATE_PENDING", - 2: "VOLUME_STATE_AVAILABLE", - 3: "VOLUME_STATE_ATTACHED", - 4: "VOLUME_STATE_DETACHED", - 5: "VOLUME_STATE_DETATCHING", - 6: "VOLUME_STATE_ERROR", - 7: "VOLUME_STATE_DELETED", - 8: "VOLUME_STATE_TRY_DETACHING", - 9: "VOLUME_STATE_RESTORE", -} -var VolumeState_value = map[string]int32{ - "VOLUME_STATE_NONE": 0, - "VOLUME_STATE_PENDING": 1, - "VOLUME_STATE_AVAILABLE": 2, - "VOLUME_STATE_ATTACHED": 3, - "VOLUME_STATE_DETACHED": 4, - "VOLUME_STATE_DETATCHING": 5, - "VOLUME_STATE_ERROR": 6, - "VOLUME_STATE_DELETED": 7, - "VOLUME_STATE_TRY_DETACHING": 8, - "VOLUME_STATE_RESTORE": 9, -} - -func (x VolumeState) String() string { - return proto.EnumName(VolumeState_name, int32(x)) -} -func (VolumeState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -// VolumeStatus represents a health status for a volume. -type VolumeStatus int32 - -const ( - VolumeStatus_VOLUME_STATUS_NONE VolumeStatus = 0 - // Volume is not present - VolumeStatus_VOLUME_STATUS_NOT_PRESENT VolumeStatus = 1 - // Volume is healthy - VolumeStatus_VOLUME_STATUS_UP VolumeStatus = 2 - // Volume is in fail mode - VolumeStatus_VOLUME_STATUS_DOWN VolumeStatus = 3 - // Volume is up but with degraded performance - // In a RAID group, this may indicate a problem with one or more drives - VolumeStatus_VOLUME_STATUS_DEGRADED VolumeStatus = 4 -) - -var VolumeStatus_name = map[int32]string{ - 0: "VOLUME_STATUS_NONE", - 1: "VOLUME_STATUS_NOT_PRESENT", - 2: "VOLUME_STATUS_UP", - 3: "VOLUME_STATUS_DOWN", - 4: "VOLUME_STATUS_DEGRADED", -} -var VolumeStatus_value = map[string]int32{ - "VOLUME_STATUS_NONE": 0, - "VOLUME_STATUS_NOT_PRESENT": 1, - "VOLUME_STATUS_UP": 2, - "VOLUME_STATUS_DOWN": 3, - "VOLUME_STATUS_DEGRADED": 4, -} - -func (x VolumeStatus) String() string { - return proto.EnumName(VolumeStatus_name, int32(x)) -} -func (VolumeStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -type StorageMedium int32 - -const ( - // Magnetic spinning disk. - StorageMedium_STORAGE_MEDIUM_MAGNETIC StorageMedium = 0 - // SSD disk - StorageMedium_STORAGE_MEDIUM_SSD StorageMedium = 1 - // NVME disk - StorageMedium_STORAGE_MEDIUM_NVME StorageMedium = 2 -) - -var StorageMedium_name = map[int32]string{ - 0: "STORAGE_MEDIUM_MAGNETIC", - 1: "STORAGE_MEDIUM_SSD", - 2: "STORAGE_MEDIUM_NVME", -} -var StorageMedium_value = map[string]int32{ - "STORAGE_MEDIUM_MAGNETIC": 0, - "STORAGE_MEDIUM_SSD": 1, - "STORAGE_MEDIUM_NVME": 2, -} - -func (x StorageMedium) String() string { - return proto.EnumName(StorageMedium_name, int32(x)) -} -func (StorageMedium) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -type ClusterNotify int32 - -const ( - // Node is down - ClusterNotify_CLUSTER_NOTIFY_DOWN ClusterNotify = 0 -) - -var ClusterNotify_name = map[int32]string{ - 0: "CLUSTER_NOTIFY_DOWN", -} -var ClusterNotify_value = map[string]int32{ - "CLUSTER_NOTIFY_DOWN": 0, -} - -func (x ClusterNotify) String() string { - return proto.EnumName(ClusterNotify_name, int32(x)) -} -func (ClusterNotify) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -type AttachState int32 - -const ( - // Attached and available externally - AttachState_ATTACH_STATE_EXTERNAL AttachState = 0 - // Attached but only available internally - AttachState_ATTACH_STATE_INTERNAL AttachState = 1 - // Switching from External to Internal - AttachState_ATTACH_STATE_INTERNAL_SWITCH AttachState = 2 -) - -var AttachState_name = map[int32]string{ - 0: "ATTACH_STATE_EXTERNAL", - 1: "ATTACH_STATE_INTERNAL", - 2: "ATTACH_STATE_INTERNAL_SWITCH", -} -var AttachState_value = map[string]int32{ - "ATTACH_STATE_EXTERNAL": 0, - "ATTACH_STATE_INTERNAL": 1, - "ATTACH_STATE_INTERNAL_SWITCH": 2, -} - -func (x AttachState) String() string { - return proto.EnumName(AttachState_name, int32(x)) -} -func (AttachState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -// StorageResource groups properties of a storage device. -type StorageResource struct { - // Id is the LUN identifier. - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // Path device path for this storage resource. - Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` - // Storage medium. - Medium StorageMedium `protobuf:"varint,3,opt,name=medium,enum=openstorage.api.StorageMedium" json:"medium,omitempty"` - // True if this device is online. - Online bool `protobuf:"varint,4,opt,name=online" json:"online,omitempty"` - // IOPS - Iops uint64 `protobuf:"varint,5,opt,name=iops" json:"iops,omitempty"` - // SeqWrite - SeqWrite float64 `protobuf:"fixed64,6,opt,name=seq_write,json=seqWrite" json:"seq_write,omitempty"` - // SeqRead - SeqRead float64 `protobuf:"fixed64,7,opt,name=seq_read,json=seqRead" json:"seq_read,omitempty"` - // RandRW - RandRW float64 `protobuf:"fixed64,8,opt,name=randRW" json:"randRW,omitempty"` - // Total size in bytes. - Size uint64 `protobuf:"varint,9,opt,name=size" json:"size,omitempty"` - // Physical Bytes used. - Used uint64 `protobuf:"varint,10,opt,name=used" json:"used,omitempty"` - // True if this device is rotational. - RotationSpeed string `protobuf:"bytes,11,opt,name=rotation_speed,json=rotationSpeed" json:"rotation_speed,omitempty"` - // Timestamp of last time this device was scanned. - LastScan *google_protobuf.Timestamp `protobuf:"bytes,12,opt,name=last_scan,json=lastScan" json:"last_scan,omitempty"` -} - -func (m *StorageResource) Reset() { *m = StorageResource{} } -func (m *StorageResource) String() string { return proto.CompactTextString(m) } -func (*StorageResource) ProtoMessage() {} -func (*StorageResource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *StorageResource) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *StorageResource) GetPath() string { - if m != nil { - return m.Path - } - return "" -} - -func (m *StorageResource) GetMedium() StorageMedium { - if m != nil { - return m.Medium - } - return StorageMedium_STORAGE_MEDIUM_MAGNETIC -} - -func (m *StorageResource) GetOnline() bool { - if m != nil { - return m.Online - } - return false -} - -func (m *StorageResource) GetIops() uint64 { - if m != nil { - return m.Iops - } - return 0 -} - -func (m *StorageResource) GetSeqWrite() float64 { - if m != nil { - return m.SeqWrite - } - return 0 -} - -func (m *StorageResource) GetSeqRead() float64 { - if m != nil { - return m.SeqRead - } - return 0 -} - -func (m *StorageResource) GetRandRW() float64 { - if m != nil { - return m.RandRW - } - return 0 -} - -func (m *StorageResource) GetSize() uint64 { - if m != nil { - return m.Size - } - return 0 -} - -func (m *StorageResource) GetUsed() uint64 { - if m != nil { - return m.Used - } - return 0 -} - -func (m *StorageResource) GetRotationSpeed() string { - if m != nil { - return m.RotationSpeed - } - return "" -} - -func (m *StorageResource) GetLastScan() *google_protobuf.Timestamp { - if m != nil { - return m.LastScan - } - return nil -} - -// StoragePool groups different storage devices based on their CosType -type StoragePool struct { - // ID pool ID - ID int32 `protobuf:"varint,1,opt,name=ID,json=iD" json:"ID,omitempty"` - // Cos reflects the capabilities of this drive pool - Cos CosType `protobuf:"varint,2,opt,name=Cos,json=cos,enum=openstorage.api.CosType" json:"Cos,omitempty"` - // Medium underlying storage type - Medium StorageMedium `protobuf:"varint,3,opt,name=Medium,json=medium,enum=openstorage.api.StorageMedium" json:"Medium,omitempty"` - // RaidLevel storage raid level - RaidLevel string `protobuf:"bytes,4,opt,name=RaidLevel,json=raidLevel" json:"RaidLevel,omitempty"` - // TotalSize of the pool - TotalSize uint64 `protobuf:"varint,7,opt,name=TotalSize,json=totalSize" json:"TotalSize,omitempty"` - // Used size of the pool - Used uint64 `protobuf:"varint,8,opt,name=Used,json=used" json:"Used,omitempty"` - // Labels is a list of user defined name-value pairs - Labels map[string]string `protobuf:"bytes,9,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` -} - -func (m *StoragePool) Reset() { *m = StoragePool{} } -func (m *StoragePool) String() string { return proto.CompactTextString(m) } -func (*StoragePool) ProtoMessage() {} -func (*StoragePool) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *StoragePool) GetID() int32 { - if m != nil { - return m.ID - } - return 0 -} - -func (m *StoragePool) GetCos() CosType { - if m != nil { - return m.Cos - } - return CosType_NONE -} - -func (m *StoragePool) GetMedium() StorageMedium { - if m != nil { - return m.Medium - } - return StorageMedium_STORAGE_MEDIUM_MAGNETIC -} - -func (m *StoragePool) GetRaidLevel() string { - if m != nil { - return m.RaidLevel - } - return "" -} - -func (m *StoragePool) GetTotalSize() uint64 { - if m != nil { - return m.TotalSize - } - return 0 -} - -func (m *StoragePool) GetUsed() uint64 { - if m != nil { - return m.Used - } - return 0 -} - -func (m *StoragePool) GetLabels() map[string]string { - if m != nil { - return m.Labels - } - return nil -} - -// VolumeLocator is a structure that is attached to a volume -// and is used to carry opaque metadata. -type VolumeLocator struct { - // User friendly identifier - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // A set of name-value pairs that acts as search filters - VolumeLabels map[string]string `protobuf:"bytes,2,rep,name=volume_labels,json=volumeLabels" json:"volume_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` -} - -func (m *VolumeLocator) Reset() { *m = VolumeLocator{} } -func (m *VolumeLocator) String() string { return proto.CompactTextString(m) } -func (*VolumeLocator) ProtoMessage() {} -func (*VolumeLocator) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *VolumeLocator) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *VolumeLocator) GetVolumeLabels() map[string]string { - if m != nil { - return m.VolumeLabels - } - return nil -} - -type Source struct { - // A volume id, if specified will create a clone of the parent. - Parent string `protobuf:"bytes,1,opt,name=parent" json:"parent,omitempty"` - // Seed will seed the volume from the specified URI - // Any additional config for the source comes from the labels in the spec - Seed string `protobuf:"bytes,2,opt,name=seed" json:"seed,omitempty"` -} - -func (m *Source) Reset() { *m = Source{} } -func (m *Source) String() string { return proto.CompactTextString(m) } -func (*Source) ProtoMessage() {} -func (*Source) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *Source) GetParent() string { - if m != nil { - return m.Parent - } - return "" -} - -func (m *Source) GetSeed() string { - if m != nil { - return m.Seed - } - return "" -} - -type Group struct { - // Id common identifier across volumes that have the same group. - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *Group) Reset() { *m = Group{} } -func (m *Group) String() string { return proto.CompactTextString(m) } -func (*Group) ProtoMessage() {} -func (*Group) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -func (m *Group) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -// VolumeSpec has the properties needed to create a volume. -type VolumeSpec struct { - // Ephemeral storage - Ephemeral bool `protobuf:"varint,1,opt,name=ephemeral" json:"ephemeral,omitempty"` - // Size specifies the thin provisioned volume size. - Size uint64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"` - // Format specifies the filesystem for this volume. - Format FSType `protobuf:"varint,3,opt,name=format,enum=openstorage.api.FSType" json:"format,omitempty"` - // BlockSize for the filesystem. - BlockSize int64 `protobuf:"varint,4,opt,name=block_size,json=blockSize" json:"block_size,omitempty"` - // HaLevel specifies the number of copies of data. - HaLevel int64 `protobuf:"varint,5,opt,name=ha_level,json=haLevel" json:"ha_level,omitempty"` - // Cos specifies the relative class of service. - Cos CosType `protobuf:"varint,6,opt,name=cos,enum=openstorage.api.CosType" json:"cos,omitempty"` - // IoProfile provides a hint about application using this volume. - IoProfile IoProfile `protobuf:"varint,7,opt,name=io_profile,json=ioProfile,enum=openstorage.api.IoProfile" json:"io_profile,omitempty"` - // Dedupe specifies if the volume data is to be de-duplicated. - Dedupe bool `protobuf:"varint,8,opt,name=dedupe" json:"dedupe,omitempty"` - // SnapshotInterval in minutes, set to 0 to disable snapshots - SnapshotInterval uint32 `protobuf:"varint,9,opt,name=snapshot_interval,json=snapshotInterval" json:"snapshot_interval,omitempty"` - // VolumeLabels configuration labels - VolumeLabels map[string]string `protobuf:"bytes,10,rep,name=volume_labels,json=volumeLabels" json:"volume_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - // Shared is true if this volume can be remotely accessed. - Shared bool `protobuf:"varint,11,opt,name=shared" json:"shared,omitempty"` - // ReplicaSet is the desired set of nodes for the volume data. - ReplicaSet *ReplicaSet `protobuf:"bytes,12,opt,name=replica_set,json=replicaSet" json:"replica_set,omitempty"` - // Aggregatiokn level Specifies the number of parts the volume can be aggregated from. - AggregationLevel uint32 `protobuf:"varint,13,opt,name=aggregation_level,json=aggregationLevel" json:"aggregation_level,omitempty"` - // Encrypted is true if this volume will be cryptographically secured. - Encrypted bool `protobuf:"varint,14,opt,name=encrypted" json:"encrypted,omitempty"` - // Passphrase for an encrypted volume - Passphrase string `protobuf:"bytes,15,opt,name=passphrase" json:"passphrase,omitempty"` - // SnapshotSchedule a well known string that specifies when snapshots should be taken. - SnapshotSchedule string `protobuf:"bytes,16,opt,name=snapshot_schedule,json=snapshotSchedule" json:"snapshot_schedule,omitempty"` - // Scale allows autocreation of volumes. - Scale uint32 `protobuf:"varint,17,opt,name=scale" json:"scale,omitempty"` - // Sticky volumes cannot be deleted until the flag is removed. - Sticky bool `protobuf:"varint,18,opt,name=sticky" json:"sticky,omitempty"` - // Group identifies a consistency group - Group *Group `protobuf:"bytes,21,opt,name=group" json:"group,omitempty"` - // GroupEnforced is true if consistency group creation is enforced. - GroupEnforced bool `protobuf:"varint,22,opt,name=group_enforced,json=groupEnforced" json:"group_enforced,omitempty"` - // Compressed is true if this volume is to be compressed. - Compressed bool `protobuf:"varint,23,opt,name=compressed" json:"compressed,omitempty"` -} - -func (m *VolumeSpec) Reset() { *m = VolumeSpec{} } -func (m *VolumeSpec) String() string { return proto.CompactTextString(m) } -func (*VolumeSpec) ProtoMessage() {} -func (*VolumeSpec) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *VolumeSpec) GetEphemeral() bool { - if m != nil { - return m.Ephemeral - } - return false -} - -func (m *VolumeSpec) GetSize() uint64 { - if m != nil { - return m.Size - } - return 0 -} - -func (m *VolumeSpec) GetFormat() FSType { - if m != nil { - return m.Format - } - return FSType_FS_TYPE_NONE -} - -func (m *VolumeSpec) GetBlockSize() int64 { - if m != nil { - return m.BlockSize - } - return 0 -} - -func (m *VolumeSpec) GetHaLevel() int64 { - if m != nil { - return m.HaLevel - } - return 0 -} - -func (m *VolumeSpec) GetCos() CosType { - if m != nil { - return m.Cos - } - return CosType_NONE -} - -func (m *VolumeSpec) GetIoProfile() IoProfile { - if m != nil { - return m.IoProfile - } - return IoProfile_IO_PROFILE_SEQUENTIAL -} - -func (m *VolumeSpec) GetDedupe() bool { - if m != nil { - return m.Dedupe - } - return false -} - -func (m *VolumeSpec) GetSnapshotInterval() uint32 { - if m != nil { - return m.SnapshotInterval - } - return 0 -} - -func (m *VolumeSpec) GetVolumeLabels() map[string]string { - if m != nil { - return m.VolumeLabels - } - return nil -} - -func (m *VolumeSpec) GetShared() bool { - if m != nil { - return m.Shared - } - return false -} - -func (m *VolumeSpec) GetReplicaSet() *ReplicaSet { - if m != nil { - return m.ReplicaSet - } - return nil -} - -func (m *VolumeSpec) GetAggregationLevel() uint32 { - if m != nil { - return m.AggregationLevel - } - return 0 -} - -func (m *VolumeSpec) GetEncrypted() bool { - if m != nil { - return m.Encrypted - } - return false -} - -func (m *VolumeSpec) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *VolumeSpec) GetSnapshotSchedule() string { - if m != nil { - return m.SnapshotSchedule - } - return "" -} - -func (m *VolumeSpec) GetScale() uint32 { - if m != nil { - return m.Scale - } - return 0 -} - -func (m *VolumeSpec) GetSticky() bool { - if m != nil { - return m.Sticky - } - return false -} - -func (m *VolumeSpec) GetGroup() *Group { - if m != nil { - return m.Group - } - return nil -} - -func (m *VolumeSpec) GetGroupEnforced() bool { - if m != nil { - return m.GroupEnforced - } - return false -} - -func (m *VolumeSpec) GetCompressed() bool { - if m != nil { - return m.Compressed - } - return false -} - -// ReplicaSet set of machine IDs (nodes) to which part of this volume is erasure -// coded - for clustered storage arrays -type ReplicaSet struct { - Nodes []string `protobuf:"bytes,1,rep,name=nodes" json:"nodes,omitempty"` -} - -func (m *ReplicaSet) Reset() { *m = ReplicaSet{} } -func (m *ReplicaSet) String() string { return proto.CompactTextString(m) } -func (*ReplicaSet) ProtoMessage() {} -func (*ReplicaSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -func (m *ReplicaSet) GetNodes() []string { - if m != nil { - return m.Nodes - } - return nil -} - -// RuntimeStateMap is a list of name value mapping of driver specific runtime -// information. -type RuntimeStateMap struct { - RuntimeState map[string]string `protobuf:"bytes,1,rep,name=runtime_state,json=runtimeState" json:"runtime_state,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` -} - -func (m *RuntimeStateMap) Reset() { *m = RuntimeStateMap{} } -func (m *RuntimeStateMap) String() string { return proto.CompactTextString(m) } -func (*RuntimeStateMap) ProtoMessage() {} -func (*RuntimeStateMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -func (m *RuntimeStateMap) GetRuntimeState() map[string]string { - if m != nil { - return m.RuntimeState - } - return nil -} - -// Volume represents an abstract storage volume. -// Volume represents an abstract storage volume. -type Volume struct { - // Self referential volume ID. - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // Source specified seed data for the volume. - Source *Source `protobuf:"bytes,2,opt,name=source" json:"source,omitempty"` - // Group volumes in the same group have the same group id. - Group *Group `protobuf:"bytes,3,opt,name=group" json:"group,omitempty"` - // Readonly is true if this volume is to be mounted with readonly access. - Readonly bool `protobuf:"varint,4,opt,name=readonly" json:"readonly,omitempty"` - // User specified locator - Locator *VolumeLocator `protobuf:"bytes,5,opt,name=locator" json:"locator,omitempty"` - // Volume creation time - Ctime *google_protobuf.Timestamp `protobuf:"bytes,6,opt,name=ctime" json:"ctime,omitempty"` - // User specified VolumeSpec - Spec *VolumeSpec `protobuf:"bytes,7,opt,name=spec" json:"spec,omitempty"` - // Usage is bytes consumed by vtheis volume. - Usage uint64 `protobuf:"varint,8,opt,name=usage" json:"usage,omitempty"` - // LastScan is the time when an integrity check was run. - LastScan *google_protobuf.Timestamp `protobuf:"bytes,9,opt,name=last_scan,json=lastScan" json:"last_scan,omitempty"` - // Format specifies the filesytem for this volume. - Format FSType `protobuf:"varint,10,opt,name=format,enum=openstorage.api.FSType" json:"format,omitempty"` - // Status is the availability status of this volume. - Status VolumeStatus `protobuf:"varint,11,opt,name=status,enum=openstorage.api.VolumeStatus" json:"status,omitempty"` - // State is the current runtime state of this volume. - State VolumeState `protobuf:"varint,12,opt,name=state,enum=openstorage.api.VolumeState" json:"state,omitempty"` - // AttachedOn is the node instance identifier for clustered systems. - AttachedOn string `protobuf:"bytes,13,opt,name=attached_on,json=attachedOn" json:"attached_on,omitempty"` - // AttachedState shows whether the device is attached for internal or external use. - AttachedState AttachState `protobuf:"varint,14,opt,name=attached_state,json=attachedState,enum=openstorage.api.AttachState" json:"attached_state,omitempty"` - // DevicePath is the device exported by block device implementations. - DevicePath string `protobuf:"bytes,15,opt,name=device_path,json=devicePath" json:"device_path,omitempty"` - // SecureDevicePath is the device path for an encrypted volume. - SecureDevicePath string `protobuf:"bytes,16,opt,name=secure_device_path,json=secureDevicePath" json:"secure_device_path,omitempty"` - // AttachPath is the mounted path in the host namespace. - AttachPath []string `protobuf:"bytes,17,rep,name=attach_path,json=attachPath" json:"attach_path,omitempty"` - // AttachInfo is a list of name value mappings that provides attach information. - AttachInfo map[string]string `protobuf:"bytes,18,rep,name=attach_info,json=attachInfo" json:"attach_info,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - // ReplicatSets storage for this volumefor clustered storage arrays. - ReplicaSets []*ReplicaSet `protobuf:"bytes,19,rep,name=replica_sets,json=replicaSets" json:"replica_sets,omitempty"` - // RuntimeState is a lst of name value mapping of driver specific runtime - // information. - RuntimeState []*RuntimeStateMap `protobuf:"bytes,20,rep,name=runtime_state,json=runtimeState" json:"runtime_state,omitempty"` - // Error is the Last recorded error. - Error string `protobuf:"bytes,21,opt,name=error" json:"error,omitempty"` -} - -func (m *Volume) Reset() { *m = Volume{} } -func (m *Volume) String() string { return proto.CompactTextString(m) } -func (*Volume) ProtoMessage() {} -func (*Volume) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *Volume) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *Volume) GetSource() *Source { - if m != nil { - return m.Source - } - return nil -} - -func (m *Volume) GetGroup() *Group { - if m != nil { - return m.Group - } - return nil -} - -func (m *Volume) GetReadonly() bool { - if m != nil { - return m.Readonly - } - return false -} - -func (m *Volume) GetLocator() *VolumeLocator { - if m != nil { - return m.Locator - } - return nil -} - -func (m *Volume) GetCtime() *google_protobuf.Timestamp { - if m != nil { - return m.Ctime - } - return nil -} - -func (m *Volume) GetSpec() *VolumeSpec { - if m != nil { - return m.Spec - } - return nil -} - -func (m *Volume) GetUsage() uint64 { - if m != nil { - return m.Usage - } - return 0 -} - -func (m *Volume) GetLastScan() *google_protobuf.Timestamp { - if m != nil { - return m.LastScan - } - return nil -} - -func (m *Volume) GetFormat() FSType { - if m != nil { - return m.Format - } - return FSType_FS_TYPE_NONE -} - -func (m *Volume) GetStatus() VolumeStatus { - if m != nil { - return m.Status - } - return VolumeStatus_VOLUME_STATUS_NONE -} - -func (m *Volume) GetState() VolumeState { - if m != nil { - return m.State - } - return VolumeState_VOLUME_STATE_NONE -} - -func (m *Volume) GetAttachedOn() string { - if m != nil { - return m.AttachedOn - } - return "" -} - -func (m *Volume) GetAttachedState() AttachState { - if m != nil { - return m.AttachedState - } - return AttachState_ATTACH_STATE_EXTERNAL -} - -func (m *Volume) GetDevicePath() string { - if m != nil { - return m.DevicePath - } - return "" -} - -func (m *Volume) GetSecureDevicePath() string { - if m != nil { - return m.SecureDevicePath - } - return "" -} - -func (m *Volume) GetAttachPath() []string { - if m != nil { - return m.AttachPath - } - return nil -} - -func (m *Volume) GetAttachInfo() map[string]string { - if m != nil { - return m.AttachInfo - } - return nil -} - -func (m *Volume) GetReplicaSets() []*ReplicaSet { - if m != nil { - return m.ReplicaSets - } - return nil -} - -func (m *Volume) GetRuntimeState() []*RuntimeStateMap { - if m != nil { - return m.RuntimeState - } - return nil -} - -func (m *Volume) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -type Stats struct { - // Reads completed successfully - Reads uint64 `protobuf:"varint,1,opt,name=reads" json:"reads,omitempty"` - // Time spent in reads in ms - ReadMs uint64 `protobuf:"varint,2,opt,name=read_ms,json=readMs" json:"read_ms,omitempty"` - ReadBytes uint64 `protobuf:"varint,3,opt,name=read_bytes,json=readBytes" json:"read_bytes,omitempty"` - // Writes completed successfully - Writes uint64 `protobuf:"varint,4,opt,name=writes" json:"writes,omitempty"` - // Time spent in writes in ms - WriteMs uint64 `protobuf:"varint,5,opt,name=write_ms,json=writeMs" json:"write_ms,omitempty"` - WriteBytes uint64 `protobuf:"varint,6,opt,name=write_bytes,json=writeBytes" json:"write_bytes,omitempty"` - // IOs curently in progress - IoProgress uint64 `protobuf:"varint,7,opt,name=io_progress,json=ioProgress" json:"io_progress,omitempty"` - // Time spent doing IOs ms - IoMs uint64 `protobuf:"varint,8,opt,name=io_ms,json=ioMs" json:"io_ms,omitempty"` - // BytesUsed - BytesUsed uint64 `protobuf:"varint,9,opt,name=bytes_used,json=bytesUsed" json:"bytes_used,omitempty"` - // Interval in ms during which stats were collected - IntervalMs uint64 `protobuf:"varint,10,opt,name=interval_ms,json=intervalMs" json:"interval_ms,omitempty"` -} - -func (m *Stats) Reset() { *m = Stats{} } -func (m *Stats) String() string { return proto.CompactTextString(m) } -func (*Stats) ProtoMessage() {} -func (*Stats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *Stats) GetReads() uint64 { - if m != nil { - return m.Reads - } - return 0 -} - -func (m *Stats) GetReadMs() uint64 { - if m != nil { - return m.ReadMs - } - return 0 -} - -func (m *Stats) GetReadBytes() uint64 { - if m != nil { - return m.ReadBytes - } - return 0 -} - -func (m *Stats) GetWrites() uint64 { - if m != nil { - return m.Writes - } - return 0 -} - -func (m *Stats) GetWriteMs() uint64 { - if m != nil { - return m.WriteMs - } - return 0 -} - -func (m *Stats) GetWriteBytes() uint64 { - if m != nil { - return m.WriteBytes - } - return 0 -} - -func (m *Stats) GetIoProgress() uint64 { - if m != nil { - return m.IoProgress - } - return 0 -} - -func (m *Stats) GetIoMs() uint64 { - if m != nil { - return m.IoMs - } - return 0 -} - -func (m *Stats) GetBytesUsed() uint64 { - if m != nil { - return m.BytesUsed - } - return 0 -} - -func (m *Stats) GetIntervalMs() uint64 { - if m != nil { - return m.IntervalMs - } - return 0 -} - -type Alert struct { - // Id for Alert - Id int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - // Severity of the Alert - Severity SeverityType `protobuf:"varint,2,opt,name=severity,enum=openstorage.api.SeverityType" json:"severity,omitempty"` - // AlertType user defined alert type - AlertType int64 `protobuf:"varint,3,opt,name=alert_type,json=alertType" json:"alert_type,omitempty"` - // Message describing the Alert - Message string `protobuf:"bytes,4,opt,name=message" json:"message,omitempty"` - // Timestamp when Alert occured - Timestamp *google_protobuf.Timestamp `protobuf:"bytes,5,opt,name=timestamp" json:"timestamp,omitempty"` - // ResourceId where Alert occured - ResourceId string `protobuf:"bytes,6,opt,name=resource_id,json=resourceId" json:"resource_id,omitempty"` - // Resource where Alert occured - Resource ResourceType `protobuf:"varint,7,opt,name=resource,enum=openstorage.api.ResourceType" json:"resource,omitempty"` - // Cleared Flag - Cleared bool `protobuf:"varint,8,opt,name=cleared" json:"cleared,omitempty"` - // TTL in seconds for this Alert - Ttl uint64 `protobuf:"varint,9,opt,name=ttl" json:"ttl,omitempty"` - // UniqueTag helps identify a unique alert for a given resouce - UniqueTag string `protobuf:"bytes,10,opt,name=unique_tag,json=uniqueTag" json:"unique_tag,omitempty"` -} - -func (m *Alert) Reset() { *m = Alert{} } -func (m *Alert) String() string { return proto.CompactTextString(m) } -func (*Alert) ProtoMessage() {} -func (*Alert) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -func (m *Alert) GetId() int64 { - if m != nil { - return m.Id - } - return 0 -} - -func (m *Alert) GetSeverity() SeverityType { - if m != nil { - return m.Severity - } - return SeverityType_SEVERITY_TYPE_NONE -} - -func (m *Alert) GetAlertType() int64 { - if m != nil { - return m.AlertType - } - return 0 -} - -func (m *Alert) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *Alert) GetTimestamp() *google_protobuf.Timestamp { - if m != nil { - return m.Timestamp - } - return nil -} - -func (m *Alert) GetResourceId() string { - if m != nil { - return m.ResourceId - } - return "" -} - -func (m *Alert) GetResource() ResourceType { - if m != nil { - return m.Resource - } - return ResourceType_RESOURCE_TYPE_NONE -} - -func (m *Alert) GetCleared() bool { - if m != nil { - return m.Cleared - } - return false -} - -func (m *Alert) GetTtl() uint64 { - if m != nil { - return m.Ttl - } - return 0 -} - -func (m *Alert) GetUniqueTag() string { - if m != nil { - return m.UniqueTag - } - return "" -} - -type Alerts struct { - Alert []*Alert `protobuf:"bytes,1,rep,name=alert" json:"alert,omitempty"` -} - -func (m *Alerts) Reset() { *m = Alerts{} } -func (m *Alerts) String() string { return proto.CompactTextString(m) } -func (*Alerts) ProtoMessage() {} -func (*Alerts) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -func (m *Alerts) GetAlert() []*Alert { - if m != nil { - return m.Alert - } - return nil -} - -type VolumeCreateRequest struct { - // User specified volume name and labels - Locator *VolumeLocator `protobuf:"bytes,1,opt,name=locator" json:"locator,omitempty"` - // Source to create volume - Source *Source `protobuf:"bytes,2,opt,name=source" json:"source,omitempty"` - // The storage spec for the volume - Spec *VolumeSpec `protobuf:"bytes,3,opt,name=spec" json:"spec,omitempty"` -} - -func (m *VolumeCreateRequest) Reset() { *m = VolumeCreateRequest{} } -func (m *VolumeCreateRequest) String() string { return proto.CompactTextString(m) } -func (*VolumeCreateRequest) ProtoMessage() {} -func (*VolumeCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *VolumeCreateRequest) GetLocator() *VolumeLocator { - if m != nil { - return m.Locator - } - return nil -} - -func (m *VolumeCreateRequest) GetSource() *Source { - if m != nil { - return m.Source - } - return nil -} - -func (m *VolumeCreateRequest) GetSpec() *VolumeSpec { - if m != nil { - return m.Spec - } - return nil -} - -type VolumeResponse struct { - Error string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` -} - -func (m *VolumeResponse) Reset() { *m = VolumeResponse{} } -func (m *VolumeResponse) String() string { return proto.CompactTextString(m) } -func (*VolumeResponse) ProtoMessage() {} -func (*VolumeResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -func (m *VolumeResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -type VolumeCreateResponse struct { - // ID of the newly created volume - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - VolumeResponse *VolumeResponse `protobuf:"bytes,2,opt,name=volume_response,json=volumeResponse" json:"volume_response,omitempty"` -} - -func (m *VolumeCreateResponse) Reset() { *m = VolumeCreateResponse{} } -func (m *VolumeCreateResponse) String() string { return proto.CompactTextString(m) } -func (*VolumeCreateResponse) ProtoMessage() {} -func (*VolumeCreateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -func (m *VolumeCreateResponse) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *VolumeCreateResponse) GetVolumeResponse() *VolumeResponse { - if m != nil { - return m.VolumeResponse - } - return nil -} - -// VolumeStateAction specifies desired actions. -type VolumeStateAction struct { - // Attach or Detach volume - Attach VolumeActionParam `protobuf:"varint,1,opt,name=attach,enum=openstorage.api.VolumeActionParam" json:"attach,omitempty"` - // Mount or unmount volume - Mount VolumeActionParam `protobuf:"varint,2,opt,name=mount,enum=openstorage.api.VolumeActionParam" json:"mount,omitempty"` - // MountPath Path where the device is mounted - MountPath string `protobuf:"bytes,3,opt,name=mount_path,json=mountPath" json:"mount_path,omitempty"` - // DevicePath Path returned in attach - DevicePath string `protobuf:"bytes,4,opt,name=device_path,json=devicePath" json:"device_path,omitempty"` - // UnmountBeforeDetach is used to check whether unmount should be done before - // a detach - UnmountBeforeDetach bool `protobuf:"varint,5,opt,name=unmount_before_detach,json=unmountBeforeDetach" json:"unmount_before_detach,omitempty"` -} - -func (m *VolumeStateAction) Reset() { *m = VolumeStateAction{} } -func (m *VolumeStateAction) String() string { return proto.CompactTextString(m) } -func (*VolumeStateAction) ProtoMessage() {} -func (*VolumeStateAction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } - -func (m *VolumeStateAction) GetAttach() VolumeActionParam { - if m != nil { - return m.Attach - } - return VolumeActionParam_VOLUME_ACTION_PARAM_NONE -} - -func (m *VolumeStateAction) GetMount() VolumeActionParam { - if m != nil { - return m.Mount - } - return VolumeActionParam_VOLUME_ACTION_PARAM_NONE -} - -func (m *VolumeStateAction) GetMountPath() string { - if m != nil { - return m.MountPath - } - return "" -} - -func (m *VolumeStateAction) GetDevicePath() string { - if m != nil { - return m.DevicePath - } - return "" -} - -func (m *VolumeStateAction) GetUnmountBeforeDetach() bool { - if m != nil { - return m.UnmountBeforeDetach - } - return false -} - -type VolumeSetRequest struct { - // User specified volume name and labels - Locator *VolumeLocator `protobuf:"bytes,1,opt,name=locator" json:"locator,omitempty"` - // The storage spec for the volume - Spec *VolumeSpec `protobuf:"bytes,2,opt,name=spec" json:"spec,omitempty"` - // State modification on this volume. - Action *VolumeStateAction `protobuf:"bytes,3,opt,name=action" json:"action,omitempty"` - // additional options - // required for the Set operation. - Options map[string]string `protobuf:"bytes,4,rep,name=options" json:"options,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` -} - -func (m *VolumeSetRequest) Reset() { *m = VolumeSetRequest{} } -func (m *VolumeSetRequest) String() string { return proto.CompactTextString(m) } -func (*VolumeSetRequest) ProtoMessage() {} -func (*VolumeSetRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } - -func (m *VolumeSetRequest) GetLocator() *VolumeLocator { - if m != nil { - return m.Locator - } - return nil -} - -func (m *VolumeSetRequest) GetSpec() *VolumeSpec { - if m != nil { - return m.Spec - } - return nil -} - -func (m *VolumeSetRequest) GetAction() *VolumeStateAction { - if m != nil { - return m.Action - } - return nil -} - -func (m *VolumeSetRequest) GetOptions() map[string]string { - if m != nil { - return m.Options - } - return nil -} - -type VolumeSetResponse struct { - Volume *Volume `protobuf:"bytes,1,opt,name=volume" json:"volume,omitempty"` - VolumeResponse *VolumeResponse `protobuf:"bytes,2,opt,name=volume_response,json=volumeResponse" json:"volume_response,omitempty"` -} - -func (m *VolumeSetResponse) Reset() { *m = VolumeSetResponse{} } -func (m *VolumeSetResponse) String() string { return proto.CompactTextString(m) } -func (*VolumeSetResponse) ProtoMessage() {} -func (*VolumeSetResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } - -func (m *VolumeSetResponse) GetVolume() *Volume { - if m != nil { - return m.Volume - } - return nil -} - -func (m *VolumeSetResponse) GetVolumeResponse() *VolumeResponse { - if m != nil { - return m.VolumeResponse - } - return nil -} - -type SnapCreateRequest struct { - // volume id - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Locator *VolumeLocator `protobuf:"bytes,2,opt,name=locator" json:"locator,omitempty"` - Readonly bool `protobuf:"varint,3,opt,name=readonly" json:"readonly,omitempty"` -} - -func (m *SnapCreateRequest) Reset() { *m = SnapCreateRequest{} } -func (m *SnapCreateRequest) String() string { return proto.CompactTextString(m) } -func (*SnapCreateRequest) ProtoMessage() {} -func (*SnapCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } - -func (m *SnapCreateRequest) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *SnapCreateRequest) GetLocator() *VolumeLocator { - if m != nil { - return m.Locator - } - return nil -} - -func (m *SnapCreateRequest) GetReadonly() bool { - if m != nil { - return m.Readonly - } - return false -} - -type SnapCreateResponse struct { - VolumeCreateResponse *VolumeCreateResponse `protobuf:"bytes,1,opt,name=volume_create_response,json=volumeCreateResponse" json:"volume_create_response,omitempty"` -} - -func (m *SnapCreateResponse) Reset() { *m = SnapCreateResponse{} } -func (m *SnapCreateResponse) String() string { return proto.CompactTextString(m) } -func (*SnapCreateResponse) ProtoMessage() {} -func (*SnapCreateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -func (m *SnapCreateResponse) GetVolumeCreateResponse() *VolumeCreateResponse { - if m != nil { - return m.VolumeCreateResponse - } - return nil -} - -type VolumeInfo struct { - VolumeId string `protobuf:"bytes,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` - Storage *VolumeSpec `protobuf:"bytes,3,opt,name=storage" json:"storage,omitempty"` -} - -func (m *VolumeInfo) Reset() { *m = VolumeInfo{} } -func (m *VolumeInfo) String() string { return proto.CompactTextString(m) } -func (*VolumeInfo) ProtoMessage() {} -func (*VolumeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } - -func (m *VolumeInfo) GetVolumeId() string { - if m != nil { - return m.VolumeId - } - return "" -} - -func (m *VolumeInfo) GetPath() string { - if m != nil { - return m.Path - } - return "" -} - -func (m *VolumeInfo) GetStorage() *VolumeSpec { - if m != nil { - return m.Storage - } - return nil -} - -// GraphDriverChanges represent a list of changes between the filesystem layers -// specified by the ID and Parent. // Parent may be an empty string, in which -// case there is no parent. -// Where the Path is the filesystem path within the layered filesystem -type GraphDriverChanges struct { - Path string `protobuf:"bytes,1,opt,name=path" json:"path,omitempty"` - Kind GraphDriverChangeType `protobuf:"varint,2,opt,name=kind,enum=openstorage.api.GraphDriverChangeType" json:"kind,omitempty"` -} - -func (m *GraphDriverChanges) Reset() { *m = GraphDriverChanges{} } -func (m *GraphDriverChanges) String() string { return proto.CompactTextString(m) } -func (*GraphDriverChanges) ProtoMessage() {} -func (*GraphDriverChanges) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } - -func (m *GraphDriverChanges) GetPath() string { - if m != nil { - return m.Path - } - return "" -} - -func (m *GraphDriverChanges) GetKind() GraphDriverChangeType { - if m != nil { - return m.Kind - } - return GraphDriverChangeType_GRAPH_DRIVER_CHANGE_TYPE_NONE -} - -type ClusterResponse struct { - Error string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` -} - -func (m *ClusterResponse) Reset() { *m = ClusterResponse{} } -func (m *ClusterResponse) String() string { return proto.CompactTextString(m) } -func (*ClusterResponse) ProtoMessage() {} -func (*ClusterResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } - -func (m *ClusterResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -type ActiveRequest struct { - ReqestKV map[int64]string `protobuf:"bytes,1,rep,name=ReqestKV,json=reqestKV" json:"ReqestKV,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` -} - -func (m *ActiveRequest) Reset() { *m = ActiveRequest{} } -func (m *ActiveRequest) String() string { return proto.CompactTextString(m) } -func (*ActiveRequest) ProtoMessage() {} -func (*ActiveRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } - -func (m *ActiveRequest) GetReqestKV() map[int64]string { - if m != nil { - return m.ReqestKV - } - return nil -} - -type ActiveRequests struct { - RequestCount int64 `protobuf:"varint,1,opt,name=RequestCount,json=requestCount" json:"RequestCount,omitempty"` - ActiveRequest []*ActiveRequest `protobuf:"bytes,2,rep,name=ActiveRequest,json=activeRequest" json:"ActiveRequest,omitempty"` -} - -func (m *ActiveRequests) Reset() { *m = ActiveRequests{} } -func (m *ActiveRequests) String() string { return proto.CompactTextString(m) } -func (*ActiveRequests) ProtoMessage() {} -func (*ActiveRequests) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } - -func (m *ActiveRequests) GetRequestCount() int64 { - if m != nil { - return m.RequestCount - } - return 0 -} - -func (m *ActiveRequests) GetActiveRequest() []*ActiveRequest { - if m != nil { - return m.ActiveRequest - } - return nil -} - -func init() { - proto.RegisterType((*StorageResource)(nil), "openstorage.api.StorageResource") - proto.RegisterType((*StoragePool)(nil), "openstorage.api.StoragePool") - proto.RegisterType((*VolumeLocator)(nil), "openstorage.api.VolumeLocator") - proto.RegisterType((*Source)(nil), "openstorage.api.Source") - proto.RegisterType((*Group)(nil), "openstorage.api.Group") - proto.RegisterType((*VolumeSpec)(nil), "openstorage.api.VolumeSpec") - proto.RegisterType((*ReplicaSet)(nil), "openstorage.api.ReplicaSet") - proto.RegisterType((*RuntimeStateMap)(nil), "openstorage.api.RuntimeStateMap") - proto.RegisterType((*Volume)(nil), "openstorage.api.Volume") - proto.RegisterType((*Stats)(nil), "openstorage.api.Stats") - proto.RegisterType((*Alert)(nil), "openstorage.api.Alert") - proto.RegisterType((*Alerts)(nil), "openstorage.api.Alerts") - proto.RegisterType((*VolumeCreateRequest)(nil), "openstorage.api.VolumeCreateRequest") - proto.RegisterType((*VolumeResponse)(nil), "openstorage.api.VolumeResponse") - proto.RegisterType((*VolumeCreateResponse)(nil), "openstorage.api.VolumeCreateResponse") - proto.RegisterType((*VolumeStateAction)(nil), "openstorage.api.VolumeStateAction") - proto.RegisterType((*VolumeSetRequest)(nil), "openstorage.api.VolumeSetRequest") - proto.RegisterType((*VolumeSetResponse)(nil), "openstorage.api.VolumeSetResponse") - proto.RegisterType((*SnapCreateRequest)(nil), "openstorage.api.SnapCreateRequest") - proto.RegisterType((*SnapCreateResponse)(nil), "openstorage.api.SnapCreateResponse") - proto.RegisterType((*VolumeInfo)(nil), "openstorage.api.VolumeInfo") - proto.RegisterType((*GraphDriverChanges)(nil), "openstorage.api.GraphDriverChanges") - proto.RegisterType((*ClusterResponse)(nil), "openstorage.api.ClusterResponse") - proto.RegisterType((*ActiveRequest)(nil), "openstorage.api.ActiveRequest") - proto.RegisterType((*ActiveRequests)(nil), "openstorage.api.ActiveRequests") - proto.RegisterEnum("openstorage.api.Status", Status_name, Status_value) - proto.RegisterEnum("openstorage.api.DriverType", DriverType_name, DriverType_value) - proto.RegisterEnum("openstorage.api.FSType", FSType_name, FSType_value) - proto.RegisterEnum("openstorage.api.GraphDriverChangeType", GraphDriverChangeType_name, GraphDriverChangeType_value) - proto.RegisterEnum("openstorage.api.SeverityType", SeverityType_name, SeverityType_value) - proto.RegisterEnum("openstorage.api.ResourceType", ResourceType_name, ResourceType_value) - proto.RegisterEnum("openstorage.api.AlertActionType", AlertActionType_name, AlertActionType_value) - proto.RegisterEnum("openstorage.api.VolumeActionParam", VolumeActionParam_name, VolumeActionParam_value) - proto.RegisterEnum("openstorage.api.CosType", CosType_name, CosType_value) - proto.RegisterEnum("openstorage.api.IoProfile", IoProfile_name, IoProfile_value) - proto.RegisterEnum("openstorage.api.VolumeState", VolumeState_name, VolumeState_value) - proto.RegisterEnum("openstorage.api.VolumeStatus", VolumeStatus_name, VolumeStatus_value) - proto.RegisterEnum("openstorage.api.StorageMedium", StorageMedium_name, StorageMedium_value) - proto.RegisterEnum("openstorage.api.ClusterNotify", ClusterNotify_name, ClusterNotify_value) - proto.RegisterEnum("openstorage.api.AttachState", AttachState_name, AttachState_value) -} - -func init() { proto.RegisterFile("api/api.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 2941 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0x4b, 0x73, 0xe3, 0xc6, - 0xb5, 0x1e, 0xf0, 0x25, 0xf2, 0x50, 0x94, 0xa0, 0x1e, 0x8d, 0xc4, 0xd1, 0xbc, 0x64, 0xd6, 0xb5, - 0xad, 0xd2, 0xf5, 0xd5, 0xb8, 0x74, 0x6d, 0xdf, 0xf1, 0xdc, 0x27, 0x45, 0x82, 0x12, 0xaf, 0xf9, - 0x90, 0x1b, 0x90, 0x66, 0xc6, 0xa9, 0x14, 0x0a, 0x43, 0xb6, 0x24, 0x64, 0x28, 0x02, 0x03, 0x80, - 0x4a, 0xc9, 0x7f, 0x20, 0x9b, 0x54, 0xb2, 0x4a, 0x52, 0x5e, 0xe5, 0x07, 0x78, 0x95, 0x75, 0x16, - 0x59, 0x67, 0x93, 0x5f, 0x92, 0x4d, 0xd6, 0xa9, 0x54, 0xa5, 0xce, 0xe9, 0x06, 0x05, 0x90, 0xd2, - 0x3c, 0x12, 0xef, 0xba, 0xbf, 0xf3, 0xe8, 0xd3, 0xa7, 0xcf, 0x0b, 0x24, 0x54, 0x1c, 0xdf, 0x7d, - 0xec, 0xf8, 0xee, 0x8e, 0x1f, 0x78, 0x91, 0xc7, 0x96, 0x3d, 0x5f, 0x8c, 0xc3, 0xc8, 0x0b, 0x9c, - 0x53, 0xb1, 0xe3, 0xf8, 0xee, 0xc6, 0xa3, 0x53, 0xcf, 0x3b, 0x1d, 0x89, 0xc7, 0x44, 0x7e, 0x39, - 0x39, 0x79, 0x1c, 0xb9, 0xe7, 0x22, 0x8c, 0x9c, 0x73, 0x5f, 0x4a, 0xd4, 0xfe, 0x92, 0x81, 0x65, - 0x53, 0x0a, 0x70, 0x11, 0x7a, 0x93, 0x60, 0x20, 0xd8, 0x12, 0x64, 0xdc, 0x61, 0x55, 0xdb, 0xd4, - 0xb6, 0x4a, 0x3c, 0xe3, 0x0e, 0x19, 0x83, 0x9c, 0xef, 0x44, 0x67, 0xd5, 0x0c, 0x21, 0xb4, 0x66, - 0x5f, 0x40, 0xe1, 0x5c, 0x0c, 0xdd, 0xc9, 0x79, 0x35, 0xbb, 0xa9, 0x6d, 0x2d, 0xed, 0x3e, 0xdc, - 0x99, 0x39, 0x7a, 0x47, 0x69, 0xed, 0x12, 0x17, 0x57, 0xdc, 0x6c, 0x0d, 0x0a, 0xde, 0x78, 0xe4, - 0x8e, 0x45, 0x35, 0xb7, 0xa9, 0x6d, 0x15, 0xb9, 0xda, 0xe1, 0x19, 0xae, 0xe7, 0x87, 0xd5, 0xfc, - 0xa6, 0xb6, 0x95, 0xe3, 0xb4, 0x66, 0xf7, 0xa0, 0x14, 0x8a, 0xd7, 0xf6, 0x4f, 0x03, 0x37, 0x12, - 0xd5, 0xc2, 0xa6, 0xb6, 0xa5, 0xf1, 0x62, 0x28, 0x5e, 0x3f, 0xc3, 0x3d, 0xbb, 0x0b, 0xb8, 0xb6, - 0x03, 0xe1, 0x0c, 0xab, 0x0b, 0x44, 0x5b, 0x08, 0xc5, 0x6b, 0x2e, 0x9c, 0x21, 0x9e, 0x11, 0x38, - 0xe3, 0x21, 0x7f, 0x56, 0x2d, 0x12, 0x41, 0xed, 0xf0, 0x8c, 0xd0, 0xfd, 0x56, 0x54, 0x4b, 0xf2, - 0x0c, 0x5c, 0x23, 0x36, 0x09, 0xc5, 0xb0, 0x0a, 0x12, 0xc3, 0x35, 0xfb, 0x10, 0x96, 0x02, 0x2f, - 0x72, 0x22, 0xd7, 0x1b, 0xdb, 0xa1, 0x2f, 0xc4, 0xb0, 0x5a, 0xa6, 0x9b, 0x57, 0x62, 0xd4, 0x44, - 0x90, 0xfd, 0x07, 0x94, 0x46, 0x4e, 0x18, 0xd9, 0xe1, 0xc0, 0x19, 0x57, 0x17, 0x37, 0xb5, 0xad, - 0xf2, 0xee, 0xc6, 0x8e, 0xf4, 0xf7, 0x4e, 0xec, 0xef, 0x1d, 0x2b, 0xf6, 0x37, 0x2f, 0x22, 0xb3, - 0x39, 0x70, 0xc6, 0xb5, 0x3f, 0x65, 0xa0, 0xac, 0xbc, 0x73, 0xe8, 0x79, 0x23, 0xf4, 0x77, 0xbb, - 0x49, 0xfe, 0xce, 0xf3, 0x8c, 0xdb, 0x64, 0xdb, 0x90, 0x6d, 0x78, 0x21, 0xb9, 0x7b, 0x69, 0xb7, - 0x3a, 0xe7, 0xd8, 0x86, 0x17, 0x5a, 0x97, 0xbe, 0xe0, 0xd9, 0x81, 0x17, 0xe2, 0x3b, 0x74, 0xff, - 0x91, 0x77, 0xb8, 0x0f, 0x25, 0xee, 0xb8, 0xc3, 0x8e, 0xb8, 0x10, 0x23, 0x7a, 0x8a, 0x12, 0x2f, - 0x05, 0x31, 0x80, 0x54, 0xcb, 0x8b, 0x9c, 0x91, 0x89, 0xee, 0x5a, 0x20, 0xd7, 0x94, 0xa2, 0x18, - 0x40, 0x9f, 0x1d, 0xa1, 0xcf, 0x8a, 0x09, 0x9f, 0xfd, 0x1f, 0x14, 0x46, 0xce, 0x4b, 0x31, 0x0a, - 0xab, 0xa5, 0xcd, 0xec, 0x56, 0x79, 0x77, 0xeb, 0x26, 0x3b, 0xf0, 0xc6, 0x3b, 0x1d, 0x62, 0x35, - 0xc6, 0x51, 0x70, 0xc9, 0x95, 0xdc, 0xc6, 0x97, 0x50, 0x4e, 0xc0, 0x4c, 0x87, 0xec, 0x2b, 0x71, - 0xa9, 0xa2, 0x10, 0x97, 0x6c, 0x15, 0xf2, 0x17, 0xce, 0x68, 0x22, 0x54, 0x1c, 0xca, 0xcd, 0xd3, - 0xcc, 0x13, 0xad, 0xf6, 0x7b, 0x0d, 0x2a, 0xc7, 0xde, 0x68, 0x72, 0x2e, 0x3a, 0xde, 0xc0, 0x89, - 0xbc, 0x00, 0x4d, 0x1c, 0x3b, 0xe7, 0x42, 0x89, 0xd3, 0x9a, 0x1d, 0x41, 0xe5, 0x82, 0x98, 0x6c, - 0x65, 0x69, 0x86, 0x2c, 0xfd, 0x74, 0xce, 0xd2, 0x94, 0xaa, 0x78, 0x97, 0xb0, 0x78, 0xf1, 0x22, - 0x01, 0x6d, 0xfc, 0x2f, 0xac, 0xcc, 0xb1, 0xbc, 0x97, 0xf5, 0x9f, 0x41, 0xc1, 0x94, 0x89, 0xb7, - 0x06, 0x05, 0xdf, 0x09, 0xc4, 0x38, 0x52, 0x82, 0x6a, 0x47, 0x81, 0x8b, 0x61, 0xa8, 0x12, 0x10, - 0xd7, 0xb5, 0x75, 0xc8, 0xef, 0x07, 0xde, 0xc4, 0x9f, 0xcd, 0xd6, 0xda, 0x5f, 0x0b, 0x00, 0xd2, - 0x20, 0xd3, 0x17, 0x03, 0x7c, 0x4a, 0xe1, 0x9f, 0x89, 0x73, 0x11, 0x38, 0x23, 0xe2, 0x2a, 0xf2, - 0x2b, 0x60, 0x9a, 0x12, 0x99, 0x44, 0x4a, 0x3c, 0x86, 0xc2, 0x89, 0x17, 0x9c, 0x3b, 0x91, 0x0a, - 0xa9, 0xf5, 0x39, 0x07, 0xb5, 0x4c, 0x0a, 0x40, 0xc5, 0xc6, 0x1e, 0x00, 0xbc, 0x1c, 0x79, 0x83, - 0x57, 0x36, 0xa9, 0xc2, 0x60, 0xca, 0xf2, 0x12, 0x21, 0x14, 0x2e, 0x77, 0xa1, 0x78, 0xe6, 0xd8, - 0x23, 0x8a, 0xb4, 0x3c, 0x11, 0x17, 0xce, 0x1c, 0x19, 0x67, 0xdb, 0x80, 0x41, 0x4c, 0xb9, 0xfd, - 0xd6, 0x48, 0xff, 0x12, 0xc0, 0xf5, 0x6c, 0x3f, 0xf0, 0x4e, 0xdc, 0x91, 0x0c, 0xca, 0xa5, 0xdd, - 0x8d, 0x39, 0x91, 0xb6, 0x77, 0x28, 0x39, 0x78, 0xc9, 0x8d, 0x97, 0xe8, 0xd7, 0xa1, 0x18, 0x4e, - 0x7c, 0x41, 0x21, 0x5b, 0xe4, 0x6a, 0xc7, 0xfe, 0x15, 0x56, 0xc2, 0xb1, 0xe3, 0x87, 0x67, 0x5e, - 0x64, 0xbb, 0xe3, 0x48, 0x04, 0x17, 0xce, 0x88, 0xaa, 0x43, 0x85, 0xeb, 0x31, 0xa1, 0xad, 0x70, - 0xc6, 0x67, 0xc3, 0x07, 0x28, 0x7c, 0xfe, 0xed, 0x86, 0xf0, 0x41, 0xe7, 0xbf, 0x2d, 0x76, 0xd0, - 0xb0, 0xf0, 0xcc, 0x09, 0x54, 0x85, 0x29, 0x72, 0xb5, 0x63, 0xff, 0x05, 0xe5, 0x40, 0xf8, 0x23, - 0x77, 0xe0, 0xd8, 0xa1, 0x88, 0x54, 0x71, 0xb9, 0x37, 0x77, 0x12, 0x97, 0x3c, 0xa6, 0x88, 0x38, - 0x04, 0xd3, 0x35, 0x5e, 0xcb, 0x39, 0x3d, 0x0d, 0xc4, 0xa9, 0x2c, 0x61, 0xd2, 0xf3, 0x15, 0x79, - 0xad, 0x04, 0x61, 0x9a, 0xea, 0x62, 0x3c, 0x08, 0x2e, 0xfd, 0x48, 0x0c, 0xab, 0x4b, 0x2a, 0x3e, - 0x62, 0x80, 0x3d, 0x04, 0xf0, 0x9d, 0x30, 0xf4, 0xcf, 0x02, 0x27, 0x14, 0xd5, 0x65, 0x0a, 0xb2, - 0x04, 0x92, 0xf2, 0x60, 0x38, 0x38, 0x13, 0xc3, 0xc9, 0x48, 0x54, 0x75, 0x62, 0x9b, 0x7a, 0xd0, - 0x54, 0x38, 0xa6, 0x40, 0x38, 0x70, 0x46, 0xa2, 0xba, 0x42, 0xb6, 0xc8, 0x0d, 0xf9, 0x20, 0x72, - 0x07, 0xaf, 0x2e, 0xab, 0x4c, 0xf9, 0x80, 0x76, 0xec, 0x13, 0xc8, 0x9f, 0x62, 0x80, 0x57, 0xef, - 0xd0, 0xed, 0xd7, 0xe6, 0x6e, 0x4f, 0xe1, 0xcf, 0x25, 0x13, 0xd6, 0x6c, 0x5a, 0xd8, 0x62, 0x7c, - 0xe2, 0x05, 0x03, 0x31, 0xac, 0xae, 0x91, 0xb6, 0x0a, 0xa1, 0x86, 0x02, 0xf1, 0x3e, 0x03, 0xef, - 0xdc, 0x0f, 0x44, 0x88, 0x05, 0x6c, 0x9d, 0x58, 0x12, 0xc8, 0x3f, 0x9f, 0xcc, 0x35, 0x80, 0xab, - 0x57, 0x41, 0xbe, 0xb1, 0x37, 0x14, 0x61, 0x55, 0xdb, 0xcc, 0x22, 0x1f, 0x6d, 0x6a, 0xdf, 0x6b, - 0xb0, 0xcc, 0x27, 0x63, 0x6c, 0xc5, 0x66, 0xe4, 0x44, 0xa2, 0xeb, 0xf8, 0xec, 0x19, 0x54, 0x02, - 0x09, 0xd9, 0x21, 0x62, 0x24, 0x51, 0xde, 0xdd, 0x9d, 0x7f, 0xf3, 0xb4, 0x60, 0x6a, 0xaf, 0x42, - 0x2c, 0x48, 0x40, 0x78, 0xa3, 0x39, 0x96, 0xf7, 0xba, 0xd1, 0x6f, 0x8a, 0x50, 0x90, 0x3e, 0x99, - 0x1b, 0x0c, 0x1e, 0x43, 0x41, 0x8e, 0x0c, 0x24, 0x55, 0xbe, 0xa6, 0x52, 0xc8, 0xc2, 0xc6, 0x15, - 0xdb, 0xd5, 0x9b, 0x66, 0xdf, 0xe5, 0x4d, 0x37, 0xa0, 0x88, 0xed, 0xdd, 0x1b, 0x8f, 0x2e, 0xd5, - 0xb4, 0x30, 0xdd, 0xb3, 0x27, 0xb0, 0x30, 0x92, 0x05, 0x9a, 0x6a, 0x4a, 0xf9, 0x9a, 0xc6, 0x97, - 0x2a, 0xe3, 0x3c, 0x66, 0x67, 0x9f, 0x42, 0x7e, 0x80, 0xee, 0xa0, 0xaa, 0xf3, 0xe6, 0x96, 0x2d, - 0x19, 0xd9, 0x63, 0xc8, 0x85, 0xbe, 0x18, 0x50, 0xcd, 0xb9, 0x2e, 0x0d, 0xaf, 0x12, 0x9e, 0x13, - 0x23, 0x3a, 0x73, 0x12, 0x3a, 0xa7, 0x42, 0x75, 0x48, 0xb9, 0x49, 0xcf, 0x0b, 0xa5, 0x77, 0x9f, - 0x17, 0x12, 0x05, 0x19, 0xde, 0xad, 0x20, 0x7f, 0x8e, 0x29, 0xe5, 0x44, 0x93, 0x90, 0xca, 0xca, - 0xd2, 0xee, 0x83, 0x9b, 0x4c, 0x26, 0x26, 0xae, 0x98, 0xd9, 0x2e, 0xe4, 0x65, 0xec, 0x2d, 0x92, - 0xd4, 0xfd, 0x37, 0x48, 0x09, 0x2e, 0x59, 0xd9, 0x23, 0x28, 0x3b, 0x51, 0xe4, 0x60, 0x8a, 0xdb, - 0xde, 0x98, 0xaa, 0x4c, 0x89, 0x43, 0x0c, 0xf5, 0xc7, 0xac, 0x01, 0x4b, 0x53, 0x06, 0xa9, 0x7d, - 0xe9, 0x06, 0xed, 0x75, 0x62, 0x93, 0xda, 0x2b, 0xb1, 0x8c, 0x19, 0x9f, 0x32, 0x14, 0x17, 0xee, - 0x40, 0xd8, 0x34, 0x88, 0xaa, 0x3a, 0x24, 0xa1, 0x43, 0x1c, 0x47, 0x3f, 0x01, 0x16, 0x8a, 0xc1, - 0x24, 0x10, 0x76, 0x92, 0x2f, 0x2e, 0x44, 0x44, 0x69, 0x5e, 0x71, 0x4f, 0x8d, 0x96, 0x6c, 0x2b, - 0x94, 0x9c, 0xca, 0x68, 0x62, 0x38, 0x98, 0x32, 0xb8, 0xe3, 0x13, 0xaf, 0xca, 0x28, 0x17, 0x3f, - 0xbe, 0xc1, 0x1f, 0xca, 0xf0, 0xf6, 0xf8, 0xc4, 0x93, 0x09, 0xa8, 0x34, 0x21, 0xc0, 0xfe, 0x07, - 0x16, 0x13, 0x95, 0x3c, 0xac, 0xde, 0x26, 0x55, 0x6f, 0x2c, 0xe5, 0xe5, 0xab, 0x52, 0x1e, 0x32, - 0x63, 0xb6, 0x2e, 0xac, 0x92, 0x82, 0xcd, 0xb7, 0xd5, 0x85, 0x74, 0x15, 0xc0, 0x88, 0x14, 0x41, - 0xe0, 0x05, 0x54, 0x4c, 0x4b, 0x5c, 0x6e, 0x36, 0xfe, 0x1b, 0x96, 0x67, 0x6c, 0x7f, 0xaf, 0xca, - 0xf0, 0xdb, 0x0c, 0xe4, 0x51, 0x7d, 0x88, 0x3c, 0x98, 0x99, 0x21, 0xc9, 0xe5, 0xb8, 0xdc, 0xb0, - 0x75, 0x58, 0xc0, 0x85, 0x7d, 0x1e, 0xaa, 0xf9, 0xa2, 0x80, 0xdb, 0x6e, 0x88, 0x03, 0x03, 0x11, - 0x5e, 0x5e, 0x46, 0x22, 0xa4, 0x5a, 0x90, 0xe3, 0x25, 0x44, 0xf6, 0x10, 0xc0, 0x8e, 0x40, 0x33, - 0x7f, 0x48, 0x59, 0x9f, 0xe3, 0x6a, 0x87, 0x83, 0x04, 0xad, 0x50, 0xa1, 0xfc, 0x4e, 0x58, 0xa0, - 0x7d, 0x37, 0xc4, 0x17, 0x95, 0x24, 0xa9, 0xb2, 0x40, 0x54, 0x20, 0x48, 0xea, 0x7c, 0x04, 0x65, - 0x39, 0x3d, 0x9c, 0x62, 0xa5, 0x57, 0x33, 0x2d, 0xd0, 0x88, 0x40, 0x08, 0xbb, 0x0d, 0x79, 0xd7, - 0x43, 0xcd, 0xc5, 0xf8, 0x0b, 0x44, 0x1a, 0x4a, 0x0a, 0x6d, 0xfa, 0x46, 0x90, 0xdf, 0x0d, 0x25, - 0x42, 0x70, 0x00, 0x26, 0xa5, 0x6a, 0x3c, 0x40, 0x49, 0x50, 0x4a, 0x15, 0xd4, 0x0d, 0x6b, 0x7f, - 0xce, 0x40, 0xbe, 0x3e, 0x12, 0x41, 0x94, 0x28, 0x9d, 0x59, 0x2a, 0x9d, 0x5f, 0xe2, 0xe7, 0xcb, - 0x85, 0x08, 0xdc, 0xe8, 0x52, 0x0d, 0xfa, 0xf3, 0x49, 0x6a, 0x2a, 0x06, 0xca, 0xed, 0x29, 0x3b, - 0x1a, 0xe5, 0xa0, 0x4e, 0x3b, 0xba, 0xf4, 0x05, 0x79, 0x2f, 0xcb, 0x4b, 0x84, 0x20, 0x23, 0xab, - 0xc2, 0xc2, 0xb9, 0x08, 0xa9, 0xfc, 0xc8, 0xb9, 0x3e, 0xde, 0xb2, 0x27, 0x50, 0x9a, 0x7e, 0xfe, - 0xa9, 0xaa, 0xf9, 0xa6, 0x02, 0x74, 0xc5, 0x8c, 0x17, 0x0d, 0xd4, 0xd7, 0xa1, 0xed, 0x0e, 0xc9, - 0xbd, 0x25, 0x1c, 0x39, 0x24, 0xd4, 0xa6, 0xeb, 0xc4, 0x3b, 0x35, 0x9a, 0x3d, 0xb8, 0x26, 0xc4, - 0x25, 0x83, 0xbc, 0x4e, 0xcc, 0x8e, 0xf6, 0x0e, 0x46, 0x82, 0x86, 0x20, 0x39, 0x9d, 0xc5, 0x5b, - 0x8c, 0xc5, 0x28, 0x1a, 0x29, 0xb7, 0xe3, 0x12, 0xaf, 0x3e, 0x19, 0xbb, 0xaf, 0x27, 0xc2, 0x8e, - 0x9c, 0x53, 0xf2, 0x77, 0x89, 0x97, 0x24, 0x62, 0x39, 0xa7, 0xb5, 0x2f, 0xa0, 0x40, 0xde, 0x0e, - 0xb1, 0xd1, 0x90, 0x47, 0x54, 0x1b, 0x9d, 0x6f, 0x34, 0xc4, 0xc7, 0x25, 0x53, 0xed, 0x77, 0x1a, - 0xdc, 0x96, 0xb9, 0xdc, 0x08, 0x04, 0x96, 0x1f, 0xf1, 0x7a, 0x22, 0xc2, 0x28, 0xd9, 0x64, 0xb4, - 0xf7, 0x6b, 0x32, 0xef, 0xdd, 0x19, 0xe3, 0x1e, 0x93, 0x7d, 0xc7, 0x1e, 0x53, 0xfb, 0x08, 0x96, - 0x24, 0xc6, 0x45, 0xe8, 0x7b, 0xe3, 0x30, 0x91, 0xe3, 0x5a, 0x22, 0xc7, 0x6b, 0x3e, 0xac, 0xa6, - 0xaf, 0xa6, 0xb8, 0x67, 0x7b, 0xf9, 0x01, 0x2c, 0xab, 0xf1, 0x36, 0x50, 0x2c, 0xca, 0xf4, 0x47, - 0x37, 0xd8, 0x12, 0x6b, 0xe2, 0x4b, 0x17, 0xa9, 0x7d, 0xed, 0x6f, 0x5a, 0x3c, 0x44, 0x51, 0xed, - 0xa9, 0x0f, 0x70, 0xd8, 0x64, 0x4f, 0xa1, 0x20, 0xcb, 0x22, 0x9d, 0xb9, 0xb4, 0x5b, 0xbb, 0x41, - 0xad, 0x64, 0x3f, 0x74, 0x02, 0xe7, 0x9c, 0x2b, 0x09, 0xf6, 0x04, 0xf2, 0xe7, 0xde, 0x64, 0x1c, - 0xa9, 0x4c, 0x79, 0x17, 0x51, 0x29, 0x80, 0x01, 0x43, 0x0b, 0x59, 0xe8, 0xb3, 0x32, 0x60, 0x08, - 0x89, 0x1b, 0x41, 0xb2, 0x5f, 0xe4, 0xe6, 0xfa, 0xca, 0x2e, 0xdc, 0x99, 0x8c, 0xa5, 0x86, 0x97, - 0xe2, 0xc4, 0xa3, 0xfe, 0x42, 0x97, 0xc8, 0x53, 0xa8, 0xde, 0x56, 0xc4, 0x3d, 0xa2, 0x35, 0x89, - 0x54, 0xfb, 0x43, 0x06, 0x74, 0x75, 0x7f, 0x11, 0xfd, 0x10, 0xa1, 0x24, 0x23, 0x23, 0xf3, 0xae, - 0xd3, 0x07, 0x7a, 0x9a, 0x3c, 0xa1, 0x82, 0xa9, 0xf6, 0xa6, 0x3e, 0x2e, 0x7d, 0xc6, 0x95, 0x04, - 0x3b, 0x80, 0x05, 0xcf, 0xc7, 0x15, 0xd6, 0x5e, 0xcc, 0x9c, 0x9d, 0x9b, 0x84, 0xa7, 0x57, 0xdb, - 0xe9, 0x4b, 0x01, 0xd9, 0xfb, 0x62, 0xf1, 0x8d, 0xa7, 0xb0, 0x98, 0x24, 0xbc, 0x57, 0x63, 0xf9, - 0xc5, 0x55, 0x04, 0xe1, 0x31, 0x2a, 0x62, 0x1f, 0x43, 0x41, 0x46, 0x9a, 0xf2, 0xe0, 0xfa, 0x4d, - 0x81, 0xa9, 0xd8, 0x7e, 0xc0, 0x90, 0xbe, 0x84, 0x15, 0x73, 0xec, 0xf8, 0xe9, 0xea, 0x30, 0x9b, - 0x41, 0x89, 0x27, 0xce, 0xbc, 0xdf, 0x13, 0x27, 0x07, 0xdd, 0x6c, 0x7a, 0xd0, 0xad, 0xbd, 0x06, - 0x96, 0x3c, 0x5a, 0xf9, 0xe2, 0x47, 0xb0, 0xa6, 0xae, 0x36, 0x20, 0xc2, 0xd5, 0x0d, 0xa5, 0x6f, - 0x3e, 0xbc, 0xe1, 0xe8, 0xb4, 0x1a, 0xbe, 0x7a, 0x71, 0x0d, 0x5a, 0x8b, 0xe2, 0x1f, 0x10, 0x68, - 0x82, 0xb9, 0x07, 0x25, 0x75, 0xd4, 0xf4, 0xb6, 0x45, 0x09, 0xb4, 0xaf, 0xff, 0x69, 0xf0, 0x73, - 0x58, 0x50, 0x07, 0xbf, 0x4b, 0x35, 0x8b, 0x79, 0x6b, 0x43, 0x60, 0xfb, 0x81, 0xe3, 0x9f, 0x35, - 0x03, 0xf7, 0x42, 0x04, 0x8d, 0x33, 0x67, 0x7c, 0x2a, 0xc2, 0xe9, 0x01, 0x5a, 0xe2, 0x80, 0xa7, - 0x90, 0x7b, 0xe5, 0x8e, 0x87, 0xaa, 0x1a, 0x7c, 0x74, 0xcd, 0x47, 0xc4, 0x8c, 0x1a, 0xea, 0x38, - 0x24, 0x53, 0xfb, 0x18, 0x96, 0x1b, 0xa3, 0x49, 0x18, 0x89, 0xe0, 0x2d, 0x75, 0xf3, 0xd7, 0x1a, - 0x54, 0x30, 0x39, 0x2e, 0xa6, 0xef, 0x7d, 0x00, 0x45, 0x2e, 0x5e, 0x8b, 0x30, 0xfa, 0xea, 0x58, - 0xb5, 0x95, 0x4f, 0xe6, 0xdb, 0x4a, 0x52, 0x62, 0x27, 0x66, 0x97, 0xa9, 0x51, 0x0c, 0xd4, 0x76, - 0xe3, 0x3f, 0xa1, 0x92, 0x22, 0x25, 0x93, 0x23, 0xfb, 0xb6, 0xe4, 0xf8, 0x16, 0x96, 0x52, 0xa7, - 0x84, 0xac, 0x06, 0x8b, 0x6a, 0xdd, 0xa0, 0x2a, 0x29, 0xd5, 0x2c, 0x06, 0x09, 0x8c, 0x35, 0x67, - 0x6e, 0xa3, 0x7e, 0xfc, 0x7a, 0xf8, 0xe6, 0x1b, 0xf0, 0x8a, 0x93, 0xdc, 0x6e, 0xff, 0x31, 0x03, - 0x05, 0xf9, 0xd1, 0xc0, 0x96, 0xa1, 0x6c, 0x5a, 0x75, 0xeb, 0xc8, 0xb4, 0x7b, 0xfd, 0x9e, 0xa1, - 0xdf, 0x4a, 0x00, 0xed, 0x5e, 0xdb, 0xd2, 0x35, 0x56, 0x81, 0x92, 0x02, 0xfa, 0x5f, 0xe9, 0x19, - 0xc6, 0x60, 0x29, 0xde, 0xb6, 0x5a, 0x9d, 0x76, 0xcf, 0xd0, 0xb3, 0x4c, 0x87, 0x45, 0x85, 0x19, - 0x9c, 0xf7, 0xb9, 0x9e, 0x63, 0x55, 0x58, 0x9d, 0xaa, 0xb5, 0xec, 0x76, 0xcf, 0xfe, 0xfa, 0xa8, - 0xcf, 0x8f, 0xba, 0x7a, 0x9e, 0xad, 0xc3, 0x6d, 0x45, 0x69, 0x1a, 0x8d, 0x7e, 0xb7, 0xdb, 0x36, - 0xcd, 0x76, 0xbf, 0xa7, 0x17, 0xd8, 0x1a, 0x30, 0x45, 0xe8, 0xd6, 0xdb, 0x3d, 0xcb, 0xe8, 0xd5, - 0x7b, 0x0d, 0x43, 0x5f, 0x48, 0x08, 0x98, 0x56, 0x9f, 0xd7, 0xf7, 0x0d, 0xbb, 0xd9, 0x7f, 0xd6, - 0xd3, 0x8b, 0xec, 0x1e, 0xac, 0xcf, 0x12, 0x8c, 0x7d, 0x5e, 0x6f, 0x1a, 0x4d, 0xbd, 0x94, 0x90, - 0xea, 0x19, 0x46, 0xd3, 0xb4, 0xb9, 0xb1, 0xd7, 0xef, 0x5b, 0x3a, 0xb0, 0xfb, 0x50, 0x9d, 0x91, - 0xe2, 0xc6, 0x5e, 0xbd, 0x43, 0x87, 0x95, 0xd9, 0x26, 0xdc, 0x9f, 0xd5, 0xc9, 0xdb, 0xc7, 0xc8, - 0x73, 0xd8, 0xa9, 0x37, 0x0c, 0x7d, 0x91, 0x2d, 0x01, 0x4c, 0xcd, 0x7c, 0xae, 0x57, 0xb6, 0xbf, - 0xd3, 0x00, 0x64, 0x90, 0xd2, 0xd8, 0xb6, 0x0a, 0x3a, 0x49, 0x70, 0xdb, 0x7a, 0x71, 0x68, 0xc4, - 0x4e, 0x9d, 0x41, 0x5b, 0xed, 0x8e, 0xa1, 0x6b, 0xec, 0x0e, 0xac, 0x24, 0xd1, 0xbd, 0x4e, 0xbf, - 0x81, 0x1e, 0x5e, 0x03, 0x96, 0x84, 0xfb, 0x7b, 0xff, 0x6f, 0x34, 0x2c, 0x3d, 0xcb, 0xee, 0xc2, - 0x9d, 0x24, 0xde, 0xe8, 0x1c, 0x99, 0x96, 0xc1, 0x8d, 0xa6, 0x9e, 0x9b, 0xd5, 0xb4, 0xcf, 0xeb, - 0x87, 0x07, 0x7a, 0x7e, 0xfb, 0x57, 0x1a, 0x14, 0xe4, 0x37, 0x25, 0x3e, 0x51, 0xcb, 0x4c, 0xd9, - 0xb4, 0x02, 0x95, 0x18, 0xd9, 0xb3, 0x78, 0xcb, 0xd4, 0xb5, 0x24, 0x93, 0xf1, 0xdc, 0xfa, 0x4c, - 0xcf, 0x24, 0x91, 0xd6, 0x91, 0x89, 0x6f, 0xbd, 0x0c, 0xe5, 0xa9, 0xa2, 0x96, 0xa9, 0xe7, 0x92, - 0xc0, 0x71, 0xcb, 0xd4, 0xf3, 0x49, 0xe0, 0x79, 0xcb, 0xd4, 0x0b, 0x49, 0xe0, 0x9b, 0x96, 0xa9, - 0x2f, 0x6c, 0x7f, 0xaf, 0xc1, 0x9d, 0x6b, 0xb3, 0x9b, 0x7d, 0x00, 0x0f, 0xc8, 0x78, 0x5b, 0x5d, - 0xa7, 0x71, 0x50, 0xef, 0xed, 0x1b, 0x29, 0xbb, 0x3f, 0x84, 0x0f, 0x6e, 0x64, 0xe9, 0xf6, 0x9b, - 0xed, 0x56, 0xdb, 0x68, 0xea, 0x1a, 0xab, 0xc1, 0xc3, 0x1b, 0xd9, 0xea, 0x4d, 0x0c, 0x92, 0x0c, - 0xfb, 0x17, 0xd8, 0xbc, 0x91, 0xa7, 0x69, 0x74, 0x0c, 0xcb, 0x68, 0xea, 0xd9, 0xed, 0x08, 0x16, - 0x93, 0x23, 0x3c, 0x05, 0xaa, 0x71, 0x6c, 0xf0, 0xb6, 0xf5, 0x22, 0x65, 0x18, 0x86, 0x5c, 0x0a, - 0xaf, 0x77, 0xea, 0xbc, 0xab, 0x6b, 0xf8, 0x70, 0x69, 0xc2, 0xb3, 0x3a, 0xef, 0xb5, 0x7b, 0xfb, - 0x7a, 0x86, 0xf2, 0x64, 0x46, 0x97, 0xd5, 0x6e, 0xbd, 0xd0, 0xb3, 0xdb, 0x3f, 0xd7, 0xb0, 0x1c, - 0x5c, 0x8d, 0xda, 0x78, 0x2c, 0x37, 0xcc, 0xfe, 0x11, 0x6f, 0xa4, 0xfd, 0x51, 0x85, 0xd5, 0x34, - 0x7e, 0xdc, 0xef, 0x1c, 0x75, 0x31, 0xbe, 0xae, 0x91, 0x68, 0x1a, 0x7a, 0x06, 0xed, 0x49, 0xe3, - 0x2a, 0x94, 0xf4, 0x2c, 0xde, 0x21, 0x4d, 0x22, 0xcf, 0xe8, 0xb9, 0xed, 0x9f, 0x69, 0xb0, 0x4c, - 0xc3, 0xb6, 0x9c, 0x34, 0xc8, 0xa2, 0x0d, 0x58, 0xab, 0x77, 0x0c, 0x6e, 0xd9, 0xf5, 0x86, 0xd5, - 0xee, 0xf7, 0x52, 0x56, 0xdd, 0x87, 0xea, 0x3c, 0x4d, 0xfa, 0x54, 0xd7, 0xae, 0xa7, 0x36, 0xb8, - 0x51, 0xb7, 0xd0, 0xbe, 0x6b, 0xa9, 0x47, 0x87, 0x4d, 0xa4, 0x66, 0xb7, 0x7f, 0x12, 0x0f, 0x15, - 0x89, 0x39, 0x11, 0x45, 0xe4, 0xb5, 0x63, 0x99, 0xc3, 0x3a, 0xaf, 0x77, 0x63, 0x63, 0xee, 0xc1, - 0xfa, 0x75, 0xd4, 0x7e, 0xab, 0xa5, 0x6b, 0x78, 0x8b, 0x6b, 0x89, 0x3d, 0x3d, 0xb3, 0xbd, 0x0b, - 0x0b, 0xea, 0xc7, 0x6b, 0x56, 0x84, 0x9c, 0xd2, 0xb6, 0x00, 0xd9, 0x4e, 0xff, 0x99, 0xae, 0x31, - 0x80, 0x42, 0xd7, 0x68, 0xb6, 0x8f, 0xba, 0x7a, 0x06, 0xc9, 0x07, 0xed, 0xfd, 0x03, 0xb2, 0xaf, - 0x34, 0xfd, 0xf5, 0x1a, 0x5d, 0xdd, 0xee, 0xdb, 0x87, 0xbc, 0x8f, 0x29, 0x6f, 0x9b, 0xc6, 0xd7, - 0x47, 0x46, 0xcf, 0x6a, 0xd7, 0x3b, 0xfa, 0x2d, 0xcc, 0xd9, 0x04, 0x89, 0xd7, 0x7b, 0xcd, 0x3e, - 0x06, 0xcb, 0x0a, 0x54, 0x12, 0x70, 0x73, 0x4f, 0x06, 0x49, 0x0a, 0xb2, 0xb9, 0xd1, 0xed, 0x93, - 0x2f, 0xbe, 0xcb, 0x40, 0x39, 0x31, 0x05, 0xa2, 0x4e, 0x75, 0x17, 0xac, 0x51, 0xc9, 0x10, 0x49, - 0xc1, 0x87, 0x46, 0xaf, 0x89, 0xf1, 0x97, 0xbc, 0xbc, 0xa4, 0xd4, 0x8f, 0xeb, 0xed, 0x4e, 0x7d, - 0xaf, 0xa3, 0xc2, 0x24, 0x4d, 0xb3, 0xac, 0x7a, 0xe3, 0x00, 0x53, 0x62, 0x8e, 0xd4, 0x34, 0x14, - 0x29, 0x97, 0xf0, 0xf5, 0x15, 0xc9, 0x6a, 0x1c, 0xe0, 0x71, 0x79, 0x8c, 0xc8, 0x14, 0x51, 0xb6, - 0x8b, 0xc2, 0x9c, 0x81, 0x71, 0xf2, 0x2d, 0xb0, 0x87, 0xb0, 0x91, 0xa2, 0x58, 0xfc, 0x85, 0x3a, - 0x0d, 0x35, 0x16, 0xe7, 0x24, 0xb9, 0x81, 0x85, 0xdb, 0xd0, 0x4b, 0xdb, 0xbf, 0xd4, 0x60, 0x31, - 0xf9, 0xfb, 0xd8, 0xcc, 0xe1, 0x57, 0x1d, 0xef, 0x01, 0xdc, 0x9d, 0xc5, 0x2d, 0xfb, 0x90, 0x1b, - 0xa6, 0xd1, 0xc3, 0xfe, 0xb7, 0x0a, 0x7a, 0x9a, 0x7c, 0x74, 0x28, 0x8b, 0x74, 0x1a, 0xa5, 0xa6, - 0x94, 0x9d, 0x71, 0x28, 0x75, 0x39, 0xd5, 0x93, 0x72, 0xdb, 0x3f, 0x86, 0x4a, 0xea, 0x5f, 0x3c, - 0xd9, 0xc1, 0x64, 0x9b, 0x91, 0x81, 0x64, 0x77, 0xeb, 0xfb, 0x3d, 0xc3, 0x6a, 0x37, 0xf4, 0x5b, - 0xb2, 0x1f, 0xa6, 0x88, 0xa6, 0x89, 0x85, 0x8d, 0x3a, 0x5b, 0x0a, 0xef, 0x1d, 0x77, 0x0d, 0x3d, - 0xb3, 0xbd, 0x05, 0x15, 0x35, 0x13, 0xf5, 0xbc, 0xc8, 0x3d, 0xb9, 0x44, 0x4e, 0x95, 0xd9, 0xaa, - 0xac, 0x48, 0x23, 0x6f, 0x6d, 0x0b, 0x28, 0x27, 0x7e, 0xa5, 0xc3, 0xd7, 0x94, 0x6f, 0x1b, 0xbf, - 0xca, 0x73, 0xcb, 0xe0, 0x3d, 0x0a, 0xd2, 0x59, 0x12, 0x36, 0x66, 0x22, 0x69, 0xd8, 0x2a, 0xaf, - 0x25, 0xd9, 0xe6, 0xb3, 0xb6, 0xd5, 0x38, 0xd0, 0x33, 0x7b, 0xf7, 0xe1, 0xf6, 0xc0, 0x3b, 0x9f, - 0x1d, 0x4d, 0x0e, 0xb5, 0x6f, 0xb2, 0x8e, 0xef, 0xbe, 0x2c, 0xd0, 0x6f, 0x15, 0xff, 0xfe, 0xf7, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xcd, 0xbf, 0x37, 0x4d, 0xfc, 0x1e, 0x00, 0x00, -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/api.proto b/vendor/github.com/libopenstorage/openstorage/api/api.proto deleted file mode 100644 index 7453874e57..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/api.proto +++ /dev/null @@ -1,471 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/timestamp.proto"; - -package openstorage.api; - -option go_package = "api"; -option java_multiple_files = true; -option java_package = "com.openstorage.api"; - -enum Status { - STATUS_NONE = 0; - STATUS_INIT = 1; - STATUS_OK = 2; - STATUS_OFFLINE = 3; - STATUS_ERROR = 4; - STATUS_NOT_IN_QUORUM = 5; - STATUS_DECOMMISSION = 6; - STATUS_MAINTENANCE = 7; - STATUS_STORAGE_DOWN = 8; - STATUS_STORAGE_DEGRADED = 9; - STATUS_NEEDS_REBOOT = 10; - STATUS_STORAGE_REBALANCE = 11; - STATUS_STORAGE_DRIVE_REPLACE = 12; - // Add statuses before MAX and update the number for MAX - STATUS_MAX = 13; -} - -enum DriverType { - DRIVER_TYPE_NONE = 0; - DRIVER_TYPE_FILE = 1; - DRIVER_TYPE_BLOCK = 2; - DRIVER_TYPE_OBJECT = 3; - DRIVER_TYPE_CLUSTERED = 4; - DRIVER_TYPE_GRAPH = 5; -} - -enum FSType { - FS_TYPE_NONE = 0; - FS_TYPE_BTRFS = 1; - FS_TYPE_EXT4 = 2; - FS_TYPE_FUSE = 3; - FS_TYPE_NFS = 4; - FS_TYPE_VFS = 5; - FS_TYPE_XFS = 6; - FS_TYPE_ZFS = 7; -} - -enum GraphDriverChangeType { - GRAPH_DRIVER_CHANGE_TYPE_NONE = 0; - GRAPH_DRIVER_CHANGE_TYPE_MODIFIED = 1; - GRAPH_DRIVER_CHANGE_TYPE_ADDED = 2; - GRAPH_DRIVER_CHANGE_TYPE_DELETED = 3; -} - -enum SeverityType { - SEVERITY_TYPE_NONE = 0; - SEVERITY_TYPE_ALARM = 1; - SEVERITY_TYPE_WARNING = 2; - SEVERITY_TYPE_NOTIFY = 3; -} - -enum ResourceType { - RESOURCE_TYPE_NONE = 0; - RESOURCE_TYPE_VOLUME = 1; - RESOURCE_TYPE_NODE = 2; - RESOURCE_TYPE_CLUSTER = 3; - RESOURCE_TYPE_DRIVE = 4; -} - -enum AlertActionType { - ALERT_ACTION_TYPE_NONE = 0; - ALERT_ACTION_TYPE_DELETE = 1; - ALERT_ACTION_TYPE_CREATE = 2; - ALERT_ACTION_TYPE_UPDATE = 3; -} - -enum VolumeActionParam { - VOLUME_ACTION_PARAM_NONE = 0; - // Maps to the boolean value false - VOLUME_ACTION_PARAM_OFF = 1; - // Maps to the boolean value true. - VOLUME_ACTION_PARAM_ON = 2; -} - -enum CosType { - NONE = 0; - LOW = 1; - MEDIUM = 2; - HIGH = 3; -} - -enum IoProfile { - IO_PROFILE_SEQUENTIAL = 0; - IO_PROFILE_RANDOM= 1; - IO_PROFILE_DB = 2; - IO_PROFILE_DB_REMOTE = 3; -} - -// VolumeState represents the state of a volume. -enum VolumeState { - VOLUME_STATE_NONE = 0; - // Volume is transitioning to new state - VOLUME_STATE_PENDING = 1; - // Volume is ready to be assigned to a container - VOLUME_STATE_AVAILABLE = 2; - // Volume is attached to container - VOLUME_STATE_ATTACHED = 3; - // Volume is detached but associated with a container - VOLUME_STATE_DETACHED = 4; - // Volume detach is in progress - VOLUME_STATE_DETATCHING = 5; - // Volume is in error state - VOLUME_STATE_ERROR = 6; - // Volume is deleted, it will remain in this state - // while resources are asynchronously reclaimed - VOLUME_STATE_DELETED = 7; - // Volume is trying to be detached - VOLUME_STATE_TRY_DETACHING = 8; - // Volume is undergoing restore - VOLUME_STATE_RESTORE = 9; -} - -// VolumeStatus represents a health status for a volume. -enum VolumeStatus { - VOLUME_STATUS_NONE = 0; - // Volume is not present - VOLUME_STATUS_NOT_PRESENT = 1; - // Volume is healthy - VOLUME_STATUS_UP = 2; - // Volume is in fail mode - VOLUME_STATUS_DOWN = 3; - // Volume is up but with degraded performance - // In a RAID group, this may indicate a problem with one or more drives - VOLUME_STATUS_DEGRADED = 4; -} - -enum StorageMedium { - // Magnetic spinning disk. - STORAGE_MEDIUM_MAGNETIC = 0; - // SSD disk - STORAGE_MEDIUM_SSD = 1; - // NVME disk - STORAGE_MEDIUM_NVME = 2; -} - -enum ClusterNotify { - // Node is down - CLUSTER_NOTIFY_DOWN = 0; -} - -enum AttachState { - // Attached and available externally - ATTACH_STATE_EXTERNAL = 0; - // Attached but only available internally - ATTACH_STATE_INTERNAL = 1; - // Switching from External to Internal - ATTACH_STATE_INTERNAL_SWITCH = 2; -} - -// StorageResource groups properties of a storage device. -message StorageResource { - // Id is the LUN identifier. - string id = 1; - // Path device path for this storage resource. - string path = 2; - // Storage medium. - StorageMedium medium = 3; - // True if this device is online. - bool online = 4;; - // IOPS - uint64 iops = 5;; - // SeqWrite - double seq_write = 6; - // SeqRead - double seq_read = 7; - // RandRW - double randRW = 8; - // Total size in bytes. - uint64 size = 9;; - // Physical Bytes used. - uint64 used = 10; - // True if this device is rotational. - string rotation_speed = 11; - // Timestamp of last time this device was scanned. - google.protobuf.Timestamp last_scan = 12; -} - -// StoragePool groups different storage devices based on their CosType -message StoragePool { - // ID pool ID - int32 ID = 1; - // Cos reflects the capabilities of this drive pool - CosType Cos = 2; - // Medium underlying storage type - StorageMedium Medium = 3; - // RaidLevel storage raid level - string RaidLevel = 4; - // TotalSize of the pool - uint64 TotalSize = 7; - // Used size of the pool - uint64 Used = 8; - // Labels is a list of user defined name-value pairs - map labels = 9; -} - -// VolumeLocator is a structure that is attached to a volume -// and is used to carry opaque metadata. -message VolumeLocator { - // User friendly identifier - string name = 1; - // A set of name-value pairs that acts as search filters - map volume_labels = 2; -} - -message Source { - // A volume id, if specified will create a clone of the parent. - string parent = 1; - // Seed will seed the volume from the specified URI - // Any additional config for the source comes from the labels in the spec - string seed = 2; -} - -message Group { - // Id common identifier across volumes that have the same group. - string id = 1; -} - -// VolumeSpec has the properties needed to create a volume. -message VolumeSpec { - // Ephemeral storage - bool ephemeral = 1; - // Size specifies the thin provisioned volume size. - uint64 size = 2; - // Format specifies the filesystem for this volume. - FSType format = 3; - // BlockSize for the filesystem. - int64 block_size = 4; - // HaLevel specifies the number of copies of data. - int64 ha_level = 5; - // Cos specifies the relative class of service. - CosType cos = 6; - // IoProfile provides a hint about application using this volume. - IoProfile io_profile = 7; - // Dedupe specifies if the volume data is to be de-duplicated. - bool dedupe = 8; - // SnapshotInterval in minutes, set to 0 to disable snapshots - uint32 snapshot_interval = 9; - // VolumeLabels configuration labels - map volume_labels = 10; - // Shared is true if this volume can be remotely accessed. - bool shared = 11; - // ReplicaSet is the desired set of nodes for the volume data. - ReplicaSet replica_set = 12; - // Aggregatiokn level Specifies the number of parts the volume can be aggregated from. - uint32 aggregation_level = 13; - // Encrypted is true if this volume will be cryptographically secured. - bool encrypted = 14; - // Passphrase for an encrypted volume - string passphrase = 15; - // SnapshotSchedule a well known string that specifies when snapshots should be taken. - string snapshot_schedule = 16; - // Scale allows autocreation of volumes. - uint32 scale = 17; - // Sticky volumes cannot be deleted until the flag is removed. - bool sticky = 18; - // Group identifies a consistency group - Group group = 21; - // GroupEnforced is true if consistency group creation is enforced. - bool group_enforced = 22; - // Compressed is true if this volume is to be compressed. - bool compressed = 23; -} - -// ReplicaSet set of machine IDs (nodes) to which part of this volume is erasure -// coded - for clustered storage arrays -message ReplicaSet { - repeated string nodes = 1; -} - -// RuntimeStateMap is a list of name value mapping of driver specific runtime -// information. -message RuntimeStateMap { - map runtime_state = 1; -} - -// Volume represents an abstract storage volume. -// Volume represents an abstract storage volume. -message Volume { - // Self referential volume ID. - string id = 1; - // Source specified seed data for the volume. - Source source = 2; - // Group volumes in the same group have the same group id. - Group group = 3; - // Readonly is true if this volume is to be mounted with readonly access. - bool readonly = 4; - // User specified locator - VolumeLocator locator = 5; - // Volume creation time - google.protobuf.Timestamp ctime = 6; - // User specified VolumeSpec - VolumeSpec spec = 7; - // Usage is bytes consumed by vtheis volume. - uint64 usage = 8; - // LastScan is the time when an integrity check was run. - google.protobuf.Timestamp last_scan = 9; - // Format specifies the filesytem for this volume. - FSType format = 10; - // Status is the availability status of this volume. - VolumeStatus status = 11; - // State is the current runtime state of this volume. - VolumeState state = 12; - // AttachedOn is the node instance identifier for clustered systems. - string attached_on = 13; - // AttachedState shows whether the device is attached for internal or external use. - AttachState attached_state = 14; - // DevicePath is the device exported by block device implementations. - string device_path = 15; - // SecureDevicePath is the device path for an encrypted volume. - string secure_device_path = 16; - // AttachPath is the mounted path in the host namespace. - repeated string attach_path = 17; - // AttachInfo is a list of name value mappings that provides attach information. - map attach_info = 18; - // ReplicatSets storage for this volumefor clustered storage arrays. - repeated ReplicaSet replica_sets = 19; - // RuntimeState is a lst of name value mapping of driver specific runtime - // information. - repeated RuntimeStateMap runtime_state = 20; - // Error is the Last recorded error. - string error = 21; -} - -message Stats { - // Reads completed successfully - uint64 reads = 1; - // Time spent in reads in ms - uint64 read_ms = 2; - uint64 read_bytes = 3; - // Writes completed successfully - uint64 writes = 4; - // Time spent in writes in ms - uint64 write_ms = 5; - uint64 write_bytes = 6; - // IOs curently in progress - uint64 io_progress = 7; - // Time spent doing IOs ms - uint64 io_ms = 8; - // BytesUsed - uint64 bytes_used = 9; - // Interval in ms during which stats were collected - uint64 interval_ms = 10; -} - -message Alert { - // Id for Alert - int64 id = 1; - // Severity of the Alert - SeverityType severity = 2; - // AlertType user defined alert type - int64 alert_type = 3; - // Message describing the Alert - string message = 4; - //Timestamp when Alert occured - google.protobuf.Timestamp timestamp = 5; - // ResourceId where Alert occured - string resource_id = 6; - // Resource where Alert occured - ResourceType resource = 7; - // Cleared Flag - bool cleared = 8; - // TTL in seconds for this Alert - uint64 ttl = 9; - // UniqueTag helps identify a unique alert for a given resouce - string unique_tag = 10; -} - -message Alerts { - repeated Alert alert = 1; -} - -message VolumeCreateRequest { - // User specified volume name and labels - VolumeLocator locator = 1; - // Source to create volume - Source source = 2; - // The storage spec for the volume - VolumeSpec spec = 3; -} - -message VolumeResponse { - string error = 1; -} - -message VolumeCreateResponse { - // ID of the newly created volume - string id = 1; - VolumeResponse volume_response = 2; -} - -// VolumeStateAction specifies desired actions. -message VolumeStateAction { - // Attach or Detach volume - VolumeActionParam attach = 1; - // Mount or unmount volume - VolumeActionParam mount = 2; - // MountPath Path where the device is mounted - string mount_path = 3; - // DevicePath Path returned in attach - string device_path = 4; - // UnmountBeforeDetach is used to check whether unmount should be done before - // a detach - bool unmount_before_detach = 5; -} - -message VolumeSetRequest { - // User specified volume name and labels - VolumeLocator locator = 1; - // The storage spec for the volume - VolumeSpec spec = 2; - // State modification on this volume. - VolumeStateAction action = 3; - // additional options - // required for the Set operation. - map options = 4; -} - -message VolumeSetResponse { - Volume volume = 1; - VolumeResponse volume_response = 2; -} - -message SnapCreateRequest { - // volume id - string id = 1; - VolumeLocator locator = 2; - bool readonly = 3; -} - -message SnapCreateResponse { - VolumeCreateResponse volume_create_response = 1; -} - -message VolumeInfo { - string volume_id = 1; - string path = 2; - VolumeSpec storage = 3; -} - -// GraphDriverChanges represent a list of changes between the filesystem layers -// specified by the ID and Parent. // Parent may be an empty string, in which -// case there is no parent. -// Where the Path is the filesystem path within the layered filesystem -message GraphDriverChanges { - string path = 1; - GraphDriverChangeType kind = 2; -} - -message ClusterResponse { - string error = 1; -} - -message ActiveRequest { - map ReqestKV = 1; -} - -message ActiveRequests { - int64 RequestCount = 1; - repeated ActiveRequest ActiveRequest = 2; -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/client/client.go b/vendor/github.com/libopenstorage/openstorage/api/client/client.go deleted file mode 100644 index 1b602d78c4..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/client/client.go +++ /dev/null @@ -1,178 +0,0 @@ -package client - -import ( - "crypto/tls" - "fmt" - "net" - "net/http" - "net/url" - "sync" - "time" -) - -var ( - httpCache = make(map[string]*http.Client) - cacheLock sync.Mutex -) - -// NewClient returns a new REST client for specified server. -func NewClient(host, version, userAgent string) (*Client, error) { - baseURL, err := url.Parse(host) - if err != nil { - return nil, err - } - if baseURL.Path == "" { - baseURL.Path = "/" - } - unix2HTTP(baseURL) - hClient := getHTTPClient(host) - if hClient == nil { - return nil, fmt.Errorf("Unable to parse provided url: %v", host) - } - c := &Client{ - base: baseURL, - version: version, - httpClient: hClient, - authstring: "", - accesstoken: "", - userAgent: fmt.Sprintf("%v/%v", userAgent, version), - } - return c, nil -} - -// NewAuthClient returns a new REST client for specified server. -func NewAuthClient(host, version, authstring, accesstoken, userAgent string) (*Client, error) { - baseURL, err := url.Parse(host) - if err != nil { - return nil, err - } - if baseURL.Path == "" { - baseURL.Path = "/" - } - unix2HTTP(baseURL) - hClient := getHTTPClient(host) - if hClient == nil { - return nil, fmt.Errorf("Unable to parse provided url: %v", host) - } - c := &Client{ - base: baseURL, - version: version, - httpClient: hClient, - authstring: authstring, - accesstoken: accesstoken, - userAgent: fmt.Sprintf("%v/%v", userAgent, version), - } - return c, nil -} - -// GetUnixServerPath returns a unix domain socket prepended with the -// provided path. -func GetUnixServerPath(socketName string, paths ...string) string { - serverPath := "unix://" - for _, path := range paths { - serverPath = serverPath + path - } - serverPath = serverPath + socketName + ".sock" - return serverPath -} - -// Client is an HTTP REST wrapper. Use one of Get/Post/Put/Delete to get a request -// object. -type Client struct { - base *url.URL - version string - httpClient *http.Client - authstring string - accesstoken string - userAgent string -} - -// Status sends a Status request at the /status REST endpoint. -func (c *Client) Status() (*Status, error) { - status := &Status{} - err := c.Get().UsePath("/status").Do().Unmarshal(status) - return status, err -} - -// Versions send a request at the /versions REST endpoint. -func (c *Client) Versions(endpoint string) ([]string, error) { - versions := []string{} - err := c.Get().Resource(endpoint + "/versions").Do().Unmarshal(&versions) - return versions, err -} - -// Get returns a Request object setup for GET call. -func (c *Client) Get() *Request { - return NewRequest(c.httpClient, c.base, "GET", c.version, c.authstring, c.userAgent) -} - -// Post returns a Request object setup for POST call. -func (c *Client) Post() *Request { - return NewRequest(c.httpClient, c.base, "POST", c.version, c.authstring, c.userAgent) -} - -// Put returns a Request object setup for PUT call. -func (c *Client) Put() *Request { - return NewRequest(c.httpClient, c.base, "PUT", c.version, c.authstring, c.userAgent) -} - -// Delete returns a Request object setup for DELETE call. -func (c *Client) Delete() *Request { - return NewRequest(c.httpClient, c.base, "DELETE", c.version, c.authstring, c.userAgent) -} - -func unix2HTTP(u *url.URL) { - if u.Scheme == "unix" { - // Override the main URL object so the HTTP lib won't complain - u.Scheme = "http" - u.Host = "unix.sock" - u.Path = "" - } -} - -func newHTTPClient( - u *url.URL, - tlsConfig *tls.Config, - timeout time.Duration, - responseTimeout time.Duration, -) *http.Client { - httpTransport := &http.Transport{ - TLSClientConfig: tlsConfig, - } - - switch u.Scheme { - case "unix": - socketPath := u.Path - unixDial := func(proto, addr string) (net.Conn, error) { - ret, err := net.DialTimeout("unix", socketPath, timeout) - return ret, err - } - httpTransport.Dial = unixDial - unix2HTTP(u) - default: - httpTransport.Dial = func(proto, addr string) (net.Conn, error) { - return net.DialTimeout(proto, addr, timeout) - } - } - - return &http.Client{Transport: httpTransport, Timeout: responseTimeout} -} - -func getHTTPClient(host string) *http.Client { - cacheLock.Lock() - defer cacheLock.Unlock() - c, ok := httpCache[host] - if !ok { - u, err := url.Parse(host) - if err != nil { - return nil - } - if u.Path == "" { - u.Path = "/" - } - c = newHTTPClient(u, nil, 10*time.Second, 5*time.Minute) - httpCache[host] = c - } - - return c -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/client/request.go b/vendor/github.com/libopenstorage/openstorage/api/client/request.go deleted file mode 100644 index 5257506440..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/client/request.go +++ /dev/null @@ -1,332 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "path" - "strconv" - "strings" - "time" - "math/rand" -) - -// Request is contructed iteratively by the client and finally dispatched. -// A REST endpoint is accessed with the following convention: -// base_url///[] -type Request struct { - client *http.Client - version string - verb string - path string - base *url.URL - params url.Values - headers http.Header - resource string - instance string - err error - body []byte - req *http.Request - resp *http.Response - timeout time.Duration - authstring string - accesstoken string -} - -// Response is a representation of HTTP response received from the server. -type Response struct { - status string - statusCode int - err error - body []byte -} - -// Status upon error, attempts to parse the body of a response into a meaningful status. -type Status struct { - Message string - ErrorCode int -} - -// NewRequest instance -func NewRequest(client *http.Client, base *url.URL, verb string, version string, authstring, userAgent string) *Request { - r := &Request{ - client: client, - verb: verb, - base: base, - path: base.Path, - version: version, - authstring: authstring, - } - r.SetHeader("User-Agent", userAgent) - return r -} - -func checkExists(mustExist string, before string) error { - if len(mustExist) == 0 { - return fmt.Errorf("%q should be set before setting %q", mustExist, before) - } - return nil -} - -func checkSet(name string, s *string, newval string) error { - if len(*s) != 0 { - return fmt.Errorf("%q already set to %q, cannot change to %q", - name, *s, newval) - } - *s = newval - return nil -} - -// Resource specifies the resource to be accessed. -func (r *Request) Resource(resource string) *Request { - if r.err == nil { - r.err = checkSet("resource", &r.resource, resource) - } - return r -} - -// Instance specifies the instance of the resource to be accessed. -func (r *Request) Instance(instance string) *Request { - if r.err == nil { - r.err = checkExists("resource", "instance") - if r.err == nil { - r.err = checkSet("instance", &r.instance, instance) - } - } - return r -} - -// UsePath use the specified path and don't build up a request. -func (r *Request) UsePath(path string) *Request { - if r.err == nil { - r.err = checkSet("path", &r.path, path) - } - return r -} - -// QueryOption adds specified options to query. -func (r *Request) QueryOption(key string, value string) *Request { - if r.err != nil { - return r - } - if r.params == nil { - r.params = make(url.Values) - } - r.params.Add(string(key), value) - return r -} - -// QueryOptionLabel adds specified label to query. -func (r *Request) QueryOptionLabel(key string, labels map[string]string) *Request { - if r.err != nil { - return r - } - if b, err := json.Marshal(labels); err != nil { - r.err = err - } else { - if r.params == nil { - r.params = make(url.Values) - } - r.params.Add(string(key), string(b)) - } - return r -} - -// SetHeader adds specified header values to query. -func (r *Request) SetHeader(key, value string) *Request { - if r.headers == nil { - r.headers = http.Header{} - } - r.headers.Set(key, value) - return r -} - -// Timeout makes the request use the given duration as a timeout. Sets the "timeout" -// parameter. -func (r *Request) Timeout(d time.Duration) *Request { - if r.err != nil { - return r - } - r.timeout = d - return r -} - -// Body sets the request Body. -func (r *Request) Body(v interface{}) *Request { - var err error - if r.err != nil { - return r - } - r.body, err = json.Marshal(v) - if err != nil { - r.err = err - return r - } - return r -} - -// URL returns the current working URL. -func (r *Request) URL() *url.URL { - u := *r.base - p := r.path - - if len(r.version) != 0 { - p = path.Join(p, strings.ToLower(r.version)) - } - if len(r.resource) != 0 { - p = path.Join(p, strings.ToLower(r.resource)) - if len(r.instance) != 0 { - p = path.Join(p, r.instance) - } - } - - u.Path = p - - query := url.Values{} - for key, values := range r.params { - for _, value := range values { - query.Add(key, value) - } - } - if r.timeout != 0 { - query.Set("timeout", r.timeout.String()) - } - u.RawQuery = query.Encode() - return &u -} - -// headerVal for key as an int. Return false if header is not present or valid. -func headerVal(key string, resp *http.Response) (int, bool) { - if h := resp.Header.Get(key); len(h) > 0 { - if i, err := strconv.Atoi(h); err == nil { - return i, true - } - } - return 0, false -} - -func parseHTTPStatus(resp *http.Response, body []byte) error { - - var ( - status *Status - err error - ) - - httpOK := resp.StatusCode >= http.StatusOK && resp.StatusCode <= http.StatusPartialContent - hasStatus := false - if body != nil { - err = json.Unmarshal(body, status) - if err == nil && status.Message != "" { - hasStatus = true - } - } - // If the status is NG, return an error regardless of HTTP status. - if hasStatus && status.ErrorCode != 0 { - return fmt.Errorf("Error %v : %v", status.ErrorCode, status.Message) - } - - // Status is good and HTTP status is good, everything is good - if httpOK { - return nil - } - - // If HTTP status is NG, return an error. - return fmt.Errorf("HTTP error %d", resp.StatusCode) -} - -// Do executes the request and returns a Response. -func (r *Request) Do() *Response { - var ( - err error - req *http.Request - resp *http.Response - url string - body []byte - ) - if r.err != nil { - return &Response{err: r.err} - } - url = r.URL().String() - req, err = http.NewRequest(r.verb, url, bytes.NewBuffer(r.body)) - if err != nil { - return &Response{err: err} - } - if r.headers == nil { - r.headers = http.Header{} - } - - req.Header = r.headers - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Date", time.Now().String()) - - if len(r.authstring) > 0 { - req.Header.Set("Authorization", "Basic "+ r.authstring) - } - - if len(r.accesstoken) > 0 { - req.Header.Set("Access-Token", r.accesstoken) - } - - resp, err = r.client.Do(req) - if err != nil { - return &Response{err: err} - } - if resp.Body != nil { - defer resp.Body.Close() - body, err = ioutil.ReadAll(resp.Body) - } - if err != nil { - return &Response{err: err} - } - return &Response{ - status: resp.Status, - statusCode: resp.StatusCode, - body: body, - err: parseHTTPStatus(resp, body), - } -} - -// Body return http body, valid only if there is no error -func (r Response) Body() ([]byte, error) { - return r.body, r.err -} - -// StatusCode HTTP status code returned. -func (r Response) StatusCode() int { - return r.statusCode -} - -// Unmarshal result into obj -func (r Response) Unmarshal(v interface{}) error { - if r.err != nil { - return r.err - } - return json.Unmarshal(r.body, v) -} - -// Error executing the request. -func (r Response) Error() error { - return r.err -} - -// FormatError formats the error -func (r Response) FormatError() error { - if len(r.body) == 0 { - return fmt.Errorf("Error: %v", r.err) - } - return fmt.Errorf("HTTP-%d: %s", r.statusCode, string(r.body)) -} - -func digest(method string, path string) string { - now := time.Now().String() - - s1 := rand.NewSource(time.Now().UnixNano()) - r1 := rand.New(s1) - - nonce := r1.Intn(10) - - return method + "+" + path + "+" + now + "+" + strconv.Itoa(nonce) -} \ No newline at end of file diff --git a/vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go b/vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go deleted file mode 100644 index a4e8b6875e..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/client/volume/client.go +++ /dev/null @@ -1,403 +0,0 @@ -package volume - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "strconv" - - "github.com/libopenstorage/openstorage/api" - "github.com/libopenstorage/openstorage/api/client" - "github.com/libopenstorage/openstorage/volume" -) - -const ( - graphPath = "/graph" - volumePath = "/osd-volumes" - snapPath = "/osd-snapshot" -) - -type volumeClient struct { - volume.IODriver - c *client.Client -} - -func newVolumeClient(c *client.Client) volume.VolumeDriver { - return &volumeClient{volume.IONotSupported, c} -} - -// String description of this driver. -func (v *volumeClient) Name() string { - return "VolumeDriver" -} - -func (v *volumeClient) Type() api.DriverType { - // Block drivers implement the superset. - return api.DriverType_DRIVER_TYPE_BLOCK -} - -func (v *volumeClient) GraphDriverCreate(id string, parent string) error { - response := "" - if err := v.c.Put().Resource(graphPath + "/create").Instance(id).Do().Unmarshal(&response); err != nil { - return err - } - if response != id { - return fmt.Errorf("Invalid response: %s", response) - } - return nil -} - -func (v *volumeClient) GraphDriverRemove(id string) error { - response := "" - if err := v.c.Put().Resource(graphPath + "/remove").Instance(id).Do().Unmarshal(&response); err != nil { - return err - } - if response != id { - return fmt.Errorf("Invalid response: %s", response) - } - return nil -} - -func (v *volumeClient) GraphDriverGet(id string, mountLabel string) (string, error) { - response := "" - if err := v.c.Get().Resource(graphPath + "/inspect").Instance(id).Do().Unmarshal(&response); err != nil { - return "", err - } - return response, nil -} - -func (v *volumeClient) GraphDriverRelease(id string) error { - response := "" - if err := v.c.Put().Resource(graphPath + "/release").Instance(id).Do().Unmarshal(&response); err != nil { - return err - } - if response != id { - return fmt.Errorf("Invalid response: %v", response) - } - return nil -} - -func (v *volumeClient) GraphDriverExists(id string) bool { - response := false - v.c.Get().Resource(graphPath + "/exists").Instance(id).Do().Unmarshal(&response) - return response -} - -func (v *volumeClient) GraphDriverDiff(id string, parent string) io.Writer { - body, _ := v.c.Get().Resource(graphPath + "/diff?id=" + id + "&parent=" + parent).Do().Body() - return bytes.NewBuffer(body) -} - -func (v *volumeClient) GraphDriverChanges(id string, parent string) ([]api.GraphDriverChanges, error) { - var changes []api.GraphDriverChanges - err := v.c.Get().Resource(graphPath + "/changes").Instance(id).Do().Unmarshal(&changes) - return changes, err -} - -func (v *volumeClient) GraphDriverApplyDiff(id string, parent string, diff io.Reader) (int, error) { - b, err := ioutil.ReadAll(diff) - if err != nil { - return 0, err - } - response := 0 - if err = v.c.Put().Resource(graphPath + "/diff?id=" + id + "&parent=" + parent).Instance(id).Body(b).Do().Unmarshal(&response); err != nil { - return 0, err - } - return response, nil -} - -func (v *volumeClient) GraphDriverDiffSize(id string, parent string) (int, error) { - size := 0 - err := v.c.Get().Resource(graphPath + "/diffsize").Instance(id).Do().Unmarshal(&size) - return size, err -} - -// Create a new Vol for the specific volume spev.c. -// It returns a system generated VolumeID that uniquely identifies the volume -func (v *volumeClient) Create(locator *api.VolumeLocator, source *api.Source, - spec *api.VolumeSpec) (string, error) { - response := &api.VolumeCreateResponse{} - request := &api.VolumeCreateRequest{ - Locator: locator, - Source: source, - Spec: spec, - } - if err := v.c.Post().Resource(volumePath).Body(request).Do().Unmarshal(response); err != nil { - return "", err - } - if response.VolumeResponse != nil && response.VolumeResponse.Error != "" { - return "", errors.New(response.VolumeResponse.Error) - } - return response.Id, nil -} - -// Status diagnostic information -func (v *volumeClient) Status() [][2]string { - return [][2]string{} -} - -// Inspect specified volumes. -// Errors ErrEnoEnt may be returned. -func (v *volumeClient) Inspect(ids []string) ([]*api.Volume, error) { - if len(ids) == 0 { - return nil, nil - } - var volumes []*api.Volume - request := v.c.Get().Resource(volumePath) - for _, id := range ids { - request.QueryOption(api.OptVolumeID, id) - } - if err := request.Do().Unmarshal(&volumes); err != nil { - return nil, err - } - return volumes, nil -} - -// Delete volume. -// Errors ErrEnoEnt, ErrVolHasSnaps may be returned. -func (v *volumeClient) Delete(volumeID string) error { - response := &api.VolumeResponse{} - if err := v.c.Delete().Resource(volumePath).Instance(volumeID).Do().Unmarshal(response); err != nil { - return err - } - if response.Error != "" { - return errors.New(response.Error) - } - return nil -} - -// Snap specified volume. IO to the underlying volume should be quiesced before -// calling this function. -// Errors ErrEnoEnt may be returned -func (v *volumeClient) Snapshot(volumeID string, readonly bool, - locator *api.VolumeLocator) (string, error) { - response := &api.SnapCreateResponse{} - request := &api.SnapCreateRequest{ - Id: volumeID, - Readonly: readonly, - Locator: locator, - } - if err := v.c.Post().Resource(snapPath).Body(request).Do().Unmarshal(response); err != nil { - return "", err - } - // TODO(pedge): this probably should not be embedded in this way - if response.VolumeCreateResponse != nil && - response.VolumeCreateResponse.VolumeResponse != nil && - response.VolumeCreateResponse.VolumeResponse.Error != "" { - return "", errors.New( - response.VolumeCreateResponse.VolumeResponse.Error) - } - if response.VolumeCreateResponse != nil { - return response.VolumeCreateResponse.Id, nil - } - return "", nil -} - -// Restore specified volume to given snapshot state -func (v *volumeClient) Restore(volumeID string, snapID string) error { - response := &api.VolumeResponse{} - req := v.c.Post().Resource(snapPath + "/restore").Instance(volumeID) - req.QueryOption(api.OptSnapID, snapID) - - if err := req.Do().Unmarshal(response); err != nil { - return err - } - if response.Error != "" { - return errors.New(response.Error) - } - return nil -} - -// Stats for specified volume. -// Errors ErrEnoEnt may be returned -func (v *volumeClient) Stats( - volumeID string, - cumulative bool, -) (*api.Stats, error) { - stats := &api.Stats{} - req := v.c.Get().Resource(volumePath + "/stats").Instance(volumeID) - req.QueryOption(api.OptCumulative, strconv.FormatBool(cumulative)) - - err := req.Do().Unmarshal(stats) - return stats, err - -} - -// UsedSize returns allocated volume size. -// Errors ErrEnoEnt may be returned -func (v *volumeClient) UsedSize( - volumeID string, -) (uint64, error) { - var usedSize uint64 - req := v.c.Get().Resource(volumePath + "/usedsize").Instance(volumeID) - err := req.Do().Unmarshal(&usedSize) - return usedSize, err -} - -// Active Requests on all volume. -func (v *volumeClient) GetActiveRequests() (*api.ActiveRequests, error) { - - requests := &api.ActiveRequests{} - resp := v.c.Get().Resource(volumePath + "/requests").Instance("vol_id").Do() - - if resp.Error() != nil { - return nil, resp.FormatError() - } - - if err := resp.Unmarshal(requests); err != nil { - return nil, err - } - - return requests, nil -} - -// Shutdown and cleanup. -func (v *volumeClient) Shutdown() {} - -// Enumerate volumes that map to the volumeLocator. Locator fields may be regexp. -// If locator fields are left blank, this will return all volumes. -func (v *volumeClient) Enumerate(locator *api.VolumeLocator, - labels map[string]string) ([]*api.Volume, error) { - var volumes []*api.Volume - req := v.c.Get().Resource(volumePath) - if locator.Name != "" { - req.QueryOption(api.OptName, locator.Name) - } - if len(locator.VolumeLabels) != 0 { - req.QueryOptionLabel(api.OptLabel, locator.VolumeLabels) - } - if len(labels) != 0 { - req.QueryOptionLabel(api.OptConfigLabel, labels) - } - resp := req.Do() - if resp.Error() != nil { - return nil, resp.FormatError() - } - if err := resp.Unmarshal(&volumes); err != nil { - return nil, err - } - - return volumes, nil -} - -// Enumerate snaps for specified volume -// Count indicates the number of snaps populated. -func (v *volumeClient) SnapEnumerate(ids []string, - snapLabels map[string]string) ([]*api.Volume, error) { - var volumes []*api.Volume - request := v.c.Get().Resource(snapPath) - for _, id := range ids { - request.QueryOption(api.OptVolumeID, id) - } - if len(snapLabels) != 0 { - request.QueryOptionLabel(api.OptLabel, snapLabels) - } - if err := request.Do().Unmarshal(&volumes); err != nil { - return nil, err - } - return volumes, nil -} - -// Attach map device to the host. -// On success the devicePath specifies location where the device is exported -// Errors ErrEnoEnt, ErrVolAttached may be returned. -func (v *volumeClient) Attach(volumeID string, attachOptions map[string]string) (string, error) { - response, err := v.doVolumeSetGetResponse( - volumeID, - &api.VolumeSetRequest{ - Action: &api.VolumeStateAction{ - Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_ON, - }, - Options: attachOptions, - }, - ) - if err != nil { - return "", err - } - if response.Volume != nil { - if response.Volume.Spec.Encrypted { - return response.Volume.SecureDevicePath, nil - } else { - return response.Volume.DevicePath, nil - } - } - return "", nil -} - -// Detach device from the host. -// Errors ErrEnoEnt, ErrVolDetached may be returned. -func (v *volumeClient) Detach(volumeID string, unmountBeforeDetach bool) error { - return v.doVolumeSet( - volumeID, - &api.VolumeSetRequest{ - Action: &api.VolumeStateAction{ - Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_OFF, - UnmountBeforeDetach: unmountBeforeDetach, - }, - }, - ) -} - -func (v *volumeClient) MountedAt(mountPath string) string { - return "" -} - -// Mount volume at specified path -// Errors ErrEnoEnt, ErrVolDetached may be returned. -func (v *volumeClient) Mount(volumeID string, mountPath string) error { - return v.doVolumeSet( - volumeID, - &api.VolumeSetRequest{ - Action: &api.VolumeStateAction{ - Mount: api.VolumeActionParam_VOLUME_ACTION_PARAM_ON, - MountPath: mountPath, - }, - }, - ) -} - -// Unmount volume at specified path -// Errors ErrEnoEnt, ErrVolDetached may be returned. -func (v *volumeClient) Unmount(volumeID string, mountPath string) error { - return v.doVolumeSet( - volumeID, - &api.VolumeSetRequest{ - Action: &api.VolumeStateAction{ - Mount: api.VolumeActionParam_VOLUME_ACTION_PARAM_OFF, - MountPath: mountPath, - }, - }, - ) -} - -// Update volume -func (v *volumeClient) Set(volumeID string, locator *api.VolumeLocator, - spec *api.VolumeSpec) error { - return v.doVolumeSet( - volumeID, - &api.VolumeSetRequest{ - Locator: locator, - Spec: spec, - }, - ) -} - -func (v *volumeClient) doVolumeSet(volumeID string, - request *api.VolumeSetRequest) error { - _, err := v.doVolumeSetGetResponse(volumeID, request) - return err -} - -func (v *volumeClient) doVolumeSetGetResponse(volumeID string, - request *api.VolumeSetRequest) (*api.VolumeSetResponse, error) { - response := &api.VolumeSetResponse{} - if err := v.c.Put().Resource(volumePath).Instance(volumeID).Body(request).Do().Unmarshal(response); err != nil { - return nil, err - } - if response.VolumeResponse != nil && response.VolumeResponse.Error != "" { - return nil, errors.New(response.VolumeResponse.Error) - } - return response, nil -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go b/vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go deleted file mode 100644 index 9394841593..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/client/volume/volume.go +++ /dev/null @@ -1,67 +0,0 @@ -package volume - -import ( - "fmt" - "github.com/libopenstorage/openstorage/api" - "github.com/libopenstorage/openstorage/api/client" - "github.com/libopenstorage/openstorage/volume" -) - -// VolumeDriver returns a REST wrapper for the VolumeDriver interface. -func VolumeDriver(c *client.Client) volume.VolumeDriver { - return newVolumeClient(c) -} - -// NewAuthDriverClient returns a new REST client of the supplied version for specified driver. -// host: REST endpoint [http://: OR unix://]. default: [unix:///var/lib/osd/.sock] -// version: Volume API version -func NewAuthDriverClient(host, driverName, version, authstring, accesstoken, userAgent string) (*client.Client, error) { - if driverName == "" { - return nil, fmt.Errorf("Driver Name cannot be empty") - } - if host == "" { - host = client.GetUnixServerPath(driverName, volume.DriverAPIBase) - } - if version == "" { - // Set the default version - version = volume.APIVersion - } - return client.NewAuthClient(host, version, authstring, accesstoken, userAgent) -} - -// NewDriverClient returns a new REST client of the supplied version for specified driver. -// host: REST endpoint [http://: OR unix://]. default: [unix:///var/lib/osd/.sock] -// version: Volume API version -func NewDriverClient(host, driverName, version, userAgent string) (*client.Client, error) { - if driverName == "" { - return nil, fmt.Errorf("Driver Name cannot be empty") - } - if host == "" { - host = client.GetUnixServerPath(driverName, volume.DriverAPIBase) - } - if version == "" { - // Set the default version - version = volume.APIVersion - } - return client.NewClient(host, version, userAgent) -} - -// GetSupportedDriverVersions returns a list of supported versions -// for the provided driver. It uses the given server endpoint or the -// standard unix domain socket -func GetSupportedDriverVersions(driverName, host string) ([]string, error) { - // Get a client handler - if host == "" { - host = client.GetUnixServerPath(driverName, volume.DriverAPIBase) - } - - client, err := client.NewClient(host, "", "") - if err != nil { - return []string{}, err - } - versions, err := client.Versions(api.OsdVolumePath) - if err != nil { - return []string{}, err - } - return versions, nil -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go b/vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go deleted file mode 100644 index 4a53ab990b..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/spec/spec_handler.go +++ /dev/null @@ -1,353 +0,0 @@ -package spec - -import ( - "fmt" - "regexp" - "strconv" - "strings" - - "github.com/libopenstorage/openstorage/api" - "github.com/libopenstorage/openstorage/pkg/parser" - "github.com/libopenstorage/openstorage/pkg/units" -) - -// SpecHandler provides conversion function from what gets passed in over the -// plugin API to an api.VolumeSpec object. -type SpecHandler interface { - // SpecFromString parses options from the name. - // If the scheduler was unable to pass in the volume spec via the API, - // the spec can be passed in via the name in the format: - // "key=value;key=value;name=volname" - // source is populated if key parent= is specified. - // If the spec was parsed, it returns: - // (true, parsed_spec, locator, source, parsed_name) - // If the input string didn't contain the string, it returns: - // (false, DefaultSpec(), nil, nil, inputString) - SpecFromString(inputString string) ( - bool, - *api.VolumeSpec, - *api.VolumeLocator, - *api.Source, - string, - ) - - // SpecFromOpts parses in docker options passed in the the docker run - // command of the form --opt name=value - // source is populated if --opt parent= is specified. - // If the options are validated then it returns: - // (resultant_VolumeSpec, source, locator, nil) - // If the options have invalid values then it returns: - // (nil, nil, nil, error) - - SpecFromOpts(opts map[string]string) ( - *api.VolumeSpec, - *api.VolumeLocator, - *api.Source, - error, - ) - - // UpdateSpecFromOpts parses in volume options passed through the opts map and updates given spec, locator & source - // If the options are validated then it returns: - // (resultant_VolumeSpec, source, locator, nil) - // If the options have invalid values then it returns: - // (nil, nil, nil, error) - UpdateSpecFromOpts(opts map[string]string, spec *api.VolumeSpec, locator *api.VolumeLocator, source *api.Source) ( - *api.VolumeSpec, - *api.VolumeLocator, - *api.Source, - error, - ) - - // Returns a default VolumeSpec if no docker options or string encoding - // was provided. - DefaultSpec() *api.VolumeSpec -} - -var ( - nameRegex = regexp.MustCompile(api.Name + "=([0-9A-Za-z_-]+),?") - nodesRegex = regexp.MustCompile(api.SpecNodes + "=([0-9A-Za-z_-]+),?") - sizeRegex = regexp.MustCompile(api.SpecSize + "=([0-9A-Za-z]+),?") - scaleRegex = regexp.MustCompile(api.SpecScale + "=([0-9]+),?") - fsRegex = regexp.MustCompile(api.SpecFilesystem + "=([0-9A-Za-z]+),?") - bsRegex = regexp.MustCompile(api.SpecBlockSize + "=([0-9]+),?") - haRegex = regexp.MustCompile(api.SpecHaLevel + "=([0-9]+),?") - cosRegex = regexp.MustCompile(api.SpecPriority + "=([A-Za-z]+),?") - sharedRegex = regexp.MustCompile(api.SpecShared + "=([A-Za-z]+),?") - passphraseRegex = regexp.MustCompile(api.SpecPassphrase + "=([0-9A-Za-z_@./#&+-]+),?") - stickyRegex = regexp.MustCompile(api.SpecSticky + "=([A-Za-z]+),?") - secureRegex = regexp.MustCompile(api.SpecSecure + "=([A-Za-z]+),?") - zonesRegex = regexp.MustCompile(api.SpecZones + "=([A-Za-z]+),?") - racksRegex = regexp.MustCompile(api.SpecRacks + "=([A-Za-z]+),?") - aggrRegex = regexp.MustCompile(api.SpecAggregationLevel + "=([0-9]+|" + - api.SpecAutoAggregationValue + "),?") - compressedRegex = regexp.MustCompile(api.SpecCompressed + "=([A-Za-z]+),?") - snapScheduleRegex = regexp.MustCompile(api.SpecSnapshotSchedule + - `=([A-Za-z0-9:;@=#]+),?`) -) - -type specHandler struct { -} - -// NewSpecHandler returns a new SpecHandler interface -func NewSpecHandler() SpecHandler { - return &specHandler{} -} - -func (d *specHandler) cosLevel(cos string) (api.CosType, error) { - cos = strings.ToLower(cos) - switch cos { - case "high", "3": - return api.CosType_HIGH, nil - case "medium", "2": - return api.CosType_MEDIUM, nil - case "low", "1", "": - return api.CosType_LOW, nil - } - return api.CosType_NONE, - fmt.Errorf("Cos must be one of %q | %q | %q", "high", "medium", "low") -} - -func (d *specHandler) getVal(r *regexp.Regexp, str string) (bool, string) { - found := r.FindString(str) - if found == "" { - return false, "" - } - - submatches := r.FindStringSubmatch(str) - if len(submatches) < 2 { - return false, "" - } - - val := submatches[1] - - return true, val -} - -func (d *specHandler) DefaultSpec() *api.VolumeSpec { - return &api.VolumeSpec{ - VolumeLabels: make(map[string]string), - Format: api.FSType_FS_TYPE_EXT4, - HaLevel: 1, - } -} - -func (d *specHandler) UpdateSpecFromOpts(opts map[string]string, spec *api.VolumeSpec, locator *api.VolumeLocator, - source *api.Source) (*api.VolumeSpec, *api.VolumeLocator, *api.Source, error) { - nodeList := make([]string, 0) - - if spec == nil { - spec = d.DefaultSpec() - } - - if source == nil { - source = &api.Source{} - } - - if locator == nil { - locator = &api.VolumeLocator{ - VolumeLabels: make(map[string]string), - } - } - - for k, v := range opts { - switch k { - case api.SpecNodes: - inputNodes := strings.Split(v, ",") - for _, node := range inputNodes { - if len(node) != 0 { - nodeList = append(nodeList, node) - } - } - spec.ReplicaSet = &api.ReplicaSet{Nodes: nodeList} - case api.SpecParent: - source.Parent = v - case api.SpecEphemeral: - spec.Ephemeral, _ = strconv.ParseBool(v) - case api.SpecSize: - if size, err := units.Parse(v); err != nil { - return nil, nil, nil, err - } else { - spec.Size = uint64(size) - } - case api.SpecScale: - if scale, err := strconv.ParseUint(v, 10, 64); err == nil { - spec.Scale = uint32(scale) - } - - case api.SpecFilesystem: - if value, err := api.FSTypeSimpleValueOf(v); err != nil { - return nil, nil, nil, err - } else { - spec.Format = value - } - case api.SpecBlockSize: - if blockSize, err := units.Parse(v); err != nil { - return nil, nil, nil, err - } else { - spec.BlockSize = blockSize - } - case api.SpecHaLevel: - haLevel, _ := strconv.ParseInt(v, 10, 64) - spec.HaLevel = haLevel - case api.SpecPriority: - cos, err := d.cosLevel(v) - if err != nil { - return nil, nil, nil, err - } - spec.Cos = cos - case api.SpecPriorityAlias: - cos, err := d.cosLevel(v) - if err != nil { - return nil, nil, nil, err - } - spec.Cos = cos - case api.SpecDedupe: - spec.Dedupe, _ = strconv.ParseBool(v) - case api.SpecSnapshotInterval: - snapshotInterval, _ := strconv.ParseUint(v, 10, 32) - spec.SnapshotInterval = uint32(snapshotInterval) - case api.SpecSnapshotSchedule: - spec.SnapshotSchedule = v - case api.SpecAggregationLevel: - if v == api.SpecAutoAggregationValue { - spec.AggregationLevel = api.AutoAggregation - } else { - aggregationLevel, _ := strconv.ParseUint(v, 10, 32) - spec.AggregationLevel = uint32(aggregationLevel) - } - case api.SpecShared: - if shared, err := strconv.ParseBool(v); err != nil { - return nil, nil, nil, err - } else { - spec.Shared = shared - } - case api.SpecSticky: - if sticky, err := strconv.ParseBool(v); err != nil { - return nil, nil, nil, err - } else { - spec.Sticky = sticky - } - case api.SpecSecure: - if secure, err := strconv.ParseBool(v); err != nil { - return nil, nil, nil, err - } else { - spec.Encrypted = secure - } - case api.SpecPassphrase: - spec.Encrypted = true - spec.Passphrase = v - case api.SpecGroup: - spec.Group = &api.Group{Id: v} - case api.SpecGroupEnforce: - if groupEnforced, err := strconv.ParseBool(v); err != nil { - return nil, nil, nil, err - } else { - spec.GroupEnforced = groupEnforced - } - case api.SpecZones, api.SpecRacks: - locator.VolumeLabels[k] = v - case api.SpecCompressed: - if compressed, err := strconv.ParseBool(v); err != nil { - return nil, nil, nil, err - } else { - spec.Compressed = compressed - } - case api.SpecLabels: - if labels, err := parser.LabelsFromString(v); err != nil { - return nil, nil, nil, err - } else { - for k, v := range labels { - locator.VolumeLabels[k] = v - } - } - case api.SpecIoProfile: - if ioProfile, err := api.IoProfileSimpleValueOf(v); err != nil { - return nil, nil, nil, err - } else { - spec.IoProfile = ioProfile - } - default: - spec.VolumeLabels[k] = v - } - } - return spec, locator, source, nil -} - -func (d *specHandler) SpecFromOpts( - opts map[string]string, -) (*api.VolumeSpec, *api.VolumeLocator, *api.Source, error) { - source := &api.Source{} - locator := &api.VolumeLocator{ - VolumeLabels: make(map[string]string), - } - - spec := d.DefaultSpec() - return d.UpdateSpecFromOpts(opts, spec, locator, source) -} - -func (d *specHandler) SpecFromString( - str string, -) (bool, *api.VolumeSpec, *api.VolumeLocator, *api.Source, string) { - // If we can't parse the name, the rest of the spec is invalid. - ok, name := d.getVal(nameRegex, str) - if !ok { - return false, d.DefaultSpec(), nil, nil, str - } - - opts := make(map[string]string) - - if ok, sz := d.getVal(sizeRegex, str); ok { - opts[api.SpecSize] = sz - } - if ok, nodes := d.getVal(nodesRegex, str); ok { - opts[api.SpecNodes] = nodes - } - if ok, scale := d.getVal(scaleRegex, str); ok { - opts[api.SpecScale] = scale - } - if ok, fs := d.getVal(fsRegex, str); ok { - opts[api.SpecFilesystem] = fs - } - if ok, bs := d.getVal(bsRegex, str); ok { - opts[api.SpecBlockSize] = bs - } - if ok, ha := d.getVal(haRegex, str); ok { - opts[api.SpecHaLevel] = ha - } - if ok, priority := d.getVal(cosRegex, str); ok { - opts[api.SpecPriority] = priority - } - if ok, shared := d.getVal(sharedRegex, str); ok { - opts[api.SpecShared] = shared - } - if ok, sticky := d.getVal(stickyRegex, str); ok { - opts[api.SpecSticky] = sticky - } - if ok, secure := d.getVal(secureRegex, str); ok { - opts[api.SpecSecure] = secure - } - if ok, passphrase := d.getVal(passphraseRegex, str); ok { - opts[api.SpecPassphrase] = passphrase - } - if ok, zones := d.getVal(zonesRegex, str); ok { - opts[api.SpecZones] = zones - } - if ok, racks := d.getVal(racksRegex, str); ok { - opts[api.SpecRacks] = racks - } - if ok, aggregationLvl := d.getVal(aggrRegex, str); ok { - opts[api.SpecAggregationLevel] = aggregationLvl - } - if ok, compressed := d.getVal(compressedRegex, str); ok { - opts[api.SpecCompressed] = compressed - } - if ok, sched := d.getVal(snapScheduleRegex, str); ok { - opts[api.SpecSnapshotSchedule] = strings.Replace(sched, "#", ",", -1) - } - - spec, locator, source, err := d.SpecFromOpts(opts) - if err != nil { - return false, d.DefaultSpec(), nil, nil, name - } - return true, spec, locator, source, name -} diff --git a/vendor/github.com/libopenstorage/openstorage/api/status.go b/vendor/github.com/libopenstorage/openstorage/api/status.go deleted file mode 100644 index d2a162d0bc..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/api/status.go +++ /dev/null @@ -1,53 +0,0 @@ -package api - -// StatusKind indicates the severity of a status -type StatusKind int32 - -const ( - // StatusSeverityLow indicates an OK status - StatusSeverityLow StatusKind = iota - // StatusSeverityMedium indicates a status which is in transition from OK to BAD or vice versa - StatusSeverityMedium - // StatusSeverityHigh indicates a BAD status - StatusSeverityHigh -) - -var statusToStatusKind = map[Status]StatusKind{ - Status_STATUS_NONE: StatusSeverityHigh, - Status_STATUS_INIT: StatusSeverityMedium, - Status_STATUS_OK: StatusSeverityLow, - Status_STATUS_OFFLINE: StatusSeverityHigh, - Status_STATUS_ERROR: StatusSeverityHigh, - Status_STATUS_NOT_IN_QUORUM: StatusSeverityHigh, - Status_STATUS_DECOMMISSION: StatusSeverityHigh, - Status_STATUS_MAINTENANCE: StatusSeverityHigh, - Status_STATUS_STORAGE_DOWN: StatusSeverityHigh, - Status_STATUS_STORAGE_DEGRADED: StatusSeverityHigh, - Status_STATUS_NEEDS_REBOOT: StatusSeverityHigh, - Status_STATUS_STORAGE_REBALANCE: StatusSeverityMedium, - Status_STATUS_STORAGE_DRIVE_REPLACE: StatusSeverityMedium, - // Add statuses before MAX - Status_STATUS_MAX: StatusSeverityHigh, -} - -// StatusSimpleValueOf returns the string format of Status -func StatusSimpleValueOf(s string) (Status, error) { - obj, err := simpleValueOf("status", Status_value, s) - return Status(obj), err -} - -// SimpleString returns the string format of Status -func (x Status) SimpleString() string { - return simpleString("status", Status_name, int32(x)) -} - -// StatusKind returns the king of status -func (x Status) StatusKind() StatusKind { - statusType, _ := statusToStatusKind[x] - return statusType -} - -// StatusKindMapLength used only for unit testing -func StatusKindMapLength() int { - return len(statusToStatusKind) -} diff --git a/vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go b/vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go deleted file mode 100644 index d2db39ad88..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/pkg/parser/labels.go +++ /dev/null @@ -1,74 +0,0 @@ -package parser - -import ( - "fmt" - "strings" -) - -const ( - NoLabel = "NoLabel" -) - -func LabelsFromString(str string) (map[string]string, error) { - if len(str) == 0 { - return nil, nil - } - labels := strings.Split(str, ",") - m := make(map[string]string, len(labels)) - for _, v := range labels { - if strings.Contains(v, "=") { - label := strings.SplitN(v, "=", 2) - if len(label) != 2 { - return m, fmt.Errorf("Malformed label: %s", v) - } - if _, ok := m[label[0]]; ok { - return m, fmt.Errorf("Duplicate label: %s", v) - } - m[label[0]] = label[1] - } else if len(v) != 0 { - m[v] = "" - } - } - return m, nil -} - -func LabelsToString(labels map[string]string) string { - l := "" - for k, v := range labels { - if len(l) != 0 { - l += "," - } - if len(v) != 0 { - l += k + "=" + v - } else if len(k) != 0 { - l += k - } - } - return l -} - -func MergeLabels(old map[string]string, new map[string]string) map[string]string { - if old == nil { - return new - } - if new == nil { - return old - } - m := make(map[string]string, len(old)+len(new)) - for k, v := range old { - m[k] = v - } - for k, v := range new { - m[k] = v - } - return m -} - -func HasLabels(set map[string]string, subset map[string]string) bool { - for k, v1 := range subset { - if v2, ok := set[k]; !ok || v1 != v2 { - return false - } - } - return true -} diff --git a/vendor/github.com/libopenstorage/openstorage/pkg/units/units.go b/vendor/github.com/libopenstorage/openstorage/pkg/units/units.go deleted file mode 100644 index 0cdfb78526..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/pkg/units/units.go +++ /dev/null @@ -1,139 +0,0 @@ -package units - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -const ( - _ = iota - // KiB 1024 bytes - KiB = 1 << (10 * iota) - // MiB 1024 KiB - MiB - // GiB 1024 MiB - GiB - // TiB 1024 GiB - TiB - // PiB 1024 TiB - PiB -) - -const ( - // KB 1000 bytes - KB = 1000 - // MB 1000 KB - MB = KB * 1000 - // GB 1000 MB - GB = MB * 1000 - // TB 1000 GB - TB = GB * 1000 - // PB 1000 TB - PB = TB * 1000 -) - -var ( - unitMap = map[string]int64{ - "B": 1, - "b": 1, - - "KB": KiB, - "kb": KiB, - "MB": MiB, - "mb": MiB, - "GB": GiB, - "gb": GiB, - "TB": TiB, - "tb": TiB, - "PB": PiB, - "pb": PiB, - - "K": KiB, - "k": KiB, - "M": MiB, - "m": MiB, - "G": GiB, - "g": GiB, - "T": TiB, - "t": TiB, - "P": PiB, - "p": PiB, - - "KiB": KiB, - "MiB": MiB, - "GiB": GiB, - "TiB": TiB, - "PiB": PiB, - - "Mi": MiB, - "Gi": GiB, - "Ti": TiB, - "Pi": PiB, - } -) - -var unitPattern = regexp.MustCompile( - "([0-9]+)(.[0-9]+)*\\s*(B|b|K|k|M|m|G|g|T|t|P|p|KB|kb|KiB|MB|mb|MiB|Mi|GB|gb|GiB|Gi|TB|tb|TiB|Ti|PB|pb|PiB|Pi|)") -var BadUnit = errors.New("Bad unit") - -func String(b uint64) string { - if b > PiB { - return fmt.Sprintf("%.2f PiB", float64(b)/float64(PiB)) - } - if b > TiB { - return fmt.Sprintf("%.2f TiB", float64(b)/float64(TiB)) - } - if b > GiB { - return fmt.Sprintf("%.1f TiB", float64(b)/float64(GiB)) - } - if b > MiB { - return fmt.Sprintf("%v MiB", b/MiB) - } - if b > KiB { - return fmt.Sprintf("%v KiB", b/KiB) - } - return fmt.Sprintf("%v bytes", b) -} - -func Parse(bUnit string) (int64, error) { - ustring := strings.TrimSpace(bUnit) - unitPattern.Longest() - if !unitPattern.MatchString(ustring) { - return -1, fmt.Errorf("Unit parse error: %s", bUnit) - } - matches := unitPattern.FindStringSubmatch(ustring) - - if len(matches) == 0 || len(matches) > 4 { - return -1, fmt.Errorf( - "Unit parse error: invalid count of fields (%v)", - len(matches)) - } - if len(matches) == 1 { - return strconv.ParseInt(ustring, 10, 64) - } - shift := 0 - if len(matches) == 4 { - shift = 1 - } - if len(matches) == 2 { - return -1, fmt.Errorf("Unit parse error: invalid fields %v", - matches) - } - if ustring != matches[0] { - return -1, fmt.Errorf("Unit parse error: invalid fields %v", - matches) - } - multiplier, ok := unitMap[matches[2+shift]] - if !ok { - multiplier = unitMap["G"] - } - base, err := strconv.ParseInt(matches[1], 10, 64) - if err != nil { - return -1, fmt.Errorf("Invalid number") - } - - return base * multiplier, nil -} diff --git a/vendor/github.com/libopenstorage/openstorage/volume/README.md b/vendor/github.com/libopenstorage/openstorage/volume/README.md deleted file mode 100644 index cb9f4eec8a..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/volume/README.md +++ /dev/null @@ -1,41 +0,0 @@ -## Volume Drivers - -Volume drivers implement the [Volume Plugin Interface](https://docs.docker.com/engine/extend/plugins_volume/). -This provides an interface to register a volume driver and advertise the driver to Docker. Registering a driver with this volume interface will cause Docker to be able to communicate with the driver to create and assign volumes to a container. - -A volume spec is needed to create a volume. A volume spec looks like: - -``` -// VolumeSpec has the properties needed to create a volume. -type VolumeSpec struct { - // Ephemeral storage - Ephemeral bool - // Thin provisioned volume size in bytes - Size uint64 - // Format disk with this FileSystem - Format Filesystem - // BlockSize for file system - BlockSize int - // HA Level specifies the number of nodes that are - // allowed to fail, and yet data is availabel. - // A value of 0 implies that data is not erasure coded, - // a failure of a node will lead to data loss. - HALevel int - // This disk's CoS - Cos VolumeCos - // Perform dedupe on this disk - Dedupe bool - // SnapshotInterval in minutes, set to 0 to disable Snapshots - SnapshotInterval int - // Volume configuration labels - ConfigLabels Labels -} -``` - -Various volume driver implementations can be found in the `drivers` directory. - -### Block Drivers -Block drivers operate at the block layer. They provide raw volumes formatted with a user specified filesystem. This volume is then mounted into the container at a path specified using the `docker run -v` option. - -### File Drivers -File drivers operate at the filesystem layer. diff --git a/vendor/github.com/libopenstorage/openstorage/volume/volume.go b/vendor/github.com/libopenstorage/openstorage/volume/volume.go deleted file mode 100644 index 9aaa61f7f0..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/volume/volume.go +++ /dev/null @@ -1,217 +0,0 @@ -package volume - -import ( - "errors" - - "github.com/libopenstorage/openstorage/api" -) - -var ( - // ErrAlreadyShutdown returned when driver is shutdown - ErrAlreadyShutdown = errors.New("VolumeDriverProvider already shutdown") - // ErrExit returned when driver already registered - ErrExist = errors.New("Already exists") - // ErrDriverNotFound returned when a driver is not registered - ErrDriverNotFound = errors.New("Driver implementation not found") - // ErrDriverInitializing returned when a driver is initializing - ErrDriverInitializing = errors.New("Driver is initializing") - // ErrEnoEnt returned when volume does not exist - ErrEnoEnt = errors.New("Volume does not exist.") - // ErrEnomem returned when we are out of memory - ErrEnomem = errors.New("Out of memory.") - // ErrEinval returned when an invalid input is provided - ErrEinval = errors.New("Invalid argument") - // ErrVolDetached returned when volume is in detached state - ErrVolDetached = errors.New("Volume is detached") - // ErrVolAttached returned when volume is in attached state - ErrVolAttached = errors.New("Volume is attached") - // ErrVolAttachedOnRemoteNode returned when volume is in attached on different node - ErrVolAttachedOnRemoteNode = errors.New("Volume is attached on another node") - // ErrVolAttachedScale returned when volume is attached and can be scaled - ErrVolAttachedScale = errors.New("Volume is attached on another node." + - " Increase scale factor to create more instances") - // ErrVolHasSnaps returned when volume has previous snapshots - ErrVolHasSnaps = errors.New("Volume has snapshots associated") - // ErrNotSupported returned when the operation is not supported - ErrNotSupported = errors.New("Operation not supported") - // ErrVolBusy returned when volume is in busy state - ErrVolBusy = errors.New("Volume is busy") -) - -// Constants used by the VolumeDriver -const ( - // APIVersion for the volume management apis - APIVersion = "v1" - // PluginAPIBase where the docker unix socket resides - PluginAPIBase = "/run/docker/plugins/" - // DriverAPIBase where the osd unix socket resides - DriverAPIBase = "/var/lib/osd/driver/" - // MountBase for osd mountpoints - MountBase = "/var/lib/osd/mounts/" - // VolumeBase for osd volumes - VolumeBase = "/var/lib/osd/" -) - -const ( - // LocationConstaint is a label that specifies data location constraint. - LocationConstraint = "LocationConstraint" - // LocalNode is an alias for this node - similar to localhost. - LocalNode = "LocalNode" -) - -// AttachOptionsKey specifies a key type from a key-value pair -// that will be passed in to the Attach api -type AttachOptionsKey string - -const ( - AttachOptionsSecret = AttachOptionsKey("SECRET_KEY") -) - -// Store defines the interface for basic volume store operations -type Store interface { - // Lock volume specified by volumeID. - Lock(volumeID string) (interface{}, error) - // Lock volume with token obtained from call to Lock. - Unlock(token interface{}) error - // CreateVol returns error if volume with the same ID already existe. - CreateVol(vol *api.Volume) error - // GetVol from volumeID. - GetVol(volumeID string) (*api.Volume, error) - // UpdateVol with vol - UpdateVol(vol *api.Volume) error - // DeleteVol. Returns error if volume does not exist. - DeleteVol(volumeID string) error -} - -// VolumeDriver is the main interface to be implemented by any storage driver. -// Every driver must at minimum implement the ProtoDriver sub interface. -type VolumeDriver interface { - IODriver - ProtoDriver - BlockDriver - Enumerator -} - -// IODriver interfaces applicable to object store interfaces. -type IODriver interface { - // Read sz bytes from specified volume at specified offset. - // Return number of bytes read and error. - Read(volumeID string, buf []byte, sz uint64, offset int64) (int64, error) - // Write sz bytes from specified volume at specified offset. - // Return number of bytes written and error. - Write(volumeID string, buf []byte, sz uint64, offset int64) (int64, error) - // Flush writes to stable storage. - // Return error. - Flush(volumeID string) error -} - -// SnapshotDriver interfaces provides snapshot capability -type SnapshotDriver interface { - // Snapshot create volume snapshot. - // Errors ErrEnoEnt may be returned - Snapshot(volumeID string, readonly bool, locator *api.VolumeLocator) (string, error) - // Restore restores volume to specified snapshot. - Restore(volumeID string, snapshotID string) error -} - -// StatsDriver interface provides stats features -type StatsDriver interface { - // Stats for specified volume. - // cumulative stats are /proc/diskstats style stats. - // nonCumulative stats are stats for specific duration. - // Errors ErrEnoEnt may be returned - Stats(volumeID string, cumulative bool) (*api.Stats, error) - // UsedSize returns currently used volume size. - // Errors ErrEnoEnt may be returned. - UsedSize(volumeID string) (uint64, error) - // GetActiveRequests get active requests - GetActiveRequests() (*api.ActiveRequests, error) -} - -// ProtoDriver must be implemented by all volume drivers. It specifies the -// most basic functionality, such as creating and deleting volumes. -type ProtoDriver interface { - SnapshotDriver - StatsDriver - // Name returns the name of the driver. - Name() string - // Type of this driver - Type() api.DriverType - // Create a new Vol for the specific volume spec. - // It returns a system generated VolumeID that uniquely identifies the volume - Create(locator *api.VolumeLocator, Source *api.Source, spec *api.VolumeSpec) (string, error) - // Delete volume. - // Errors ErrEnoEnt, ErrVolHasSnaps may be returned. - Delete(volumeID string) error - // Mount volume at specified path - // Errors ErrEnoEnt, ErrVolDetached may be returned. - Mount(volumeID string, mountPath string) error - // MountedAt return volume mounted at specified mountpath. - MountedAt(mountPath string) string - // Unmount volume at specified path - // Errors ErrEnoEnt, ErrVolDetached may be returned. - Unmount(volumeID string, mountPath string) error - // Update not all fields of the spec are supported, ErrNotSupported will be thrown for unsupported - // updates. - Set(volumeID string, locator *api.VolumeLocator, spec *api.VolumeSpec) error - // Status returns a set of key-value pairs which give low - // level diagnostic status about this driver. - Status() [][2]string - // Shutdown and cleanup. - Shutdown() -} - -// Enumerator provides a set of interfaces to get details on a set of volumes. -type Enumerator interface { - // Inspect specified volumes. - // Returns slice of volumes that were found. - Inspect(volumeIDs []string) ([]*api.Volume, error) - // Enumerate volumes that map to the volumeLocator. Locator fields may be regexp. - // If locator fields are left blank, this will return all volumes. - Enumerate(locator *api.VolumeLocator, labels map[string]string) ([]*api.Volume, error) - // Enumerate snaps for specified volumes - SnapEnumerate(volID []string, snapLabels map[string]string) ([]*api.Volume, error) -} - -// StoreEnumerator combines Store and Enumerator capabilities -type StoreEnumerator interface { - Store - Enumerator -} - -// BlockDriver needs to be implemented by block volume drivers. Filesystem volume -// drivers can ignore this interface and include the builtin DefaultBlockDriver. -type BlockDriver interface { - // Attach map device to the host. - // On success the devicePath specifies location where the device is exported - // Errors ErrEnoEnt, ErrVolAttached may be returned. - Attach(volumeID string, attachOptions map[string]string) (string, error) - // Detach device from the host. - // Errors ErrEnoEnt, ErrVolDetached may be returned. - Detach(volumeID string, unmountBeforeDetach bool) error -} - -// VolumeDriverProvider provides VolumeDrivers. -type VolumeDriverProvider interface { - // Get gets the VolumeDriver for the given name. - // If a VolumeDriver was not created for the given name, the error ErrDriverNotFound is returned. - Get(name string) (VolumeDriver, error) - // Shutdown shuts down all volume drivers. - Shutdown() error -} - -// VolumeDriverRegistry registers VolumeDrivers. -type VolumeDriverRegistry interface { - VolumeDriverProvider - // New creates the VolumeDriver for the given name. - // If a VolumeDriver was already created for the given name, the error ErrExist is returned. - Register(name string, params map[string]string) error - - // Add inserts a new VolumeDriver provider with a well known name. - Add(name string, init func(map[string]string) (VolumeDriver, error)) error -} - -// NewVolumeDriverRegistry constructs a new VolumeDriverRegistry. -func NewVolumeDriverRegistry(nameToInitFunc map[string]func(map[string]string) (VolumeDriver, error)) VolumeDriverRegistry { - return newVolumeDriverRegistry(nameToInitFunc) -} diff --git a/vendor/github.com/libopenstorage/openstorage/volume/volume_driver_registry.go b/vendor/github.com/libopenstorage/openstorage/volume/volume_driver_registry.go deleted file mode 100644 index 760f24b348..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/volume/volume_driver_registry.go +++ /dev/null @@ -1,71 +0,0 @@ -package volume - -import "sync" - -type volumeDriverRegistry struct { - nameToInitFunc map[string]func(map[string]string) (VolumeDriver, error) - nameToVolumeDriver map[string]VolumeDriver - lock *sync.RWMutex - isShutdown bool -} - -func newVolumeDriverRegistry(nameToInitFunc map[string]func(map[string]string) (VolumeDriver, error)) *volumeDriverRegistry { - return &volumeDriverRegistry{ - nameToInitFunc, - make(map[string]VolumeDriver), - &sync.RWMutex{}, - false, - } -} - -func (v *volumeDriverRegistry) Get(name string) (VolumeDriver, error) { - v.lock.RLock() - defer v.lock.RUnlock() - if v.isShutdown { - return nil, ErrAlreadyShutdown - } - volumeDriver, ok := v.nameToVolumeDriver[name] - if !ok { - return nil, ErrDriverNotFound - } - return volumeDriver, nil -} - -func (v *volumeDriverRegistry) Add(name string, init func(map[string]string) (VolumeDriver, error)) error { - v.nameToInitFunc[name] = init - - return nil -} - -func (v *volumeDriverRegistry) Register(name string, params map[string]string) error { - initFunc, ok := v.nameToInitFunc[name] - if !ok { - return ErrNotSupported - } - v.lock.Lock() - defer v.lock.Unlock() - if v.isShutdown { - return ErrAlreadyShutdown - } - if _, ok := v.nameToVolumeDriver[name]; ok { - return ErrExist - } - volumeDriver, err := initFunc(params) - if err != nil { - return err - } - v.nameToVolumeDriver[name] = volumeDriver - return nil -} - -func (v *volumeDriverRegistry) Shutdown() error { - v.lock.Lock() - if v.isShutdown { - return ErrAlreadyShutdown - } - for _, volumeDriver := range v.nameToVolumeDriver { - volumeDriver.Shutdown() - } - v.isShutdown = true - return nil -} diff --git a/vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go b/vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go deleted file mode 100644 index 270e3a8797..0000000000 --- a/vendor/github.com/libopenstorage/openstorage/volume/volume_not_supported.go +++ /dev/null @@ -1,74 +0,0 @@ -package volume - -import ( - "github.com/libopenstorage/openstorage/api" -) - -var ( - // BlockNotSupported is a default (null) block driver implementation. This can be - // used by drivers that do not want to (or care about) implementing the attach, - // format and detach interfaces. - BlockNotSupported = &blockNotSupported{} - // SnapshotNotSupported is a null snapshot driver implementation. This can be used - // by drivers that do not want to implement the snapshot interface - SnapshotNotSupported = &snapshotNotSupported{} - // IONotSupported is a null IODriver interface - IONotSupported = &ioNotSupported{} - // StatsNotSupported is a null stats driver implementation. This can be used - // by drivers that do not want to implement the stats interface. - StatsNotSupported = &statsNotSupported{} -) - -type blockNotSupported struct{} - -func (b *blockNotSupported) Attach(volumeID string, attachOptions map[string]string) (string, error) { - return "", ErrNotSupported -} - -func (b *blockNotSupported) Detach(volumeID string, unmountBeforeDetach bool) error { - return ErrNotSupported -} - -type snapshotNotSupported struct{} - -func (s *snapshotNotSupported) Snapshot(volumeID string, readonly bool, locator *api.VolumeLocator) (string, error) { - return "", ErrNotSupported -} - -func (s *snapshotNotSupported) Restore(volumeID, snapshotID string) error { - return ErrNotSupported -} - -type ioNotSupported struct{} - -func (i *ioNotSupported) Read(volumeID string, buffer []byte, size uint64, offset int64) (int64, error) { - return 0, ErrNotSupported -} - -func (i *ioNotSupported) Write(volumeID string, buffer []byte, size uint64, offset int64) (int64, error) { - return 0, ErrNotSupported -} - -func (i *ioNotSupported) Flush(volumeID string) error { - return ErrNotSupported -} - -type statsNotSupported struct{} - -// Stats returns stats -func (s *statsNotSupported) Stats( - volumeID string, - cumulative bool, -) (*api.Stats, error) { - return nil, ErrNotSupported -} - -// UsedSize returns allocated size -func (s *statsNotSupported) UsedSize(volumeID string) (uint64, error) { - return 0, ErrNotSupported -} - -// GetActiveRequests gets active requests -func (s *statsNotSupported) GetActiveRequests() (*api.ActiveRequests, error) { - return nil, nil -} diff --git a/vendor/github.com/moby/spdystream/NOTICE b/vendor/github.com/moby/spdystream/NOTICE index b9b11c9ab7..24e2e2aa32 100644 --- a/vendor/github.com/moby/spdystream/NOTICE +++ b/vendor/github.com/moby/spdystream/NOTICE @@ -3,3 +3,15 @@ Copyright 2014-2021 Docker Inc. This product includes software developed at Docker Inc. (https://www.docker.com/). + +SPDY implementation (spdy/) + +The spdy directory contains code derived from the Go project (golang.org/x/net). + +Copyright 2009-2013 The Go Authors. +Licensed under the BSD 3-Clause License. + +Modifications Copyright 2014-2021 Docker Inc. + +The BSD license text and Go patent grant are included in +spdy/LICENSE and spdy/PATENTS. diff --git a/vendor/github.com/moby/spdystream/connection.go b/vendor/github.com/moby/spdystream/connection.go index 1394d0ad4c..69ce4777ea 100644 --- a/vendor/github.com/moby/spdystream/connection.go +++ b/vendor/github.com/moby/spdystream/connection.go @@ -224,7 +224,13 @@ type Connection struct { // NewConnection creates a new spdy connection from an existing // network connection. func NewConnection(conn net.Conn, server bool) (*Connection, error) { - framer, framerErr := spdy.NewFramer(conn, conn) + return NewConnectionWithOptions(conn, server) +} + +// NewConnectionWithOptions creates a new spdy connection and applies frame +// parsing limits via options. +func NewConnectionWithOptions(conn net.Conn, server bool, opts ...spdy.FramerOption) (*Connection, error) { + framer, framerErr := spdy.NewFramerWithOptions(conn, conn, opts...) if framerErr != nil { return nil, framerErr } @@ -350,6 +356,9 @@ Loop: } else { debugMessage("(%p) EOF received", s) } + if spdyErr, ok := err.(*spdy.Error); ok && spdyErr.Err == spdy.InvalidControlFrame { + _ = s.conn.Close() + } break } var priority uint8 diff --git a/vendor/github.com/moby/spdystream/spdy/LICENSE b/vendor/github.com/moby/spdystream/spdy/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +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 +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/moby/spdystream/spdy/PATENTS b/vendor/github.com/moby/spdystream/spdy/PATENTS new file mode 100644 index 0000000000..733099041f --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/github.com/moby/spdystream/spdy/dictionary.go b/vendor/github.com/moby/spdystream/spdy/dictionary.go index 392232f174..5a5ff0e14c 100644 --- a/vendor/github.com/moby/spdystream/spdy/dictionary.go +++ b/vendor/github.com/moby/spdystream/spdy/dictionary.go @@ -1,19 +1,3 @@ -/* - Copyright 2014-2021 Docker Inc. - - 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. -*/ - // Copyright 2013 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. diff --git a/vendor/github.com/moby/spdystream/spdy/options.go b/vendor/github.com/moby/spdystream/spdy/options.go new file mode 100644 index 0000000000..ec03e0b9a9 --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/options.go @@ -0,0 +1,25 @@ +package spdy + +// FramerOption allows callers to customize frame parsing limits. +type FramerOption func(*Framer) + +// WithMaxControlFramePayloadSize sets the control-frame payload limit. +func WithMaxControlFramePayloadSize(size uint32) FramerOption { + return func(f *Framer) { + f.maxFrameLength = size + } +} + +// WithMaxHeaderFieldSize sets the per-header name/value size limit. +func WithMaxHeaderFieldSize(size uint32) FramerOption { + return func(f *Framer) { + f.maxHeaderFieldSize = size + } +} + +// WithMaxHeaderCount sets the maximum number of headers in a frame. +func WithMaxHeaderCount(count uint32) FramerOption { + return func(f *Framer) { + f.maxHeaderCount = count + } +} diff --git a/vendor/github.com/moby/spdystream/spdy/read.go b/vendor/github.com/moby/spdystream/spdy/read.go index 75ea045b8e..2abb69433d 100644 --- a/vendor/github.com/moby/spdystream/spdy/read.go +++ b/vendor/github.com/moby/spdystream/spdy/read.go @@ -1,19 +1,3 @@ -/* - Copyright 2014-2021 Docker Inc. - - 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. -*/ - // Copyright 2011 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. @@ -24,6 +8,7 @@ import ( "compress/zlib" "encoding/binary" "io" + "io/ioutil" "net/http" "strings" ) @@ -59,6 +44,11 @@ func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error { if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil { return err } + // Each setting is 8 bytes (4-byte id + 4-byte value). + // Payload is 4 bytes for numSettings + numSettings*8. + if h.length < 4 || numSettings > (h.length-4)/8 { + return &Error{InvalidControlFrame, 0} + } frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings) for i := uint32(0); i < numSettings; i++ { if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil { @@ -177,8 +167,19 @@ func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) ( if err := binary.Read(f.r, binary.BigEndian, &length); err != nil { return nil, err } + maxControlFramePayload := uint32(MaxDataLength) + if f.maxFrameLength > 0 { + maxControlFramePayload = f.maxFrameLength + } + flags := ControlFlags((length & 0xff000000) >> 24) length &= 0xffffff + if length > maxControlFramePayload { + if _, err := io.CopyN(ioutil.Discard, f.r, int64(length)); err != nil { + return nil, err + } + return nil, &Error{InvalidControlFrame, 0} + } header := ControlFrameHeader{version, frameType, flags, length} cframe, err := newControlFrame(frameType) if err != nil { @@ -190,11 +191,22 @@ func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) ( return cframe, nil } -func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) { +func (f *Framer) parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) { var numHeaders uint32 if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil { return nil, err } + maxHeaders := defaultMaxHeaderCount + if f.maxHeaderCount > 0 { + maxHeaders = f.maxHeaderCount + } + if numHeaders > maxHeaders { + return nil, &Error{InvalidControlFrame, streamId} + } + maxFieldSize := defaultMaxHeaderFieldSize + if f.maxHeaderFieldSize > 0 { + maxFieldSize = f.maxHeaderFieldSize + } var e error h := make(http.Header, int(numHeaders)) for i := 0; i < int(numHeaders); i++ { @@ -202,6 +214,9 @@ func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) if err := binary.Read(r, binary.BigEndian, &length); err != nil { return nil, err } + if length > maxFieldSize { + return nil, &Error{InvalidControlFrame, streamId} + } nameBytes := make([]byte, length) if _, err := io.ReadFull(r, nameBytes); err != nil { return nil, err @@ -217,6 +232,9 @@ func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) if err := binary.Read(r, binary.BigEndian, &length); err != nil { return nil, err } + if length > maxFieldSize { + return nil, &Error{InvalidControlFrame, streamId} + } value := make([]byte, length) if _, err := io.ReadFull(r, value); err != nil { return nil, err @@ -256,7 +274,7 @@ func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) } reader = f.headerDecompressor } - frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { err = &Error{WrongCompressedPayloadSize, 0} } @@ -288,7 +306,7 @@ func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) e } reader = f.headerDecompressor } - frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { err = &Error{WrongCompressedPayloadSize, 0} } @@ -320,7 +338,7 @@ func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) err } reader = f.headerDecompressor } - frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + frame.Headers, err = f.parseHeaderValueBlock(reader, frame.StreamId) if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { err = &Error{WrongCompressedPayloadSize, 0} } diff --git a/vendor/github.com/moby/spdystream/spdy/types.go b/vendor/github.com/moby/spdystream/spdy/types.go index a254a43ab9..a5528618ca 100644 --- a/vendor/github.com/moby/spdystream/spdy/types.go +++ b/vendor/github.com/moby/spdystream/spdy/types.go @@ -1,23 +1,9 @@ -/* - Copyright 2014-2021 Docker Inc. - - 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. -*/ - // Copyright 2011 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. +// Modifications Copyright 2014-2021 Docker Inc. + // Package spdy implements the SPDY protocol (currently SPDY/3), described in // http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3. package spdy @@ -63,8 +49,20 @@ const ( ) // MaxDataLength is the maximum number of bytes that can be stored in one frame. +// +// SPDY frame headers encode the payload length using a 24-bit field, +// so the maximum representable size for both data and control frames +// is 2^24-1 bytes. +// +// See the SPDY/3 specification, "Frame Format": +// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1/ const MaxDataLength = 1<<24 - 1 +const ( + defaultMaxHeaderFieldSize uint32 = 1 << 20 + defaultMaxHeaderCount uint32 = 1000 +) + // headerValueSepator separates multiple header values. const headerValueSeparator = "\x00" @@ -269,6 +267,10 @@ type Framer struct { r io.Reader headerReader io.LimitedReader headerDecompressor io.ReadCloser + + maxFrameLength uint32 // overrides the default frame payload length limit. + maxHeaderFieldSize uint32 // overrides the default per-header name/value length limit. + maxHeaderCount uint32 // overrides the default header count limit. } // NewFramer allocates a new Framer for a given SPDY connection, represented by @@ -276,6 +278,16 @@ type Framer struct { // from/to the Reader and Writer, so the caller should pass in an appropriately // buffered implementation to optimize performance. func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { + return newFramer(w, r) +} + +// NewFramerWithOptions allocates a new Framer for a given SPDY connection and +// applies frame parsing limits via options. +func NewFramerWithOptions(w io.Writer, r io.Reader, opts ...FramerOption) (*Framer, error) { + return newFramer(w, r, opts...) +} + +func newFramer(w io.Writer, r io.Reader, opts ...FramerOption) (*Framer, error) { compressBuf := new(bytes.Buffer) compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary)) if err != nil { @@ -287,5 +299,10 @@ func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { headerCompressor: compressor, r: r, } + for _, opt := range opts { + if opt != nil { + opt(framer) + } + } return framer, nil } diff --git a/vendor/github.com/moby/spdystream/spdy/write.go b/vendor/github.com/moby/spdystream/spdy/write.go index ab6d91f3b8..75084d35d9 100644 --- a/vendor/github.com/moby/spdystream/spdy/write.go +++ b/vendor/github.com/moby/spdystream/spdy/write.go @@ -1,19 +1,3 @@ -/* - Copyright 2014-2021 Docker Inc. - - 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. -*/ - // Copyright 2011 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. @@ -23,6 +7,7 @@ package spdy import ( "encoding/binary" "io" + "math" "net/http" "strings" ) @@ -63,13 +48,21 @@ func (frame *RstStreamFrame) write(f *Framer) (err error) { func (frame *SettingsFrame) write(f *Framer) (err error) { frame.CFHeader.version = Version frame.CFHeader.frameType = TypeSettings - frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4) + payloadLen := len(frame.FlagIdValues)*8 + 4 + if payloadLen > MaxDataLength { + return &Error{InvalidControlFrame, 0} + } + frame.CFHeader.length = uint32(payloadLen) // Serialize frame to Writer. if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { return } - if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil { + n := len(frame.FlagIdValues) + if uint64(n) > math.MaxUint32 { + return &Error{InvalidControlFrame, 0} + } + if err = binary.Write(f.w, binary.BigEndian, uint32(n)); err != nil { return } for _, flagIdValue := range frame.FlagIdValues { @@ -170,29 +163,41 @@ func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error { func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) { n = 0 - if err = binary.Write(w, binary.BigEndian, uint32(len(h))); err != nil { + numHeaders := len(h) + if numHeaders > math.MaxInt32 { + return n, &Error{InvalidControlFrame, 0} + } + if err = binary.Write(w, binary.BigEndian, uint32(numHeaders)); err != nil { return } - n += 2 + n += 4 for name, values := range h { - if err = binary.Write(w, binary.BigEndian, uint32(len(name))); err != nil { + nameLen := len(name) + if nameLen > math.MaxInt32 { + return n, &Error{InvalidControlFrame, 0} + } + if err = binary.Write(w, binary.BigEndian, uint32(nameLen)); err != nil { return } - n += 2 + n += 4 name = strings.ToLower(name) if _, err = io.WriteString(w, name); err != nil { return } - n += len(name) + n += nameLen v := strings.Join(values, headerValueSeparator) - if err = binary.Write(w, binary.BigEndian, uint32(len(v))); err != nil { + vLen := len(v) + if vLen > math.MaxInt32 { + return n, &Error{InvalidControlFrame, 0} + } + if err = binary.Write(w, binary.BigEndian, uint32(vLen)); err != nil { return } - n += 2 + n += 4 if _, err = io.WriteString(w, v); err != nil { return } - n += len(v) + n += vLen } return } @@ -216,7 +221,11 @@ func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) { // Set ControlFrameHeader. frame.CFHeader.version = Version frame.CFHeader.frameType = TypeSynStream - frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10) + hLen := len(f.headerBuf.Bytes()) + 10 + if hLen > MaxDataLength { + return &Error{InvalidControlFrame, 0} + } + frame.CFHeader.length = uint32(hLen) // Serialize frame to Writer. if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { @@ -260,7 +269,11 @@ func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) { // Set ControlFrameHeader. frame.CFHeader.version = Version frame.CFHeader.frameType = TypeSynReply - frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) + hLen := len(f.headerBuf.Bytes()) + 4 + if hLen > MaxDataLength { + return &Error{InvalidControlFrame, 0} + } + frame.CFHeader.length = uint32(hLen) // Serialize frame to Writer. if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { @@ -295,7 +308,11 @@ func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) { // Set ControlFrameHeader. frame.CFHeader.version = Version frame.CFHeader.frameType = TypeHeaders - frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) + hLen := len(f.headerBuf.Bytes()) + 4 + if hLen > MaxDataLength { + return &Error{InvalidControlFrame, 0} + } + frame.CFHeader.length = uint32(hLen) // Serialize frame to Writer. if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { @@ -323,7 +340,11 @@ func (f *Framer) writeDataFrame(frame *DataFrame) (err error) { if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { return } - flagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data)) + dLen := len(frame.Data) + if dLen > MaxDataLength { + return &Error{InvalidDataFrame, frame.StreamId} + } + flagsAndLength := uint32(frame.Flags)<<24 | uint32(dLen) if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil { return } diff --git a/vendor/github.com/mohae/deepcopy/.gitignore b/vendor/github.com/mohae/deepcopy/.gitignore deleted file mode 100644 index 5846dd1531..0000000000 --- a/vendor/github.com/mohae/deepcopy/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*~ -*.out -*.log diff --git a/vendor/github.com/mohae/deepcopy/.travis.yml b/vendor/github.com/mohae/deepcopy/.travis.yml deleted file mode 100644 index fd47a8cf78..0000000000 --- a/vendor/github.com/mohae/deepcopy/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go - -go: - - tip - -matrix: - allow_failures: - - go: tip - -script: - - go test ./... diff --git a/vendor/github.com/mohae/deepcopy/LICENSE b/vendor/github.com/mohae/deepcopy/LICENSE deleted file mode 100644 index 419673f005..0000000000 --- a/vendor/github.com/mohae/deepcopy/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Joel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mohae/deepcopy/README.md b/vendor/github.com/mohae/deepcopy/README.md deleted file mode 100644 index f81841885b..0000000000 --- a/vendor/github.com/mohae/deepcopy/README.md +++ /dev/null @@ -1,8 +0,0 @@ -deepCopy -======== -[![GoDoc](https://godoc.org/github.com/mohae/deepcopy?status.svg)](https://godoc.org/github.com/mohae/deepcopy)[![Build Status](https://travis-ci.org/mohae/deepcopy.png)](https://travis-ci.org/mohae/deepcopy) - -DeepCopy makes deep copies of things: unexported field values are not copied. - -## Usage - cpy := deepcopy.Copy(orig) diff --git a/vendor/github.com/mohae/deepcopy/deepcopy.go b/vendor/github.com/mohae/deepcopy/deepcopy.go deleted file mode 100644 index ba763ad091..0000000000 --- a/vendor/github.com/mohae/deepcopy/deepcopy.go +++ /dev/null @@ -1,125 +0,0 @@ -// deepcopy makes deep copies of things. A standard copy will copy the -// pointers: deep copy copies the values pointed to. Unexported field -// values are not copied. -// -// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved. -// License: MIT, for more details check the included LICENSE file. -package deepcopy - -import ( - "reflect" - "time" -) - -// Interface for delegating copy process to type -type Interface interface { - DeepCopy() interface{} -} - -// Iface is an alias to Copy; this exists for backwards compatibility reasons. -func Iface(iface interface{}) interface{} { - return Copy(iface) -} - -// Copy creates a deep copy of whatever is passed to it and returns the copy -// in an interface{}. The returned value will need to be asserted to the -// correct type. -func Copy(src interface{}) interface{} { - if src == nil { - return nil - } - - // Make the interface a reflect.Value - original := reflect.ValueOf(src) - - // Make a copy of the same type as the original. - cpy := reflect.New(original.Type()).Elem() - - // Recursively copy the original. - copyRecursive(original, cpy) - - // Return the copy as an interface. - return cpy.Interface() -} - -// copyRecursive does the actual copying of the interface. It currently has -// limited support for what it can handle. Add as needed. -func copyRecursive(original, cpy reflect.Value) { - // check for implement deepcopy.Interface - if original.CanInterface() { - if copier, ok := original.Interface().(Interface); ok { - cpy.Set(reflect.ValueOf(copier.DeepCopy())) - return - } - } - - // handle according to original's Kind - switch original.Kind() { - case reflect.Ptr: - // Get the actual value being pointed to. - originalValue := original.Elem() - - // if it isn't valid, return. - if !originalValue.IsValid() { - return - } - cpy.Set(reflect.New(originalValue.Type())) - copyRecursive(originalValue, cpy.Elem()) - - case reflect.Interface: - // If this is a nil, don't do anything - if original.IsNil() { - return - } - // Get the value for the interface, not the pointer. - originalValue := original.Elem() - - // Get the value by calling Elem(). - copyValue := reflect.New(originalValue.Type()).Elem() - copyRecursive(originalValue, copyValue) - cpy.Set(copyValue) - - case reflect.Struct: - t, ok := original.Interface().(time.Time) - if ok { - cpy.Set(reflect.ValueOf(t)) - return - } - // Go through each field of the struct and copy it. - for i := 0; i < original.NumField(); i++ { - // The Type's StructField for a given field is checked to see if StructField.PkgPath - // is set to determine if the field is exported or not because CanSet() returns false - // for settable fields. I'm not sure why. -mohae - if original.Type().Field(i).PkgPath != "" { - continue - } - copyRecursive(original.Field(i), cpy.Field(i)) - } - - case reflect.Slice: - if original.IsNil() { - return - } - // Make a new slice and copy each element. - cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap())) - for i := 0; i < original.Len(); i++ { - copyRecursive(original.Index(i), cpy.Index(i)) - } - - case reflect.Map: - if original.IsNil() { - return - } - cpy.Set(reflect.MakeMap(original.Type())) - for _, key := range original.MapKeys() { - originalValue := original.MapIndex(key) - copyValue := reflect.New(originalValue.Type()).Elem() - copyRecursive(originalValue, copyValue) - copyKey := Copy(key.Interface()) - cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue) - } - - default: - cpy.Set(original) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md index 0921794114..70050f35d1 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,3 +1,41 @@ +## 2.28.1 + +Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months. + +## 2.28.0 + +Ginkgo's SemVer filter now supports filtering multiple components by SemVer version: + +```go +It("should work in a specific version range (1.0.0, 2.0.0) and third-party dependency redis in [8.0.0, ~)", SemVerConstraint(">= 3.2.0"), ComponentSemVerConstraint("redis", ">= 8.0.0") func() { + // This test will only run when version is between 1.0.0 (exclusive) and 2.0.0 (exclusive) and redis version is >= 8.0.0 +}) +``` + +can be filtered in or out with an invocation like: + +```bash +ginkgo --sem-ver-filter="2.1.1, redis=8.2.0" +``` + +Huge thanks to @Icarus9913 for working on this! + +## 2.27.5 + +### Fixes +Don't make a new formatter for each GinkgoT(); that's just silly and uses precious memory + +## 2.27.4 + +### Fixes +- CurrentTreeConstructionNodeReport: fix for nested container nodes [59bc751] + +## 2.27.3 + +### Fixes +report exit result in case of failure [1c9f356] +fix data race [ece19c8] + ## 2.27.2 ### Fixes diff --git a/vendor/github.com/onsi/ginkgo/v2/README.md b/vendor/github.com/onsi/ginkgo/v2/README.md index 7b7ab9e39c..b4c3ce0ad2 100644 --- a/vendor/github.com/onsi/ginkgo/v2/README.md +++ b/vendor/github.com/onsi/ginkgo/v2/README.md @@ -119,7 +119,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year. If you're an organization that makes use of Ginkgo please consider becoming a sponsor!

Browser testing via - - + +

diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go index 7e165e4738..1c5a39a1f5 100644 --- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go @@ -20,6 +20,7 @@ import ( "io" "os" "path/filepath" + "slices" "strings" "github.com/go-logr/logr" @@ -268,7 +269,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool { } defer global.PopClone() - suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args) + suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args) var reporter reporters.Reporter if suiteConfig.ParallelTotal == 1 { @@ -311,7 +312,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool { suitePath, err = filepath.Abs(suitePath) exitIfErr(err) - passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) + passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) outputInterceptor.Shutdown() flagSet.ValidateDeprecations(deprecationTracker) @@ -330,9 +331,10 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool { return passed } -func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.AroundNodes) { +func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, ComponentSemVerConstraints, types.AroundNodes) { suiteLabels := Labels{} suiteSemVerConstraints := SemVerConstraints{} + suiteComponentSemVerConstraints := ComponentSemVerConstraints{} aroundNodes := types.AroundNodes{} configErrors := []error{} for _, arg := range args { @@ -345,6 +347,11 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro suiteLabels = append(suiteLabels, arg...) case SemVerConstraints: suiteSemVerConstraints = append(suiteSemVerConstraints, arg...) + case ComponentSemVerConstraints: + for component, constraints := range arg { + suiteComponentSemVerConstraints[component] = append(suiteComponentSemVerConstraints[component], constraints...) + suiteComponentSemVerConstraints[component] = slices.Compact(suiteComponentSemVerConstraints[component]) + } case types.AroundNodeDecorator: aroundNodes = append(aroundNodes, arg) default: @@ -355,14 +362,14 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro configErrors = types.VetConfig(flagSet, suiteConfig, reporterConfig) if len(configErrors) > 0 { - fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n")) + fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n")) for _, err := range configErrors { - fmt.Fprintf(formatter.ColorableStdErr, err.Error()) + fmt.Fprint(formatter.ColorableStdErr, err.Error()) } os.Exit(1) } - return suiteLabels, suiteSemVerConstraints, aroundNodes + return suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, aroundNodes } func getwd() (string, error) { @@ -385,7 +392,7 @@ func PreviewSpecs(description string, args ...any) Report { } defer global.PopClone() - suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args) + suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args) priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1 defer func() { @@ -403,7 +410,7 @@ func PreviewSpecs(description string, args ...any) Report { suitePath, err = filepath.Abs(suitePath) exitIfErr(err) - global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) + global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) return global.Suite.GetPreviewReport() } diff --git a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go index e331d7cf8c..ce1d71cec8 100644 --- a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go @@ -117,6 +117,27 @@ You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-fi */ type SemVerConstraints = internal.SemVerConstraints +/* +ComponentSemVerConstraint decorates specs with ComponentSemVerConstraints. Multiple components semantic version constraints can be passed to ComponentSemVerConstraint and the component can't be empy, also the version strings must follow the semantic version constraint rules. +ComponentSemVerConstraints can be applied to container and subject nodes, but not setup nodes. You can provide multiple ComponentSemVerConstraints to a given node and a spec's component semantic version constraints is the union of all component semantic version constraints in its node hierarchy. + +You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering +You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference +*/ +func ComponentSemVerConstraint(component string, semVerConstraints ...string) ComponentSemVerConstraints { + componentSemVerConstraints := ComponentSemVerConstraints{ + component: semVerConstraints, + } + + return componentSemVerConstraints +} + +/* +ComponentSemVerConstraints are the type for spec ComponentSemVerConstraint decorators. Use ComponentSemVerConstraint(...) to construct ComponentSemVerConstraints. +You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering +*/ +type ComponentSemVerConstraints = internal.ComponentSemVerConstraints + /* PollProgressAfter allows you to override the configured value for --poll-progress-after for a particular node. diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go index 79b83a3af1..a30a2ecc92 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go @@ -22,11 +22,11 @@ type Command struct { func (c Command) Run(args []string, additionalArgs []string) { args, err := c.Flags.Parse(args) if err != nil { - AbortWithUsage(err.Error()) + AbortWithUsage("%s", err.Error()) } for _, arg := range args { if len(arg) > 1 && strings.HasPrefix(arg, "-") { - AbortWith(types.GinkgoErrors.FlagAfterPositionalParameter().Error()) + AbortWith("%s", types.GinkgoErrors.FlagAfterPositionalParameter().Error()) } } c.Command(args, additionalArgs) @@ -49,6 +49,6 @@ func (c Command) EmitUsage(writer io.Writer) { } flagUsage := c.Flags.Usage() if flagUsage != "" { - fmt.Fprintf(writer, formatter.F(flagUsage)) + fmt.Fprint(writer, formatter.F(flagUsage)) } } diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go index 30d8096cd6..68830d9ae2 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go @@ -9,6 +9,7 @@ import ( "path/filepath" "regexp" "strings" + "sync/atomic" "syscall" "time" @@ -159,12 +160,15 @@ func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig t func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite { type procResult struct { + proc int + exitResult string passed bool hasProgrammaticFocus bool } numProcs := cliConfig.ComputedProcs() procOutput := make([]*bytes.Buffer, numProcs) + procExitResult := make([]string, numProcs) coverProfiles := []string{} blockProfiles := []string{} @@ -224,16 +228,20 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig args = append(args, additionalArgs...) cmd, buf := buildAndStartCommand(suite, args, false) + var exited atomic.Bool procOutput[proc-1] = buf - server.RegisterAlive(proc, func() bool { return cmd.ProcessState == nil || !cmd.ProcessState.Exited() }) + server.RegisterAlive(proc, func() bool { return !exited.Load() }) go func() { cmd.Wait() exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() procResults <- procResult{ + proc: proc, + exitResult: cmd.ProcessState.String(), passed: (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE), hasProgrammaticFocus: exitStatus == types.GINKGO_FOCUS_EXIT_CODE, } + exited.Store(true) }() } @@ -242,6 +250,7 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig result := <-procResults passed = passed && result.passed suite.HasProgrammaticFocus = suite.HasProgrammaticFocus || result.hasProgrammaticFocus + procExitResult[result.proc-1] = result.exitResult } if passed { suite.State = TestSuiteStatePassed @@ -259,8 +268,10 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig fmt.Fprint(formatter.ColorableStdErr, formatter.Fiw(0, formatter.COLS, "This occurs if a parallel process exits before it reports its results to the Ginkgo CLI. The CLI will now print out all the stdout/stderr output it's collected from the running processes. However you may not see anything useful in these logs because the individual test processes usually intercept output to stdout/stderr in order to capture it in the spec reports.\n\nYou may want to try rerunning your test suite with {{light-gray}}--output-interceptor-mode=none{{/}} to see additional output here and debug your suite.\n")) fmt.Fprintln(formatter.ColorableStdErr, " ") for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ { - fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc)) + fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc)) fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s", procOutput[proc-1].String())) + fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Exit result of proc %d:{{/}}\n", proc)) + fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s\n", procExitResult[proc-1])) } fmt.Fprintf(os.Stderr, "** End **") } diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go index 03875b9796..c5091e6de8 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go @@ -33,7 +33,7 @@ func BuildRunCommand() command.Command { Usage: "ginkgo run -- ", ShortDoc: "Run the tests in the passed in (or the package in the current directory if left blank)", Documentation: "Any arguments after -- will be passed to the test.", - DocLink: "running-tests", + DocLink: "running-specs", Command: func(args []string, additionalArgs []string) { var errors []error cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig) diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go index a39daf5a60..498e707dbf 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go @@ -56,7 +56,7 @@ This function sets the `Skip` property on specs by applying Ginkgo's focus polic *Note:* specs with pending nodes are Skipped when created by NewSpec. */ -func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) { +func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) { focusString := strings.Join(suiteConfig.FocusStrings, "|") skipString := strings.Join(suiteConfig.SkipStrings, "|") @@ -87,7 +87,24 @@ func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suit if suiteConfig.SemVerFilter != "" { semVerFilter, _ := types.ParseSemVerFilter(suiteConfig.SemVerFilter) skipChecks = append(skipChecks, func(spec Spec) bool { - return !semVerFilter(UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints())) + noRun := false + + // non-component-specific constraints + constraints := UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints()) + if len(constraints) != 0 && semVerFilter("", constraints) == false { + noRun = true + } + + // component-specific constraints + componentConstraints := UnionOfComponentSemVerConstraints(suiteComponentSemVerConstraints, spec.Nodes.UnionOfComponentSemVerConstraints()) + for component, constraints := range componentConstraints { + if semVerFilter(component, constraints) == false { + noRun = true + break + } + } + + return noRun }) } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/group.go b/vendor/github.com/onsi/ginkgo/v2/internal/group.go index cc794903e7..5e66113343 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/group.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/group.go @@ -113,22 +113,24 @@ func newGroup(suite *Suite) *group { // initialReportForSpec constructs a new SpecReport right before running the spec. func (g *group) initialReportForSpec(spec Spec) types.SpecReport { return types.SpecReport{ - ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(), - ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(), - ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(), - ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(), - LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation, - LeafNodeType: types.NodeTypeIt, - LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text, - LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels), - LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints), - ParallelProcess: g.suite.config.ParallelProcess, - RunningInParallel: g.suite.isRunningInParallel(), - IsSerial: spec.Nodes.HasNodeMarkedSerial(), - IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(), - MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(), - MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(), - SpecPriority: spec.Nodes.GetSpecPriority(), + ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(), + ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(), + ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(), + ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(), + ContainerHierarchyComponentSemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).ComponentSemVerConstraints(), + LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation, + LeafNodeType: types.NodeTypeIt, + LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text, + LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels), + LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints), + LeafNodeComponentSemVerConstraints: map[string][]string(spec.FirstNodeWithType(types.NodeTypeIt).ComponentSemVerConstraints), + ParallelProcess: g.suite.config.ParallelProcess, + RunningInParallel: g.suite.isRunningInParallel(), + IsSerial: spec.Nodes.HasNodeMarkedSerial(), + IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(), + MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(), + MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(), + SpecPriority: spec.Nodes.GetSpecPriority(), } } @@ -152,6 +154,7 @@ func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode report.ContainerHierarchyLocations = append(report.ContainerHierarchyLocations, node.Node.CodeLocation) report.ContainerHierarchyLabels = append(report.ContainerHierarchyLabels, node.Node.Labels) report.ContainerHierarchySemVerConstraints = append(report.ContainerHierarchySemVerConstraints, node.Node.SemVerConstraints) + report.ContainerHierarchyComponentSemVerConstraints = append(report.ContainerHierarchyComponentSemVerConstraints, node.Node.ComponentSemVerConstraints) if node.Node.MarkedSerial { report.IsSerial = true } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/node.go b/vendor/github.com/onsi/ginkgo/v2/internal/node.go index 2bccec2dbf..b0c8de8d69 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/node.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/node.go @@ -57,6 +57,7 @@ type Node struct { MustPassRepeatedly int Labels Labels SemVerConstraints SemVerConstraints + ComponentSemVerConstraints ComponentSemVerConstraints PollProgressAfter time.Duration PollProgressInterval time.Duration NodeTimeout time.Duration @@ -106,7 +107,24 @@ func (l Labels) MatchesLabelFilter(query string) bool { type SemVerConstraints []string func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool { - return types.MustParseSemVerFilter(version)(svc) + return types.MustParseSemVerFilter(version)("", svc) +} + +type ComponentSemVerConstraints map[string][]string + +func (csvc ComponentSemVerConstraints) MatchesSemVerFilter(component, version string) bool { + for comp, constraints := range csvc { + if comp != component { + continue + } + + input := version + if len(component) > 0 { + input = fmt.Sprintf("%s=%s", component, version) + } + return types.MustParseSemVerFilter(input)(component, constraints) + } + return false } func unionOf[S ~[]E, E comparable](slices ...S) S { @@ -131,6 +149,16 @@ func UnionOfSemVerConstraints(semVerConstraints ...SemVerConstraints) SemVerCons return unionOf(semVerConstraints...) } +func UnionOfComponentSemVerConstraints(componentSemVerConstraintsSlice ...ComponentSemVerConstraints) ComponentSemVerConstraints { + unionComponentSemVerConstraints := ComponentSemVerConstraints{} + for _, componentSemVerConstraints := range componentSemVerConstraintsSlice { + for component, constraints := range componentSemVerConstraints { + unionComponentSemVerConstraints[component] = unionOf(unionComponentSemVerConstraints[component], constraints) + } + } + return unionComponentSemVerConstraints +} + func PartitionDecorations(args ...any) ([]any, []any) { decorations := []any{} remainingArgs := []any{} @@ -174,6 +202,8 @@ func isDecoration(arg any) bool { return true case t == reflect.TypeOf(SemVerConstraints{}): return true + case t == reflect.TypeOf(ComponentSemVerConstraints{}): + return true case t == reflect.TypeOf(PollProgressInterval(0)): return true case t == reflect.TypeOf(PollProgressAfter(0)): @@ -214,16 +244,17 @@ var specContextType = reflect.TypeOf(new(SpecContext)).Elem() func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) { baseOffset := 2 node := Node{ - ID: UniqueNodeID(), - NodeType: nodeType, - Text: text, - Labels: Labels{}, - SemVerConstraints: SemVerConstraints{}, - CodeLocation: types.NewCodeLocation(baseOffset), - NestingLevel: -1, - PollProgressAfter: -1, - PollProgressInterval: -1, - GracePeriod: -1, + ID: UniqueNodeID(), + NodeType: nodeType, + Text: text, + Labels: Labels{}, + SemVerConstraints: SemVerConstraints{}, + ComponentSemVerConstraints: ComponentSemVerConstraints{}, + CodeLocation: types.NewCodeLocation(baseOffset), + NestingLevel: -1, + PollProgressAfter: -1, + PollProgressInterval: -1, + GracePeriod: -1, } errors := []error{} @@ -360,6 +391,36 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy appendError(err) } } + case t == reflect.TypeOf(ComponentSemVerConstraints{}): + if !nodeType.Is(types.NodeTypesForContainerAndIt) { + appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "ComponentSemVerConstraint")) + } + for component, semVerConstraints := range arg.(ComponentSemVerConstraints) { + // while using ComponentSemVerConstraints, we should not allow empty component names. + // you should use SemVerConstraints for that. + hasErr := false + if len(component) == 0 { + appendError(types.GinkgoErrors.InvalidEmptyComponentForSemVerConstraint(node.CodeLocation)) + hasErr = true + } + for _, semVerConstraint := range semVerConstraints { + _, err := types.ValidateAndCleanupSemVerConstraint(semVerConstraint, node.CodeLocation) + if err != nil { + appendError(err) + hasErr = true + } + } + + if !hasErr { + // merge constraints if the component already exists + constraints := slices.Clone(semVerConstraints) + if existingConstraints, exists := node.ComponentSemVerConstraints[component]; exists { + constraints = UnionOfSemVerConstraints([]string(existingConstraints), constraints) + } + + node.ComponentSemVerConstraints[component] = slices.Clone(constraints) + } + } case t.Kind() == reflect.Func: if nodeType.Is(types.NodeTypeContainer) { if node.Body != nil { @@ -899,6 +960,34 @@ func (n Nodes) UnionOfSemVerConstraints() []string { return out } +func (n Nodes) ComponentSemVerConstraints() []map[string][]string { + out := make([]map[string][]string, len(n)) + for i := range n { + if n[i].ComponentSemVerConstraints == nil { + out[i] = map[string][]string{} + } else { + out[i] = map[string][]string(n[i].ComponentSemVerConstraints) + } + } + return out +} + +func (n Nodes) UnionOfComponentSemVerConstraints() map[string][]string { + out := map[string][]string{} + seen := map[string]bool{} + for i := range n { + for component := range n[i].ComponentSemVerConstraints { + if !seen[component] { + seen[component] = true + out[component] = n[i].ComponentSemVerConstraints[component] + } else { + out[component] = UnionOfSemVerConstraints(out[component], n[i].ComponentSemVerConstraints[component]) + } + } + } + return out +} + func (n Nodes) CodeLocations() []types.CodeLocation { out := make([]types.CodeLocation, len(n)) for i := range n { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go index e0f1431d51..319278ded3 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go @@ -9,6 +9,24 @@ import ( "golang.org/x/sys/unix" ) +// dupStdout creates a clone of stdout's file descriptor that can be used +// to write to the original terminal even after stdout has been redirected. +// Returns nil if the clone cannot be created. +func dupStdout() *os.File { + stdoutCloneFD, err := unix.Dup(1) + if err != nil { + return nil + } + + // Set FD_CLOEXEC to prevent leaking into child processes + flags, err := unix.FcntlInt(uintptr(stdoutCloneFD), unix.F_GETFD, 0) + if err == nil { + unix.FcntlInt(uintptr(stdoutCloneFD), unix.F_SETFD, flags|unix.FD_CLOEXEC) + } + + return os.NewFile(uintptr(stdoutCloneFD), "stdout-clone-for-forwarding") +} + func NewOutputInterceptor() OutputInterceptor { return &genericOutputInterceptor{ interceptedContent: make(chan string), diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_wasm.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_wasm.go index 4c374935b8..3cffcb5340 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_wasm.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_wasm.go @@ -2,6 +2,13 @@ package internal +import "os" + +// dupStdout returns nil on WASM since output interception is not supported. +func dupStdout() *os.File { + return nil +} + func NewOutputInterceptor() OutputInterceptor { return &NoopOutputInterceptor{} } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_win.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_win.go index 30c2851a81..710cbe04ae 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_win.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_win.go @@ -2,6 +2,15 @@ package internal +import "os" + +// dupStdout returns the current os.Stdout. On Windows, the output interceptor +// uses osGlobalReassigning which only changes the Go variable, so capturing +// the current os.Stdout before interception starts is sufficient. +func dupStdout() *os.File { + return os.Stdout +} + func NewOutputInterceptor() OutputInterceptor { return NewOSGlobalReassigningOutputInterceptor() } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go index 8b7a9ceabf..751543ea78 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go @@ -83,7 +83,7 @@ func goJSONActionFromSpecState(state types.SpecState) GoJSONAction { type gojsonReport struct { o types.Report // Extra calculated fields - goPkg string + goPkg string elapsed float64 } @@ -109,8 +109,8 @@ type gojsonSpecReport struct { o types.SpecReport // extra calculated fields testName string - elapsed float64 - action GoJSONAction + elapsed float64 + action GoJSONAction } func newSpecReport(in types.SpecReport) *gojsonSpecReport { @@ -141,18 +141,31 @@ func suitePathToPkg(dir string) (string, error) { } func createTestName(spec types.SpecReport) string { - name := fmt.Sprintf("[%s]", spec.LeafNodeType) - if spec.FullText() != "" { - name = name + " " + spec.FullText() - } - labels := spec.Labels() - if len(labels) > 0 { - name = name + " [" + strings.Join(labels, ", ") + "]" - } - semVerConstraints := spec.SemVerConstraints() - if len(semVerConstraints) > 0 { - name = name + " [" + strings.Join(semVerConstraints, ", ") + "]" - } - name = strings.TrimSpace(name) - return name + name := fmt.Sprintf("[%s]", spec.LeafNodeType) + if spec.FullText() != "" { + name = name + " " + spec.FullText() + } + labels := spec.Labels() + if len(labels) > 0 { + name = name + " [" + strings.Join(labels, ", ") + "]" + } + semVerConstraints := spec.SemVerConstraints() + if len(semVerConstraints) > 0 { + name = name + " [" + strings.Join(semVerConstraints, ", ") + "]" + } + componentSemVerConstraints := spec.ComponentSemVerConstraints() + if len(componentSemVerConstraints) > 0 { + name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]" + } + name = strings.TrimSpace(name) + return name +} + +func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string { + var tmpStr string + for component, semVerConstraints := range componentSemVerConstraints { + tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", component, semVerConstraints) + } + tmpStr = strings.TrimSuffix(tmpStr, ", ") + return tmpStr } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go index 204446e820..c22d4e40ec 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go @@ -110,7 +110,7 @@ func (suite *Suite) BuildTree() error { return nil } -func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) { +func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) { if suite.phase != PhaseBuildTree { panic("cannot run before building the tree = call suite.BuildTree() first") } @@ -121,7 +121,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst suite.annotateFn(spec.Text(), spec) } } - specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteConfig) + specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteConfig) specs = ComputeAroundNodes(specs) suite.phase = PhaseRun @@ -140,7 +140,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal) - success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suitePath, hasProgrammaticFocus, specs) + success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suitePath, hasProgrammaticFocus, specs) cancelProgressHandler() @@ -215,9 +215,12 @@ func (suite *Suite) PushNode(node Node) error { // Ensure that code running in the body of the container node // has access to information about the current container node(s). + // The current one (nil in top-level container nodes, non-nil in an + // embedded container node) gets restored when the node is done. + oldConstructionNodeReport := suite.currentConstructionNodeReport suite.currentConstructionNodeReport = constructionNodeReportForTreeNode(suite.tree) defer func() { - suite.currentConstructionNodeReport = nil + suite.currentConstructionNodeReport = oldConstructionNodeReport }() node.Body(nil) @@ -460,16 +463,17 @@ func (suite *Suite) processCurrentSpecReport() { } } -func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool { +func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool { numSpecsThatWillBeRun := specs.CountWithoutSkip() suite.report = types.Report{ - SuitePath: suitePath, - SuiteDescription: description, - SuiteLabels: suiteLabels, - SuiteSemVerConstraints: suiteSemVerConstraints, - SuiteConfig: suite.config, - SuiteHasProgrammaticFocus: hasProgrammaticFocus, + SuitePath: suitePath, + SuiteDescription: description, + SuiteLabels: suiteLabels, + SuiteSemVerConstraints: suiteSemVerConstraints, + SuiteComponentSemVerConstraints: suiteComponentSemVerConstraints, + SuiteConfig: suite.config, + SuiteHasProgrammaticFocus: hasProgrammaticFocus, PreRunStats: types.PreRunStats{ TotalSpecs: len(specs), SpecsThatWillRun: numSpecsThatWillBeRun, @@ -1046,7 +1050,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ } progressReport = progressReport.WithoutOtherGoroutines() - sc.cancel(fmt.Errorf(interruptStatus.Message())) + sc.cancel(fmt.Errorf("%s", interruptStatus.Message())) if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut { if interruptStatus.ShouldIncludeProgressReport() { diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go index 2f0ccfc575..83eb1f8d5d 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go @@ -1,6 +1,9 @@ package internal import ( + "io" + "os" + "strings" "time" "github.com/onsi/ginkgo/v2/internal/interrupt_handler" @@ -8,6 +11,70 @@ import ( "github.com/onsi/ginkgo/v2/types" ) +// ForwardingOutputInterceptor wraps a real OutputInterceptor but forwards +// captured output to stdout in real-time. This allows stdout/stderr to be +// captured in test results while still showing output during test execution. +type ForwardingOutputInterceptor struct { + interceptor OutputInterceptor + stdoutClone *os.File +} + +// NewForwardingOutputInterceptor creates an output interceptor that captures +// stdout/stderr while also forwarding it to a clone of stdout in real-time. +// The stdout clone is created using dupStdout() (platform-specific) before +// the interceptor redirects output, ensuring output is always forwarded to +// the original terminal. +func NewForwardingOutputInterceptor() *ForwardingOutputInterceptor { + // Create a clone of stdout BEFORE the interceptor can redirect it. + // This ensures we always have a handle to the original terminal for + // forwarding output. The dupStdout() function is platform-specific. + stdoutClone := dupStdout() + if stdoutClone == nil { + // If we can't dup stdout, fall back to NoopOutputInterceptor behavior + return &ForwardingOutputInterceptor{ + interceptor: NoopOutputInterceptor{}, + stdoutClone: nil, + } + } + + return &ForwardingOutputInterceptor{ + interceptor: NewOutputInterceptor(), + stdoutClone: stdoutClone, + } +} + +func (f *ForwardingOutputInterceptor) StartInterceptingOutput() { + if f.stdoutClone != nil { + f.interceptor.StartInterceptingOutputAndForwardTo(f.stdoutClone) + } else { + f.interceptor.StartInterceptingOutput() + } +} + +func (f *ForwardingOutputInterceptor) StartInterceptingOutputAndForwardTo(w io.Writer) { + f.interceptor.StartInterceptingOutputAndForwardTo(w) +} + +func (f *ForwardingOutputInterceptor) StopInterceptingAndReturnOutput() string { + return f.interceptor.StopInterceptingAndReturnOutput() +} + +func (f *ForwardingOutputInterceptor) PauseIntercepting() { + f.interceptor.PauseIntercepting() +} + +func (f *ForwardingOutputInterceptor) ResumeIntercepting() { + f.interceptor.ResumeIntercepting() +} + +func (f *ForwardingOutputInterceptor) Shutdown() { + f.interceptor.Shutdown() + if f.stdoutClone != nil { + f.stdoutClone.Close() + f.stdoutClone = nil + } +} + type AnnotateFunc func(testName string, test types.TestSpec) func (suite *Suite) SetAnnotateFn(fn AnnotateFunc) { @@ -58,14 +125,18 @@ func (suite *Suite) RunSpec(spec types.TestSpec, suiteLabels Labels, suiteDescri suite.failer = failer suite.reporter = reporters.NewDefaultReporter(reporterConfig, writer) suite.writer = writer - suite.outputInterceptor = NoopOutputInterceptor{} + if strings.ToLower(suiteConfig.OutputInterceptorMode) == "none" { + suite.outputInterceptor = NoopOutputInterceptor{} + } else { + suite.outputInterceptor = NewForwardingOutputInterceptor() + } if suite.config.Timeout > 0 { suite.deadline = time.Now().Add(suiteConfig.Timeout) } suite.interruptHandler = interrupt_handler.NewInterruptHandler(nil) suite.config = suiteConfig - success := suite.runSpecs(suiteDescription, suiteLabels, SemVerConstraints{}, suitePath, false, []Spec{spec.(Spec)}) + success := suite.runSpecs(suiteDescription, suiteLabels, SemVerConstraints{}, ComponentSemVerConstraints{}, suitePath, false, []Spec{spec.(Spec)}) return success, false } diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go index 9806e315a6..5704f0fdf9 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go @@ -27,6 +27,11 @@ type ginkgoWriterInterface interface { type ginkgoRecoverFunc func() type attachProgressReporterFunc func(func() string) func() +var formatters = map[bool]formatter.Formatter{ + true: formatter.NewWithNoColorBool(true), + false: formatter.NewWithNoColorBool(false), +} + func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cleanupFunc, report reportFunc, addReportEntry addReportEntryFunc, ginkgoRecover ginkgoRecoverFunc, attachProgressReporter attachProgressReporterFunc, randomSeed int64, parallelProcess int, parallelTotal int, noColor bool, offset int) *ginkgoTestingTProxy { return &ginkgoTestingTProxy{ fail: fail, @@ -41,7 +46,7 @@ func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cle randomSeed: randomSeed, parallelProcess: parallelProcess, parallelTotal: parallelTotal, - f: formatter.NewWithNoColorBool(noColor), + f: formatters[noColor], //minimize allocations by reusing formatters } } diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go index 026d9cf9b3..ef66b22898 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go @@ -75,6 +75,9 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) { if len(report.SuiteSemVerConstraints) > 0 { r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteSemVerConstraints, ", "))) } + if len(report.SuiteComponentSemVerConstraints) > 0 { + r.emit(r.f("{{coral}}[Components: %s]{{/}} ", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints))) + } r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs)) if report.SuiteConfig.ParallelTotal > 1 { r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal)) @@ -97,6 +100,13 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) { bannerWidth = len(semVerConstraints) + 2 } } + if len(report.SuiteComponentSemVerConstraints) > 0 { + componentSemVerConstraints := formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints) + r.emitBlock(r.f("{{coral}}[Components: %s]{{/}} ", componentSemVerConstraints)) + if len(componentSemVerConstraints)+2 > bannerWidth { + bannerWidth = len(componentSemVerConstraints) + 2 + } + } r.emitBlock(strings.Repeat("=", bannerWidth)) out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed) @@ -725,8 +735,12 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string { } func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string { - texts, locations, labels, semVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{} - texts, locations, labels, semVerConstraints = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...), append(semVerConstraints, report.ContainerHierarchySemVerConstraints...) + texts, locations, labels, semVerConstraints, componentSemVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}, []map[string][]string{} + texts = append(texts, report.ContainerHierarchyTexts...) + locations = append(locations, report.ContainerHierarchyLocations...) + labels = append(labels, report.ContainerHierarchyLabels...) + semVerConstraints = append(semVerConstraints, report.ContainerHierarchySemVerConstraints...) + componentSemVerConstraints = append(componentSemVerConstraints, report.ContainerHierarchyComponentSemVerConstraints...) if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText)) @@ -735,6 +749,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo } labels = append(labels, report.LeafNodeLabels) semVerConstraints = append(semVerConstraints, report.LeafNodeSemVerConstraints) + componentSemVerConstraints = append(componentSemVerConstraints, report.LeafNodeComponentSemVerConstraints) locations = append(locations, report.LeafNodeLocation) failureLocation := report.Failure.FailureNodeLocation @@ -749,6 +764,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo locations = append([]types.CodeLocation{failureLocation}, locations...) labels = append([][]string{{}}, labels...) semVerConstraints = append([][]string{{}}, semVerConstraints...) + componentSemVerConstraints = append([]map[string][]string{{}}, componentSemVerConstraints...) highlightIndex = 0 case types.FailureNodeInContainer: i := report.Failure.FailureNodeContainerIndex @@ -779,6 +795,9 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo if len(semVerConstraints[i]) > 0 { out += r.f(" {{coral}}[%s]{{/}}", strings.Join(semVerConstraints[i], ", ")) } + if len(componentSemVerConstraints[i]) > 0 { + out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(componentSemVerConstraints[i])) + } out += "\n" out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) } @@ -806,6 +825,10 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo if len(flattenedSemVerConstraints) > 0 { out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedSemVerConstraints, ", ")) } + flattenedComponentSemVerConstraints := report.ComponentSemVerConstraints() + if len(flattenedComponentSemVerConstraints) > 0 { + out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(flattenedComponentSemVerConstraints)) + } out += "\n" if usePreciseFailureLocation { out += r.f("{{gray}}%s{{/}}", failureLocation) diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go index 828f893fb8..d4720ee949 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go @@ -13,9 +13,11 @@ package reporters import ( "encoding/xml" "fmt" + "maps" "os" "path" "regexp" + "slices" "strings" "github.com/onsi/ginkgo/v2/config" @@ -39,6 +41,9 @@ type JunitReportConfig struct { // Enable OmitSpecSemVerConstraints to prevent semantic version constraints from appearing in the spec name OmitSpecSemVerConstraints bool + // Enable OmitSpecComponentSemVerConstraints to prevent component semantic version constraints from appearing in the spec name + OmitSpecComponentSemVerConstraints bool + // Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name OmitLeafNodeType bool @@ -173,6 +178,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit {"SpecialSuiteFailureReason", strings.Join(report.SpecialSuiteFailureReasons, ",")}, {"SuiteLabels", fmt.Sprintf("[%s]", strings.Join(report.SuiteLabels, ","))}, {"SuiteSemVerConstraints", fmt.Sprintf("[%s]", strings.Join(report.SuiteSemVerConstraints, ","))}, + {"SuiteComponentSemVerConstraints", fmt.Sprintf("[%s]", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints))}, {"RandomSeed", fmt.Sprintf("%d", report.SuiteConfig.RandomSeed)}, {"RandomizeAllSpecs", fmt.Sprintf("%t", report.SuiteConfig.RandomizeAllSpecs)}, {"LabelFilter", report.SuiteConfig.LabelFilter}, @@ -216,6 +222,10 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit if len(semVerConstraints) > 0 && !config.OmitSpecSemVerConstraints { name = name + " [" + strings.Join(semVerConstraints, ", ") + "]" } + componentSemVerConstraints := spec.ComponentSemVerConstraints() + if len(componentSemVerConstraints) > 0 && !config.OmitSpecComponentSemVerConstraints { + name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]" + } name = strings.TrimSpace(name) test := JUnitTestCase{ @@ -387,6 +397,16 @@ func systemOutForUnstructuredReporters(spec types.SpecReport) string { return spec.CapturedStdOutErr } +func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string { + var tmpStr string + for _, key := range slices.Sorted(maps.Keys(componentSemVerConstraints)) { + tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", key, componentSemVerConstraints[key]) + } + + tmpStr = strings.TrimSuffix(tmpStr, ", ") + return tmpStr +} + // Deprecated JUnitReporter (so folks can still compile their suites) type JUnitReporter struct{} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go index 55e1d1f4f7..ed3e3a2bb9 100644 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go +++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go @@ -39,12 +39,16 @@ func GenerateTeamcityReport(report types.Report, dst string) error { name := report.SuiteDescription labels := report.SuiteLabels semVerConstraints := report.SuiteSemVerConstraints + componentSemVerConstraints := report.SuiteComponentSemVerConstraints if len(labels) > 0 { name = name + " [" + strings.Join(labels, ", ") + "]" } if len(semVerConstraints) > 0 { name = name + " [" + strings.Join(semVerConstraints, ", ") + "]" } + if len(componentSemVerConstraints) > 0 { + name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]" + } fmt.Fprintf(f, "##teamcity[testSuiteStarted name='%s']\n", tcEscape(name)) for _, spec := range report.SpecReports { name := fmt.Sprintf("[%s]", spec.LeafNodeType) @@ -59,6 +63,10 @@ func GenerateTeamcityReport(report types.Report, dst string) error { if len(semVerConstraints) > 0 { name = name + " [" + strings.Join(semVerConstraints, ", ") + "]" } + componentSemVerConstraints := spec.ComponentSemVerConstraints() + if len(componentSemVerConstraints) > 0 { + name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]" + } name = tcEscape(name) fmt.Fprintf(f, "##teamcity[testStarted name='%s']\n", name) diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go index 59313238cf..623e54b66e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go @@ -450,6 +450,15 @@ func (g ginkgoErrors) InvalidEmptySemVerConstraint(cl CodeLocation) error { } } +func (g ginkgoErrors) InvalidEmptyComponentForSemVerConstraint(cl CodeLocation) error { + return GinkgoError{ + Heading: "Invalid Empty Component for ComponentSemVerConstraint", + Message: "ComponentSemVerConstraint requires a non-empty component name", + CodeLocation: cl, + DocLink: "spec-semantic-version-filtering", + } +} + /* Table errors */ func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error { return GinkgoError{ diff --git a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go index 3fc2ed144b..71778078da 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go @@ -2,11 +2,12 @@ package types import ( "fmt" + "strings" "github.com/Masterminds/semver/v3" ) -type SemVerFilter func([]string) bool +type SemVerFilter func(component string, constraints []string) bool func MustParseSemVerFilter(input string) SemVerFilter { filter, err := ParseSemVerFilter(input) @@ -16,30 +17,90 @@ func MustParseSemVerFilter(input string) SemVerFilter { return filter } -func ParseSemVerFilter(filterVersion string) (SemVerFilter, error) { - if filterVersion == "" { - return func(_ []string) bool { return true }, nil +// ParseSemVerFilter parses non-component and component-specific semantic version filter string. +// The filter string can contain multiple non-component and component-specific versions separated by commas. +// Each component-specific version is in the format "component=version". +// If a version is specified without a component, it applies to non-component-specific constraints. +func ParseSemVerFilter(componentFilterVersions string) (SemVerFilter, error) { + if componentFilterVersions == "" { + return func(_ string, _ []string) bool { return true }, nil } - targetVersion, err := semver.NewVersion(filterVersion) - if err != nil { - return nil, fmt.Errorf("invalid filter version: %w", err) + result := map[string]*semver.Version{} + parts := strings.Split(componentFilterVersions, ",") + for _, part := range parts { + part = strings.TrimSpace(part) + if len(part) == 0 { + continue + } + if strings.Contains(part, "=") { + // validate component-specific version string + invalidPart, invalidErr := false, fmt.Errorf("invalid component filter version: %s", part) + subParts := strings.Split(part, "=") + if len(subParts) != 2 { + invalidPart = true + } + component := strings.TrimSpace(subParts[0]) + versionStr := strings.TrimSpace(subParts[1]) + if len(component) == 0 || len(versionStr) == 0 { + invalidPart = true + } + if invalidPart { + return nil, invalidErr + } + + // validate semver + v, err := semver.NewVersion(versionStr) + if err != nil { + return nil, fmt.Errorf("invalid component filter version: %s, error: %w", part, err) + } + result[component] = v + } else { + v, err := semver.NewVersion(part) + if err != nil { + return nil, fmt.Errorf("invalid filter version: %s, error: %w", part, err) + } + result[""] = v + } } - return func(constraints []string) bool { + return func(component string, constraints []string) bool { // unconstrained specs always run - if len(constraints) == 0 { + if len(component) == 0 && len(constraints) == 0 { return true } - for _, constraintStr := range constraints { - constraint, err := semver.NewConstraint(constraintStr) - if err != nil { - return false + // check non-component specific version constraints + if len(component) == 0 && len(constraints) != 0 { + v := result[""] + if v != nil { + for _, constraintStr := range constraints { + constraint, err := semver.NewConstraint(constraintStr) + if err != nil { + return false + } + + if !constraint.Check(v) { + return false + } + } } + } + + // check component-specific version constraints + if len(component) != 0 && len(constraints) != 0 { + v := result[component] + if v != nil { + for _, constraintStr := range constraints { + constraint, err := semver.NewConstraint(constraintStr) + if err != nil { + return false + } - if !constraint.Check(targetVersion) { - return false + if !constraint.Check(v) { + return false + } + } } } diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go index 9981a0dd68..2401505120 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/types.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go @@ -38,6 +38,10 @@ type ConstructionNodeReport struct { // all Describe/Context/When containers in this spec's hierarchy ContainerHierarchySemVerConstraints [][]string + // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of + // all Describe/Context/When containers in this spec's hierarchy + ContainerHierarchyComponentSemVerConstraints []map[string][]string + // IsSerial captures whether the any container has the Serial decorator IsSerial bool @@ -85,6 +89,9 @@ type Report struct { //SuiteSemVerConstraints captures any semVerConstraints attached to the suite by the DSL's RunSpecs() function SuiteSemVerConstraints []string + //SuiteComponentSemVerConstraints captures any component-specific semVerConstraints attached to the suite by the DSL's RunSpecs() function + SuiteComponentSemVerConstraints map[string][]string + //SuiteSucceeded captures the success or failure status of the test run //If true, the test run is considered successful. //If false, the test run is considered unsuccessful @@ -188,14 +195,19 @@ type SpecReport struct { // all Describe/Context/When containers in this spec's hierarchy ContainerHierarchySemVerConstraints [][]string + // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of + // all Describe/Context/When containers in this spec's hierarchy + ContainerHierarchyComponentSemVerConstraints []map[string][]string + // LeafNodeType, LeafNodeLocation, LeafNodeLabels, LeafNodeSemVerConstraints and LeafNodeText capture the NodeType, CodeLocation, and text // of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be // one of the NodeTypesForSuiteLevelNodes node types) - LeafNodeType NodeType - LeafNodeLocation CodeLocation - LeafNodeLabels []string - LeafNodeSemVerConstraints []string - LeafNodeText string + LeafNodeType NodeType + LeafNodeLocation CodeLocation + LeafNodeLabels []string + LeafNodeSemVerConstraints []string + LeafNodeComponentSemVerConstraints map[string][]string + LeafNodeText string // Captures the Spec Priority SpecPriority int @@ -261,52 +273,54 @@ type SpecReport struct { func (report SpecReport) MarshalJSON() ([]byte, error) { //All this to avoid emitting an empty Failure struct in the JSON out := struct { - ContainerHierarchyTexts []string - ContainerHierarchyLocations []CodeLocation - ContainerHierarchyLabels [][]string - ContainerHierarchySemVerConstraints [][]string - LeafNodeType NodeType - LeafNodeLocation CodeLocation - LeafNodeLabels []string - LeafNodeSemVerConstraints []string - LeafNodeText string - State SpecState - StartTime time.Time - EndTime time.Time - RunTime time.Duration - ParallelProcess int - Failure *Failure `json:",omitempty"` - NumAttempts int - MaxFlakeAttempts int - MaxMustPassRepeatedly int - CapturedGinkgoWriterOutput string `json:",omitempty"` - CapturedStdOutErr string `json:",omitempty"` - ReportEntries ReportEntries `json:",omitempty"` - ProgressReports []ProgressReport `json:",omitempty"` - AdditionalFailures []AdditionalFailure `json:",omitempty"` - SpecEvents SpecEvents `json:",omitempty"` + ContainerHierarchyTexts []string + ContainerHierarchyLocations []CodeLocation + ContainerHierarchyLabels [][]string + ContainerHierarchySemVerConstraints [][]string + ContainerHierarchyComponentSemVerConstraints []map[string][]string + LeafNodeType NodeType + LeafNodeLocation CodeLocation + LeafNodeLabels []string + LeafNodeSemVerConstraints []string + LeafNodeText string + State SpecState + StartTime time.Time + EndTime time.Time + RunTime time.Duration + ParallelProcess int + Failure *Failure `json:",omitempty"` + NumAttempts int + MaxFlakeAttempts int + MaxMustPassRepeatedly int + CapturedGinkgoWriterOutput string `json:",omitempty"` + CapturedStdOutErr string `json:",omitempty"` + ReportEntries ReportEntries `json:",omitempty"` + ProgressReports []ProgressReport `json:",omitempty"` + AdditionalFailures []AdditionalFailure `json:",omitempty"` + SpecEvents SpecEvents `json:",omitempty"` }{ - ContainerHierarchyTexts: report.ContainerHierarchyTexts, - ContainerHierarchyLocations: report.ContainerHierarchyLocations, - ContainerHierarchyLabels: report.ContainerHierarchyLabels, - ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints, - LeafNodeType: report.LeafNodeType, - LeafNodeLocation: report.LeafNodeLocation, - LeafNodeLabels: report.LeafNodeLabels, - LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints, - LeafNodeText: report.LeafNodeText, - State: report.State, - StartTime: report.StartTime, - EndTime: report.EndTime, - RunTime: report.RunTime, - ParallelProcess: report.ParallelProcess, - Failure: nil, - ReportEntries: nil, - NumAttempts: report.NumAttempts, - MaxFlakeAttempts: report.MaxFlakeAttempts, - MaxMustPassRepeatedly: report.MaxMustPassRepeatedly, - CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput, - CapturedStdOutErr: report.CapturedStdOutErr, + ContainerHierarchyTexts: report.ContainerHierarchyTexts, + ContainerHierarchyLocations: report.ContainerHierarchyLocations, + ContainerHierarchyLabels: report.ContainerHierarchyLabels, + ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints, + ContainerHierarchyComponentSemVerConstraints: report.ContainerHierarchyComponentSemVerConstraints, + LeafNodeType: report.LeafNodeType, + LeafNodeLocation: report.LeafNodeLocation, + LeafNodeLabels: report.LeafNodeLabels, + LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints, + LeafNodeText: report.LeafNodeText, + State: report.State, + StartTime: report.StartTime, + EndTime: report.EndTime, + RunTime: report.RunTime, + ParallelProcess: report.ParallelProcess, + Failure: nil, + ReportEntries: nil, + NumAttempts: report.NumAttempts, + MaxFlakeAttempts: report.MaxFlakeAttempts, + MaxMustPassRepeatedly: report.MaxMustPassRepeatedly, + CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput, + CapturedStdOutErr: report.CapturedStdOutErr, } if !report.Failure.IsZero() { @@ -404,6 +418,34 @@ func (report SpecReport) SemVerConstraints() []string { return out } +// ComponentSemVerConstraints returns a deduped map of all the spec's component-specific SemVerConstraints. +func (report SpecReport) ComponentSemVerConstraints() map[string][]string { + out := map[string][]string{} + seen := map[string]bool{} + for _, compSemVerConstraints := range report.ContainerHierarchyComponentSemVerConstraints { + for component := range compSemVerConstraints { + if !seen[component] { + seen[component] = true + out[component] = compSemVerConstraints[component] + } else { + out[component] = append(out[component], compSemVerConstraints[component]...) + out[component] = slices.Compact(out[component]) + } + } + } + for component := range report.LeafNodeComponentSemVerConstraints { + if !seen[component] { + seen[component] = true + out[component] = report.LeafNodeComponentSemVerConstraints[component] + } else { + out[component] = append(out[component], report.LeafNodeComponentSemVerConstraints[component]...) + out[component] = slices.Compact(out[component]) + } + } + + return out +} + // MatchesLabelFilter returns true if the spec satisfies the passed in label filter query func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { filter, err := ParseLabelFilter(query) @@ -419,7 +461,22 @@ func (report SpecReport) MatchesSemVerFilter(version string) (bool, error) { if err != nil { return false, err } - return filter(report.SemVerConstraints()), nil + + semVerConstraints := report.SemVerConstraints() + if len(semVerConstraints) != 0 && filter("", report.SemVerConstraints()) == false { + return false, nil + } + + componentSemVerConstraints := report.ComponentSemVerConstraints() + if len(componentSemVerConstraints) != 0 { + for component, constraints := range componentSemVerConstraints { + if filter(component, constraints) == false { + return false, nil + } + } + } + + return true, nil } // FileName() returns the name of the file containing the spec diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index b9c1ea9856..1df09be005 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.27.2" +const VERSION = "2.28.1" diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index b7d7309f3f..91e65521b4 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,18 @@ +## 1.39.1 + +Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months. + +## 1.39.0 + +### Features + +Add `MatchErrorStrictly` which only passes if `errors.Is(actual, expected)` returns true. `MatchError`, by contrast, will fallback to string comparison. + +## 1.38.3 + +### Fixes +make string formatitng more consistent for users who use format.Object directly + ## 1.38.2 - roll back to go 1.23.0 [c404969] diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go index 96f04b2104..6c23ba338b 100644 --- a/vendor/github.com/onsi/gomega/format/format.go +++ b/vendor/github.com/onsi/gomega/format/format.go @@ -262,7 +262,7 @@ func Object(object any, indentation uint) string { if err, ok := object.(error); ok && !isNilValue(value) { // isNilValue check needed here to avoid nil deref due to boxed nil commonRepresentation += "\n" + IndentString(err.Error(), indentation) + "\n" + indent } - return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation)) + return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation, true)) } /* @@ -306,7 +306,7 @@ func formatType(v reflect.Value) string { } } -func formatValue(value reflect.Value, indentation uint) string { +func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string { if indentation > MaxDepth { return "..." } @@ -367,11 +367,11 @@ func formatValue(value reflect.Value, indentation uint) string { case reflect.Func: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Ptr: - return formatValue(value.Elem(), indentation) + return formatValue(value.Elem(), indentation, isTopLevel) case reflect.Slice: return truncateLongStrings(formatSlice(value, indentation)) case reflect.String: - return truncateLongStrings(formatString(value.String(), indentation)) + return truncateLongStrings(formatString(value.String(), indentation, isTopLevel)) case reflect.Array: return truncateLongStrings(formatSlice(value, indentation)) case reflect.Map: @@ -392,8 +392,8 @@ func formatValue(value reflect.Value, indentation uint) string { } } -func formatString(object any, indentation uint) string { - if indentation == 1 { +func formatString(object any, indentation uint, isTopLevel bool) string { + if isTopLevel { s := fmt.Sprintf("%s", object) components := strings.Split(s, "\n") result := "" @@ -416,14 +416,14 @@ func formatString(object any, indentation uint) string { func formatSlice(v reflect.Value, indentation uint) string { if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && isPrintableString(string(v.Bytes())) { - return formatString(v.Bytes(), indentation) + return formatString(v.Bytes(), indentation, false) } l := v.Len() result := make([]string, l) longest := 0 - for i := 0; i < l; i++ { - result[i] = formatValue(v.Index(i), indentation+1) + for i := range l { + result[i] = formatValue(v.Index(i), indentation+1, false) if len(result[i]) > longest { longest = len(result[i]) } @@ -443,7 +443,7 @@ func formatMap(v reflect.Value, indentation uint) string { longest := 0 for i, key := range v.MapKeys() { value := v.MapIndex(key) - result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1), formatValue(value, indentation+1)) + result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false), formatValue(value, indentation+1, false)) if len(result[i]) > longest { longest = len(result[i]) } @@ -462,10 +462,10 @@ func formatStruct(v reflect.Value, indentation uint) string { l := v.NumField() result := []string{} longest := 0 - for i := 0; i < l; i++ { + for i := range l { structField := t.Field(i) fieldEntry := v.Field(i) - representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1)) + representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false)) result = append(result, representation) if len(representation) > longest { longest = len(representation) @@ -479,7 +479,7 @@ func formatStruct(v reflect.Value, indentation uint) string { } func formatInterface(v reflect.Value, indentation uint) string { - return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation)) + return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false)) } func isNilValue(a reflect.Value) bool { diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index fdba34ee9d..87c70692bf 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.38.2" +const GOMEGA_VERSION = "1.39.1" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index 10b6693fd6..16ca8f46dc 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -146,6 +146,24 @@ func MatchError(expected any, functionErrorDescription ...any) types.GomegaMatch } } +// MatchErrorStrictly succeeds iff actual is a non-nil error that matches the passed in +// expected error according to errors.Is(actual, expected). +// +// This behavior differs from MatchError where +// +// Expect(errors.New("some error")).To(MatchError(errors.New("some error"))) +// +// succeeds, but errors.Is would return false so: +// +// Expect(errors.New("some error")).To(MatchErrorStrictly(errors.New("some error"))) +// +// fails. +func MatchErrorStrictly(expected error) types.GomegaMatcher { + return &matchers.MatchErrorStrictlyMatcher{ + Expected: expected, + } +} + // BeClosed succeeds if actual is a closed channel. // It is an error to pass a non-channel to BeClosed, it is also an error to pass nil // @@ -515,8 +533,8 @@ func HaveExistingField(field string) types.GomegaMatcher { // and even interface values. // // actual := 42 -// Expect(actual).To(HaveValue(42)) -// Expect(&actual).To(HaveValue(42)) +// Expect(actual).To(HaveValue(Equal(42))) +// Expect(&actual).To(HaveValue(Equal(42))) func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher { return &matchers.HaveValueMatcher{ Matcher: matcher, diff --git a/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go index 9e16dcf5d6..16630c18e3 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go @@ -39,7 +39,7 @@ func (matcher *HaveKeyMatcher) Match(actual any) (success bool, err error) { } keys := reflect.ValueOf(actual).MapKeys() - for i := 0; i < len(keys); i++ { + for i := range keys { success, err := keyMatcher.Match(keys[i].Interface()) if err != nil { return false, fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error()) diff --git a/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go index 1c53f1e56a..0cd7081532 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go @@ -52,7 +52,7 @@ func (matcher *HaveKeyWithValueMatcher) Match(actual any) (success bool, err err } keys := reflect.ValueOf(actual).MapKeys() - for i := 0; i < len(keys); i++ { + for i := range keys { success, err := keyMatcher.Match(keys[i].Interface()) if err != nil { return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error()) diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go new file mode 100644 index 0000000000..63969b2663 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go @@ -0,0 +1,39 @@ +package matchers + +import ( + "errors" + "fmt" + + "github.com/onsi/gomega/format" +) + +type MatchErrorStrictlyMatcher struct { + Expected error +} + +func (matcher *MatchErrorStrictlyMatcher) Match(actual any) (success bool, err error) { + + if isNil(matcher.Expected) { + return false, fmt.Errorf("Expected error is nil, use \"ToNot(HaveOccurred())\" to explicitly check for nil errors") + } + + if isNil(actual) { + return false, fmt.Errorf("Expected an error, got nil") + } + + if !isError(actual) { + return false, fmt.Errorf("Expected an error. Got:\n%s", format.Object(actual, 1)) + } + + actualErr := actual.(error) + + return errors.Is(actualErr, matcher.Expected), nil +} + +func (matcher *MatchErrorStrictlyMatcher) FailureMessage(actual any) (message string) { + return format.Message(actual, "to match error", matcher.Expected) +} + +func (matcher *MatchErrorStrictlyMatcher) NegatedFailureMessage(actual any) (message string) { + return format.Message(actual, "not to match error", matcher.Expected) +} diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go index 8c38411b28..72edba20f7 100644 --- a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go +++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go @@ -1,6 +1,9 @@ package edge -import . "github.com/onsi/gomega/matchers/support/goraph/node" +import ( + . "github.com/onsi/gomega/matchers/support/goraph/node" + "slices" +) type Edge struct { Node1 int @@ -20,13 +23,7 @@ func (ec EdgeSet) Free(node Node) bool { } func (ec EdgeSet) Contains(edge Edge) bool { - for _, e := range ec { - if e == edge { - return true - } - } - - return false + return slices.Contains(ec, edge) } func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) { diff --git a/vendor/github.com/opencontainers/cgroups/cgroups.go b/vendor/github.com/opencontainers/cgroups/cgroups.go index 1f127550c0..5a97bd36b7 100644 --- a/vendor/github.com/opencontainers/cgroups/cgroups.go +++ b/vendor/github.com/opencontainers/cgroups/cgroups.go @@ -29,6 +29,11 @@ type Manager interface { // can be used to merely create a cgroup. Apply(pid int) error + // AddPid adds a process with a given pid to an existing cgroup. + // The subcgroup argument is either empty, or a path relative to + // a cgroup under under the manager's cgroup. + AddPid(subcgroup string, pid int) error + // GetPids returns the PIDs of all processes inside the cgroup. GetPids() ([]int, error) diff --git a/vendor/github.com/opencontainers/cgroups/config_linux.go b/vendor/github.com/opencontainers/cgroups/config_linux.go index 9bc58a3789..3d29d938bf 100644 --- a/vendor/github.com/opencontainers/cgroups/config_linux.go +++ b/vendor/github.com/opencontainers/cgroups/config_linux.go @@ -90,8 +90,8 @@ type Resources struct { // Cgroup's SCHED_IDLE value. CPUIdle *int64 `json:"cpu_idle,omitempty"` - // Process limit; set <= `0' to disable limit. - PidsLimit int64 `json:"pids_limit,omitempty"` + // Process limit; set < `0' to disable limit. `nil` means "keep current limit". + PidsLimit *int64 `json:"pids_limit,omitempty"` // Specifies per cgroup weight, range is from 10 to 1000. BlkioWeight uint16 `json:"blkio_weight,omitempty"` diff --git a/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go b/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go index 391a023c75..bde25b0759 100644 --- a/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go +++ b/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go @@ -129,12 +129,16 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) { defer fd.Close() scanner := bufio.NewScanner(fd) - scanner.Scan() // skipping header line + scanner.Scan() // Read header line. + const want = "cpu user system" + if hdr := scanner.Text(); !strings.HasPrefix(hdr, want) { + return nil, nil, malformedLine(path, file, hdr) + } for scanner.Scan() { - // Each line is: cpu user system - fields := strings.SplitN(scanner.Text(), " ", 3) - if len(fields) != 3 { + // Each line is: cpu user system. Keep N at 4 to ignore extra fields. + fields := strings.SplitN(scanner.Text(), " ", 4) + if len(fields) < 3 { continue } diff --git a/vendor/github.com/opencontainers/cgroups/fs/fs.go b/vendor/github.com/opencontainers/cgroups/fs/fs.go index 23a8fb8742..625931193e 100644 --- a/vendor/github.com/opencontainers/cgroups/fs/fs.go +++ b/vendor/github.com/opencontainers/cgroups/fs/fs.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "os" + "path" + "strings" "sync" "golang.org/x/sys/unix" @@ -139,6 +141,33 @@ func (m *Manager) Apply(pid int) (retErr error) { return retErr } +// AddPid adds a process with a given pid to an existing cgroup. +// The subcgroup argument is either empty, or a path relative to +// a cgroup under under the manager's cgroup. +func (m *Manager) AddPid(subcgroup string, pid int) (retErr error) { + m.mu.Lock() + defer m.mu.Unlock() + + c := m.cgroups + + for _, dir := range m.paths { + path := path.Join(dir, subcgroup) + if !strings.HasPrefix(path, dir) { + return fmt.Errorf("bad sub cgroup path: %s", subcgroup) + } + + if err := cgroups.WriteCgroupProc(path, pid); err != nil { + if isIgnorableError(c.Rootless, err) && c.Path == "" { + retErr = cgroups.ErrRootless + continue + } + return err + } + } + + return retErr +} + func (m *Manager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() diff --git a/vendor/github.com/opencontainers/cgroups/fs/pids.go b/vendor/github.com/opencontainers/cgroups/fs/pids.go index 9319761e6a..36bd339af8 100644 --- a/vendor/github.com/opencontainers/cgroups/fs/pids.go +++ b/vendor/github.com/opencontainers/cgroups/fs/pids.go @@ -19,19 +19,24 @@ func (s *PidsGroup) Apply(path string, _ *cgroups.Resources, pid int) error { } func (s *PidsGroup) Set(path string, r *cgroups.Resources) error { - if r.PidsLimit != 0 { - // "max" is the fallback value. - limit := "max" - - if r.PidsLimit > 0 { - limit = strconv.FormatInt(r.PidsLimit, 10) - } - - if err := cgroups.WriteFile(path, "pids.max", limit); err != nil { - return err - } + if r.PidsLimit == nil { + return nil } + // "max" is the fallback value. + val := "max" + if limit := *r.PidsLimit; limit > 0 { + val = strconv.FormatInt(limit, 10) + } else if limit == 0 { + // systemd doesn't support setting pids.max to "0", so when setting + // TasksMax we need to remap it to "1". We do the same thing here to + // avoid flip-flop behaviour between the fs and systemd drivers. In + // practice, the pids cgroup behaviour is basically identical. + val = "1" + } + if err := cgroups.WriteFile(path, "pids.max", val); err != nil { + return err + } return nil } diff --git a/vendor/github.com/opencontainers/cgroups/fs2/freezer.go b/vendor/github.com/opencontainers/cgroups/fs2/freezer.go index f0192f0955..6307e68db7 100644 --- a/vendor/github.com/opencontainers/cgroups/fs2/freezer.go +++ b/vendor/github.com/opencontainers/cgroups/fs2/freezer.go @@ -53,12 +53,9 @@ func setFreezer(dirPath string, state cgroups.FreezerState) error { func getFreezer(dirPath string) (cgroups.FreezerState, error) { fd, err := cgroups.OpenFile(dirPath, "cgroup.freeze", unix.O_RDONLY) if err != nil { - // If the kernel is too old, then we just treat the freezer as being in - // an "undefined" state. - if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) { - err = nil - } - return cgroups.Undefined, err + // If the kernel is too old, then we just treat the freezer as + // being in an "undefined" state and ignore the error. + return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err) } defer fd.Close() @@ -67,11 +64,15 @@ func getFreezer(dirPath string) (cgroups.FreezerState, error) { func readFreezer(dirPath string, fd *os.File) (cgroups.FreezerState, error) { if _, err := fd.Seek(0, 0); err != nil { - return cgroups.Undefined, err + // If the cgroup path is deleted at this point, then we just treat the freezer as + // being in an "undefined" state and ignore the error. + return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err) } state := make([]byte, 2) if _, err := fd.Read(state); err != nil { - return cgroups.Undefined, err + // If the cgroup path is deleted at this point, then we just treat the freezer as + // being in an "undefined" state and ignore the error. + return cgroups.Undefined, ignoreNotExistOrNoDeviceError(err) } switch string(state) { case "0\n": @@ -83,6 +84,21 @@ func readFreezer(dirPath string, fd *os.File) (cgroups.FreezerState, error) { } } +// ignoreNotExistOrNoDeviceError checks if the error is either a "not exist" error +// or a "no device" error, and returns nil in those cases. Otherwise, it returns the error. +func ignoreNotExistOrNoDeviceError(err error) error { + // We can safely ignore the error in the following two common situations: + // 1. The cgroup path does not exist at the time of opening(eg: the kernel is too old) + // — indicated by os.IsNotExist. + // 2. The cgroup path is deleted during the seek/read operation — indicated by + // errors.Is(err, unix.ENODEV). + // These conditions are expected and do not require special handling. + if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) { + return nil + } + return err +} + // waitFrozen polls cgroup.events until it sees "frozen 1" in it. func waitFrozen(dirPath string) (cgroups.FreezerState, error) { fd, err := cgroups.OpenFile(dirPath, "cgroup.events", unix.O_RDONLY) diff --git a/vendor/github.com/opencontainers/cgroups/fs2/fs2.go b/vendor/github.com/opencontainers/cgroups/fs2/fs2.go index c5d5a1f8ec..356d087985 100644 --- a/vendor/github.com/opencontainers/cgroups/fs2/fs2.go +++ b/vendor/github.com/opencontainers/cgroups/fs2/fs2.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "path/filepath" "strings" "github.com/opencontainers/cgroups" @@ -83,6 +84,18 @@ func (m *Manager) Apply(pid int) error { return nil } +// AddPid adds a process with a given pid to an existing cgroup. +// The subcgroup argument is either empty, or a path relative to +// a cgroup under under the manager's cgroup. +func (m *Manager) AddPid(subcgroup string, pid int) error { + path := filepath.Join(m.dirPath, subcgroup) + if !strings.HasPrefix(path, m.dirPath) { + return fmt.Errorf("bad sub cgroup path: %s", subcgroup) + } + + return cgroups.WriteCgroupProc(path, pid) +} + func (m *Manager) GetPids() ([]int, error) { return cgroups.GetPids(m.dirPath) } diff --git a/vendor/github.com/opencontainers/cgroups/fs2/hugetlb.go b/vendor/github.com/opencontainers/cgroups/fs2/hugetlb.go index 8e1ac874a5..bab9b55687 100644 --- a/vendor/github.com/opencontainers/cgroups/fs2/hugetlb.go +++ b/vendor/github.com/opencontainers/cgroups/fs2/hugetlb.go @@ -43,10 +43,11 @@ func setHugeTlb(dirPath string, r *cgroups.Resources) error { func statHugeTlb(dirPath string, stats *cgroups.Stats) error { hugetlbStats := cgroups.HugetlbStats{} rsvd := ".rsvd" + for _, pagesize := range cgroups.HugePageSizes() { + prefix := "hugetlb." + pagesize again: - prefix := "hugetlb." + pagesize + rsvd - value, err := fscommon.GetCgroupParamUint(dirPath, prefix+".current") + value, err := fscommon.GetCgroupParamUint(dirPath, prefix+rsvd+".current") if err != nil { if rsvd != "" && errors.Is(err, os.ErrNotExist) { rsvd = "" diff --git a/vendor/github.com/opencontainers/cgroups/fs2/io.go b/vendor/github.com/opencontainers/cgroups/fs2/io.go index 0f6ef7fea5..3c6dcc3bf2 100644 --- a/vendor/github.com/opencontainers/cgroups/fs2/io.go +++ b/vendor/github.com/opencontainers/cgroups/fs2/io.go @@ -165,11 +165,22 @@ func statIo(dirPath string, stats *cgroups.Stats) error { case "wios": op = "Write" targetTable = &parsedStats.IoServicedRecursive + + case "cost.usage": + op = "Count" + targetTable = &parsedStats.IoCostUsage + case "cost.wait": + op = "Count" + targetTable = &parsedStats.IoCostWait + case "cost.indebt": + op = "Count" + targetTable = &parsedStats.IoCostIndebt + case "cost.indelay": + op = "Count" + targetTable = &parsedStats.IoCostIndelay + default: - // Skip over entries we cannot map to cgroupv1 stats for now. - // In the future we should expand the stats struct to include - // them. - logrus.Debugf("cgroupv2 io stats: skipping over unmappable %s entry", item) + logrus.Debugf("cgroupv2 io stats: unknown entry %s", item) continue } diff --git a/vendor/github.com/opencontainers/cgroups/fs2/pids.go b/vendor/github.com/opencontainers/cgroups/fs2/pids.go index 9b82b90115..f932259ad5 100644 --- a/vendor/github.com/opencontainers/cgroups/fs2/pids.go +++ b/vendor/github.com/opencontainers/cgroups/fs2/pids.go @@ -4,6 +4,7 @@ import ( "errors" "math" "os" + "strconv" "strings" "golang.org/x/sys/unix" @@ -13,19 +14,26 @@ import ( ) func isPidsSet(r *cgroups.Resources) bool { - return r.PidsLimit != 0 + return r.PidsLimit != nil } func setPids(dirPath string, r *cgroups.Resources) error { if !isPidsSet(r) { return nil } - if val := numToStr(r.PidsLimit); val != "" { - if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil { - return err - } + val := "max" + if limit := *r.PidsLimit; limit > 0 { + val = strconv.FormatInt(limit, 10) + } else if limit == 0 { + // systemd doesn't support setting pids.max to "0", so when setting + // TasksMax we need to remap it to "1". We do the same thing here to + // avoid flip-flop behaviour between the fs and systemd drivers. In + // practice, the pids cgroup behaviour is basically identical. + val = "1" + } + if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil { + return err } - return nil } diff --git a/vendor/github.com/opencontainers/cgroups/stats.go b/vendor/github.com/opencontainers/cgroups/stats.go index 6cd6253ee0..01701333ab 100644 --- a/vendor/github.com/opencontainers/cgroups/stats.go +++ b/vendor/github.com/opencontainers/cgroups/stats.go @@ -159,6 +159,10 @@ type BlkioStats struct { IoTimeRecursive []BlkioStatEntry `json:"io_time_recursive,omitempty"` SectorsRecursive []BlkioStatEntry `json:"sectors_recursive,omitempty"` PSI *PSIStats `json:"psi,omitempty"` + IoCostUsage []BlkioStatEntry `json:"io_cost_usage,omitempty"` + IoCostWait []BlkioStatEntry `json:"io_cost_wait,omitempty"` + IoCostIndebt []BlkioStatEntry `json:"io_cost_indebt,omitempty"` + IoCostIndelay []BlkioStatEntry `json:"io_cost_indelay,omitempty"` } type HugetlbStats struct { diff --git a/vendor/github.com/opencontainers/cgroups/systemd/common.go b/vendor/github.com/opencontainers/cgroups/systemd/common.go index 875a589e3d..537defbf2d 100644 --- a/vendor/github.com/opencontainers/cgroups/systemd/common.go +++ b/vendor/github.com/opencontainers/cgroups/systemd/common.go @@ -6,6 +6,7 @@ import ( "fmt" "math" "os" + "path" "strconv" "strings" "sync" @@ -208,6 +209,20 @@ func stopUnit(cm *dbusConnManager, unitName string) error { return nil } +func addPid(cm *dbusConnManager, unitName, subcgroup string, pid int) error { + absSubcgroup := subcgroup + if !path.IsAbs(absSubcgroup) { + absSubcgroup = "/" + subcgroup + } + if absSubcgroup != path.Clean(absSubcgroup) { + return fmt.Errorf("bad sub cgroup path: %s", subcgroup) + } + + return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error { + return c.AttachProcessesToUnit(context.TODO(), unitName, absSubcgroup, []uint32{uint32(pid)}) + }) +} + func resetFailedUnit(cm *dbusConnManager, name string) error { return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error { return c.ResetFailedUnitContext(context.TODO(), name) diff --git a/vendor/github.com/opencontainers/cgroups/systemd/dbus.go b/vendor/github.com/opencontainers/cgroups/systemd/dbus.go index bb87ae83ae..c492372a7a 100644 --- a/vendor/github.com/opencontainers/cgroups/systemd/dbus.go +++ b/vendor/github.com/opencontainers/cgroups/systemd/dbus.go @@ -4,10 +4,13 @@ import ( "context" "errors" "fmt" + "math/rand/v2" "sync" + "time" systemdDbus "github.com/coreos/go-systemd/v22/dbus" dbus "github.com/godbus/dbus/v5" + "golang.org/x/sys/unix" ) var ( @@ -64,10 +67,27 @@ func (d *dbusConnManager) getConnection() (*systemdDbus.Conn, error) { } func (d *dbusConnManager) newConnection() (*systemdDbus.Conn, error) { - if dbusRootless { - return newUserSystemdDbus() + newDbusConn := func() (*systemdDbus.Conn, error) { + if dbusRootless { + return newUserSystemdDbus() + } + return systemdDbus.NewWithContext(context.TODO()) + } + + var err error + for retry := range 7 { + var conn *systemdDbus.Conn + conn, err = newDbusConn() + if !errors.Is(err, unix.EAGAIN) { + return conn, err + } + // Exponential backoff (100ms * 2^attempt + ~12.5% jitter). + // At most we would expect 15 seconds of delay with 7 attempts. + delay := 100 * time.Millisecond << retry + delay += time.Duration(rand.Int64N(1 + (delay.Milliseconds() >> 3))) + time.Sleep(delay) } - return systemdDbus.NewWithContext(context.TODO()) + return nil, fmt.Errorf("dbus connection failed after several retries: %w", err) } // resetConnection resets the connection to its initial state diff --git a/vendor/github.com/opencontainers/cgroups/systemd/v1.go b/vendor/github.com/opencontainers/cgroups/systemd/v1.go index b8959adbfa..96e69bb860 100644 --- a/vendor/github.com/opencontainers/cgroups/systemd/v1.go +++ b/vendor/github.com/opencontainers/cgroups/systemd/v1.go @@ -2,6 +2,7 @@ package systemd import ( "errors" + "math" "os" "path/filepath" "strings" @@ -97,9 +98,17 @@ func genV1ResourcesProperties(r *cgroups.Resources, cm *dbusConnManager) ([]syst newProp("BlockIOWeight", uint64(r.BlkioWeight))) } - if r.PidsLimit > 0 || r.PidsLimit == -1 { + if r.PidsLimit != nil { + var tasksMax uint64 + if limit := *r.PidsLimit; limit < 0 { + tasksMax = math.MaxUint64 // "infinity" + } else if limit == 0 { + tasksMax = 1 // systemd does not accept "0" for TasksMax + } else { + tasksMax = uint64(limit) + } properties = append(properties, - newProp("TasksMax", uint64(r.PidsLimit))) + newProp("TasksMax", tasksMax)) } err = addCpuset(cm, &properties, r.CpusetCpus, r.CpusetMems) @@ -215,6 +224,25 @@ func (m *LegacyManager) Apply(pid int) error { return nil } +// AddPid adds a process with a given pid to an existing cgroup. +// The subcgroup argument is either empty, or a path relative to +// a cgroup under under the manager's cgroup. +func (m *LegacyManager) AddPid(subcgroup string, pid int) error { + m.mu.Lock() + defer m.mu.Unlock() + + if err := addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid); err != nil { + return err + } + + // Since systemd only joins controllers it knows, use cgroupfs for the rest. + fsMgr, err := fs.NewManager(m.cgroups, m.paths) + if err != nil { + return err + } + return fsMgr.AddPid(subcgroup, pid) +} + func (m *LegacyManager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() diff --git a/vendor/github.com/opencontainers/cgroups/systemd/v2.go b/vendor/github.com/opencontainers/cgroups/systemd/v2.go index 636b9cb01b..f76c93e844 100644 --- a/vendor/github.com/opencontainers/cgroups/systemd/v2.go +++ b/vendor/github.com/opencontainers/cgroups/systemd/v2.go @@ -176,6 +176,9 @@ func unifiedResToSystemdProps(cm *dbusConnManager, res map[string]string) (props return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err) } } + if num == 0 { + num = 1 // systemd does not accept "0" for TasksMax + } props = append(props, newProp("TasksMax", num)) @@ -256,9 +259,17 @@ func genV2ResourcesProperties(dirPath string, r *cgroups.Resources, cm *dbusConn addCPUQuota(cm, &properties, &r.CpuQuota, r.CpuPeriod) - if r.PidsLimit > 0 || r.PidsLimit == -1 { + if r.PidsLimit != nil { + var tasksMax uint64 + if limit := *r.PidsLimit; limit < 0 { + tasksMax = math.MaxUint64 // "infinity" + } else if limit == 0 { + tasksMax = 1 // systemd does not accept "0" for TasksMax + } else { + tasksMax = uint64(limit) + } properties = append(properties, - newProp("TasksMax", uint64(r.PidsLimit))) + newProp("TasksMax", tasksMax)) } err = addCpuset(cm, &properties, r.CpusetCpus, r.CpusetMems) @@ -383,6 +394,16 @@ func cgroupFilesToChown() ([]string, error) { return filesToChown, nil } +// AddPid adds a process with a given pid to an existing cgroup. +// The subcgroup argument is either empty, or a path relative to +// a cgroup under under the manager's cgroup. +func (m *UnifiedManager) AddPid(subcgroup string, pid int) error { + m.mu.Lock() + defer m.mu.Unlock() + + return addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid) +} + func (m *UnifiedManager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go index 998fd70409..0649286ab7 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go @@ -3,6 +3,7 @@ package cmdrun import ( "context" "encoding/json" + "errors" "fmt" "os" "os/signal" @@ -10,7 +11,6 @@ import ( "syscall" "time" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/openshift-eng/openshift-tests-extension/pkg/extension" @@ -36,7 +36,7 @@ func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command { cmd := &cobra.Command{ Use: "run-suite NAME", Short: "Run a group of tests by suite. This is more limited than origin, and intended for light local " + - "development use. Orchestration parameters, scheduling, isolation, etc are not obeyed, and Ginkgo tests are executed serially.", + "development use. Ginkgo tests are executed in parallel, controlled by --max-concurrency (default 10).", SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { ctx, cancelCause := context.WithCancelCause(context.Background()) @@ -74,7 +74,7 @@ func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command { } suite, err := ext.GetSuite(args[0]) if err != nil { - return errors.Wrapf(err, "couldn't find suite: %s", args[0]) + return fmt.Errorf("couldn't find suite %q: %w", args[0], err) } compositeWriter := extensiontests.NewCompositeResultWriter() @@ -88,7 +88,7 @@ func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command { if opts.junitPath != "" { junitWriter, err := extensiontests.NewJUnitResultWriter(opts.junitPath, suite.Name) if err != nil { - return errors.Wrap(err, "couldn't create junit writer") + return fmt.Errorf("couldn't create junit writer: %w", err) } compositeWriter.AddWriter(junitWriter) } @@ -96,7 +96,7 @@ func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command { if opts.htmlPath != "" { htmlWriter, err := extensiontests.NewHTMLResultWriter(opts.htmlPath, suite.Name) if err != nil { - return errors.Wrap(err, "couldn't create html writer") + return fmt.Errorf("couldn't create html writer: %w", err) } compositeWriter.AddWriter(htmlWriter) } @@ -111,14 +111,26 @@ func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command { specs, err := ext.GetSpecs().Filter(suite.Qualifiers) if err != nil { - return errors.Wrap(err, "couldn't filter specs") + return fmt.Errorf("couldn't filter specs: %w", err) + } + + if suite.TestTimeout != nil { + for _, spec := range specs { + if spec.Timeout == 0 { + spec.Timeout = *suite.TestTimeout + } + } } concurrency := opts.concurrencyFlags.MaxConcurency if suite.Parallelism > 0 { concurrency = min(concurrency, suite.Parallelism) } - results, runErr := specs.Run(ctx, compositeWriter, concurrency) + var runOpts []extensiontests.SchedulerOption + if len(suite.ResourcePools) > 0 { + runOpts = append(runOpts, extensiontests.WithResourcePoolCapacity(suite.ResourcePools)) + } + results, runErr := specs.Run(ctx, compositeWriter, concurrency, runOpts...) if opts.junitPath != "" { // we want to commit the results to disk regardless of the success or failure of the specs if err := writeResults(opts.junitPath, results); err != nil { diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go index c62021e7ec..86e10e02e2 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go @@ -23,6 +23,7 @@ func NewRunTestCommand(registry *extension.Registry) *cobra.Command { concurrencyFlags *flags.ConcurrencyFlags nameFlags *flags.NamesFlags outputFlags *flags.OutputFlags + timeout time.Duration }{ componentFlags: flags.NewComponentFlags(), nameFlags: flags.NewNamesFlags(), @@ -37,6 +38,11 @@ func NewRunTestCommand(registry *extension.Registry) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ctx, cancelCause := context.WithCancelCause(context.Background()) defer cancelCause(errors.New("exiting")) + if opts.timeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, opts.timeout) + defer cancel() + } abortCh := make(chan os.Signal, 2) go func() { @@ -104,6 +110,7 @@ func NewRunTestCommand(registry *extension.Registry) *cobra.Command { return err }, } + cmd.Flags().DurationVar(&opts.timeout, "timeout", 0, "Maximum duration for the test. When set, the test context will have a deadline, causing blocking operations like PollUntilDone to fail cleanly instead of hanging until the parent kills the process.") opts.componentFlags.BindFlags(cmd.Flags()) opts.nameFlags.BindFlags(cmd.Flags()) opts.outputFlags.BindFlags(cmd.Flags()) diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/scheduler.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/scheduler.go new file mode 100644 index 0000000000..eb44dfddbd --- /dev/null +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/scheduler.go @@ -0,0 +1,367 @@ +package extensiontests + +import ( + "context" + "fmt" + "maps" + "os" + "sync" + + "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets" +) + +const defaultConflictGroup = "default" + +// SchedulerOption configures optional scheduler behavior. +type SchedulerOption func(*testScheduler) + +// WithResourcePoolCapacity configures named resource pools with finite capacity. +// The scheduler will only dispatch a test when all of its declared pool demands +// can be satisfied by currently available capacity. +func WithResourcePoolCapacity(pools map[string]int) SchedulerOption { + return func(ts *testScheduler) { + ts.poolCapacity = maps.Clone(pools) + ts.poolAvailable = maps.Clone(pools) + } +} + +// WithSchedulerAccessor registers a callback that receives the Scheduler during +// construction, before NewScheduler returns. This allows callers that don't +// directly create the scheduler (e.g., code invoking Run()) to store a reference +// for external observability. The Scheduler is fully initialized when the callback +// fires; type-assert to SchedulerDiagnostics to access GetSnapshot. +func WithSchedulerAccessor(fn func(Scheduler)) SchedulerOption { + return func(ts *testScheduler) { + ts.accessor = fn + } +} + +// SchedulerSnapshot is a point-in-time view of scheduler state for diagnostics. +type SchedulerSnapshot struct { + QueueLength int + QueueFront string + QueueFrontResourcePools map[string]int + ResourcePoolCapacity map[string]int + ResourcePoolAvailable map[string]int + ActiveCount int +} + +// Scheduler defines the interface for test scheduling. +// It manages scheduling based on isolation requirements (conflicts, taints, tolerations) +// and optional named resource pool capacity. +// +// Callers must follow a get-once, complete-once protocol: every non-nil spec returned by +// GetNextTestToRun must eventually be passed to MarkTestComplete exactly once, including +// when test execution panics. +type Scheduler interface { + // GetNextTestToRun blocks until a test is available, then returns it. + // Returns nil when all tests have been distributed (queue is empty) or context is cancelled. + // When a test is returned, it is atomically removed from queue and marked as running. + // This method can be safely called from multiple goroutines concurrently. + GetNextTestToRun(ctx context.Context) *ExtensionTestSpec + + // MarkTestComplete marks a test as complete, cleaning up its conflicts, taints, and + // pool reservations. This may unblock other tests that were waiting. + // This method can be safely called from multiple goroutines concurrently. + MarkTestComplete(spec *ExtensionTestSpec) +} + +// SchedulerDiagnostics provides observability into scheduler state. +// The testScheduler implements this interface; callers can type-assert to access it. +type SchedulerDiagnostics interface { + // GetSnapshot returns a point-in-time view of the scheduler's internal state + // for diagnostics and external observability (e.g., stall detection). + GetSnapshot() SchedulerSnapshot +} + +// testScheduler manages test scheduling based on conflicts, taints, tolerations, +// and named resource pool capacity. It maintains an ordered queue of tests and +// provides thread-safe scheduling operations. +type testScheduler struct { + mu sync.Mutex + cond *sync.Cond // condition variable to signal when tests complete + tests []*ExtensionTestSpec + runningConflicts map[string]sets.Set[string] // tracks which conflicts are running per group: group -> set of conflicts + activeTaints map[string]int // tracks how many tests are currently applying each taint + poolCapacity map[string]int // total capacity per pool (nil if no pools configured) + poolAvailable map[string]int // currently available per pool + activeCount int // tests dispatched but not yet completed + accessor func(Scheduler) +} + +// NewScheduler creates a test scheduler. It accepts tests in any order and schedules +// them based on isolation requirements (conflicts, taints, tolerations) and optional +// pool capacity constraints. When pool capacity is configured via WithResourcePoolCapacity, +// the constructor validates that no test demands more than the total pool capacity, +// references only defined pools, and has non-negative demand. +func NewScheduler(tests []*ExtensionTestSpec, opts ...SchedulerOption) (Scheduler, error) { + ts := &testScheduler{ + tests: append([]*ExtensionTestSpec(nil), tests...), + runningConflicts: make(map[string]sets.Set[string]), + activeTaints: make(map[string]int), + } + ts.cond = sync.NewCond(&ts.mu) + + for _, opt := range opts { + opt(ts) + } + + if ts.poolCapacity != nil { + for pool, capacity := range ts.poolCapacity { + if capacity < 0 { + return nil, fmt.Errorf("pool %q has negative capacity (%d)", pool, capacity) + } + } + for _, t := range tests { + for pool, demand := range t.Resources.ResourcePools { + if demand < 0 { + return nil, fmt.Errorf("test %q has negative demand (%d) for pool %q", t.Name, demand, pool) + } + if demand == 0 { + fmt.Fprintf(os.Stderr, "[scheduler] WARNING: test %q declares zero demand for pool %q (likely misconfiguration)\n", t.Name, pool) + } + poolCap, ok := ts.poolCapacity[pool] + if !ok { + return nil, fmt.Errorf("test %q declares pool %q but no capacity defined for it", t.Name, pool) + } + if demand > poolCap { + return nil, fmt.Errorf("test %q demands %d units of pool %q but total capacity is %d", + t.Name, demand, pool, poolCap) + } + } + } + } else { + for _, t := range tests { + if len(t.Resources.ResourcePools) > 0 { + fmt.Fprintf(os.Stderr, "[scheduler] WARNING: test %q declares resource pool demands but no pool capacity is configured\n", t.Name) + break + } + } + } + + if ts.accessor != nil { + ts.accessor(ts) + } + + return ts, nil +} + +// GetSnapshot returns a point-in-time snapshot of the scheduler's internal state. +func (ts *testScheduler) GetSnapshot() SchedulerSnapshot { + ts.mu.Lock() + defer ts.mu.Unlock() + + snap := SchedulerSnapshot{ + QueueLength: len(ts.tests), + ActiveCount: ts.activeCount, + } + + if len(ts.tests) > 0 { + snap.QueueFront = ts.tests[0].Name + snap.QueueFrontResourcePools = maps.Clone(ts.tests[0].Resources.ResourcePools) + } + + if ts.poolCapacity != nil { + snap.ResourcePoolCapacity = maps.Clone(ts.poolCapacity) + snap.ResourcePoolAvailable = maps.Clone(ts.poolAvailable) + } + + return snap +} + +// GetNextTestToRun blocks until a test is available to run, or returns nil +// if all tests have been distributed or the context is cancelled. +// It continuously scans the queue and waits for state changes when no tests are runnable. +// When a test is returned, it is atomically removed from queue and marked as running. +func (ts *testScheduler) GetNextTestToRun(ctx context.Context) *ExtensionTestSpec { + ts.mu.Lock() + defer ts.mu.Unlock() + + // Set up context cancellation to wake up any waiting goroutine + done := make(chan struct{}) + defer close(done) + go func() { + select { + case <-ctx.Done(): + ts.mu.Lock() + ts.cond.Broadcast() + ts.mu.Unlock() + case <-done: + // Normal exit, nothing to do + } + }() + + for { + // Check if context is cancelled + if ctx.Err() != nil { + return nil + } + + // Check if all tests have been distributed + if len(ts.tests) == 0 { + return nil + } + + // Scan from beginning to find first runnable test + for i, spec := range ts.tests { + conflictGroup := getConflictGroup(spec) + + // Ensure the conflict group set exists + if ts.runningConflicts[conflictGroup] == nil { + ts.runningConflicts[conflictGroup] = sets.New[string]() + } + + // Check if any of the test's conflicts are currently running within its group + hasConflict := ts.hasActiveConflict(spec, conflictGroup) + + // Check if test can tolerate all currently active taints + canTolerate := ts.canTolerateTaints(spec) + + // Check if pool capacity is available for this test + hasCapacity := ts.hasPoolCapacity(spec) + + if !hasConflict && canTolerate && hasCapacity { + isolation := &spec.Resources.Isolation + + // Found a runnable test - ATOMICALLY: + // 1. Mark conflicts as running + for _, conflict := range isolation.Conflict { + ts.runningConflicts[conflictGroup].Insert(conflict) + } + + // 2. Activate taints + for _, taint := range isolation.Taint { + ts.activeTaints[taint]++ + } + + // 3. Decrement pool availability and log transitions + if ts.poolCapacity != nil { + for pool, demand := range spec.Resources.ResourcePools { + before := ts.poolAvailable[pool] + ts.poolAvailable[pool] -= demand + fmt.Fprintf(os.Stderr, "[scheduler] dispatch %s (pool %s: %d->%d/%d available)\n", + spec.Name, pool, before, ts.poolAvailable[pool], ts.poolCapacity[pool]) + } + } + + // 4. Track active count + ts.activeCount++ + + // 5. Remove test from queue + ts.tests = append(ts.tests[:i], ts.tests[i+1:]...) + + // 6. Return the test (now safe to run) + return spec + } + } + + // No runnable test found, but tests still exist in queue - wait for state change + ts.cond.Wait() + } +} + +func getConflictGroup(_ *ExtensionTestSpec) string { + return defaultConflictGroup +} + +// hasActiveConflict checks if the spec has any conflicts with currently running tests. +func (ts *testScheduler) hasActiveConflict(spec *ExtensionTestSpec, conflictGroup string) bool { + for _, conflict := range spec.Resources.Isolation.Conflict { + if ts.runningConflicts[conflictGroup].Has(conflict) { + return true + } + } + return false +} + +// canTolerateTaints checks if a spec can tolerate all currently active taints. +func (ts *testScheduler) canTolerateTaints(spec *ExtensionTestSpec) bool { + // If no taints are active, any test can run + if len(ts.activeTaints) == 0 { + return true + } + + // Build a set of tolerations for efficient lookup + tolerations := sets.New(spec.Resources.Isolation.Toleration...) + + // Check if test tolerates all active taints + for taint, count := range ts.activeTaints { + // Skip taints with zero count (should be cleaned up but being defensive) + if count <= 0 { + continue + } + + if !tolerations.Has(taint) { + return false // Test cannot tolerate this active taint + } + } + return true +} + +// hasPoolCapacity checks if the scheduler has enough capacity in all pools for the spec. +func (ts *testScheduler) hasPoolCapacity(spec *ExtensionTestSpec) bool { + if ts.poolCapacity == nil || len(spec.Resources.ResourcePools) == 0 { + return true + } + for pool, demand := range spec.Resources.ResourcePools { + if ts.poolAvailable[pool] < demand { + return false + } + } + return true +} + +// MarkTestComplete marks all conflicts, taints, and pool reservations of a spec as +// no longer running/active and signals waiting workers that blocked tests may now be runnable. +// This should be called after a test completes execution. +func (ts *testScheduler) MarkTestComplete(spec *ExtensionTestSpec) { + ts.mu.Lock() + defer ts.mu.Unlock() + + if spec == nil { + ts.cond.Broadcast() + return + } + + isolation := &spec.Resources.Isolation + conflictGroup := getConflictGroup(spec) + + // Clean up conflicts within this group + if groupConflicts, exists := ts.runningConflicts[conflictGroup]; exists { + for _, conflict := range isolation.Conflict { + groupConflicts.Delete(conflict) + } + } + + // Clean up taints with reference counting + for _, taint := range isolation.Taint { + ts.activeTaints[taint]-- + if ts.activeTaints[taint] <= 0 { + delete(ts.activeTaints, taint) + } + } + + // Return pool units and log transitions + if ts.poolCapacity != nil { + for pool, demand := range spec.Resources.ResourcePools { + before := ts.poolAvailable[pool] + ts.poolAvailable[pool] += demand + if ts.poolAvailable[pool] > ts.poolCapacity[pool] { + fmt.Fprintf(os.Stderr, "[scheduler] WARNING: pool %q overflow: available %d > capacity %d, capping\n", + pool, ts.poolAvailable[pool], ts.poolCapacity[pool]) + ts.poolAvailable[pool] = ts.poolCapacity[pool] + } + fmt.Fprintf(os.Stderr, "[scheduler] complete %s (pool %s: %d->%d/%d available)\n", + spec.Name, pool, before, ts.poolAvailable[pool], ts.poolCapacity[pool]) + } + } + + // Track active count + if ts.activeCount > 0 { + ts.activeCount-- + } + + // Signal waiting workers that the state has changed + // Some blocked tests might now be runnable + ts.cond.Broadcast() +} diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go index e87809c8a2..40446041fa 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go @@ -196,11 +196,26 @@ func (specs ExtensionTestSpecs) Names() []string { // are written to the given ResultWriter after each spec has completed execution. BeforeEach, // BeforeAll, AfterEach, AfterAll hooks are executed when specified. "Each" hooks must be thread // safe. Returns an error if any test spec failed, indicating the quantity of failures. -func (specs ExtensionTestSpecs) Run(ctx context.Context, w ResultWriter, maxConcurrent int) ([]*ExtensionTestResult, error) { - queue := make(chan *ExtensionTestSpec) +// +// Tests are scheduled using isolation-aware scheduling that respects conflicts, taints, and +// tolerations defined in each spec's Resources.Isolation field. +func (specs ExtensionTestSpecs) Run(ctx context.Context, w ResultWriter, maxConcurrent int, opts ...SchedulerOption) ([]*ExtensionTestResult, error) { terminalFailures := atomic.Int64{} nonTerminalFailures := atomic.Int64{} + // if we have only a single spec to run, we do that differently than running multiple. + // multiple specs can run in parallel and do so by exec-ing back into the binary with `run-test` with a single test to execute. + // This means that to avoid infinite recursion, when requesting a single test to run + // we need to run it in process. + runSingleSpec := len(specs) == 1 + + // Create scheduler before BeforeAll hooks so validation errors don't leave + // setup side effects without cleanup. + scheduler, err := NewScheduler(specs, opts...) + if err != nil { + return nil, fmt.Errorf("failed to create scheduler: %w", err) + } + // Execute beforeAll for _, spec := range specs { for _, beforeAllTask := range spec.beforeAll { @@ -208,20 +223,6 @@ func (specs ExtensionTestSpecs) Run(ctx context.Context, w ResultWriter, maxConc } } - // Feed the queue - go func() { - specs.Walk(func(spec *ExtensionTestSpec) { - queue <- spec - }) - close(queue) - }() - - // if we have only a single spec to run, we do that differently than running multiple. - // multiple specs can run in parallel and do so by exec-ing back into the binary with `run-test` with a single test to execute. - // This means that to avoid infinite recursion, when requesting a single test to run - // we need to run it in process. - runSingleSpec := len(specs) == 1 - // Start consumers var wg sync.WaitGroup resultChan := make(chan *ExtensionTestResult, len(specs)) @@ -229,29 +230,39 @@ func (specs ExtensionTestSpecs) Run(ctx context.Context, w ResultWriter, maxConc wg.Add(1) go func() { defer wg.Done() - for spec := range queue { - for _, beforeEachTask := range spec.beforeEach { - beforeEachTask.Run(*spec) + for { + // Get next runnable test from scheduler (blocks until available or done) + spec := scheduler.GetNextTestToRun(ctx) + if spec == nil { + return // No more tests or context cancelled } - res := runSpec(ctx, spec, runSingleSpec) - if res.Result == ResultFailed { - if res.Lifecycle.IsTerminal() { - terminalFailures.Add(1) - } else { - nonTerminalFailures.Add(1) + func() { + defer scheduler.MarkTestComplete(spec) + + for _, beforeEachTask := range spec.beforeEach { + beforeEachTask.Run(*spec) } - } - for _, afterEachTask := range spec.afterEach { - afterEachTask.Run(res) - } + res := runSpec(ctx, spec, runSingleSpec) + if res.Result == ResultFailed { + if res.Lifecycle.IsTerminal() { + terminalFailures.Add(1) + } else { + nonTerminalFailures.Add(1) + } + } + + for _, afterEachTask := range spec.afterEach { + afterEachTask.Run(res) + } - // We can't assume the runner will set the name of a test; it may not know it. Even if - // it does, we may want to modify it (e.g. k8s-tests for annotations currently). - res.Name = spec.Name - w.Write(res) - resultChan <- res + // We can't assume the runner will set the name of a test; it may not know it. Even if + // it does, we may want to modify it (e.g. k8s-tests for annotations currently). + res.Name = spec.Name + w.Write(res) + resultChan <- res + }() } }() } diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go index cd23be81ff..5251509a20 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go @@ -2,6 +2,7 @@ package extensiontests import ( "context" + "time" "github.com/openshift-eng/openshift-tests-extension/pkg/dbtime" "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets" @@ -59,6 +60,10 @@ type ExtensionTestSpec struct { // to the `ote-binary run-test "test name"` commmand and interpretting the result. RunParallel func(ctx context.Context) *ExtensionTestResult `json:"-"` + // Timeout is the maximum duration for this test. If set, it overrides the default 90-minute + // timeout used by SpawnProcessToRunTest. This is typically populated from Suite.TestTimeout. + Timeout time.Duration `json:"-"` + // Hook functions afterAll []*OneTimeTask beforeAll []*OneTimeTask @@ -67,10 +72,11 @@ type ExtensionTestSpec struct { } type Resources struct { - Isolation Isolation `json:"isolation"` - Memory string `json:"memory,omitempty"` - Duration string `json:"duration,omitempty"` - Timeout string `json:"timeout,omitempty"` + Isolation Isolation `json:"isolation"` + ResourcePools map[string]int `json:"resourcePools,omitempty"` + Memory string `json:"memory,omitempty"` + Duration string `json:"duration,omitempty"` + Timeout string `json:"timeout,omitempty"` } type Isolation struct { diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go index 00d2d9d663..f05a156670 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go @@ -81,6 +81,9 @@ type Suite struct { ClusterStability ClusterStability `json:"clusterStability,omitempty"` // TestTimeout is the default timeout for tests in this suite. TestTimeout *time.Duration `json:"testTimeout,omitempty"` + // ResourcePools defines the total capacity of named resource pools for this suite. + // The scheduler enforces that parallel test demand does not exceed pool capacity. + ResourcePools map[string]int `json:"resourcePools,omitempty"` } type Image struct { diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go index 24f49f6387..af62bbf13b 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go @@ -2,10 +2,11 @@ package flags import ( "encoding/json" + "errors" + "fmt" "reflect" "strings" - "github.com/pkg/errors" "github.com/spf13/pflag" ) @@ -90,6 +91,6 @@ func (o *OutputFlags) Marshal(v interface{}) ([]byte, error) { } return nil, errors.New("names format requires an array of structs") default: - return nil, errors.Errorf("invalid output format: %s", o.Output) + return nil, fmt.Errorf("invalid output format: %s", o.Output) } } diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go index 890cebb094..b7f95838a8 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go @@ -25,7 +25,7 @@ func SpawnProcessToRunTest(ctx context.Context, testName string, timeout time.Du stdout := &bytes.Buffer{} stderr := &bytes.Buffer{} - command := exec.CommandContext(longerCtx, os.Args[0], "run-test", "--output=json", testName) + command := exec.CommandContext(longerCtx, os.Args[0], "run-test", "--output=json", fmt.Sprintf("--timeout=%s", timeout), testName) command.Stdout = stdout command.Stderr = stderr @@ -37,30 +37,22 @@ func SpawnProcessToRunTest(ctx context.Context, testName string, timeout time.Du } go func() { + // interrupt after timeout, or exit early if the process finishes first select { - // interrupt tests after timeout, and abort if they don't complete quick enough case <-time.After(timeout): - if command.Process != nil { - // we're not going to do anything with the err - _ = command.Process.Signal(syscall.SIGINT) - } - // if the process appears to be hung a significant amount of time after the timeout - // send an ABRT so we get a stack dump - select { - case <-time.After(time.Minute): - if command.Process != nil { - // we're not going to do anything with the err - _ = command.Process.Signal(syscall.SIGABRT) - } - case <-timeoutCtx.Done(): - if command.Process != nil { - _ = command.Process.Signal(syscall.SIGABRT) - } - } case <-timeoutCtx.Done(): - if command.Process != nil { - _ = command.Process.Signal(syscall.SIGINT) - } + } + if command.Process != nil { + _ = command.Process.Signal(syscall.SIGINT) + } + // Canceled means the process exited and the context was cancelled — no need to escalate + if timeoutCtx.Err() == context.Canceled { + return + } + // if the process is hung, send SIGABRT after a grace period for a stack dump + <-time.After(time.Minute) + if command.Process != nil { + _ = command.Process.Signal(syscall.SIGABRT) } }() @@ -74,7 +66,7 @@ func SpawnProcessToRunTest(ctx context.Context, testName string, timeout time.Du } fmt.Fprintf(stderr, "Command Error: %v\n", cmdErr) - fmt.Fprintf(stderr, "Deserializaion Error: %v\n", parseErr) + fmt.Fprintf(stderr, "Deserialization Error: %v\n", parseErr) return newTestResult(testName, result, start, time.Now(), stdout, stderr) } @@ -83,28 +75,61 @@ func newTestResultFromOutput(stdout *bytes.Buffer) (*extensiontests.ExtensionTes return nil, errors.New("no output from command") } + jsonData, err := extractJSON(stdout.Bytes()) + if err != nil { + return nil, err + } + // when the command runs correctly, we get json or json slice output retArray := []extensiontests.ExtensionTestResult{} - if arrayItemErr := json.Unmarshal(stdout.Bytes(), &retArray); arrayItemErr == nil { + if arrayItemErr := json.Unmarshal(jsonData, &retArray); arrayItemErr == nil { if len(retArray) != 1 { - return nil, errors.New("expected 1 result, got %v results") + return nil, fmt.Errorf("expected 1 result, got %d results", len(retArray)) } return &retArray[0], nil } // when the command runs correctly, we get json output ret := &extensiontests.ExtensionTestResult{} - if singleItemErr := json.Unmarshal(stdout.Bytes(), ret); singleItemErr != nil { + if singleItemErr := json.Unmarshal(jsonData, ret); singleItemErr != nil { return nil, singleItemErr } return ret, nil } +// extractJSON finds the first JSON object or array in output, skipping any non-JSON +// lines that precede it (e.g. klog lines, Ginkgo reporter output). It also ignores +// trailing non-JSON content after the JSON payload. This is necessary because extension +// binaries may emit log output to stdout before or after the JSON result, which would +// otherwise cause deserialization failures. +func extractJSON(output []byte) ([]byte, error) { + lines := bytes.Split(output, []byte("\n")) + for i, line := range lines { + trimmed := bytes.TrimSpace(line) + if len(trimmed) > 0 && (trimmed[0] == '{' || trimmed[0] == '[') { + // Calculate byte offset to the start of the JSON content + offset := 0 + for j := 0; j < i; j++ { + offset += len(lines[j]) + 1 // +1 for the newline + } + + var raw json.RawMessage + dec := json.NewDecoder(bytes.NewReader(output[offset:])) + if err := dec.Decode(&raw); err != nil { + continue // not valid JSON, try next candidate line + } + return raw, nil + } + } + + return nil, fmt.Errorf("no JSON object or array found in output (%d bytes)", len(output)) +} + func newTestResult(name string, result extensiontests.Result, start, end time.Time, stdout, stderr *bytes.Buffer) *extensiontests.ExtensionTestResult { duration := end.Sub(start) dbStart := dbtime.DBTime(start) - dbEnd := dbtime.DBTime(start) + dbEnd := dbtime.DBTime(end) ret := &extensiontests.ExtensionTestResult{ Name: name, Lifecycle: "", // lifecycle is completed one level above this. diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go index e970d46ad4..90c5c2bd17 100644 --- a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go +++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go @@ -11,7 +11,6 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" "github.com/onsi/gomega" - "github.com/pkg/errors" "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets" @@ -21,7 +20,7 @@ import ( func configureGinkgo() (*types.SuiteConfig, *types.ReporterConfig, error) { if !ginkgo.GetSuite().InPhaseBuildTree() { if err := ginkgo.GetSuite().BuildTree(); err != nil { - return nil, nil, errors.Wrapf(err, "couldn't build ginkgo tree") + return nil, nil, fmt.Errorf("couldn't build ginkgo tree: %w", err) } } @@ -57,7 +56,7 @@ func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunc cwd, err := os.Getwd() if err != nil { - return nil, errors.Wrap(err, "couldn't get current working directory") + return nil, fmt.Errorf("couldn't get current working directory: %w", err) } ginkgo.GetSuite().WalkTests(func(name string, spec types.TestSpec) { @@ -81,22 +80,17 @@ func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunc Name: spec.Text(), } - var summary types.SpecReport ginkgo.GetSuite().RunSpec(spec, ginkgo.Labels{}, "", cwd, ginkgo.GetFailer(), ginkgo.GetWriter(), *suiteConfig, *reporterConfig) - for _, report := range ginkgo.GetSuite().GetReport().SpecReports { - if report.NumAttempts > 0 { - summary = report - } - } + summary := findSpecReport(ginkgo.GetSuite().GetReport().SpecReports) result.Output = summary.CapturedGinkgoWriterOutput result.Error = summary.CapturedStdOutErr - switch { - case summary.State == types.SpecStatePassed: + switch summary.State { + case types.SpecStatePassed: result.Result = ext.ResultPassed - case summary.State == types.SpecStateSkipped, summary.State == types.SpecStatePending: + case types.SpecStateSkipped, types.SpecStatePending: result.Result = ext.ResultSkipped if len(summary.Failure.Message) > 0 { result.Output = fmt.Sprintf( @@ -115,7 +109,7 @@ func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunc summary.Failure.ForwardedPanic, ) } - case summary.State == types.SpecStateFailed, summary.State == types.SpecStatePanicked, summary.State == types.SpecStateInterrupted, summary.State == types.SpecStateAborted: + case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateInterrupted, types.SpecStateAborted: result.Result = ext.ResultFailed var errors []string if len(summary.Failure.ForwardedPanic) > 0 { @@ -126,7 +120,7 @@ func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunc } errors = append(errors, fmt.Sprintf("fail [%s:%d]: %s", lastFilenameSegment(summary.Failure.Location.FileName), summary.Failure.Location.LineNumber, summary.Failure.Message)) result.Error = strings.Join(errors, "\n") - case summary.State == types.SpecStateTimedout: + case types.SpecStateTimedout: result.Result = ext.ResultFailed var errors []string for _, additionalFailure := range summary.AdditionalFailures { @@ -137,16 +131,23 @@ func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunc } errors = append(errors, fmt.Sprintf("fail [%s:%d]: %s", lastFilenameSegment(summary.Failure.Location.FileName), summary.Failure.Location.LineNumber, summary.Failure.Message)) result.Error = strings.Join(errors, "\n") + case types.SpecStateInvalid: + result.Result = ext.ResultFailed + result.Error = fmt.Sprintf("test produced no spec report; this is a bug in the test framework: %#v", summary) default: - panic(fmt.Sprintf("test produced unknown outcome: %#v", summary)) + result.Result = ext.ResultFailed + result.Error = fmt.Sprintf("test produced unknown outcome: %#v", summary) } return result }, - RunParallel: func(ctx context.Context) *ext.ExtensionTestResult { - // TODO pass through timeout and determine Lifecycle - return SpawnProcessToRunTest(ctx, name, 90*time.Minute) - }, + } + testCase.RunParallel = func(ctx context.Context) *ext.ExtensionTestResult { + timeout := 90 * time.Minute + if testCase.Timeout > 0 { + timeout = testCase.Timeout + } + return SpawnProcessToRunTest(ctx, name, timeout) } specs = append(specs, testCase) }) @@ -210,6 +211,25 @@ func lastFilenameSegment(filename string) string { return filename } +// findSpecReport selects the best matching spec report from the list of reports +// produced by RunSpec. It first looks for a report that was actually attempted +// (NumAttempts > 0), which covers passed/failed/panicked specs. If none is found +// (as happens with Pending or Skipped specs where Ginkgo never enters the +// execution loop), it falls back to the last report in the list. +func findSpecReport(reports types.SpecReports) types.SpecReport { + var summary types.SpecReport + for _, report := range reports { + if report.NumAttempts > 0 { + summary = report + } + } + // Pending/Skipped specs have NumAttempts==0; fall back to the last report + if summary.State == types.SpecStateInvalid && len(reports) > 0 { + summary = reports[len(reports)-1] + } + return summary +} + func collectAdditionalFailures(errors *[]string, suffix string, failure types.Failure) { if failure.IsZero() { return diff --git a/vendor/github.com/openshift/api/.golangci.yaml b/vendor/github.com/openshift/api/.golangci.yaml index 53c9b4009e..e4e5b97612 100644 --- a/vendor/github.com/openshift/api/.golangci.yaml +++ b/vendor/github.com/openshift/api/.golangci.yaml @@ -106,6 +106,10 @@ linters: # This regex must always be updated in tandem with the regex in .golangci.go-validated.yaml that prevents `optionalfields` from being applied to the files in the path. path: machine/v1beta1/(types_awsprovider.go|types_azureprovider.go|types_gcpprovider.go|types_vsphereprovider.go)|machine/v1alpha1/types_openstack.go text: "optionalfields" + - linters: + - kubeapilinter + # osin/v1 types are config file APIs, not CRDs — validation is handled in Go code at config load time. + path: osin/v1/types.go - linters: - kubeapilinter # Silence norefs lint for `Ref` field in ClusterAPI as it refers to an OCI image reference, not a kube object reference. diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 8b85144eaf..b6c0de378c 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -4,7 +4,7 @@ all: build update: update-non-codegen update-codegen RUNTIME ?= podman -RUNTIME_IMAGE_NAME ?= registry.ci.openshift.org/openshift/release:rhel-9-release-golang-1.25-openshift-4.22 +RUNTIME_IMAGE_NAME ?= registry.ci.openshift.org/openshift/release:rhel-9-release-golang-1.26-openshift-5.0 EXCLUDE_DIRS := _output/ dependencymagnet/ hack/ third_party/ tls/ tools/ vendor/ tests/ GO_PACKAGES :=$(addsuffix ...,$(addprefix ./,$(filter-out $(EXCLUDE_DIRS), $(wildcard */)))) @@ -220,7 +220,7 @@ write-available-featuresets: .PHONY: clean clean: - rm -f render write-available-featuresets models-schema + rm -f render write-available-featuresets rm -rf tools/_output VERSION ?= $(shell git describe --always --abbrev=7) diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go index e8aaa810f5..5d9f10374e 100644 --- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go +++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go @@ -660,7 +660,6 @@ type AzurePlatformStatus struct { // // +default={"dnsType": "PlatformDefault"} // +kubebuilder:default={"dnsType": "PlatformDefault"} - // +openshift:enable:FeatureGate=AzureClusterHostedDNSInstall // +optional CloudLoadBalancerConfig *CloudLoadBalancerConfig `json:"cloudLoadBalancerConfig,omitempty"` diff --git a/vendor/github.com/openshift/api/config/v1/types_ingress.go b/vendor/github.com/openshift/api/config/v1/types_ingress.go index 26e0ebf218..bb461e2f3e 100644 --- a/vendor/github.com/openshift/api/config/v1/types_ingress.go +++ b/vendor/github.com/openshift/api/config/v1/types_ingress.go @@ -64,10 +64,12 @@ type IngressSpec struct { // To determine the set of configurable Routes, look at namespace and name of entries in the // .status.componentRoutes list, where participating operators write the status of // configurable routes. + // A maximum of 250 component routes may be configured. // +optional // +listType=map // +listMapKey=namespace // +listMapKey=name + // +kubebuilder:validation:MaxItems=250 ComponentRoutes []ComponentRouteSpec `json:"componentRoutes,omitempty"` // requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes @@ -164,6 +166,14 @@ const ( Classic AWSLBType = "Classic" ) +// LabelValue is the value part of a Kubernetes label. +// A label value must be either empty or 1-63 characters, consisting of +// alphanumeric characters, '-', '_', or '.', starting and ending with +// an alphanumeric character. +// +kubebuilder:validation:MaxLength=63 +// +kubebuilder:validation:XValidation:rule="!format.labelValue().validate(self).hasValue()",message="label values must be valid Kubernetes label values (at most 63 characters, alphanumeric, '-', '_', or '.', must start and end with alphanumeric)" +type LabelValue string + // ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. // +kubebuilder:validation:Pattern="^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" // +kubebuilder:validation:MinLength=1 @@ -245,6 +255,32 @@ type ComponentRouteSpec struct { // the Secret specification for a serving certificate will not be needed. // +optional ServingCertKeyPairSecret SecretNameReference `json:"servingCertKeyPairSecret"` + + // labels defines additional labels to be applied to the route created + // for the component. These labels are used by the IngressController to + // determine which routes it should manage. Changing labels may cause the + // route to be reassigned to a different IngressController. + // When omitted, no additional labels are applied to the component route. + // When specified, labels must contain at least one entry, up to a maximum of 8. + // Label keys must be valid qualified names, consisting of a name segment and + // an optional prefix separated by a slash (/). The name segment must be at most + // 63 characters in length and must consist only of alphanumeric characters, + // dashes (-), underscores (_), and dots (.), and must start and end with + // alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + // at most 253 characters in length, consisting of dot-separated segments where + // each segment starts and ends with an alphanumeric character. + // Label values must be either empty or 1-63 characters, consisting of + // alphanumeric characters, dashes (-), underscores (_), or dots (.), + // starting and ending with an alphanumeric character. + // Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + // +openshift:enable:FeatureGate=IngressComponentRouteLabels + // +optional + // +mapType=granular + // +kubebuilder:validation:MinProperties=1 + // +kubebuilder:validation:MaxProperties=8 + // +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid qualified names, consisting of an optional DNS subdomain prefix of up to 253 characters followed by a slash and a name segment of 1-63 characters, that consists only of alphanumeric characters, dashes, underscores, and dots, and must start and end with an alphanumeric character" + // +kubebuilder:validation:XValidation:rule="self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') && !key.startsWith('openshift.io/'))",message="kubernetes.io/, k8s.io/, and openshift.io/ prefixed label keys are reserved and may not be used" + Labels map[string]LabelValue `json:"labels,omitempty"` } // ComponentRouteStatus contains information allowing configuration of a route's hostname and serving certificate. diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml index de0dd293a8..d883307d84 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -446,6 +446,434 @@ spec: ? has(self.requiredClaim) : !has(self.requiredClaim)' type: array x-kubernetes-list-type: atomic + externalClaimsSources: + description: |- + externalClaimsSources is an optional field that can be used to configure + sources, external to the token provided in a request, in which claims + should be fetched from and made available to the claim mapping process + that is used to build the identity of a token holder. + + For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint. + + When not specified, only claims present in the token itself will be available + in the claim mapping process. + + When specified, at least one external claim source must be specified and no more than 5 + sources may be specified. + All external claim sources must have unique claim mappings. + When an external source responds and resolves additional claims successfully, they will + be made available as claims during the claim mapping process. + Externally sourced claims with the same name as a claim existing within the token will + overwrite the claim data from the token with the externally sourced information. + If an external source does not respond, responds with an error, or the additional + claim data cannot be resolved from the response successfully it will not be + included in the claim data passed to the claim mapping process. + items: + description: ExternalClaimsSource provides the configuration + for a single external claim source. + properties: + authentication: + description: |- + authentication is an optional field that configures how the apiserver authenticates with an external claims source. + When not specified, anonymous authentication is used which means no 'Authorization' header + is sent in the HTTP request to fetch the external claims. + properties: + clientCredential: + description: |- + clientCredential configures the client credentials + and token endpoint to use to get an access token. + clientCredential is required when type is 'ClientCredential', and forbidden otherwise. + properties: + clientID: + description: |- + clientID is a required client identifier to use during the OAuth2 client credentials flow. + clientID must be at least 1 character in length, must not exceed 256 characters in length, + and must only contain printable ASCII characters. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: clientID must only contain printable + ASCII characters + rule: self.matches('^[[:print:]]+$') + clientSecret: + description: |- + clientSecret is a required reference to a Secret in the openshift-config namespace to be used + as the client secret during the OAuth2 client credentials flow. + + The key 'client-secret' is used to locate the client secret data in the Secret. + properties: + name: + description: |- + name is the required name of the Secret that exists in the openshift-config namespace. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with a + lowercase alphanumeric character, and + must only contain lowercase alphanumeric + characters, '-' or '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + scopes: + description: |- + scopes is an optional list of OAuth2 scopes to request when obtaining + an access token. + + If not specified, the token endpoint's default scopes + will be used. + + When specified, there must be at least 1 entry and must not exceed 16 entries. + Each entry must be at least 1 character in length and must not exceed 256 characters in length. + Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. + Entries must be unique. + items: + description: |- + OAuth2Scope is a string alias that represents an OAuth2 Scope as defined by https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.4 + Must be at least 1 character in length, must not exceed 256 characters in length and must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: scopes must only contain printable + ASCII characters excluding spaces, double + quotes and backslashes + rule: self.matches('^[!#-[\\]-~]+$') + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-type: set + tls: + description: |- + tls is an optional field that allows configuring the TLS + settings used to interact with the identity provider + as an OAuth2 client. + + When omitted, system default TLS settings will be used + for the OAuth2 client. + properties: + certificateAuthority: + description: |- + certificateAuthority is a required reference to a ConfigMap in the openshift-config + namespace that contains the CA certificate to use to validate TLS connections with the external claims source. + The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used + to verify the external source's TLS certificate. + properties: + name: + description: |- + name is the required name of the ConfigMap that exists in the openshift-config namespace. + The key "ca-bundle.crt" must be present and must contain the CA certificate to be used + to verify the external source's TLS certificate. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with + a lowercase alphanumeric character, + and must only contain lowercase alphanumeric + characters, '-' or '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - certificateAuthority + type: object + tokenEndpoint: + description: |- + tokenEndpoint is a required URL to query for an access token using + the client credential OAuth2 flow. + tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length. + tokenEndpoint must be a valid HTTPS URL. + tokenEndpoint must have a host and a path. + tokenEndpoint must not contain query parameters, fragments, + or user information (e.g., "user:password@host"). + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: tokenEndpoint must be a valid HTTPS + url + rule: isURL(self) + - message: tokenEndpoint must be a valid HTTPS + url + rule: isURL(self) && url(self).getScheme() == + 'https' + - message: tokenEndpoint must have a hostname + rule: isURL(self) && url(self).getHost() != + '' + - message: tokenEndpoint must have a path + rule: isURL(self) && url(self).getEscapedPath() + != '' + - message: tokenEndpoint must not have query parameters + rule: isURL(self) && url(self).getQuery() == + {} + - message: tokenEndpoint must not have a fragment + rule: isURL(self) && self.find('#(.+)$') == + '' + - message: tokenEndpoint must not have user info + rule: isURL(self) && !self.matches('^https://[^/]+@.+$') + required: + - clientID + - clientSecret + - tokenEndpoint + type: object + type: + description: |- + type is a required field that sets the type of + authentication method used by the authenticator + when fetching external claims. + + Allowed values are 'RequestProvidedToken' and 'ClientCredential'. + + When set to 'RequestProvidedToken', the authenticator will + use the token provided to the kube-apiserver as part of the + request to authenticate with the external claims source. + + When set to 'ClientCredential', the authenticator will + use the configured client-id, client-secret, and token endpoint + to fetch an access token using the OAuth2 client credentials grant + flow. The fetched access token will then be used to authenticate + with the external claims source. + enum: + - RequestProvidedToken + - ClientCredential + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: clientCredential is required when type is ClientCredential, + and forbidden otherwise + rule: 'self.type == ''ClientCredential'' ? has(self.clientCredential) + : !has(self.clientCredential)' + mappings: + description: |- + mappings is a required list of the claim + and response handling expression pairs + that produces the claims from the external source. + mappings must have at least 1 entry and must not exceed 16 entries. + Entries must have a unique name across all external claim sources. + items: + description: |- + SourcedClaimMapping configures the mapping behavior for a single external claim + from the response the apiserver received from the external claim source. + properties: + expression: + description: |- + expression is a required CEL expression that + will produce a value to be assigned to the claim. + The full response body from the request to the + external claim source is provided via the + `response.body` variable. + + The contents of the `response.body` variable varies based on the response received + from the external source. It is the responsibility of those configuring + this expression to understand what is returned from the external source. + + expression must be at least 1 character and must not exceed 1024 characters in length. + maxLength: 1024 + minLength: 1 + type: string + name: + description: |- + name is a required name of the claim that + will be produced and made available during + the claim-to-identity mapping process. + name must consist of only lowercase alpha characters and underscores ('_'). + name must be at least 1 character and must not exceed 256 characters in length. + maxLength: 256 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must consist of only lowercase alpha + characters and underscores + rule: self.matches('^[a-z_]+$') + required: + - expression + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + predicates: + description: |- + predicates is an optional list of constraints in + which claims should attempt to be fetched from this + external source. + + When omitted, claims are always fetched + from this external source. + + When specified, all predicates must evaluate to 'true' + before claims are attempted to be fetched from this external source. + predicates must have at least 1 entry and must not exceed 16 entries. + Entries must have unique expressions. + items: + description: |- + ExternalSourcePredicate configures a singular condition + that must return true before the external source is queried + to retrieve external claims. + properties: + expression: + description: |- + expression is a required CEL expression that + is used to determine whether or not an external + source should be used to fetch external claims. + + The expression must return a boolean value, + where true means that the source should be consulted + and false means that it should not. + + Claims from the token used for the request to the kube-apiserver + are made available via the `claims` variable. + + The contents of the `claims` variable varies based on the claims that are + present in the token being validated. It is the responsibility of those configuring this + field to understand what claims the identity provider includes when issuing tokens. + + expression must be at least 1 character and must not exceed 1024 characters in length. + maxLength: 1024 + minLength: 1 + type: string + required: + - expression + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - expression + x-kubernetes-list-type: map + tls: + description: |- + tls is an optional field that configures the http client TLS + settings when fetching external claims from this source. + + When omitted, system default TLS settings will be used + for fetching claims from the external source. + properties: + certificateAuthority: + description: |- + certificateAuthority is a required reference to a ConfigMap in the openshift-config + namespace that contains the CA certificate to use to validate TLS connections with the external claims source. + The key "ca-bundle.crt" must be present in the referenced ConfigMap and must contain the CA certificate to be used + to verify the external source's TLS certificate. + properties: + name: + description: |- + name is the required name of the ConfigMap that exists in the openshift-config namespace. + The key "ca-bundle.crt" must be present and must contain the CA certificate to be used + to verify the external source's TLS certificate. + + It must be at least 1 character in length, must not exceed 253 characters in length, + must start and end with a lowercase alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or '.'. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: name must start and end with a lowercase + alphanumeric character, and must only contain + lowercase alphanumeric characters, '-' or + '.' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - certificateAuthority + type: object + url: + description: |- + url is a required configuration of the URL + for which the external claims are located. + properties: + hostname: + description: |- + hostname is a required hostname for which the external claims are located. + + It must be a valid DNS subdomain name as per RFC1123. + + This means that it must start and end with a lowercase alphanumeric character, + must only consist of lowercase alphanumeric characters, '-', and '.'. + hostname may optionally specify a port in the format ':{port}'. + If a port is specified it must not exceed 65535. + + hostname must be at least 1 character in length. + When specifying a port, hostname must not exceed 259 characters in length. + When not specifying a port, hostname must not exceed 253 characters in length. + maxLength: 259 + minLength: 1 + type: string + x-kubernetes-validations: + - message: hostname must be a valid hostname + rule: isURL('https://'+self) + - message: hostname before port must start and end + with a lowercase alphanumeric character, and must + only contain lowercase alphanumeric characters, + '-' or '.' + rule: '!format.dns1123Subdomain().validate(self.split('':'')[0]).hasValue()' + - message: port must not exceed 65535 + rule: 'self.split('':'').size() > 1 ? int(self.split('':'')[1]) + <= 65535 : true' + pathExpression: + description: |- + pathExpression is a required CEL expression that returns a list + of string values used to construct the URL path. + Claims from the token used for the request to the kube-apiserver + are made available via the `claims` variable. + expression must be at least 1 character in length and must not exceed 1024 characters in length. + + Values in the returned list will be joined with the hostname using a forward slash + (`/`) as a separator. Values in the returned list do not need to include the forward slash. + If a forward slash is included in a returned value, it will be encoded as `%2F`. + + Example of a static path configuration: + + pathExpression: ['realms', 'k8s', 'protocol', 'openid-connect', 'userinfo'] + + The above example would resolve to the path: '/realms/k8s/protocol/openid-connect/userinfo' + + Example of a dynamic path configuration: + + pathExpression: "['admin', 'realms', 'k8s', 'users'] + [claims.sub] + ['groups']" + + Assuming 'claims.sub' is set to '12345', the above example would resolve to the path: '/admin/realms/k8s/users/12345/groups' + maxLength: 1024 + minLength: 1 + type: string + required: + - hostname + - pathExpression + type: object + required: + - mappings + - url + type: object + maxItems: 5 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: mapping names must be unique across all external + claim sources. + rule: self.all(s, s.mappings.all(m, self.filter(s2, s2.mappings.exists(m2, + m2.name == m.name)).size() == 1)) issuer: description: issuer is a required field that configures how the platform interacts with the identity provider and how diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml index 9aa182639b..7a720440ac 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_criocredentialproviderconfigs.crd.yaml @@ -209,7 +209,7 @@ spec: be 'cluster' rule: self.metadata.name == 'cluster' served: true - storage: true + storage: false subresources: status: {} - name: v1alpha1 @@ -404,6 +404,6 @@ spec: be 'cluster' rule: self.metadata.name == 'cluster' served: true - storage: false + storage: true subresources: status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml new file mode 100644 index 0000000000..92f2913150 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: CustomNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml new file mode 100644 index 0000000000..70c87e6e48 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml @@ -0,0 +1,546 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: Default + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000000..42e4209c6b --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: DevPreviewNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml similarity index 99% rename from vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml rename to vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml index 603d58d6d8..2c5b410efc 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml @@ -7,6 +7,7 @@ metadata: include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: OKD name: ingresses.config.openshift.io spec: group: config.openshift.io @@ -66,6 +67,7 @@ spec: To determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes. + A maximum of 250 component routes may be configured. items: description: ComponentRouteSpec allows for configuration of a route's hostname and serving certificate. @@ -113,6 +115,7 @@ spec: - name - namespace type: object + maxItems: 250 type: array x-kubernetes-list-map-keys: - namespace diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml new file mode 100644 index 0000000000..d7fc151b11 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml @@ -0,0 +1,593 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/470 + api.openshift.io/merged-by-featuregates: "true" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + release.openshift.io/bootstrap-required: "true" + release.openshift.io/feature-set: TechPreviewNoUpgrade + name: ingresses.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Ingress + listKind: IngressList + plural: ingresses + singular: ingress + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Ingress holds cluster-wide information about ingress, including the default ingress domain + used for routes. The canonical name is `cluster`. + + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds user settable values for configuration + properties: + appsDomain: + description: |- + appsDomain is an optional domain to use instead of the one specified + in the domain field when a Route is created without specifying an explicit + host. If appsDomain is nonempty, this value is used to generate default + host values for Route. Unlike domain, appsDomain may be modified after + installation. + This assumes a new ingresscontroller has been setup with a wildcard + certificate. + type: string + componentRoutes: + description: |- + componentRoutes is an optional list of routes that are managed by OpenShift components + that a cluster-admin is able to configure the hostname and serving certificate for. + The namespace and name of each route in this list should match an existing entry in the + status.componentRoutes list. + + To determine the set of configurable Routes, look at namespace and name of entries in the + .status.componentRoutes list, where participating operators write the status of + configurable routes. + A maximum of 250 component routes may be configured. + items: + description: ComponentRouteSpec allows for configuration of a route's + hostname and serving certificate. + properties: + hostname: + description: hostname is the hostname that should be used by + the route. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + labels: + additionalProperties: + description: |- + LabelValue is the value part of a Kubernetes label. + A label value must be either empty or 1-63 characters, consisting of + alphanumeric characters, '-', '_', or '.', starting and ending with + an alphanumeric character. + maxLength: 63 + type: string + x-kubernetes-validations: + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: '!format.labelValue().validate(self).hasValue()' + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. Changing labels may cause the + route to be reassigned to a different IngressController. + When omitted, no additional labels are applied to the component route. + When specified, labels must contain at least one entry, up to a maximum of 8. + Label keys must be valid qualified names, consisting of a name segment and + an optional prefix separated by a slash (/). The name segment must be at most + 63 characters in length and must consist only of alphanumeric characters, + dashes (-), underscores (_), and dots (.), and must start and end with + alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + at most 253 characters in length, consisting of dot-separated segments where + each segment starts and ends with an alphanumeric character. + Label values must be either empty or 1-63 characters, consisting of + alphanumeric characters, dashes (-), underscores (_), or dots (.), + starting and ending with an alphanumeric character. + Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + maxProperties: 8 + minProperties: 1 + type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid qualified names, consisting + of an optional DNS subdomain prefix of up to 253 characters + followed by a slash and a name segment of 1-63 characters, + that consists only of alphanumeric characters, dashes, underscores, + and dots, and must start and end with an alphanumeric character + rule: self.all(key, !format.qualifiedName().validate(key).hasValue()) + - message: kubernetes.io/, k8s.io/, and openshift.io/ prefixed + label keys are reserved and may not be used + rule: self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/') + && !key.startsWith('openshift.io/')) + name: + description: |- + name is the logical name of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of status.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + servingCertKeyPairSecret: + description: |- + servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. + The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. + If the custom hostname uses the default routing suffix of the cluster, + the Secret specification for a serving certificate will not be needed. + properties: + name: + description: name is the metadata.name of the referenced + secret + type: string + required: + - name + type: object + required: + - hostname + - name + - namespace + type: object + maxItems: 250 + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + domain: + description: |- + domain is used to generate a default host name for a route when the + route's host name is empty. The generated host name will follow this + pattern: "..". + + It is also used as the default wildcard domain suffix for ingress. The + default ingresscontroller domain will follow this pattern: "*.". + + Once set, changing domain is not currently supported. + type: string + x-kubernetes-validations: + - message: domain is immutable once set + rule: self == oldSelf + loadBalancer: + description: |- + loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure + provider of the current cluster and are required for Ingress Controller to work on OpenShift. + properties: + platform: + description: |- + platform holds configuration specific to the underlying + infrastructure provider for the ingress load balancers. + When omitted, this means the user has no opinion and the platform is left + to choose reasonable defaults. These defaults are subject to change over time. + properties: + aws: + description: aws contains settings specific to the Amazon + Web Services infrastructure provider. + properties: + type: + description: |- + type allows user to set a load balancer type. + When this field is set the default ingresscontroller will get created using the specified LBType. + If this field is not set then the default ingress controller of LBType Classic will be created. + Valid values are: + + * "Classic": A Classic Load Balancer that makes routing decisions at either + the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See + the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb + + * "NLB": A Network Load Balancer that makes routing decisions at the + transport layer (TCP/SSL). See the following for additional details: + + https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb + enum: + - NLB + - Classic + type: string + required: + - type + type: object + type: + description: |- + type is the underlying infrastructure provider for the cluster. + Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", + "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + and must handle unrecognized platforms as None if they do not support that platform. + enum: + - "" + - AWS + - Azure + - BareMetal + - GCP + - Libvirt + - OpenStack + - None + - VSphere + - oVirt + - IBMCloud + - KubeVirt + - EquinixMetal + - PowerVS + - AlibabaCloud + - Nutanix + - External + type: string + type: object + type: object + requiredHSTSPolicies: + description: |- + requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes + matching the domainPattern/s and namespaceSelector/s that are specified in the policy. + Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route + annotation, and affect route admission. + + A candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: + "haproxy.router.openshift.io/hsts_header" + E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains + + - For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, + then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route + is rejected. + - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies + determines the route's admission status. + - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, + then it may use any HSTS Policy annotation. + + The HSTS policy configuration may be changed after routes have already been created. An update to a previously + admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. + However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working. + + Note that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid. + items: + properties: + domainPatterns: + description: |- + domainPatterns is a list of domains for which the desired HSTS annotations are required. + If domainPatterns is specified and a route is created with a spec.host matching one of the domains, + the route must specify the HSTS Policy components described in the matching RequiredHSTSPolicy. + + The use of wildcards is allowed like this: *.foo.com matches everything under foo.com. + foo.com only matches foo.com, so to cover foo.com and everything under it, you must specify *both*. + items: + type: string + minItems: 1 + type: array + includeSubDomainsPolicy: + description: |- + includeSubDomainsPolicy means the HSTS Policy should apply to any subdomains of the host's + domain name. Thus, for the host bar.foo.com, if includeSubDomainsPolicy was set to RequireIncludeSubDomains: + - the host app.bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host bar.foo.com would inherit the HSTS Policy of bar.foo.com + - the host foo.com would NOT inherit the HSTS Policy of bar.foo.com + - the host def.foo.com would NOT inherit the HSTS Policy of bar.foo.com + enum: + - RequireIncludeSubDomains + - RequireNoIncludeSubDomains + - NoOpinion + type: string + maxAge: + description: |- + maxAge is the delta time range in seconds during which hosts are regarded as HSTS hosts. + If set to 0, it negates the effect, and hosts are removed as HSTS hosts. + If set to 0 and includeSubdomains is specified, all subdomains of the host are also removed as HSTS hosts. + maxAge is a time-to-live value, and if this policy is not refreshed on a client, the HSTS + policy will eventually expire on that client. + properties: + largestMaxAge: + description: |- + The largest allowed value (in seconds) of the RequiredHSTSPolicy max-age + This value can be left unspecified, in which case no upper limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + smallestMaxAge: + description: |- + The smallest allowed value (in seconds) of the RequiredHSTSPolicy max-age + Setting max-age=0 allows the deletion of an existing HSTS header from a host. This is a necessary + tool for administrators to quickly correct mistakes. + This value can be left unspecified, in which case no lower limit is enforced. + format: int32 + maximum: 2147483647 + minimum: 0 + type: integer + type: object + namespaceSelector: + description: |- + namespaceSelector specifies a label selector such that the policy applies only to those routes that + are in namespaces with labels that match the selector, and are in one of the DomainPatterns. + Defaults to the empty LabelSelector, which matches everything. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + preloadPolicy: + description: |- + preloadPolicy directs the client to include hosts in its host preload list so that + it never needs to do an initial load to get the HSTS header (note that this is not defined + in RFC 6797 and is therefore client implementation-dependent). + enum: + - RequirePreload + - RequireNoPreload + - NoOpinion + type: string + required: + - domainPatterns + type: object + type: array + type: object + status: + description: status holds observed values from the cluster. They may not + be overridden. + properties: + componentRoutes: + description: |- + componentRoutes is where participating operators place the current route status for routes whose + hostnames and serving certificates can be customized by the cluster-admin. + items: + description: ComponentRouteStatus contains information allowing + configuration of a route's hostname and serving certificate. + properties: + conditions: + description: |- + conditions are used to communicate the state of the componentRoutes entry. + + Supported conditions include Available, Degraded and Progressing. + + If available is true, the content served by the route can be accessed by users. This includes cases + where a default may continue to serve content while the customized route specified by the cluster-admin + is being configured. + + If Degraded is true, that means something has gone wrong trying to handle the componentRoutes entry. + The currentHostnames field may or may not be in effect. + + If Progressing is true, that means the component is taking some action related to the componentRoutes entry. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + consumingUsers: + description: consumingUsers is a slice of ServiceAccounts that + need to have read permission on the servingCertKeyPairSecret + secret. + items: + description: ConsumingUser is an alias for string which we + add validation to. Currently only service accounts are supported. + maxLength: 512 + minLength: 1 + pattern: ^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 5 + type: array + currentHostnames: + description: |- + currentHostnames is the list of current names used by the route. Typically, this list should consist of a single + hostname, but if multiple hostnames are supported by the route the operator may write multiple entries to this list. + items: + description: Hostname is a host name as defined by RFC-1123. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + minItems: 1 + type: array + defaultHostname: + description: defaultHostname is the hostname of this route prior + to customization. + pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ + type: string + name: + description: |- + name is the logical name of the route to customize. It does not have to be the actual name of a route resource + but it cannot be renamed. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 256 + minLength: 1 + type: string + namespace: + description: |- + namespace is the namespace of the route to customize. It must be a real namespace. Using an actual namespace + ensures that no two components will conflict and the same component can be installed multiple times. + + The namespace and name of this componentRoute must match a corresponding + entry in the list of spec.componentRoutes if the route is to be customized. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + relatedObjects: + description: relatedObjects is a list of resources which are + useful when debugging or inspecting how spec.componentRoutes + is applied. + items: + description: ObjectReference contains enough information to + let you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + minItems: 1 + type: array + required: + - defaultHostname + - name + - namespace + - relatedObjects + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + defaultPlacement: + description: |- + defaultPlacement is set at installation time to control which + nodes will host the ingress router pods by default. The options are + control-plane nodes or worker nodes. + + This field works by dictating how the Cluster Ingress Operator will + consider unset replicas and nodePlacement fields in IngressController + resources when creating the corresponding Deployments. + + See the documentation for the IngressController replicas and nodePlacement + fields for more information. + + When omitted, the default value is Workers + enum: + - ControlPlane + - Workers + - "" + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 3c75062bb7..4b194b226a 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -1640,6 +1640,13 @@ func (in *ComponentOverride) DeepCopy() *ComponentOverride { func (in *ComponentRouteSpec) DeepCopyInto(out *ComponentRouteSpec) { *out = *in out.ServingCertKeyPairSecret = in.ServingCertKeyPairSecret + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]LabelValue, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } @@ -3914,7 +3921,9 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { if in.ComponentRoutes != nil { in, out := &in.ComponentRoutes, &out.ComponentRoutes *out = make([]ComponentRouteSpec, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.RequiredHSTSPolicies != nil { in, out := &in.RequiredHSTSPolicies, &out.RequiredHSTSPolicies diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml index 5426057a88..76f78df82d 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml @@ -396,7 +396,6 @@ infrastructures.config.openshift.io: FeatureGates: - AWSClusterHostedDNSInstall - AWSDualStackInstall - - AzureClusterHostedDNSInstall - AzureDualStackInstall - DualReplica - DyanmicServiceEndpointIBMCloud @@ -427,7 +426,8 @@ ingresses.config.openshift.io: CRDName: ingresses.config.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - IngressComponentRouteLabels FilenameOperatorName: config-operator FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_10" diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index e853db9793..631f11a1b2 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -2283,6 +2283,7 @@ var map_ComponentRouteSpec = map[string]string{ "name": "name is the logical name of the route to customize.\n\nThe namespace and name of this componentRoute must match a corresponding entry in the list of status.componentRoutes if the route is to be customized.", "hostname": "hostname is the hostname that should be used by the route.", "servingCertKeyPairSecret": "servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. If the custom hostname uses the default routing suffix of the cluster, the Secret specification for a serving certificate will not be needed.", + "labels": "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. Changing labels may cause the route to be reassigned to a different IngressController. When omitted, no additional labels are applied to the component route. When specified, labels must contain at least one entry, up to a maximum of 8. Label keys must be valid qualified names, consisting of a name segment and an optional prefix separated by a slash (/). The name segment must be at most 63 characters in length and must consist only of alphanumeric characters, dashes (-), underscores (_), and dots (.), and must start and end with alphanumeric characters. The prefix, if specified, must be a DNS subdomain: at most 253 characters in length, consisting of dot-separated segments where each segment starts and ends with an alphanumeric character. Label values must be either empty or 1-63 characters, consisting of alphanumeric characters, dashes (-), underscores (_), or dots (.), starting and ending with an alphanumeric character. Keys with the \"kubernetes.io/\", \"k8s.io/\", and \"openshift.io/\" prefixes are reserved and may not be used.", } func (ComponentRouteSpec) SwaggerDoc() map[string]string { @@ -2337,7 +2338,7 @@ func (IngressPlatformSpec) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "domain": "domain is used to generate a default host name for a route when the route's host name is empty. The generated host name will follow this pattern: \"..\".\n\nIt is also used as the default wildcard domain suffix for ingress. The default ingresscontroller domain will follow this pattern: \"*.\".\n\nOnce set, changing domain is not currently supported.", "appsDomain": "appsDomain is an optional domain to use instead of the one specified in the domain field when a Route is created without specifying an explicit host. If appsDomain is nonempty, this value is used to generate default host values for Route. Unlike domain, appsDomain may be modified after installation. This assumes a new ingresscontroller has been setup with a wildcard certificate.", - "componentRoutes": "componentRoutes is an optional list of routes that are managed by OpenShift components that a cluster-admin is able to configure the hostname and serving certificate for. The namespace and name of each route in this list should match an existing entry in the status.componentRoutes list.\n\nTo determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes.", + "componentRoutes": "componentRoutes is an optional list of routes that are managed by OpenShift components that a cluster-admin is able to configure the hostname and serving certificate for. The namespace and name of each route in this list should match an existing entry in the status.componentRoutes list.\n\nTo determine the set of configurable Routes, look at namespace and name of entries in the .status.componentRoutes list, where participating operators write the status of configurable routes. A maximum of 250 component routes may be configured.", "requiredHSTSPolicies": "requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes matching the domainPattern/s and namespaceSelector/s that are specified in the policy. Each requiredHSTSPolicy must have at least a domainPattern and a maxAge to validate a route HSTS Policy route annotation, and affect route admission.\n\nA candidate route is checked for HSTS Policies if it has the HSTS Policy route annotation: \"haproxy.router.openshift.io/hsts_header\" E.g. haproxy.router.openshift.io/hsts_header: max-age=31536000;preload;includeSubDomains\n\n- For each candidate route, if it matches a requiredHSTSPolicy domainPattern and optional namespaceSelector, then the maxAge, preloadPolicy, and includeSubdomainsPolicy must be valid to be admitted. Otherwise, the route is rejected. - The first match, by domainPattern and optional namespaceSelector, in the ordering of the RequiredHSTSPolicies determines the route's admission status. - If the candidate route doesn't match any requiredHSTSPolicy domainPattern and optional namespaceSelector, then it may use any HSTS Policy annotation.\n\nThe HSTS policy configuration may be changed after routes have already been created. An update to a previously admitted route may then fail if the updated route does not conform to the updated HSTS policy configuration. However, changing the HSTS policy configuration will not cause a route that is already admitted to stop working.\n\nNote that if there are no RequiredHSTSPolicies, any HSTS Policy annotation on the route is valid.", "loadBalancer": "loadBalancer contains the load balancer details in general which are not only specific to the underlying infrastructure provider of the current cluster and are required for Ingress Controller to work on OpenShift.", } diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md index 43c2d694b0..c78d402696 100644 --- a/vendor/github.com/openshift/api/features.md +++ b/vendor/github.com/openshift/api/features.md @@ -12,12 +12,12 @@ | ShortCertRotation| | | | | | | | | | KarpenterOperator| | | | Enabled | | | | | | MutableTopology| | | | Enabled | | | | | +| AuthenticationComponentProxy| | | | Enabled | | | | Enabled | | ClusterAPIComputeInstall| | | Enabled | Enabled | | | | | | ClusterAPIControlPlaneInstall| | | Enabled | Enabled | | | | | | ClusterUpdatePreflight| | | Enabled | Enabled | | | | | | ConfidentialCluster| | | Enabled | Enabled | | | | | | Example2| | | Enabled | Enabled | | | | | -| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | | | | MachineAPIMigrationVSphere| | | Enabled | Enabled | | | | | | NetworkConnect| | | Enabled | Enabled | | | | | | NewOLMBoxCutterRuntime| | | | Enabled | | | | Enabled | @@ -59,6 +59,7 @@ | DyanmicServiceEndpointIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled | | EtcdBackendQuota| | | Enabled | Enabled | | | Enabled | Enabled | | Example| | | Enabled | Enabled | | | Enabled | Enabled | +| ExternalOIDCExternalClaimsSourcing| | | Enabled | Enabled | | | Enabled | Enabled | | ExternalOIDCWithUpstreamParity| | | Enabled | Enabled | | | Enabled | Enabled | | ExternalSnapshotMetadata| | | Enabled | Enabled | | | Enabled | Enabled | | GCPCustomAPIEndpoints| | | Enabled | Enabled | | | Enabled | Enabled | @@ -66,6 +67,7 @@ | GCPDualStackInstall| | | Enabled | Enabled | | | Enabled | Enabled | | HyperShiftOnlyDynamicResourceAllocation| Enabled | | Enabled | | Enabled | | Enabled | | | ImageModeStatusReporting| | | Enabled | Enabled | | | Enabled | Enabled | +| IngressComponentRouteLabels| | | Enabled | Enabled | | | Enabled | Enabled | | IngressControllerDynamicConfigurationManager| | | Enabled | Enabled | | | Enabled | Enabled | | IngressControllerMultipleHAProxyVersions| | | Enabled | Enabled | | | Enabled | Enabled | | IrreconcilableMachineConfig| | | Enabled | Enabled | | | Enabled | Enabled | @@ -95,7 +97,6 @@ | OSStreams| | Enabled | Enabled | Enabled | | Enabled | Enabled | Enabled | | AWSClusterHostedDNSInstall| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | AWSServiceLBNetworkSecurityGroup| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| AzureClusterHostedDNSInstall| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | AzureWorkloadIdentity| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BootImageSkewEnforcement| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BuildCSIVolumes| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | diff --git a/vendor/github.com/openshift/api/features/features.go b/vendor/github.com/openshift/api/features/features.go index 393bf7e6f1..b45bef7705 100644 --- a/vendor/github.com/openshift/api/features/features.go +++ b/vendor/github.com/openshift/api/features/features.go @@ -272,14 +272,6 @@ var ( enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() - FeatureGateAzureClusterHostedDNSInstall = newFeatureGate("AzureClusterHostedDNSInstall"). - reportProblemsToJiraComponent("Installer"). - contactPerson("sadasu"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1468"). - enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). - mustRegister() - FeatureGateMixedCPUsAllocation = newFeatureGate("MixedCPUsAllocation"). reportProblemsToJiraComponent("NodeTuningOperator"). contactPerson("titzhak"). @@ -368,6 +360,14 @@ var ( enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateAuthenticationComponentProxy = newFeatureGate("AuthenticationComponentProxy"). + reportProblemsToJiraComponent("authentication"). + contactPerson("liouk"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/2015"). + enable(inClusterProfile(SelfManaged), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + mustRegister() + FeatureGateExternalOIDCWithAdditionalClaimMappings = newFeatureGate("ExternalOIDCWithUIDAndExtraClaimMappings"). reportProblemsToJiraComponent("authentication"). contactPerson("bpalmer"). @@ -389,7 +389,7 @@ var ( contactPerson("bpalmer"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1907"). - enable(inDevPreviewNoUpgrade()). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() FeatureGateExample = newFeatureGate("Example"). @@ -666,6 +666,14 @@ var ( enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() + FeatureGateIngressComponentRouteLabels = newFeatureGate("IngressComponentRouteLabels"). + reportProblemsToJiraComponent("Management Console"). + contactPerson("leoli"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/2033"). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). + mustRegister() + FeatureGateIngressControllerMultipleHAProxyVersions = newFeatureGate("IngressControllerMultipleHAProxyVersions"). reportProblemsToJiraComponent("Networking/router"). contactPerson("miciah"). diff --git a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml index 4baab07508..6eb9f97c6a 100644 --- a/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml @@ -32,7 +32,6 @@ controllerconfigs.machineconfiguration.openshift.io: - AWSClusterHostedDNSInstall - AWSDualStackInstall - AWSEuropeanSovereignCloudInstall - - AzureClusterHostedDNSInstall - AzureDualStackInstall - DualReplica - DyanmicServiceEndpointIBMCloud diff --git a/vendor/github.com/openshift/api/operator/v1/types_authentication.go b/vendor/github.com/openshift/api/operator/v1/types_authentication.go index 4d0e9f6d68..55fc62a791 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/operator/v1/types_authentication.go @@ -33,6 +33,94 @@ type Authentication struct { type AuthenticationSpec struct { OperatorSpec `json:",inline"` + + // proxy configures proxy settings for outbound connections made + // by the authentication stack. When set, it replaces the + // cluster-wide proxy (proxy.config.openshift.io/cluster) + // entirely for authentication — individual fields are not + // inherited from the cluster-wide configuration. When omitted, + // the cluster-wide proxy is used if configured; otherwise no + // proxy is used. + // +openshift:enable:FeatureGate=AuthenticationComponentProxy + // +optional + Proxy AuthenticationProxyConfig `json:"proxy,omitzero"` +} + +// AuthenticationProxyConfig holds proxy configuration scoped to +// authentication components (the OAuth server and the cluster +// authentication operator). +// +kubebuilder:validation:MinProperties=1 +// +kubebuilder:validation:XValidation:rule="has(self.httpProxy) || has(self.httpsProxy)",message="at least one of httpProxy or httpsProxy must be specified" +type AuthenticationProxyConfig struct { + // httpProxy is the URL of the proxy for HTTP requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpProxy must not contain a fragment" + // +optional + HTTPProxy string `json:"httpProxy,omitempty"` + + // httpsProxy is the URL of the proxy for HTTPS requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpsProxy must be a valid URL" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getScheme() in ['http', 'https']",message="httpsProxy must use http or https scheme" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || size(url(self).getHostname()) > 0",message="httpsProxy must contain a hostname" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getEscapedPath() == '' || url(self).getEscapedPath() == '/'",message="httpsProxy must not contain a path" + // +kubebuilder:validation:XValidation:rule="!isURL(self) || url(self).getQuery().size() == 0",message="httpsProxy must not contain query parameters" + // +kubebuilder:validation:XValidation:rule="!self.matches('.*#.*')",message="httpsProxy must not contain a fragment" + // +optional + HTTPSProxy string `json:"httpsProxy,omitempty"` + + // noProxy is a list of hostnames and/or CIDRs and/or IPs for which + // the proxy should not be used. Must contain at least one entry + // when set. Each entry must be between 1 and 253 characters long + // and at most 64 entries are allowed. Duplicate + // entries are not permitted. Entries that are not valid hostnames, + // CIDRs, or IPs are silently ignored. Cluster-internal defaults + // (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + // automatically and do not need to be included. + // +listType=set + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=64 + // +kubebuilder:validation:items:MinLength=1 + // +kubebuilder:validation:items:MaxLength=253 + // +optional + NoProxy []string `json:"noProxy,omitempty"` + + // trustedCA is a reference to a ConfigMap in the openshift-config + // namespace containing a CA certificate bundle under the key + // "ca-bundle.crt". This bundle is appended to the system trust store + // used by authentication components for proxy TLS connections. + // When omitted, only the system trust store is used. + // +optional + TrustedCA AuthenticationConfigMapReference `json:"trustedCA,omitzero"` +} + +// AuthenticationConfigMapReference references a ConfigMap in the +// openshift-config namespace. +type AuthenticationConfigMapReference struct { + // name is the metadata.name of the referenced ConfigMap. + // Must be a valid DNS subdomain name (RFC 1123): at most 253 + // characters, only lowercase alphanumeric characters, '-' or + // '.', starting and ending with an alphanumeric character. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must be a valid DNS subdomain name: contain no more than 253 characters, contain only lowercase alphanumeric characters, '-' or '.', and start and end with an alphanumeric character" + // +required + Name string `json:"name,omitempty"` } type AuthenticationStatus struct { diff --git a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go index 51ecab70c8..fca2c808d3 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go +++ b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go @@ -506,16 +506,28 @@ type SecretsStoreSecretRotation struct { // CustomSecretRotation holds configuration for custom secret rotation behavior. // +kubebuilder:validation:MinProperties=1 type CustomSecretRotation struct { - // rotationPollIntervalSeconds is the minimum time in seconds between secret - // rotation attempts. The driver skips provider calls if less than this interval - // has elapsed since the last successful rotation. + // minimumRefreshAge is the minimum time in seconds between secret + // rotation attempts. Each time kubelet calls NodePublishVolume, the driver + // checks whether this interval has elapsed since the last successful provider + // call. If it has, the driver contacts the secret provider to fetch the latest + // secret values and updates the mounted volume. + // Setting this value below the kubelet syncFrequency (default: 1 minute) + // has no additional effect on the actual rotation cadence. // Must be at least 1 second and no more than 31560000 seconds (~1 year). // When omitted, this means no opinion and the platform is left to choose a // reasonable default, which is subject to change over time. // +kubebuilder:validation:Minimum=1 // +kubebuilder:validation:Maximum=31560000 // +optional - RotationPollIntervalSeconds int32 `json:"rotationPollIntervalSeconds,omitempty"` + MinimumRefreshAge int32 `json:"minimumRefreshAge,omitempty"` + + // --- TOMBSTONE --- + // rotationPollIntervalSeconds was the previous name for minimumRefreshAge. + // The field has been renamed to better reflect its semantics. + // The JSON key is reserved to prevent reuse. + // + // +optional + // RotationPollIntervalSeconds int32 `json:"rotationPollIntervalSeconds,omitempty"` } // SecretsStoreTokenRequest specifies a service account token audience configuration diff --git a/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go b/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go index 52bfdede3e..2d442d4b41 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go +++ b/vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go @@ -385,6 +385,31 @@ type IngressControllerSpec struct { // +kubebuilder:default:="Continue" // +default="Continue" ClosedClientConnectionPolicy IngressControllerClosedClientConnectionPolicy `json:"closedClientConnectionPolicy,omitempty"` + + // haproxyVersion specifies the HAProxy version to use for this + // IngressController. + // + // OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + // HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + // release introduces a new default HAProxy version, that HAProxy version + // becomes available as a pinnable value in subsequent OpenShift releases, + // providing a smooth migration path for administrators who want to defer + // HAProxy upgrades. + // + // Valid values for OpenShift 5.0: + // - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + // - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + // upgrades to future OpenShift releases + // - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + // be dropped in the next OpenShift release) + // + // If a specific HAProxy version is set and would become unsupported in a + // target cluster upgrade, a preflight check will block the cluster upgrade + // until this field is updated to unset or a supported version. + // + // +optional + // +openshift:enable:FeatureGate=IngressControllerMultipleHAProxyVersions + HAProxyVersion HAProxyVersion `json:"haproxyVersion,omitempty"` } // httpCompressionPolicy turns on compression for the specified MIME types. @@ -2263,6 +2288,19 @@ type IngressControllerStatus struct { // routeSelector is the actual routeSelector in use. // +optional RouteSelector *metav1.LabelSelector `json:"routeSelector,omitempty"` + + // effectiveHAProxyVersion reports the HAProxy version currently in use by + // this IngressController. This reflects the resolved value of the + // spec.haproxyVersion field. When omitted, the effective value has not yet + // been resolved by the operator or the feature is not enabled for this cluster. + // + // Examples for OpenShift 5.0: + // - "3.2": Using HAProxy 3.2 + // - "2.8": Using HAProxy 2.8 + // + // +optional + // +openshift:enable:FeatureGate=IngressControllerMultipleHAProxyVersions + EffectiveHAProxyVersion HAProxyVersion `json:"effectiveHAProxyVersion,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -2331,3 +2369,18 @@ const ( // server's response regardless of the client having closed the connection. IngressControllerClosedClientConnectionPolicyContinue IngressControllerClosedClientConnectionPolicy = "Continue" ) + +// HAProxyVersion is a string representing a HAProxy minor version in "X.Y" +// format. The allowed values are constrained by enum validation and vary by +// OpenShift release. +// +// +kubebuilder:validation:Enum="2.8";"3.2" +type HAProxyVersion string + +const ( + // HAProxyVersion28 represents HAProxy 2.8, shipped with OpenShift 4.22. + HAProxyVersion28 HAProxyVersion = "2.8" + + // HAProxyVersion32 represents HAProxy 3.2, introduced in OpenShift 5.0. + HAProxyVersion32 HAProxyVersion = "3.2" +) diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml index 3d5beb8c3c..a1d80bd5d9 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml index 9c6a6de7db..9e8ba13fd5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml index 196a05d604..03b3daf02a 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml @@ -85,6 +85,113 @@ spec: - Trace - TraceAll type: string + proxy: + description: |- + proxy configures proxy settings for outbound connections made + by the authentication stack. When set, it replaces the + cluster-wide proxy (proxy.config.openshift.io/cluster) + entirely for authentication — individual fields are not + inherited from the cluster-wide configuration. When omitted, + the cluster-wide proxy is used if configured; otherwise no + proxy is used. + minProperties: 1 + properties: + httpProxy: + description: |- + httpProxy is the URL of the proxy for HTTP requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpProxy must be a valid URL + rule: isURL(self) + - message: httpProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + httpsProxy: + description: |- + httpsProxy is the URL of the proxy for HTTPS requests. + Must be a valid URL with http or https scheme, a non-empty + hostname, and no path, query parameters, or fragment. + Userinfo (e.g. user:password@host) is allowed for proxy + authentication. Maximum length is 2048 characters. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: httpsProxy must be a valid URL + rule: isURL(self) + - message: httpsProxy must use http or https scheme + rule: '!isURL(self) || url(self).getScheme() in [''http'', ''https'']' + - message: httpsProxy must contain a hostname + rule: '!isURL(self) || size(url(self).getHostname()) > 0' + - message: httpsProxy must not contain a path + rule: '!isURL(self) || url(self).getEscapedPath() == '''' || + url(self).getEscapedPath() == ''/''' + - message: httpsProxy must not contain query parameters + rule: '!isURL(self) || url(self).getQuery().size() == 0' + - message: httpsProxy must not contain a fragment + rule: '!self.matches(''.*#.*'')' + noProxy: + description: |- + noProxy is a list of hostnames and/or CIDRs and/or IPs for which + the proxy should not be used. Must contain at least one entry + when set. Each entry must be between 1 and 253 characters long + and at most 64 entries are allowed. Duplicate + entries are not permitted. Entries that are not valid hostnames, + CIDRs, or IPs are silently ignored. Cluster-internal defaults + (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + automatically and do not need to be included. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-type: set + trustedCA: + description: |- + trustedCA is a reference to a ConfigMap in the openshift-config + namespace containing a CA certificate bundle under the key + "ca-bundle.crt". This bundle is appended to the system trust store + used by authentication components for proxy TLS connections. + When omitted, only the system trust store is used. + properties: + name: + description: |- + name is the metadata.name of the referenced ConfigMap. + Must be a valid DNS subdomain name (RFC 1123): at most 253 + characters, only lowercase alphanumeric characters, '-' or + '.', starting and ending with an alphanumeric character. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: 'name must be a valid DNS subdomain name: contain + no more than 253 characters, contain only lowercase alphanumeric + characters, ''-'' or ''.'', and start and end with an + alphanumeric character' + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: at least one of httpProxy or httpsProxy must be specified + rule: has(self.httpProxy) || has(self.httpsProxy) unsupportedConfigOverrides: description: |- unsupportedConfigOverrides overrides the final configuration that was computed by the operator. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml index f6f31fb401..ee5f83e6c5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_console_01_consoles.crd.yaml @@ -531,7 +531,7 @@ spec: x-kubernetes-list-type: atomic type: object group: - description: Group is the API Group of the + description: group is the API Group of the Resource. "*" means all. type: string labelSelector: @@ -584,32 +584,32 @@ spec: x-kubernetes-list-type: atomic type: object name: - description: Name is the name of the resource + description: name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. type: string namespace: description: |- - Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: - description: Resource is one of the existing + description: resource is one of the existing resource types. "*" means all. type: string subresource: - description: Subresource is one of the existing + description: subresource is one of the existing resource types. "" means none. type: string verb: - description: 'Verb is a kubernetes resource + description: 'verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.' type: string version: - description: Version is the API Version of + description: version is the API Version of the Resource. "*" means all. type: string type: object @@ -678,7 +678,7 @@ spec: x-kubernetes-list-type: atomic type: object group: - description: Group is the API Group of the + description: group is the API Group of the Resource. "*" means all. type: string labelSelector: @@ -731,32 +731,32 @@ spec: x-kubernetes-list-type: atomic type: object name: - description: Name is the name of the resource + description: name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. type: string namespace: description: |- - Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces "" (empty) is defaulted for LocalSubjectAccessReviews "" (empty) is empty for cluster-scoped resources "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: - description: Resource is one of the existing + description: resource is one of the existing resource types. "*" means all. type: string subresource: - description: Subresource is one of the existing + description: subresource is one of the existing resource types. "" means none. type: string verb: - description: 'Verb is a kubernetes resource + description: 'verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.' type: string version: - description: Version is the API Version of + description: version is the API Version of the Resource. "*" means all. type: string type: object diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml index 02b95f82fe..6c5120e1a6 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml index 56859fc15a..2ea91955ba 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml index f2be3b2eeb..d30ab1abe9 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml index de5190a522..118bcd135d 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml index 51ffcfd974..bd6f1a14d8 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml @@ -278,11 +278,15 @@ spec: Only valid when type is "Custom". minProperties: 1 properties: - rotationPollIntervalSeconds: + minimumRefreshAge: description: |- - rotationPollIntervalSeconds is the minimum time in seconds between secret - rotation attempts. The driver skips provider calls if less than this interval - has elapsed since the last successful rotation. + minimumRefreshAge is the minimum time in seconds between secret + rotation attempts. Each time kubelet calls NodePublishVolume, the driver + checks whether this interval has elapsed since the last successful provider + call. If it has, the driver contacts the secret provider to fetch the latest + secret values and updates the mounted volume. + Setting this value below the kubelet syncFrequency (default: 1 minute) + has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml index 66b935c916..3a55f7bdf0 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml index a9600ab839..0a638843f5 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml index ea37a2261d..27dcb3bab6 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml @@ -924,6 +924,32 @@ spec: required: - type type: object + haproxyVersion: + description: |- + haproxyVersion specifies the HAProxy version to use for this + IngressController. + + OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + release introduces a new default HAProxy version, that HAProxy version + becomes available as a pinnable value in subsequent OpenShift releases, + providing a smooth migration path for administrators who want to defer + HAProxy upgrades. + + Valid values for OpenShift 5.0: + - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + upgrades to future OpenShift releases + - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + be dropped in the next OpenShift release) + + If a specific HAProxy version is set and would become unsupported in a + target cluster upgrade, a preflight check will block the cluster upgrade + until this field is updated to unset or a supported version. + enum: + - "2.8" + - "3.2" + type: string httpCompression: description: |- httpCompression defines a policy for HTTP traffic compression. @@ -2601,6 +2627,20 @@ spec: domain: description: domain is the actual domain in use. type: string + effectiveHAProxyVersion: + description: |- + effectiveHAProxyVersion reports the HAProxy version currently in use by + this IngressController. This reflects the resolved value of the + spec.haproxyVersion field. When omitted, the effective value has not yet + been resolved by the operator or the feature is not enabled for this cluster. + + Examples for OpenShift 5.0: + - "3.2": Using HAProxy 3.2 + - "2.8": Using HAProxy 2.8 + enum: + - "2.8" + - "3.2" + type: string endpointPublishingStrategy: description: endpointPublishingStrategy is the actual strategy in use. diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go index 0a6726b199..3c244a9867 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go @@ -285,6 +285,22 @@ func (in *Authentication) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationConfigMapReference) DeepCopyInto(out *AuthenticationConfigMapReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationConfigMapReference. +func (in *AuthenticationConfigMapReference) DeepCopy() *AuthenticationConfigMapReference { + if in == nil { + return nil + } + out := new(AuthenticationConfigMapReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationList) DeepCopyInto(out *AuthenticationList) { *out = *in @@ -318,10 +334,33 @@ func (in *AuthenticationList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationProxyConfig) DeepCopyInto(out *AuthenticationProxyConfig) { + *out = *in + if in.NoProxy != nil { + in, out := &in.NoProxy, &out.NoProxy + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.TrustedCA = in.TrustedCA + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationProxyConfig. +func (in *AuthenticationProxyConfig) DeepCopy() *AuthenticationProxyConfig { + if in == nil { + return nil + } + out := new(AuthenticationProxyConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in in.OperatorSpec.DeepCopyInto(&out.OperatorSpec) + in.Proxy.DeepCopyInto(&out.Proxy) return } diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml index 9edb02ec6e..aab9e3564f 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -6,6 +6,7 @@ authentications.operator.openshift.io: Capability: "" Category: "" FeatureGates: + - AuthenticationComponentProxy - KMSEncryption FilenameOperatorName: authentication FilenameOperatorOrdering: "01" @@ -179,6 +180,7 @@ ingresscontrollers.operator.openshift.io: Category: "" FeatureGates: - IngressControllerDynamicConfigurationManager + - IngressControllerMultipleHAProxyVersions - TLSGroupPreferences FilenameOperatorName: ingress FilenameOperatorOrdering: "00" diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go index c6a047d2ce..271665a7ec 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go @@ -65,11 +65,21 @@ func (in Authentication) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.Authentication" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationConfigMapReference) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationConfigMapReference" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationList) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationList" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in AuthenticationProxyConfig) OpenAPIModelName() string { + return "com.github.openshift.api.operator.v1.AuthenticationProxyConfig" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuthenticationSpec) OpenAPIModelName() string { return "com.github.openshift.api.operator.v1.AuthenticationSpec" diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index a79189ffc2..114b5c7a68 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -118,6 +118,15 @@ func (Authentication) SwaggerDoc() map[string]string { return map_Authentication } +var map_AuthenticationConfigMapReference = map[string]string{ + "": "AuthenticationConfigMapReference references a ConfigMap in the openshift-config namespace.", + "name": "name is the metadata.name of the referenced ConfigMap. Must be a valid DNS subdomain name (RFC 1123): at most 253 characters, only lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character.", +} + +func (AuthenticationConfigMapReference) SwaggerDoc() map[string]string { + return map_AuthenticationConfigMapReference +} + var map_AuthenticationList = map[string]string{ "": "AuthenticationList is a collection of items\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -127,6 +136,26 @@ func (AuthenticationList) SwaggerDoc() map[string]string { return map_AuthenticationList } +var map_AuthenticationProxyConfig = map[string]string{ + "": "AuthenticationProxyConfig holds proxy configuration scoped to authentication components (the OAuth server and the cluster authentication operator).", + "httpProxy": "httpProxy is the URL of the proxy for HTTP requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "httpsProxy": "httpsProxy is the URL of the proxy for HTTPS requests. Must be a valid URL with http or https scheme, a non-empty hostname, and no path, query parameters, or fragment. Userinfo (e.g. user:password@host) is allowed for proxy authentication. Maximum length is 2048 characters.", + "noProxy": "noProxy is a list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. Must contain at least one entry when set. Each entry must be between 1 and 253 characters long and at most 64 entries are allowed. Duplicate entries are not permitted. Entries that are not valid hostnames, CIDRs, or IPs are silently ignored. Cluster-internal defaults (.cluster.local, .svc, 127.0.0.1, localhost) are always appended automatically and do not need to be included.", + "trustedCA": "trustedCA is a reference to a ConfigMap in the openshift-config namespace containing a CA certificate bundle under the key \"ca-bundle.crt\". This bundle is appended to the system trust store used by authentication components for proxy TLS connections. When omitted, only the system trust store is used.", +} + +func (AuthenticationProxyConfig) SwaggerDoc() map[string]string { + return map_AuthenticationProxyConfig +} + +var map_AuthenticationSpec = map[string]string{ + "proxy": "proxy configures proxy settings for outbound connections made by the authentication stack. When set, it replaces the cluster-wide proxy (proxy.config.openshift.io/cluster) entirely for authentication — individual fields are not inherited from the cluster-wide configuration. When omitted, the cluster-wide proxy is used if configured; otherwise no proxy is used.", +} + +func (AuthenticationSpec) SwaggerDoc() map[string]string { + return map_AuthenticationSpec +} + var map_AuthenticationStatus = map[string]string{ "oauthAPIServer": "oauthAPIServer holds status specific only to oauth-apiserver", } @@ -569,8 +598,8 @@ func (ClusterCSIDriverStatus) SwaggerDoc() map[string]string { } var map_CustomSecretRotation = map[string]string{ - "": "CustomSecretRotation holds configuration for custom secret rotation behavior.", - "rotationPollIntervalSeconds": "rotationPollIntervalSeconds is the minimum time in seconds between secret rotation attempts. The driver skips provider calls if less than this interval has elapsed since the last successful rotation. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", + "": "CustomSecretRotation holds configuration for custom secret rotation behavior.", + "minimumRefreshAge": "minimumRefreshAge is the minimum time in seconds between secret rotation attempts. Each time kubelet calls NodePublishVolume, the driver checks whether this interval has elapsed since the last successful provider call. If it has, the driver contacts the secret provider to fetch the latest secret values and updates the mounted volume. Setting this value below the kubelet syncFrequency (default: 1 minute) has no additional effect on the actual rotation cadence. Must be at least 1 second and no more than 31560000 seconds (~1 year). When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", } func (CustomSecretRotation) SwaggerDoc() map[string]string { @@ -1143,6 +1172,7 @@ var map_IngressControllerSpec = map[string]string{ "httpCompression": "httpCompression defines a policy for HTTP traffic compression. By default, there is no HTTP compression.", "idleConnectionTerminationPolicy": "idleConnectionTerminationPolicy maps directly to HAProxy's idle-close-on-response option and controls whether HAProxy keeps idle frontend connections open during a soft stop (router reload).\n\nAllowed values for this field are \"Immediate\" and \"Deferred\". The default value is \"Immediate\".\n\nWhen set to \"Immediate\", idle connections are closed immediately during router reloads. This ensures immediate propagation of route changes but may impact clients sensitive to connection resets.\n\nWhen set to \"Deferred\", HAProxy will maintain idle connections during a soft reload instead of closing them immediately. These connections remain open until any of the following occurs:\n\n - A new request is received on the connection, in which\n case HAProxy handles it in the old process and closes\n the connection after sending the response.\n\n - HAProxy's `timeout http-keep-alive` duration expires.\n By default this is 300 seconds, but it can be changed\n using httpKeepAliveTimeout tuning option.\n\n - The client's keep-alive timeout expires, causing the\n client to close the connection.\n\nSetting Deferred can help prevent errors in clients or load balancers that do not properly handle connection resets. Additionally, this option allows you to retain the pre-2.4 HAProxy behaviour: in HAProxy version 2.2 (OpenShift versions < 4.14), maintaining idle connections during a soft reload was the default behaviour, but starting with HAProxy 2.4, the default changed to closing idle connections immediately.\n\nImportant Consideration:\n\n - Using Deferred will result in temporary inconsistencies\n for the first request on each persistent connection\n after a route update and router reload. This request\n will be processed by the old HAProxy process using its\n old configuration. Subsequent requests will use the\n updated configuration.\n\nOperational Considerations:\n\n - Keeping idle connections open during reloads may lead\n to an accumulation of old HAProxy processes if\n connections remain idle for extended periods,\n especially in environments where frequent reloads\n occur.\n\n - Consider monitoring the number of HAProxy processes in\n the router pods when Deferred is set.\n\n - You may need to enable or adjust the\n `ingress.operator.openshift.io/hard-stop-after`\n duration (configured via an annotation on the\n IngressController resource) in environments with\n frequent reloads to prevent resource exhaustion.", "closedClientConnectionPolicy": "closedClientConnectionPolicy controls how the IngressController behaves when the client closes the TCP connection while the TLS handshake or HTTP request is in progress. This option maps directly to HAProxy’s \"abortonclose\" option.\n\nValid values are: \"Abort\" and \"Continue\". The default value is \"Continue\".\n\nWhen set to \"Abort\", the router will stop processing the TLS handshake if it is in progress, and it will not send an HTTP request to the backend server if the request has not yet been sent when the client closes the connection.\n\nWhen set to \"Continue\", the router will complete the TLS handshake if it is in progress, or send an HTTP request to the backend server and wait for the backend server's response, regardless of whether the client has closed the connection.\n\nSetting \"Abort\" can help free CPU resources otherwise spent on TLS computation for connections the client has already closed, and can reduce request queue size, thereby reducing the load on saturated backend servers.\n\nImportant Considerations:\n\n - The default policy (\"Continue\") is HTTP-compliant, and requests\n for aborted client connections will still be served.\n Use the \"Continue\" policy to allow a client to send a request\n and then immediately close its side of the connection while\n still receiving a response on the half-closed connection.\n\n - When clients use keep-alive connections, the most common case for premature\n closure is when the user wants to cancel the transfer or when a timeout\n occurs. In that case, the \"Abort\" policy may be used to reduce resource consumption.\n\n - Using RSA keys larger than 2048 bits can significantly slow down\n TLS computations. Consider using the \"Abort\" policy to reduce CPU usage.", + "haproxyVersion": "haproxyVersion specifies the HAProxy version to use for this IngressController.\n\nOpenShift 5.0 introduces HAProxy 3.2 as its default version and supports HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift release introduces a new default HAProxy version, that HAProxy version becomes available as a pinnable value in subsequent OpenShift releases, providing a smooth migration path for administrators who want to defer HAProxy upgrades.\n\nValid values for OpenShift 5.0: - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) - \"3.2\": Explicitly pins HAProxy 3.2 for preservation during cluster\n upgrades to future OpenShift releases\n- \"2.8\": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will\n be dropped in the next OpenShift release)\n\nIf a specific HAProxy version is set and would become unsupported in a target cluster upgrade, a preflight check will block the cluster upgrade until this field is updated to unset or a supported version.", } func (IngressControllerSpec) SwaggerDoc() map[string]string { @@ -1160,6 +1190,7 @@ var map_IngressControllerStatus = map[string]string{ "observedGeneration": "observedGeneration is the most recent generation observed.", "namespaceSelector": "namespaceSelector is the actual namespaceSelector in use.", "routeSelector": "routeSelector is the actual routeSelector in use.", + "effectiveHAProxyVersion": "effectiveHAProxyVersion reports the HAProxy version currently in use by this IngressController. This reflects the resolved value of the spec.haproxyVersion field. When omitted, the effective value has not yet been resolved by the operator or the feature is not enabled for this cluster.\n\nExamples for OpenShift 5.0: - \"3.2\": Using HAProxy 3.2 - \"2.8\": Using HAProxy 2.8", } func (IngressControllerStatus) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go b/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go index 719893f8a5..291cedc145 100644 --- a/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go +++ b/vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go @@ -244,13 +244,24 @@ type ClusterAPIInstallerComponentSource struct { Image ClusterAPIInstallerComponentImage `json:"image,omitzero"` } -// ImageDigestFormat is a type that conforms to the format host[:port][/namespace]/name@sha256:. +// The image name validation regex is derived from the OCI distribution reference: +// https://github.com/distribution/reference/blob/main/regexp.go +// It matches: domainAndPort "/" remoteName +// +// domainAndPort = (domainName | "[" ipv6 "]") [ ":" port ] +// domainName = label ("." label)* +// label = alphanumeric, may contain hyphens but must start/end with [a-zA-Z0-9] +// remoteName = pathComponent ("/" pathComponent)* +// pathComponent = [a-z0-9]+ separated by ".", "_", "__", or "-"+ + +// ImageDigestFormat is a type that conforms to the format host[:port][/namespace[/namespace...]]/name@sha256:. +// The host may be a dotted domain name (including IPv4 addresses like 192.168.1.1), or an IPv6 address in brackets (e.g. [fd00::1]). // The digest must be 64 characters long, and consist only of lowercase hexadecimal characters, a-f and 0-9. // The length of the field must be between 1 to 447 characters. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=447 // +kubebuilder:validation:XValidation:rule=`(self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$'))`,message="the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" -// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" +// +kubebuilder:validation:XValidation:rule=`(self.split('@')[0].matches('^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\\[(?:[a-fA-F0-9:]+)\\])(?::[0-9]+)?/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*$'))`,message="the OCI Image name should follow the host[:port][/namespace[/namespace...]]/name format, where host is a domain name, IPv4, or IPv6 address in brackets" type ImageDigestFormat string // ClusterAPIInstallerComponentImage defines an image source for a component. diff --git a/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml b/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml index 67d384d3eb..501ad52418 100644 --- a/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml +++ b/vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis.crd.yaml @@ -172,9 +172,10 @@ spec: valid '@sha256:' suffix, where '' is 64 characters long rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) - - message: the OCI Image name should follow the host[:port][/namespace]/name - format, resembling a valid URL without the scheme - rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + - message: the OCI Image name should follow the host[:port][/namespace[/namespace...]]/name + format, where host is a domain name, IPv4, or + IPv6 address in brackets + rule: (self.split('@')[0].matches('^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))*|\\[(?:[a-fA-F0-9:]+)\\])(?::[0-9]+)?/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*)*$')) required: - profile - ref diff --git a/vendor/github.com/openshift/api/osin/v1/types.go b/vendor/github.com/openshift/api/osin/v1/types.go index 35eb3ee8b0..3f3af3cfa5 100644 --- a/vendor/github.com/openshift/api/osin/v1/types.go +++ b/vendor/github.com/openshift/api/osin/v1/types.go @@ -80,6 +80,11 @@ type OAuthConfig struct { // templates allow you to customize pages like the login page. Templates *OAuthTemplates `json:"templates"` + + // proxyTrustedCA is an optional path to a PEM-encoded CA bundle used to + // verify connections to an HTTPS proxy during outbound IdP requests. + // When omitted, proxy connections use the system trust roots only. + ProxyTrustedCA string `json:"proxyTrustedCA,omitempty"` } // OAuthTemplates allow for customization of pages like the login page diff --git a/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go index 890928a7a4..6594af9451 100644 --- a/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go @@ -154,6 +154,7 @@ var map_OAuthConfig = map[string]string{ "sessionConfig": "sessionConfig hold information about configuring sessions.", "tokenConfig": "tokenConfig contains options for authorization and access tokens", "templates": "templates allow you to customize pages like the login page.", + "proxyTrustedCA": "proxyTrustedCA is an optional path to a PEM-encoded CA bundle used to verify connections to an HTTPS proxy during outbound IdP requests. When omitted, proxy connections use the system trust roots only.", } func (OAuthConfig) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/client-go/apps/applyconfigurations/internal/internal.go b/vendor/github.com/openshift/client-go/apps/applyconfigurations/internal/internal.go index 437388ff7a..d34284e991 100644 --- a/vendor/github.com/openshift/client-go/apps/applyconfigurations/internal/internal.go +++ b/vendor/github.com/openshift/client-go/apps/applyconfigurations/internal/internal.go @@ -1579,6 +1579,16 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.core.v1.PodSchedulingGroup + map: + fields: + - name: podGroupName + type: + scalar: string + unions: + - fields: + - fieldName: podGroupName + discriminatorValue: PodGroupName - name: io.k8s.api.core.v1.PodSecurityContext map: fields: @@ -1766,6 +1776,9 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name + - name: schedulingGroup + type: + namedType: io.k8s.api.core.v1.PodSchedulingGroup - name: securityContext type: namedType: io.k8s.api.core.v1.PodSecurityContext @@ -1810,9 +1823,6 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name - - name: workloadRef - type: - namedType: io.k8s.api.core.v1.WorkloadReference - name: io.k8s.api.core.v1.PodTemplateSpec map: fields: @@ -2511,20 +2521,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: runAsUserName type: scalar: string -- name: io.k8s.api.core.v1.WorkloadReference - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: podGroup - type: - scalar: string - default: "" - - name: podGroupReplicaKey - type: - scalar: string - name: io.k8s.apimachinery.pkg.api.resource.Quantity scalar: untyped - name: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1 diff --git a/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutespec.go b/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutespec.go index f4e3838447..990a7230a1 100644 --- a/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutespec.go +++ b/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/componentroutespec.go @@ -28,6 +28,24 @@ type ComponentRouteSpecApplyConfiguration struct { // If the custom hostname uses the default routing suffix of the cluster, // the Secret specification for a serving certificate will not be needed. ServingCertKeyPairSecret *SecretNameReferenceApplyConfiguration `json:"servingCertKeyPairSecret,omitempty"` + // labels defines additional labels to be applied to the route created + // for the component. These labels are used by the IngressController to + // determine which routes it should manage. Changing labels may cause the + // route to be reassigned to a different IngressController. + // When omitted, no additional labels are applied to the component route. + // When specified, labels must contain at least one entry, up to a maximum of 8. + // Label keys must be valid qualified names, consisting of a name segment and + // an optional prefix separated by a slash (/). The name segment must be at most + // 63 characters in length and must consist only of alphanumeric characters, + // dashes (-), underscores (_), and dots (.), and must start and end with + // alphanumeric characters. The prefix, if specified, must be a DNS subdomain: + // at most 253 characters in length, consisting of dot-separated segments where + // each segment starts and ends with an alphanumeric character. + // Label values must be either empty or 1-63 characters, consisting of + // alphanumeric characters, dashes (-), underscores (_), or dots (.), + // starting and ending with an alphanumeric character. + // Keys with the "kubernetes.io/", "k8s.io/", and "openshift.io/" prefixes are reserved and may not be used. + Labels map[string]configv1.LabelValue `json:"labels,omitempty"` } // ComponentRouteSpecApplyConfiguration constructs a declarative configuration of the ComponentRouteSpec type for use with @@ -67,3 +85,17 @@ func (b *ComponentRouteSpecApplyConfiguration) WithServingCertKeyPairSecret(valu b.ServingCertKeyPairSecret = value return b } + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ComponentRouteSpecApplyConfiguration) WithLabels(entries map[string]configv1.LabelValue) *ComponentRouteSpecApplyConfiguration { + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]configv1.LabelValue, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} diff --git a/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ingressspec.go b/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ingressspec.go index ed804bd000..50d8252389 100644 --- a/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ingressspec.go +++ b/vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ingressspec.go @@ -30,6 +30,7 @@ type IngressSpecApplyConfiguration struct { // To determine the set of configurable Routes, look at namespace and name of entries in the // .status.componentRoutes list, where participating operators write the status of // configurable routes. + // A maximum of 250 component routes may be configured. ComponentRoutes []ComponentRouteSpecApplyConfiguration `json:"componentRoutes,omitempty"` // requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes // matching the domainPattern/s and namespaceSelector/s that are specified in the policy. diff --git a/vendor/github.com/openshift/client-go/config/applyconfigurations/internal/internal.go b/vendor/github.com/openshift/client-go/config/applyconfigurations/internal/internal.go index ba8ba86cf8..d71561a0bf 100644 --- a/vendor/github.com/openshift/client-go/config/applyconfigurations/internal/internal.go +++ b/vendor/github.com/openshift/client-go/config/applyconfigurations/internal/internal.go @@ -562,15 +562,45 @@ var schemaYAML = typed.YAMLObject(`types: namedType: com.github.openshift.api.config.v1.BuildOverrides default: {} - name: com.github.openshift.api.config.v1.CRIOCredentialProviderConfig - scalar: untyped - list: - elementType: - namedType: __untyped_atomic_ - elementRelationship: atomic map: - elementType: - namedType: __untyped_deduced_ - elementRelationship: separable + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: com.github.openshift.api.config.v1.CRIOCredentialProviderConfigSpec + - name: status + type: + namedType: com.github.openshift.api.config.v1.CRIOCredentialProviderConfigStatus + default: {} +- name: com.github.openshift.api.config.v1.CRIOCredentialProviderConfigSpec + map: + fields: + - name: matchImages + type: + list: + elementType: + scalar: string + elementRelationship: associative +- name: com.github.openshift.api.config.v1.CRIOCredentialProviderConfigStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type - name: com.github.openshift.api.config.v1.ClientCredentialConfig map: fields: @@ -956,6 +986,12 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" + - name: labels + type: + map: + elementType: + scalar: string + elementRelationship: separable - name: name type: scalar: string @@ -1663,9 +1699,17 @@ var schemaYAML = typed.YAMLObject(`types: - name: com.github.openshift.api.config.v1.HubSourceStatus map: fields: + - name: disabled + type: + scalar: boolean + default: false - name: message type: scalar: string + - name: name + type: + scalar: string + default: "" - name: status type: scalar: string diff --git a/vendor/github.com/openshift/client-go/config/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/config/clientset/versioned/fake/clientset_generated.go index 0a3678b49a..f69c38e77b 100644 --- a/vendor/github.com/openshift/client-go/config/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/config/clientset/versioned/fake/clientset_generated.go @@ -23,10 +23,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -72,7 +68,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -87,6 +83,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/apiserver.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/apiserver.go index 7fa3cc852e..e7107fe1f9 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/apiserver.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/apiserver.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type aPIServerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredAPIServerInformer(client, resyncPeriod, indexers, nil) + return NewAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredAPIServerInformer constructs a new informer for APIServer type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewAPIServerInformerWithOptions constructs a new informer for APIServer type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewAPIServerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "apiservers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().APIServers().List(context.Background(), options) + return client.ConfigV1().APIServers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().APIServers().Watch(context.Background(), options) + return client.ConfigV1().APIServers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().APIServers().List(ctx, options) + return client.ConfigV1().APIServers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().APIServers().Watch(ctx, options) + return client.ConfigV1().APIServers().Watch(ctx, opts) }, }, client), &apiconfigv1.APIServer{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *aPIServerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredAPIServerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *aPIServerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/authentication.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/authentication.go index 902537e4ec..b3aca8cd2c 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/authentication.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/authentication.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type authenticationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewAuthenticationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredAuthenticationInformer(client, resyncPeriod, indexers, nil) + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredAuthenticationInformer constructs a new informer for Authentication type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredAuthenticationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewAuthenticationInformerWithOptions constructs a new informer for Authentication type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewAuthenticationInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "authentications"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Authentications().List(context.Background(), options) + return client.ConfigV1().Authentications().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Authentications().Watch(context.Background(), options) + return client.ConfigV1().Authentications().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Authentications().List(ctx, options) + return client.ConfigV1().Authentications().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Authentications().Watch(ctx, options) + return client.ConfigV1().Authentications().Watch(ctx, opts) }, }, client), &apiconfigv1.Authentication{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *authenticationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredAuthenticationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *authenticationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/build.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/build.go index f1680fe8b2..3cfc51f9a2 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/build.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/build.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type buildInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewBuildInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredBuildInformer(client, resyncPeriod, indexers, nil) + return NewBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredBuildInformer constructs a new informer for Build type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredBuildInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewBuildInformerWithOptions constructs a new informer for Build type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewBuildInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "builds"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Builds().List(context.Background(), options) + return client.ConfigV1().Builds().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Builds().Watch(context.Background(), options) + return client.ConfigV1().Builds().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Builds().List(ctx, options) + return client.ConfigV1().Builds().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Builds().Watch(ctx, options) + return client.ConfigV1().Builds().Watch(ctx, opts) }, }, client), &apiconfigv1.Build{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *buildInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredBuildInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *buildInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterimagepolicy.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterimagepolicy.go index d172bdecf5..8825c60f1f 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterimagepolicy.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterimagepolicy.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterImagePolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterImagePolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterImagePolicyInformer(client, resyncPeriod, indexers, nil) + return NewClusterImagePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterImagePolicyInformer constructs a new informer for ClusterImagePolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterImagePolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterImagePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterImagePolicyInformerWithOptions constructs a new informer for ClusterImagePolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterImagePolicyInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "clusterimagepolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterImagePolicies().List(context.Background(), options) + return client.ConfigV1().ClusterImagePolicies().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterImagePolicies().Watch(context.Background(), options) + return client.ConfigV1().ClusterImagePolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterImagePolicies().List(ctx, options) + return client.ConfigV1().ClusterImagePolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterImagePolicies().Watch(ctx, options) + return client.ConfigV1().ClusterImagePolicies().Watch(ctx, opts) }, }, client), &apiconfigv1.ClusterImagePolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterImagePolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterImagePolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterImagePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterImagePolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusteroperator.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusteroperator.go index 0b524565e9..a49d4f314b 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusteroperator.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusteroperator.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterOperatorInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterOperatorInformer(client, resyncPeriod, indexers, nil) + return NewClusterOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterOperatorInformer constructs a new informer for ClusterOperator type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterOperatorInformerWithOptions constructs a new informer for ClusterOperator type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterOperatorInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "clusteroperators"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterOperators().List(context.Background(), options) + return client.ConfigV1().ClusterOperators().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterOperators().Watch(context.Background(), options) + return client.ConfigV1().ClusterOperators().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterOperators().List(ctx, options) + return client.ConfigV1().ClusterOperators().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterOperators().Watch(ctx, options) + return client.ConfigV1().ClusterOperators().Watch(ctx, opts) }, }, client), &apiconfigv1.ClusterOperator{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterOperatorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterOperatorInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterOperatorInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterversion.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterversion.go index 5ba9f5e2e8..aeb49b2791 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterversion.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/clusterversion.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterVersionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterVersionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterVersionInformer(client, resyncPeriod, indexers, nil) + return NewClusterVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterVersionInformer constructs a new informer for ClusterVersion type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterVersionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterVersionInformerWithOptions constructs a new informer for ClusterVersion type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterVersionInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "clusterversions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterVersions().List(context.Background(), options) + return client.ConfigV1().ClusterVersions().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterVersions().Watch(context.Background(), options) + return client.ConfigV1().ClusterVersions().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterVersions().List(ctx, options) + return client.ConfigV1().ClusterVersions().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ClusterVersions().Watch(ctx, options) + return client.ConfigV1().ClusterVersions().Watch(ctx, opts) }, }, client), &apiconfigv1.ClusterVersion{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterVersionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterVersionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterVersionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/console.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/console.go index 8c4a901dc6..66074549d3 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/console.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/console.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type consoleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewConsoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredConsoleInformer(client, resyncPeriod, indexers, nil) + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredConsoleInformer constructs a new informer for Console type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredConsoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewConsoleInformerWithOptions constructs a new informer for Console type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConsoleInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "consoles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Consoles().List(context.Background(), options) + return client.ConfigV1().Consoles().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Consoles().Watch(context.Background(), options) + return client.ConfigV1().Consoles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Consoles().List(ctx, options) + return client.ConfigV1().Consoles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Consoles().Watch(ctx, options) + return client.ConfigV1().Consoles().Watch(ctx, opts) }, }, client), &apiconfigv1.Console{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *consoleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredConsoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *consoleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/criocredentialproviderconfig.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/criocredentialproviderconfig.go index 6f7db0c7bd..aaae42ac3d 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/criocredentialproviderconfig.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/criocredentialproviderconfig.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type cRIOCredentialProviderConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCRIOCredentialProviderConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCRIOCredentialProviderConfigInformer(client, resyncPeriod, indexers, nil) + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCRIOCredentialProviderConfigInformer constructs a new informer for CRIOCredentialProviderConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCRIOCredentialProviderConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCRIOCredentialProviderConfigInformerWithOptions constructs a new informer for CRIOCredentialProviderConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCRIOCredentialProviderConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "criocredentialproviderconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().CRIOCredentialProviderConfigs().List(context.Background(), options) + return client.ConfigV1().CRIOCredentialProviderConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().CRIOCredentialProviderConfigs().Watch(context.Background(), options) + return client.ConfigV1().CRIOCredentialProviderConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().CRIOCredentialProviderConfigs().List(ctx, options) + return client.ConfigV1().CRIOCredentialProviderConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().CRIOCredentialProviderConfigs().Watch(ctx, options) + return client.ConfigV1().CRIOCredentialProviderConfigs().Watch(ctx, opts) }, }, client), &apiconfigv1.CRIOCredentialProviderConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cRIOCredentialProviderConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCRIOCredentialProviderConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cRIOCredentialProviderConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/dns.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/dns.go index 2e8ae5b572..9a235ad346 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/dns.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/dns.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type dNSInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDNSInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDNSInformer(client, resyncPeriod, indexers, nil) + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDNSInformer constructs a new informer for DNS type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDNSInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDNSInformerWithOptions constructs a new informer for DNS type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDNSInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "dnss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().DNSes().List(context.Background(), options) + return client.ConfigV1().DNSes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().DNSes().Watch(context.Background(), options) + return client.ConfigV1().DNSes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().DNSes().List(ctx, options) + return client.ConfigV1().DNSes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().DNSes().Watch(ctx, options) + return client.ConfigV1().DNSes().Watch(ctx, opts) }, }, client), &apiconfigv1.DNS{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *dNSInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDNSInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *dNSInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/featuregate.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/featuregate.go index e26cdb9ac3..f8956e01e0 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/featuregate.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/featuregate.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type featureGateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFeatureGateInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFeatureGateInformer(client, resyncPeriod, indexers, nil) + return NewFeatureGateInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredFeatureGateInformer constructs a new informer for FeatureGate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredFeatureGateInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewFeatureGateInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewFeatureGateInformerWithOptions constructs a new informer for FeatureGate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFeatureGateInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "featuregates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().FeatureGates().List(context.Background(), options) + return client.ConfigV1().FeatureGates().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().FeatureGates().Watch(context.Background(), options) + return client.ConfigV1().FeatureGates().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().FeatureGates().List(ctx, options) + return client.ConfigV1().FeatureGates().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().FeatureGates().Watch(ctx, options) + return client.ConfigV1().FeatureGates().Watch(ctx, opts) }, }, client), &apiconfigv1.FeatureGate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *featureGateInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFeatureGateInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFeatureGateInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *featureGateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/image.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/image.go index 0992eba82b..81f93f678d 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/image.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/image.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageInformer(client, resyncPeriod, indexers, nil) + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageInformer constructs a new informer for Image type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageInformerWithOptions constructs a new informer for Image type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "images"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Images().List(context.Background(), options) + return client.ConfigV1().Images().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Images().Watch(context.Background(), options) + return client.ConfigV1().Images().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Images().List(ctx, options) + return client.ConfigV1().Images().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Images().Watch(ctx, options) + return client.ConfigV1().Images().Watch(ctx, opts) }, }, client), &apiconfigv1.Image{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagecontentpolicy.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagecontentpolicy.go index 9960674341..36e7af7997 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagecontentpolicy.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagecontentpolicy.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageContentPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageContentPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageContentPolicyInformer(client, resyncPeriod, indexers, nil) + return NewImageContentPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageContentPolicyInformer constructs a new informer for ImageContentPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageContentPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageContentPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageContentPolicyInformerWithOptions constructs a new informer for ImageContentPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageContentPolicyInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "imagecontentpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageContentPolicies().List(context.Background(), options) + return client.ConfigV1().ImageContentPolicies().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageContentPolicies().Watch(context.Background(), options) + return client.ConfigV1().ImageContentPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageContentPolicies().List(ctx, options) + return client.ConfigV1().ImageContentPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageContentPolicies().Watch(ctx, options) + return client.ConfigV1().ImageContentPolicies().Watch(ctx, opts) }, }, client), &apiconfigv1.ImageContentPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageContentPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageContentPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageContentPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageContentPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagedigestmirrorset.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagedigestmirrorset.go index 7efd71d7e0..ac43768aca 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagedigestmirrorset.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagedigestmirrorset.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageDigestMirrorSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageDigestMirrorSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageDigestMirrorSetInformer(client, resyncPeriod, indexers, nil) + return NewImageDigestMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageDigestMirrorSetInformer constructs a new informer for ImageDigestMirrorSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageDigestMirrorSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageDigestMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageDigestMirrorSetInformerWithOptions constructs a new informer for ImageDigestMirrorSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageDigestMirrorSetInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "imagedigestmirrorsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageDigestMirrorSets().List(context.Background(), options) + return client.ConfigV1().ImageDigestMirrorSets().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageDigestMirrorSets().Watch(context.Background(), options) + return client.ConfigV1().ImageDigestMirrorSets().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageDigestMirrorSets().List(ctx, options) + return client.ConfigV1().ImageDigestMirrorSets().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageDigestMirrorSets().Watch(ctx, options) + return client.ConfigV1().ImageDigestMirrorSets().Watch(ctx, opts) }, }, client), &apiconfigv1.ImageDigestMirrorSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageDigestMirrorSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageDigestMirrorSetInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageDigestMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageDigestMirrorSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagepolicy.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagepolicy.go index 64a4d13bce..237e5259b4 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagepolicy.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagepolicy.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type imagePolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImagePolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImagePolicyInformer(client, namespace, resyncPeriod, indexers, nil) + return NewImagePolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImagePolicyInformer constructs a new informer for ImagePolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImagePolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImagePolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImagePolicyInformerWithOptions constructs a new informer for ImagePolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImagePolicyInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "imagepolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImagePolicies(namespace).List(context.Background(), options) + return client.ConfigV1().ImagePolicies(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImagePolicies(namespace).Watch(context.Background(), options) + return client.ConfigV1().ImagePolicies(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImagePolicies(namespace).List(ctx, options) + return client.ConfigV1().ImagePolicies(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImagePolicies(namespace).Watch(ctx, options) + return client.ConfigV1().ImagePolicies(namespace).Watch(ctx, opts) }, }, client), &apiconfigv1.ImagePolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imagePolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImagePolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImagePolicyInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imagePolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagetagmirrorset.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagetagmirrorset.go index e50f27fdeb..49109c8379 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagetagmirrorset.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/imagetagmirrorset.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageTagMirrorSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageTagMirrorSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageTagMirrorSetInformer(client, resyncPeriod, indexers, nil) + return NewImageTagMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageTagMirrorSetInformer constructs a new informer for ImageTagMirrorSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageTagMirrorSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageTagMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageTagMirrorSetInformerWithOptions constructs a new informer for ImageTagMirrorSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageTagMirrorSetInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "imagetagmirrorsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageTagMirrorSets().List(context.Background(), options) + return client.ConfigV1().ImageTagMirrorSets().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageTagMirrorSets().Watch(context.Background(), options) + return client.ConfigV1().ImageTagMirrorSets().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageTagMirrorSets().List(ctx, options) + return client.ConfigV1().ImageTagMirrorSets().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().ImageTagMirrorSets().Watch(ctx, options) + return client.ConfigV1().ImageTagMirrorSets().Watch(ctx, opts) }, }, client), &apiconfigv1.ImageTagMirrorSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageTagMirrorSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageTagMirrorSetInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageTagMirrorSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageTagMirrorSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/infrastructure.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/infrastructure.go index a5bbe9f513..1c8d5716c3 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/infrastructure.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/infrastructure.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type infrastructureInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInfrastructureInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInfrastructureInformer(client, resyncPeriod, indexers, nil) + return NewInfrastructureInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInfrastructureInformer constructs a new informer for Infrastructure type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInfrastructureInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInfrastructureInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInfrastructureInformerWithOptions constructs a new informer for Infrastructure type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInfrastructureInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "infrastructures"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Infrastructures().List(context.Background(), options) + return client.ConfigV1().Infrastructures().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Infrastructures().Watch(context.Background(), options) + return client.ConfigV1().Infrastructures().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Infrastructures().List(ctx, options) + return client.ConfigV1().Infrastructures().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Infrastructures().Watch(ctx, options) + return client.ConfigV1().Infrastructures().Watch(ctx, opts) }, }, client), &apiconfigv1.Infrastructure{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *infrastructureInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInfrastructureInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInfrastructureInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *infrastructureInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/ingress.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/ingress.go index 112b941af9..fd2a7cbf76 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/ingress.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/ingress.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type ingressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, resyncPeriod, indexers, nil) + return NewIngressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressInformer constructs a new informer for Ingress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressInformerWithOptions constructs a new informer for Ingress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "ingresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Ingresses().List(context.Background(), options) + return client.ConfigV1().Ingresses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Ingresses().Watch(context.Background(), options) + return client.ConfigV1().Ingresses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Ingresses().List(ctx, options) + return client.ConfigV1().Ingresses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Ingresses().Watch(ctx, options) + return client.ConfigV1().Ingresses().Watch(ctx, opts) }, }, client), &apiconfigv1.Ingress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/insightsdatagather.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/insightsdatagather.go index 5872bfc6ab..afbffdfa03 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/insightsdatagather.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/insightsdatagather.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type insightsDataGatherInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, indexers, nil) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInsightsDataGatherInformer constructs a new informer for InsightsDataGather type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInsightsDataGatherInformerWithOptions constructs a new informer for InsightsDataGather type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInsightsDataGatherInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "insightsdatagathers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().InsightsDataGathers().List(context.Background(), options) + return client.ConfigV1().InsightsDataGathers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().InsightsDataGathers().Watch(context.Background(), options) + return client.ConfigV1().InsightsDataGathers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().InsightsDataGathers().List(ctx, options) + return client.ConfigV1().InsightsDataGathers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().InsightsDataGathers().Watch(ctx, options) + return client.ConfigV1().InsightsDataGathers().Watch(ctx, opts) }, }, client), &apiconfigv1.InsightsDataGather{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *insightsDataGatherInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *insightsDataGatherInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/network.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/network.go index ad36857a1a..66456bbf66 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/network.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/network.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type networkInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNetworkInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNetworkInformer(client, resyncPeriod, indexers, nil) + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNetworkInformer constructs a new informer for Network type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNetworkInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNetworkInformerWithOptions constructs a new informer for Network type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "networks"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Networks().List(context.Background(), options) + return client.ConfigV1().Networks().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Networks().Watch(context.Background(), options) + return client.ConfigV1().Networks().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Networks().List(ctx, options) + return client.ConfigV1().Networks().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Networks().Watch(ctx, options) + return client.ConfigV1().Networks().Watch(ctx, opts) }, }, client), &apiconfigv1.Network{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *networkInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNetworkInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *networkInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/node.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/node.go index 666868895c..4f5f58479a 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/node.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/node.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type nodeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNodeInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, indexers, nil) + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNodeInformer constructs a new informer for Node type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNodeInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNodeInformerWithOptions constructs a new informer for Node type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNodeInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "nodes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Nodes().List(context.Background(), options) + return client.ConfigV1().Nodes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Nodes().Watch(context.Background(), options) + return client.ConfigV1().Nodes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Nodes().List(ctx, options) + return client.ConfigV1().Nodes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Nodes().Watch(ctx, options) + return client.ConfigV1().Nodes().Watch(ctx, opts) }, }, client), &apiconfigv1.Node{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *nodeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *nodeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/oauth.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/oauth.go index bd19ddeea6..a0162ac6f7 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/oauth.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/oauth.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type oAuthInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOAuthInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOAuthInformer(client, resyncPeriod, indexers, nil) + return NewOAuthInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOAuthInformer constructs a new informer for OAuth type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOAuthInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOAuthInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOAuthInformerWithOptions constructs a new informer for OAuth type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOAuthInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "oauths"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OAuths().List(context.Background(), options) + return client.ConfigV1().OAuths().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OAuths().Watch(context.Background(), options) + return client.ConfigV1().OAuths().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OAuths().List(ctx, options) + return client.ConfigV1().OAuths().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OAuths().Watch(ctx, options) + return client.ConfigV1().OAuths().Watch(ctx, opts) }, }, client), &apiconfigv1.OAuth{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *oAuthInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOAuthInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOAuthInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *oAuthInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/operatorhub.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/operatorhub.go index eb76c7694b..0633f748e6 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/operatorhub.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/operatorhub.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type operatorHubInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOperatorHubInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOperatorHubInformer(client, resyncPeriod, indexers, nil) + return NewOperatorHubInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOperatorHubInformer constructs a new informer for OperatorHub type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOperatorHubInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOperatorHubInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOperatorHubInformerWithOptions constructs a new informer for OperatorHub type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOperatorHubInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "operatorhubs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OperatorHubs().List(context.Background(), options) + return client.ConfigV1().OperatorHubs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OperatorHubs().Watch(context.Background(), options) + return client.ConfigV1().OperatorHubs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OperatorHubs().List(ctx, options) + return client.ConfigV1().OperatorHubs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().OperatorHubs().Watch(ctx, options) + return client.ConfigV1().OperatorHubs().Watch(ctx, opts) }, }, client), &apiconfigv1.OperatorHub{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *operatorHubInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOperatorHubInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOperatorHubInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *operatorHubInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/project.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/project.go index bcbdabcc6e..cdc3875a83 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/project.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/project.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type projectInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewProjectInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredProjectInformer(client, resyncPeriod, indexers, nil) + return NewProjectInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredProjectInformer constructs a new informer for Project type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredProjectInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewProjectInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewProjectInformerWithOptions constructs a new informer for Project type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewProjectInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "projects"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Projects().List(context.Background(), options) + return client.ConfigV1().Projects().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Projects().Watch(context.Background(), options) + return client.ConfigV1().Projects().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Projects().List(ctx, options) + return client.ConfigV1().Projects().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Projects().Watch(ctx, options) + return client.ConfigV1().Projects().Watch(ctx, opts) }, }, client), &apiconfigv1.Project{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *projectInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredProjectInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewProjectInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *projectInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/proxy.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/proxy.go index 12dc67e518..be463759c5 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/proxy.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/proxy.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type proxyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewProxyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredProxyInformer(client, resyncPeriod, indexers, nil) + return NewProxyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredProxyInformer constructs a new informer for Proxy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredProxyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewProxyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewProxyInformerWithOptions constructs a new informer for Proxy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewProxyInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "proxys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Proxies().List(context.Background(), options) + return client.ConfigV1().Proxies().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Proxies().Watch(context.Background(), options) + return client.ConfigV1().Proxies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Proxies().List(ctx, options) + return client.ConfigV1().Proxies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Proxies().Watch(ctx, options) + return client.ConfigV1().Proxies().Watch(ctx, opts) }, }, client), &apiconfigv1.Proxy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *proxyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredProxyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewProxyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *proxyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/scheduler.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/scheduler.go index f31b64a3a4..6a390cd6ce 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/scheduler.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/scheduler.go @@ -12,6 +12,7 @@ import ( configv1 "github.com/openshift/client-go/config/listers/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type schedulerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredSchedulerInformer(client, resyncPeriod, indexers, nil) + return NewSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredSchedulerInformer constructs a new informer for Scheduler type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewSchedulerInformerWithOptions constructs a new informer for Scheduler type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewSchedulerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1", Resource: "schedulers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Schedulers().List(context.Background(), options) + return client.ConfigV1().Schedulers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Schedulers().Watch(context.Background(), options) + return client.ConfigV1().Schedulers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Schedulers().List(ctx, options) + return client.ConfigV1().Schedulers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1().Schedulers().Watch(ctx, options) + return client.ConfigV1().Schedulers().Watch(ctx, opts) }, }, client), &apiconfigv1.Scheduler{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *schedulerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredSchedulerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *schedulerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/backup.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/backup.go index 43a7e5abc6..e3ddf964a3 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/backup.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/backup.go @@ -12,6 +12,7 @@ import ( configv1alpha1 "github.com/openshift/client-go/config/listers/config/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type backupInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewBackupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredBackupInformer(client, resyncPeriod, indexers, nil) + return NewBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredBackupInformer constructs a new informer for Backup type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredBackupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewBackupInformerWithOptions constructs a new informer for Backup type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewBackupInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha1", Resource: "backups"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().Backups().List(context.Background(), options) + return client.ConfigV1alpha1().Backups().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().Backups().Watch(context.Background(), options) + return client.ConfigV1alpha1().Backups().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().Backups().List(ctx, options) + return client.ConfigV1alpha1().Backups().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().Backups().Watch(ctx, options) + return client.ConfigV1alpha1().Backups().Watch(ctx, opts) }, }, client), &apiconfigv1alpha1.Backup{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *backupInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredBackupInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *backupInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/clustermonitoring.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/clustermonitoring.go index 36e2fa631e..73d70fb331 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/clustermonitoring.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/clustermonitoring.go @@ -12,6 +12,7 @@ import ( configv1alpha1 "github.com/openshift/client-go/config/listers/config/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterMonitoringInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterMonitoringInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterMonitoringInformer(client, resyncPeriod, indexers, nil) + return NewClusterMonitoringInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterMonitoringInformer constructs a new informer for ClusterMonitoring type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterMonitoringInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterMonitoringInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterMonitoringInformerWithOptions constructs a new informer for ClusterMonitoring type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterMonitoringInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha1", Resource: "clustermonitorings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().ClusterMonitorings().List(context.Background(), options) + return client.ConfigV1alpha1().ClusterMonitorings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().ClusterMonitorings().Watch(context.Background(), options) + return client.ConfigV1alpha1().ClusterMonitorings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().ClusterMonitorings().List(ctx, options) + return client.ConfigV1alpha1().ClusterMonitorings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().ClusterMonitorings().Watch(ctx, options) + return client.ConfigV1alpha1().ClusterMonitorings().Watch(ctx, opts) }, }, client), &apiconfigv1alpha1.ClusterMonitoring{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterMonitoringInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterMonitoringInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterMonitoringInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterMonitoringInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/criocredentialproviderconfig.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/criocredentialproviderconfig.go index 132ca8041e..c3c241a388 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/criocredentialproviderconfig.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/criocredentialproviderconfig.go @@ -12,6 +12,7 @@ import ( configv1alpha1 "github.com/openshift/client-go/config/listers/config/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type cRIOCredentialProviderConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCRIOCredentialProviderConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCRIOCredentialProviderConfigInformer(client, resyncPeriod, indexers, nil) + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCRIOCredentialProviderConfigInformer constructs a new informer for CRIOCredentialProviderConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCRIOCredentialProviderConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCRIOCredentialProviderConfigInformerWithOptions constructs a new informer for CRIOCredentialProviderConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCRIOCredentialProviderConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha1", Resource: "criocredentialproviderconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().List(context.Background(), options) + return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().Watch(context.Background(), options) + return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().List(ctx, options) + return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().Watch(ctx, options) + return client.ConfigV1alpha1().CRIOCredentialProviderConfigs().Watch(ctx, opts) }, }, client), &apiconfigv1alpha1.CRIOCredentialProviderConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cRIOCredentialProviderConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCRIOCredentialProviderConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCRIOCredentialProviderConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cRIOCredentialProviderConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/insightsdatagather.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/insightsdatagather.go index 39624071e4..44e980ff79 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/insightsdatagather.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/insightsdatagather.go @@ -12,6 +12,7 @@ import ( configv1alpha1 "github.com/openshift/client-go/config/listers/config/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type insightsDataGatherInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, indexers, nil) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInsightsDataGatherInformer constructs a new informer for InsightsDataGather type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInsightsDataGatherInformerWithOptions constructs a new informer for InsightsDataGather type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInsightsDataGatherInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha1", Resource: "insightsdatagathers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().InsightsDataGathers().List(context.Background(), options) + return client.ConfigV1alpha1().InsightsDataGathers().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().InsightsDataGathers().Watch(context.Background(), options) + return client.ConfigV1alpha1().InsightsDataGathers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().InsightsDataGathers().List(ctx, options) + return client.ConfigV1alpha1().InsightsDataGathers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().InsightsDataGathers().Watch(ctx, options) + return client.ConfigV1alpha1().InsightsDataGathers().Watch(ctx, opts) }, }, client), &apiconfigv1alpha1.InsightsDataGather{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *insightsDataGatherInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *insightsDataGatherInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/pki.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/pki.go index 3613eec8c0..1dce29e56b 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/pki.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha1/pki.go @@ -12,6 +12,7 @@ import ( configv1alpha1 "github.com/openshift/client-go/config/listers/config/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type pKIInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPKIInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPKIInformer(client, resyncPeriod, indexers, nil) + return NewPKIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPKIInformer constructs a new informer for PKI type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPKIInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPKIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPKIInformerWithOptions constructs a new informer for PKI type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPKIInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha1", Resource: "pkis"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().PKIs().List(context.Background(), options) + return client.ConfigV1alpha1().PKIs().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().PKIs().Watch(context.Background(), options) + return client.ConfigV1alpha1().PKIs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().PKIs().List(ctx, options) + return client.ConfigV1alpha1().PKIs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha1().PKIs().Watch(ctx, options) + return client.ConfigV1alpha1().PKIs().Watch(ctx, opts) }, }, client), &apiconfigv1alpha1.PKI{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *pKIInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPKIInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPKIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *pKIInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha2/insightsdatagather.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha2/insightsdatagather.go index 471c79f1e8..1b20501cf6 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha2/insightsdatagather.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1alpha2/insightsdatagather.go @@ -12,6 +12,7 @@ import ( configv1alpha2 "github.com/openshift/client-go/config/listers/config/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type insightsDataGatherInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, indexers, nil) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInsightsDataGatherInformer constructs a new informer for InsightsDataGather type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInsightsDataGatherInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInsightsDataGatherInformerWithOptions constructs a new informer for InsightsDataGather type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInsightsDataGatherInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "config.openshift.io", Version: "v1alpha2", Resource: "insightsdatagathers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha2().InsightsDataGathers().List(context.Background(), options) + return client.ConfigV1alpha2().InsightsDataGathers().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha2().InsightsDataGathers().Watch(context.Background(), options) + return client.ConfigV1alpha2().InsightsDataGathers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha2().InsightsDataGathers().List(ctx, options) + return client.ConfigV1alpha2().InsightsDataGathers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ConfigV1alpha2().InsightsDataGathers().Watch(ctx, options) + return client.ConfigV1alpha2().InsightsDataGathers().Watch(ctx, opts) }, }, client), &apiconfigv1alpha2.InsightsDataGather{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *insightsDataGatherInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInsightsDataGatherInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInsightsDataGatherInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *insightsDataGatherInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/factory.go index befdfaabd0..1e357ea7b4 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/config/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/config/informers/externalversions/internalinterfaces/factory_interfaces.go index 720235c485..28d9ec5e5e 100644 --- a/vendor/github.com/openshift/client-go/config/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/config/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/image/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/image/clientset/versioned/fake/clientset_generated.go index 0be85415ac..c2a62a2ee9 100644 --- a/vendor/github.com/openshift/client-go/image/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/image/clientset/versioned/fake/clientset_generated.go @@ -19,10 +19,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -68,7 +64,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -83,6 +79,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/image/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/image/informers/externalversions/factory.go index 74bef556ae..c41e80e53a 100644 --- a/vendor/github.com/openshift/client-go/image/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/image/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/image.go b/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/image.go index e6eaccb365..00c0885f79 100644 --- a/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/image.go +++ b/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/image.go @@ -12,6 +12,7 @@ import ( imagev1 "github.com/openshift/client-go/image/listers/image/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageInformer(client, resyncPeriod, indexers, nil) + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageInformer constructs a new informer for Image type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageInformerWithOptions constructs a new informer for Image type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "image.openshift.io", Version: "v1", Resource: "images"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().Images().List(context.Background(), options) + return client.ImageV1().Images().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().Images().Watch(context.Background(), options) + return client.ImageV1().Images().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().Images().List(ctx, options) + return client.ImageV1().Images().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().Images().Watch(ctx, options) + return client.ImageV1().Images().Watch(ctx, opts) }, }, client), &apiimagev1.Image{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/imagestream.go b/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/imagestream.go index fab01df76e..3ea9f432fd 100644 --- a/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/imagestream.go +++ b/vendor/github.com/openshift/client-go/image/informers/externalversions/image/v1/imagestream.go @@ -12,6 +12,7 @@ import ( imagev1 "github.com/openshift/client-go/image/listers/image/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type imageStreamInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageStreamInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageStreamInformer(client, namespace, resyncPeriod, indexers, nil) + return NewImageStreamInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageStreamInformer constructs a new informer for ImageStream type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageStreamInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageStreamInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageStreamInformerWithOptions constructs a new informer for ImageStream type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageStreamInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "image.openshift.io", Version: "v1", Resource: "imagestreams"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().ImageStreams(namespace).List(context.Background(), options) + return client.ImageV1().ImageStreams(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().ImageStreams(namespace).Watch(context.Background(), options) + return client.ImageV1().ImageStreams(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().ImageStreams(namespace).List(ctx, options) + return client.ImageV1().ImageStreams(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ImageV1().ImageStreams(namespace).Watch(ctx, options) + return client.ImageV1().ImageStreams(namespace).Watch(ctx, opts) }, }, client), &apiimagev1.ImageStream{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageStreamInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageStreamInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageStreamInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageStreamInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/image/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/image/informers/externalversions/internalinterfaces/factory_interfaces.go index c35dcbfa44..dbceaeaae5 100644 --- a/vendor/github.com/openshift/client-go/image/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/image/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/machine/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/machine/clientset/versioned/fake/clientset_generated.go index a0fcc03a0d..6f4c36c24e 100644 --- a/vendor/github.com/openshift/client-go/machine/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/machine/clientset/versioned/fake/clientset_generated.go @@ -21,10 +21,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -70,7 +66,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -85,6 +81,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/factory.go index bd59558491..ddda4a9e2e 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/internalinterfaces/factory_interfaces.go index d777be27e1..7c0de31b67 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1/controlplanemachineset.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1/controlplanemachineset.go index 9b487899c2..63450985e7 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1/controlplanemachineset.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1/controlplanemachineset.go @@ -12,6 +12,7 @@ import ( machinev1 "github.com/openshift/client-go/machine/listers/machine/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type controlPlaneMachineSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewControlPlaneMachineSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControlPlaneMachineSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewControlPlaneMachineSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredControlPlaneMachineSetInformer constructs a new informer for ControlPlaneMachineSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredControlPlaneMachineSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewControlPlaneMachineSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewControlPlaneMachineSetInformerWithOptions constructs a new informer for ControlPlaneMachineSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControlPlaneMachineSetInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machine.openshift.io", Version: "v1", Resource: "controlplanemachinesets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1().ControlPlaneMachineSets(namespace).List(context.Background(), options) + return client.MachineV1().ControlPlaneMachineSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1().ControlPlaneMachineSets(namespace).Watch(context.Background(), options) + return client.MachineV1().ControlPlaneMachineSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1().ControlPlaneMachineSets(namespace).List(ctx, options) + return client.MachineV1().ControlPlaneMachineSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1().ControlPlaneMachineSets(namespace).Watch(ctx, options) + return client.MachineV1().ControlPlaneMachineSets(namespace).Watch(ctx, opts) }, }, client), &apimachinev1.ControlPlaneMachineSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *controlPlaneMachineSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControlPlaneMachineSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewControlPlaneMachineSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *controlPlaneMachineSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machine.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machine.go index 57cd60a0d2..5fa0c5be30 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machine.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machine.go @@ -12,6 +12,7 @@ import ( machinev1beta1 "github.com/openshift/client-go/machine/listers/machine/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type machineInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineInformer(client, namespace, resyncPeriod, indexers, nil) + return NewMachineInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineInformer constructs a new informer for Machine type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineInformerWithOptions constructs a new informer for Machine type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machine.openshift.io", Version: "v1beta1", Resource: "machines"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().Machines(namespace).List(context.Background(), options) + return client.MachineV1beta1().Machines(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().Machines(namespace).Watch(context.Background(), options) + return client.MachineV1beta1().Machines(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().Machines(namespace).List(ctx, options) + return client.MachineV1beta1().Machines(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().Machines(namespace).Watch(ctx, options) + return client.MachineV1beta1().Machines(namespace).Watch(ctx, opts) }, }, client), &apimachinev1beta1.Machine{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machinehealthcheck.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machinehealthcheck.go index 68c9c5e274..e24f79e821 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machinehealthcheck.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machinehealthcheck.go @@ -12,6 +12,7 @@ import ( machinev1beta1 "github.com/openshift/client-go/machine/listers/machine/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type machineHealthCheckInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineHealthCheckInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineHealthCheckInformer(client, namespace, resyncPeriod, indexers, nil) + return NewMachineHealthCheckInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineHealthCheckInformer constructs a new informer for MachineHealthCheck type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineHealthCheckInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineHealthCheckInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineHealthCheckInformerWithOptions constructs a new informer for MachineHealthCheck type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineHealthCheckInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machine.openshift.io", Version: "v1beta1", Resource: "machinehealthchecks"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineHealthChecks(namespace).List(context.Background(), options) + return client.MachineV1beta1().MachineHealthChecks(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineHealthChecks(namespace).Watch(context.Background(), options) + return client.MachineV1beta1().MachineHealthChecks(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineHealthChecks(namespace).List(ctx, options) + return client.MachineV1beta1().MachineHealthChecks(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineHealthChecks(namespace).Watch(ctx, options) + return client.MachineV1beta1().MachineHealthChecks(namespace).Watch(ctx, opts) }, }, client), &apimachinev1beta1.MachineHealthCheck{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineHealthCheckInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineHealthCheckInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineHealthCheckInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineHealthCheckInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machineset.go b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machineset.go index 838c5bedd2..7ad1a3d5e8 100644 --- a/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machineset.go +++ b/vendor/github.com/openshift/client-go/machine/informers/externalversions/machine/v1beta1/machineset.go @@ -12,6 +12,7 @@ import ( machinev1beta1 "github.com/openshift/client-go/machine/listers/machine/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type machineSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewMachineSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineSetInformer constructs a new informer for MachineSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineSetInformerWithOptions constructs a new informer for MachineSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineSetInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machine.openshift.io", Version: "v1beta1", Resource: "machinesets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineSets(namespace).List(context.Background(), options) + return client.MachineV1beta1().MachineSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineSets(namespace).Watch(context.Background(), options) + return client.MachineV1beta1().MachineSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineSets(namespace).List(ctx, options) + return client.MachineV1beta1().MachineSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineV1beta1().MachineSets(namespace).Watch(ctx, options) + return client.MachineV1beta1().MachineSets(namespace).Watch(ctx, opts) }, }, client), &apimachinev1beta1.MachineSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/machineconfiguration/clientset/versioned/fake/clientset_generated.go index a447d0d2a9..ee49610b67 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/clientset/versioned/fake/clientset_generated.go @@ -21,10 +21,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -70,7 +66,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -85,6 +81,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/factory.go index dab233eb00..3dd981969d 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/internalinterfaces/factory_interfaces.go index 86df6d5292..a5f17c4e0e 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/containerruntimeconfig.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/containerruntimeconfig.go index 9196eb03b1..61a39a1187 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/containerruntimeconfig.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/containerruntimeconfig.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type containerRuntimeConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewContainerRuntimeConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredContainerRuntimeConfigInformer(client, resyncPeriod, indexers, nil) + return NewContainerRuntimeConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredContainerRuntimeConfigInformer constructs a new informer for ContainerRuntimeConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredContainerRuntimeConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewContainerRuntimeConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewContainerRuntimeConfigInformerWithOptions constructs a new informer for ContainerRuntimeConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewContainerRuntimeConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "containerruntimeconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ContainerRuntimeConfigs().List(context.Background(), options) + return client.MachineconfigurationV1().ContainerRuntimeConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ContainerRuntimeConfigs().Watch(context.Background(), options) + return client.MachineconfigurationV1().ContainerRuntimeConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ContainerRuntimeConfigs().List(ctx, options) + return client.MachineconfigurationV1().ContainerRuntimeConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ContainerRuntimeConfigs().Watch(ctx, options) + return client.MachineconfigurationV1().ContainerRuntimeConfigs().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.ContainerRuntimeConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *containerRuntimeConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredContainerRuntimeConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewContainerRuntimeConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *containerRuntimeConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/controllerconfig.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/controllerconfig.go index f224a4eac3..0f71550a43 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/controllerconfig.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/controllerconfig.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type controllerConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewControllerConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControllerConfigInformer(client, resyncPeriod, indexers, nil) + return NewControllerConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredControllerConfigInformer constructs a new informer for ControllerConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredControllerConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewControllerConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewControllerConfigInformerWithOptions constructs a new informer for ControllerConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "controllerconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ControllerConfigs().List(context.Background(), options) + return client.MachineconfigurationV1().ControllerConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ControllerConfigs().Watch(context.Background(), options) + return client.MachineconfigurationV1().ControllerConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ControllerConfigs().List(ctx, options) + return client.MachineconfigurationV1().ControllerConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().ControllerConfigs().Watch(ctx, options) + return client.MachineconfigurationV1().ControllerConfigs().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.ControllerConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *controllerConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControllerConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewControllerConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *controllerConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/internalreleaseimage.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/internalreleaseimage.go index 0316261249..f7156d2142 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/internalreleaseimage.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/internalreleaseimage.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type internalReleaseImageInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInternalReleaseImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInternalReleaseImageInformer(client, resyncPeriod, indexers, nil) + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInternalReleaseImageInformer constructs a new informer for InternalReleaseImage type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInternalReleaseImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInternalReleaseImageInformerWithOptions constructs a new informer for InternalReleaseImage type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInternalReleaseImageInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "internalreleaseimages"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().InternalReleaseImages().List(context.Background(), options) + return client.MachineconfigurationV1().InternalReleaseImages().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().InternalReleaseImages().Watch(context.Background(), options) + return client.MachineconfigurationV1().InternalReleaseImages().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().InternalReleaseImages().List(ctx, options) + return client.MachineconfigurationV1().InternalReleaseImages().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().InternalReleaseImages().Watch(ctx, options) + return client.MachineconfigurationV1().InternalReleaseImages().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.InternalReleaseImage{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *internalReleaseImageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInternalReleaseImageInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *internalReleaseImageInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/kubeletconfig.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/kubeletconfig.go index 12fbcaa013..45a50bb8d6 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/kubeletconfig.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/kubeletconfig.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type kubeletConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewKubeletConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredKubeletConfigInformer(client, resyncPeriod, indexers, nil) + return NewKubeletConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredKubeletConfigInformer constructs a new informer for KubeletConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredKubeletConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewKubeletConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewKubeletConfigInformerWithOptions constructs a new informer for KubeletConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKubeletConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "kubeletconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().KubeletConfigs().List(context.Background(), options) + return client.MachineconfigurationV1().KubeletConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().KubeletConfigs().Watch(context.Background(), options) + return client.MachineconfigurationV1().KubeletConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().KubeletConfigs().List(ctx, options) + return client.MachineconfigurationV1().KubeletConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().KubeletConfigs().Watch(ctx, options) + return client.MachineconfigurationV1().KubeletConfigs().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.KubeletConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *kubeletConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredKubeletConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewKubeletConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *kubeletConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfig.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfig.go index 5fd5ac0b8a..1a13461972 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfig.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfig.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineConfigInformer(client, resyncPeriod, indexers, nil) + return NewMachineConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineConfigInformer constructs a new informer for MachineConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineConfigInformerWithOptions constructs a new informer for MachineConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "machineconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigs().List(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigs().Watch(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigs().List(ctx, options) + return client.MachineconfigurationV1().MachineConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigs().Watch(ctx, options) + return client.MachineconfigurationV1().MachineConfigs().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.MachineConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfignode.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfignode.go index b897ed6aee..0c54a47a91 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfignode.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfignode.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineConfigNodeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineConfigNodeInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineConfigNodeInformer(client, resyncPeriod, indexers, nil) + return NewMachineConfigNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineConfigNodeInformer constructs a new informer for MachineConfigNode type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineConfigNodeInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineConfigNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineConfigNodeInformerWithOptions constructs a new informer for MachineConfigNode type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineConfigNodeInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "machineconfignodes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigNodes().List(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigNodes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigNodes().Watch(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigNodes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigNodes().List(ctx, options) + return client.MachineconfigurationV1().MachineConfigNodes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigNodes().Watch(ctx, options) + return client.MachineconfigurationV1().MachineConfigNodes().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.MachineConfigNode{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineConfigNodeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineConfigNodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineConfigNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineConfigNodeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfigpool.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfigpool.go index b790436cea..d80c0c8a03 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfigpool.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineconfigpool.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineConfigPoolInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineConfigPoolInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineConfigPoolInformer(client, resyncPeriod, indexers, nil) + return NewMachineConfigPoolInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineConfigPoolInformer constructs a new informer for MachineConfigPool type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineConfigPoolInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineConfigPoolInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineConfigPoolInformerWithOptions constructs a new informer for MachineConfigPool type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineConfigPoolInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "machineconfigpools"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigPools().List(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigPools().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigPools().Watch(context.Background(), options) + return client.MachineconfigurationV1().MachineConfigPools().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigPools().List(ctx, options) + return client.MachineconfigurationV1().MachineConfigPools().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineConfigPools().Watch(ctx, options) + return client.MachineconfigurationV1().MachineConfigPools().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.MachineConfigPool{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineConfigPoolInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineConfigPoolInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineConfigPoolInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineConfigPoolInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosbuild.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosbuild.go index a6c8e2f1fa..c57dc0fc65 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosbuild.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosbuild.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineOSBuildInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineOSBuildInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineOSBuildInformer(client, resyncPeriod, indexers, nil) + return NewMachineOSBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineOSBuildInformer constructs a new informer for MachineOSBuild type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineOSBuildInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineOSBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineOSBuildInformerWithOptions constructs a new informer for MachineOSBuild type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineOSBuildInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "machineosbuilds"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSBuilds().List(context.Background(), options) + return client.MachineconfigurationV1().MachineOSBuilds().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSBuilds().Watch(context.Background(), options) + return client.MachineconfigurationV1().MachineOSBuilds().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSBuilds().List(ctx, options) + return client.MachineconfigurationV1().MachineOSBuilds().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSBuilds().Watch(ctx, options) + return client.MachineconfigurationV1().MachineOSBuilds().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.MachineOSBuild{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineOSBuildInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineOSBuildInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineOSBuildInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineOSBuildInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosconfig.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosconfig.go index acf7e64f83..134ca5d8cf 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosconfig.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/machineosconfig.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineOSConfigInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineOSConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineOSConfigInformer(client, resyncPeriod, indexers, nil) + return NewMachineOSConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineOSConfigInformer constructs a new informer for MachineOSConfig type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineOSConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineOSConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineOSConfigInformerWithOptions constructs a new informer for MachineOSConfig type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineOSConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "machineosconfigs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSConfigs().List(context.Background(), options) + return client.MachineconfigurationV1().MachineOSConfigs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSConfigs().Watch(context.Background(), options) + return client.MachineconfigurationV1().MachineOSConfigs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSConfigs().List(ctx, options) + return client.MachineconfigurationV1().MachineOSConfigs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().MachineOSConfigs().Watch(ctx, options) + return client.MachineconfigurationV1().MachineOSConfigs().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.MachineOSConfig{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineOSConfigInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineOSConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineOSConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineOSConfigInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/osimagestream.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/osimagestream.go index 95e690b6a0..c0ea0c0d45 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/osimagestream.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/osimagestream.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type oSImageStreamInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOSImageStreamInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOSImageStreamInformer(client, resyncPeriod, indexers, nil) + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOSImageStreamInformer constructs a new informer for OSImageStream type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOSImageStreamInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOSImageStreamInformerWithOptions constructs a new informer for OSImageStream type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOSImageStreamInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "osimagestreams"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().OSImageStreams().List(context.Background(), options) + return client.MachineconfigurationV1().OSImageStreams().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().OSImageStreams().Watch(context.Background(), options) + return client.MachineconfigurationV1().OSImageStreams().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().OSImageStreams().List(ctx, options) + return client.MachineconfigurationV1().OSImageStreams().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().OSImageStreams().Watch(ctx, options) + return client.MachineconfigurationV1().OSImageStreams().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.OSImageStream{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *oSImageStreamInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOSImageStreamInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *oSImageStreamInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/pinnedimageset.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/pinnedimageset.go index 0923acc90b..6fc123860e 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/pinnedimageset.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1/pinnedimageset.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type pinnedImageSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPinnedImageSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPinnedImageSetInformer(client, resyncPeriod, indexers, nil) + return NewPinnedImageSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPinnedImageSetInformer constructs a new informer for PinnedImageSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPinnedImageSetInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPinnedImageSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPinnedImageSetInformerWithOptions constructs a new informer for PinnedImageSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPinnedImageSetInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1", Resource: "pinnedimagesets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().PinnedImageSets().List(context.Background(), options) + return client.MachineconfigurationV1().PinnedImageSets().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().PinnedImageSets().Watch(context.Background(), options) + return client.MachineconfigurationV1().PinnedImageSets().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().PinnedImageSets().List(ctx, options) + return client.MachineconfigurationV1().PinnedImageSets().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1().PinnedImageSets().Watch(ctx, options) + return client.MachineconfigurationV1().PinnedImageSets().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1.PinnedImageSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *pinnedImageSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPinnedImageSetInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPinnedImageSetInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *pinnedImageSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/internalreleaseimage.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/internalreleaseimage.go index cd70c5cb2e..5005904274 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/internalreleaseimage.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/internalreleaseimage.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1alpha1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type internalReleaseImageInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInternalReleaseImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInternalReleaseImageInformer(client, resyncPeriod, indexers, nil) + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInternalReleaseImageInformer constructs a new informer for InternalReleaseImage type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInternalReleaseImageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInternalReleaseImageInformerWithOptions constructs a new informer for InternalReleaseImage type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInternalReleaseImageInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1alpha1", Resource: "internalreleaseimages"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().InternalReleaseImages().List(context.Background(), options) + return client.MachineconfigurationV1alpha1().InternalReleaseImages().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().InternalReleaseImages().Watch(context.Background(), options) + return client.MachineconfigurationV1alpha1().InternalReleaseImages().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().InternalReleaseImages().List(ctx, options) + return client.MachineconfigurationV1alpha1().InternalReleaseImages().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().InternalReleaseImages().Watch(ctx, options) + return client.MachineconfigurationV1alpha1().InternalReleaseImages().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1alpha1.InternalReleaseImage{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *internalReleaseImageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInternalReleaseImageInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInternalReleaseImageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *internalReleaseImageInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/osimagestream.go b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/osimagestream.go index c6fa427c8c..e968c2b7bc 100644 --- a/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/osimagestream.go +++ b/vendor/github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1alpha1/osimagestream.go @@ -12,6 +12,7 @@ import ( machineconfigurationv1alpha1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type oSImageStreamInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOSImageStreamInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOSImageStreamInformer(client, resyncPeriod, indexers, nil) + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOSImageStreamInformer constructs a new informer for OSImageStream type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOSImageStreamInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOSImageStreamInformerWithOptions constructs a new informer for OSImageStream type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOSImageStreamInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "machineconfiguration.openshift.io", Version: "v1alpha1", Resource: "osimagestreams"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().OSImageStreams().List(context.Background(), options) + return client.MachineconfigurationV1alpha1().OSImageStreams().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().OSImageStreams().Watch(context.Background(), options) + return client.MachineconfigurationV1alpha1().OSImageStreams().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().OSImageStreams().List(ctx, options) + return client.MachineconfigurationV1alpha1().OSImageStreams().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.MachineconfigurationV1alpha1().OSImageStreams().Watch(ctx, options) + return client.MachineconfigurationV1alpha1().OSImageStreams().Watch(ctx, opts) }, }, client), &apimachineconfigurationv1alpha1.OSImageStream{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *oSImageStreamInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOSImageStreamInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOSImageStreamInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *oSImageStreamInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go index a7f34e2640..7e41cc30bf 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go @@ -222,6 +222,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic + - name: protocol + type: + scalar: string - name: subnets type: namedType: com.github.openshift.api.operator.v1.AWSSubnets @@ -322,6 +325,31 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: com.github.openshift.api.operator.v1.AuthenticationStatus default: {} +- name: com.github.openshift.api.operator.v1.AuthenticationConfigMapReference + map: + fields: + - name: name + type: + scalar: string +- name: com.github.openshift.api.operator.v1.AuthenticationProxyConfig + map: + fields: + - name: httpProxy + type: + scalar: string + - name: httpsProxy + type: + scalar: string + - name: noProxy + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: trustedCA + type: + namedType: com.github.openshift.api.operator.v1.AuthenticationConfigMapReference + default: {} - name: com.github.openshift.api.operator.v1.AuthenticationSpec map: fields: @@ -338,6 +366,10 @@ var schemaYAML = typed.YAMLObject(`types: - name: operatorLogLevel type: scalar: string + - name: proxy + type: + namedType: com.github.openshift.api.operator.v1.AuthenticationProxyConfig + default: {} - name: unsupportedConfigOverrides type: namedType: __untyped_atomic_ @@ -466,6 +498,10 @@ var schemaYAML = typed.YAMLObject(`types: - name: ibmcloud type: namedType: com.github.openshift.api.operator.v1.IBMCloudCSIDriverConfigSpec + - name: secretsStore + type: + namedType: com.github.openshift.api.operator.v1.SecretsStoreCSIDriverConfigSpec + default: {} - name: vSphere type: namedType: com.github.openshift.api.operator.v1.VSphereCSIDriverConfigSpec @@ -480,6 +516,8 @@ var schemaYAML = typed.YAMLObject(`types: discriminatorValue: GCP - fieldName: ibmcloud discriminatorValue: IBMCloud + - fieldName: secretsStore + discriminatorValue: SecretsStore - fieldName: vSphere discriminatorValue: VSphere - name: com.github.openshift.api.operator.v1.CSISnapshotController @@ -1054,6 +1092,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: maxLength type: scalar: numeric +- name: com.github.openshift.api.operator.v1.CustomSecretRotation + map: + fields: + - name: minimumRefreshAge + type: + scalar: numeric - name: com.github.openshift.api.operator.v1.DNS map: fields: @@ -1895,6 +1939,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: endpointPublishingStrategy type: namedType: com.github.openshift.api.operator.v1.EndpointPublishingStrategy + - name: haproxyVersion + type: + scalar: string - name: httpCompression type: namedType: com.github.openshift.api.operator.v1.HTTPCompressionPolicy @@ -1960,6 +2007,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" + - name: effectiveHAProxyVersion + type: + scalar: string - name: endpointPublishingStrategy type: namedType: com.github.openshift.api.operator.v1.EndpointPublishingStrategy @@ -2751,6 +2801,17 @@ var schemaYAML = typed.YAMLObject(`types: keys: - resource - apiGroup +- name: com.github.openshift.api.operator.v1.ManagedTokenRequests + map: + fields: + - name: audiences + type: + list: + elementType: + namedType: com.github.openshift.api.operator.v1.SecretsStoreTokenRequest + elementRelationship: associative + keys: + - audience - name: com.github.openshift.api.operator.v1.NetFlowConfig map: fields: @@ -3649,6 +3710,56 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic +- name: com.github.openshift.api.operator.v1.SecretsStoreCSIDriverConfigSpec + map: + fields: + - name: secretRotation + type: + namedType: com.github.openshift.api.operator.v1.SecretsStoreSecretRotation + default: {} + - name: tokenRequests + type: + namedType: com.github.openshift.api.operator.v1.SecretsStoreTokenRequests + default: {} +- name: com.github.openshift.api.operator.v1.SecretsStoreSecretRotation + map: + fields: + - name: custom + type: + namedType: com.github.openshift.api.operator.v1.CustomSecretRotation + default: {} + - name: type + type: + scalar: string + unions: + - discriminator: type + fields: + - fieldName: custom + discriminatorValue: Custom +- name: com.github.openshift.api.operator.v1.SecretsStoreTokenRequest + map: + fields: + - name: audience + type: + scalar: string + - name: expirationSeconds + type: + scalar: numeric +- name: com.github.openshift.api.operator.v1.SecretsStoreTokenRequests + map: + fields: + - name: managed + type: + namedType: com.github.openshift.api.operator.v1.ManagedTokenRequests + default: {} + - name: type + type: + scalar: string + unions: + - discriminator: type + fields: + - fieldName: managed + discriminatorValue: Managed - name: com.github.openshift.api.operator.v1.Server map: fields: diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationconfigmapreference.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationconfigmapreference.go new file mode 100644 index 0000000000..0743906641 --- /dev/null +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationconfigmapreference.go @@ -0,0 +1,30 @@ +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// AuthenticationConfigMapReferenceApplyConfiguration represents a declarative configuration of the AuthenticationConfigMapReference type for use +// with apply. +// +// AuthenticationConfigMapReference references a ConfigMap in the +// openshift-config namespace. +type AuthenticationConfigMapReferenceApplyConfiguration struct { + // name is the metadata.name of the referenced ConfigMap. + // Must be a valid DNS subdomain name (RFC 1123): at most 253 + // characters, only lowercase alphanumeric characters, '-' or + // '.', starting and ending with an alphanumeric character. + Name *string `json:"name,omitempty"` +} + +// AuthenticationConfigMapReferenceApplyConfiguration constructs a declarative configuration of the AuthenticationConfigMapReference type for use with +// apply. +func AuthenticationConfigMapReference() *AuthenticationConfigMapReferenceApplyConfiguration { + return &AuthenticationConfigMapReferenceApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *AuthenticationConfigMapReferenceApplyConfiguration) WithName(value string) *AuthenticationConfigMapReferenceApplyConfiguration { + b.Name = &value + return b +} diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationproxyconfig.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationproxyconfig.go new file mode 100644 index 0000000000..8b5e291443 --- /dev/null +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationproxyconfig.go @@ -0,0 +1,79 @@ +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// AuthenticationProxyConfigApplyConfiguration represents a declarative configuration of the AuthenticationProxyConfig type for use +// with apply. +// +// AuthenticationProxyConfig holds proxy configuration scoped to +// authentication components (the OAuth server and the cluster +// authentication operator). +type AuthenticationProxyConfigApplyConfiguration struct { + // httpProxy is the URL of the proxy for HTTP requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + HTTPProxy *string `json:"httpProxy,omitempty"` + // httpsProxy is the URL of the proxy for HTTPS requests. + // Must be a valid URL with http or https scheme, a non-empty + // hostname, and no path, query parameters, or fragment. + // Userinfo (e.g. user:password@host) is allowed for proxy + // authentication. Maximum length is 2048 characters. + HTTPSProxy *string `json:"httpsProxy,omitempty"` + // noProxy is a list of hostnames and/or CIDRs and/or IPs for which + // the proxy should not be used. Must contain at least one entry + // when set. Each entry must be between 1 and 253 characters long + // and at most 64 entries are allowed. Duplicate + // entries are not permitted. Entries that are not valid hostnames, + // CIDRs, or IPs are silently ignored. Cluster-internal defaults + // (.cluster.local, .svc, 127.0.0.1, localhost) are always appended + // automatically and do not need to be included. + NoProxy []string `json:"noProxy,omitempty"` + // trustedCA is a reference to a ConfigMap in the openshift-config + // namespace containing a CA certificate bundle under the key + // "ca-bundle.crt". This bundle is appended to the system trust store + // used by authentication components for proxy TLS connections. + // When omitted, only the system trust store is used. + TrustedCA *AuthenticationConfigMapReferenceApplyConfiguration `json:"trustedCA,omitempty"` +} + +// AuthenticationProxyConfigApplyConfiguration constructs a declarative configuration of the AuthenticationProxyConfig type for use with +// apply. +func AuthenticationProxyConfig() *AuthenticationProxyConfigApplyConfiguration { + return &AuthenticationProxyConfigApplyConfiguration{} +} + +// WithHTTPProxy sets the HTTPProxy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HTTPProxy field is set to the value of the last call. +func (b *AuthenticationProxyConfigApplyConfiguration) WithHTTPProxy(value string) *AuthenticationProxyConfigApplyConfiguration { + b.HTTPProxy = &value + return b +} + +// WithHTTPSProxy sets the HTTPSProxy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HTTPSProxy field is set to the value of the last call. +func (b *AuthenticationProxyConfigApplyConfiguration) WithHTTPSProxy(value string) *AuthenticationProxyConfigApplyConfiguration { + b.HTTPSProxy = &value + return b +} + +// WithNoProxy adds the given value to the NoProxy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the NoProxy field. +func (b *AuthenticationProxyConfigApplyConfiguration) WithNoProxy(values ...string) *AuthenticationProxyConfigApplyConfiguration { + for i := range values { + b.NoProxy = append(b.NoProxy, values[i]) + } + return b +} + +// WithTrustedCA sets the TrustedCA field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TrustedCA field is set to the value of the last call. +func (b *AuthenticationProxyConfigApplyConfiguration) WithTrustedCA(value *AuthenticationConfigMapReferenceApplyConfiguration) *AuthenticationProxyConfigApplyConfiguration { + b.TrustedCA = value + return b +} diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationspec.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationspec.go index ac90816bce..4d2fb8c7ce 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationspec.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/authenticationspec.go @@ -11,6 +11,14 @@ import ( // with apply. type AuthenticationSpecApplyConfiguration struct { OperatorSpecApplyConfiguration `json:",inline"` + // proxy configures proxy settings for outbound connections made + // by the authentication stack. When set, it replaces the + // cluster-wide proxy (proxy.config.openshift.io/cluster) + // entirely for authentication — individual fields are not + // inherited from the cluster-wide configuration. When omitted, + // the cluster-wide proxy is used if configured; otherwise no + // proxy is used. + Proxy *AuthenticationProxyConfigApplyConfiguration `json:"proxy,omitempty"` } // AuthenticationSpecApplyConfiguration constructs a declarative configuration of the AuthenticationSpec type for use with @@ -58,3 +66,11 @@ func (b *AuthenticationSpecApplyConfiguration) WithObservedConfig(value runtime. b.OperatorSpecApplyConfiguration.ObservedConfig = &value return b } + +// WithProxy sets the Proxy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Proxy field is set to the value of the last call. +func (b *AuthenticationSpecApplyConfiguration) WithProxy(value *AuthenticationProxyConfigApplyConfiguration) *AuthenticationSpecApplyConfiguration { + b.Proxy = value + return b +} diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/customsecretrotation.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/customsecretrotation.go index 1dd976a86a..189d31ad7e 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/customsecretrotation.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/customsecretrotation.go @@ -7,13 +7,17 @@ package v1 // // CustomSecretRotation holds configuration for custom secret rotation behavior. type CustomSecretRotationApplyConfiguration struct { - // rotationPollIntervalSeconds is the minimum time in seconds between secret - // rotation attempts. The driver skips provider calls if less than this interval - // has elapsed since the last successful rotation. + // minimumRefreshAge is the minimum time in seconds between secret + // rotation attempts. Each time kubelet calls NodePublishVolume, the driver + // checks whether this interval has elapsed since the last successful provider + // call. If it has, the driver contacts the secret provider to fetch the latest + // secret values and updates the mounted volume. + // Setting this value below the kubelet syncFrequency (default: 1 minute) + // has no additional effect on the actual rotation cadence. // Must be at least 1 second and no more than 31560000 seconds (~1 year). // When omitted, this means no opinion and the platform is left to choose a // reasonable default, which is subject to change over time. - RotationPollIntervalSeconds *int32 `json:"rotationPollIntervalSeconds,omitempty"` + MinimumRefreshAge *int32 `json:"minimumRefreshAge,omitempty"` } // CustomSecretRotationApplyConfiguration constructs a declarative configuration of the CustomSecretRotation type for use with @@ -22,10 +26,10 @@ func CustomSecretRotation() *CustomSecretRotationApplyConfiguration { return &CustomSecretRotationApplyConfiguration{} } -// WithRotationPollIntervalSeconds sets the RotationPollIntervalSeconds field in the declarative configuration to the given value +// WithMinimumRefreshAge sets the MinimumRefreshAge field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RotationPollIntervalSeconds field is set to the value of the last call. -func (b *CustomSecretRotationApplyConfiguration) WithRotationPollIntervalSeconds(value int32) *CustomSecretRotationApplyConfiguration { - b.RotationPollIntervalSeconds = &value +// If called multiple times, the MinimumRefreshAge field is set to the value of the last call. +func (b *CustomSecretRotationApplyConfiguration) WithMinimumRefreshAge(value int32) *CustomSecretRotationApplyConfiguration { + b.MinimumRefreshAge = &value return b } diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerspec.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerspec.go index 9874c3b63b..b6337158c3 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerspec.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerspec.go @@ -285,6 +285,27 @@ type IngressControllerSpecApplyConfiguration struct { // - Using RSA keys larger than 2048 bits can significantly slow down // TLS computations. Consider using the "Abort" policy to reduce CPU usage. ClosedClientConnectionPolicy *operatorv1.IngressControllerClosedClientConnectionPolicy `json:"closedClientConnectionPolicy,omitempty"` + // haproxyVersion specifies the HAProxy version to use for this + // IngressController. + // + // OpenShift 5.0 introduces HAProxy 3.2 as its default version and supports + // HAProxy 2.8 from OpenShift 4.22 for migration purposes. When an OpenShift + // release introduces a new default HAProxy version, that HAProxy version + // becomes available as a pinnable value in subsequent OpenShift releases, + // providing a smooth migration path for administrators who want to defer + // HAProxy upgrades. + // + // Valid values for OpenShift 5.0: + // - Unset (default): Uses HAProxy 3.2 (the default for OpenShift 5.0) + // - "3.2": Explicitly pins HAProxy 3.2 for preservation during cluster + // upgrades to future OpenShift releases + // - "2.8": Uses HAProxy 2.8 from OpenShift 4.22 (migration support, will + // be dropped in the next OpenShift release) + // + // If a specific HAProxy version is set and would become unsupported in a + // target cluster upgrade, a preflight check will block the cluster upgrade + // until this field is updated to unset or a supported version. + HAProxyVersion *operatorv1.HAProxyVersion `json:"haproxyVersion,omitempty"` } // IngressControllerSpecApplyConfiguration constructs a declarative configuration of the IngressControllerSpec type for use with @@ -444,3 +465,11 @@ func (b *IngressControllerSpecApplyConfiguration) WithClosedClientConnectionPoli b.ClosedClientConnectionPolicy = &value return b } + +// WithHAProxyVersion sets the HAProxyVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HAProxyVersion field is set to the value of the last call. +func (b *IngressControllerSpecApplyConfiguration) WithHAProxyVersion(value operatorv1.HAProxyVersion) *IngressControllerSpecApplyConfiguration { + b.HAProxyVersion = &value + return b +} diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerstatus.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerstatus.go index d42313f040..169f158b6f 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerstatus.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerstatus.go @@ -4,6 +4,7 @@ package v1 import ( configv1 "github.com/openshift/api/config/v1" + operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/client-go/applyconfigurations/meta/v1" ) @@ -64,6 +65,15 @@ type IngressControllerStatusApplyConfiguration struct { NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` // routeSelector is the actual routeSelector in use. RouteSelector *metav1.LabelSelectorApplyConfiguration `json:"routeSelector,omitempty"` + // effectiveHAProxyVersion reports the HAProxy version currently in use by + // this IngressController. This reflects the resolved value of the + // spec.haproxyVersion field. When omitted, the effective value has not yet + // been resolved by the operator or the feature is not enabled for this cluster. + // + // Examples for OpenShift 5.0: + // - "3.2": Using HAProxy 3.2 + // - "2.8": Using HAProxy 2.8 + EffectiveHAProxyVersion *operatorv1.HAProxyVersion `json:"effectiveHAProxyVersion,omitempty"` } // IngressControllerStatusApplyConfiguration constructs a declarative configuration of the IngressControllerStatus type for use with @@ -148,3 +158,11 @@ func (b *IngressControllerStatusApplyConfiguration) WithRouteSelector(value *met b.RouteSelector = value return b } + +// WithEffectiveHAProxyVersion sets the EffectiveHAProxyVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the EffectiveHAProxyVersion field is set to the value of the last call. +func (b *IngressControllerStatusApplyConfiguration) WithEffectiveHAProxyVersion(value operatorv1.HAProxyVersion) *IngressControllerStatusApplyConfiguration { + b.EffectiveHAProxyVersion = &value + return b +} diff --git a/vendor/github.com/openshift/client-go/operator/applyconfigurations/utils.go b/vendor/github.com/openshift/client-go/operator/applyconfigurations/utils.go index cd03dd84d0..bd16457a7a 100644 --- a/vendor/github.com/openshift/client-go/operator/applyconfigurations/utils.go +++ b/vendor/github.com/openshift/client-go/operator/applyconfigurations/utils.go @@ -28,6 +28,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &operatorv1.AddPageApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("Authentication"): return &operatorv1.AuthenticationApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("AuthenticationConfigMapReference"): + return &operatorv1.AuthenticationConfigMapReferenceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("AuthenticationProxyConfig"): + return &operatorv1.AuthenticationProxyConfigApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("AuthenticationSpec"): return &operatorv1.AuthenticationSpecApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("AuthenticationStatus"): diff --git a/vendor/github.com/openshift/client-go/operator/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/operator/clientset/versioned/fake/clientset_generated.go index 9cb092b253..9d7aa5dc74 100644 --- a/vendor/github.com/openshift/client-go/operator/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/operator/clientset/versioned/fake/clientset_generated.go @@ -21,10 +21,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -70,7 +66,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -85,6 +81,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/factory.go index 4f1751045f..cc57daa2a3 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/internalinterfaces/factory_interfaces.go index bf4618167f..e3fe8030d3 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/authentication.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/authentication.go index f0f0e0d198..eb63815e2e 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/authentication.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/authentication.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type authenticationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewAuthenticationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredAuthenticationInformer(client, resyncPeriod, indexers, nil) + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredAuthenticationInformer constructs a new informer for Authentication type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredAuthenticationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewAuthenticationInformerWithOptions constructs a new informer for Authentication type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewAuthenticationInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "authentications"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Authentications().List(context.Background(), options) + return client.OperatorV1().Authentications().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Authentications().Watch(context.Background(), options) + return client.OperatorV1().Authentications().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Authentications().List(ctx, options) + return client.OperatorV1().Authentications().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Authentications().Watch(ctx, options) + return client.OperatorV1().Authentications().Watch(ctx, opts) }, }, client), &apioperatorv1.Authentication{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *authenticationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredAuthenticationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewAuthenticationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *authenticationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/cloudcredential.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/cloudcredential.go index 726cdea8c4..82a15b21ca 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/cloudcredential.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/cloudcredential.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type cloudCredentialInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCloudCredentialInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCloudCredentialInformer(client, resyncPeriod, indexers, nil) + return NewCloudCredentialInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCloudCredentialInformer constructs a new informer for CloudCredential type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCloudCredentialInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCloudCredentialInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCloudCredentialInformerWithOptions constructs a new informer for CloudCredential type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCloudCredentialInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "cloudcredentials"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CloudCredentials().List(context.Background(), options) + return client.OperatorV1().CloudCredentials().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CloudCredentials().Watch(context.Background(), options) + return client.OperatorV1().CloudCredentials().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CloudCredentials().List(ctx, options) + return client.OperatorV1().CloudCredentials().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CloudCredentials().Watch(ctx, options) + return client.OperatorV1().CloudCredentials().Watch(ctx, opts) }, }, client), &apioperatorv1.CloudCredential{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cloudCredentialInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCloudCredentialInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCloudCredentialInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cloudCredentialInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/clustercsidriver.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/clustercsidriver.go index c2ff698afc..4c9c3dfad4 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/clustercsidriver.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/clustercsidriver.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterCSIDriverInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterCSIDriverInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterCSIDriverInformer(client, resyncPeriod, indexers, nil) + return NewClusterCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterCSIDriverInformer constructs a new informer for ClusterCSIDriver type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterCSIDriverInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterCSIDriverInformerWithOptions constructs a new informer for ClusterCSIDriver type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterCSIDriverInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "clustercsidrivers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ClusterCSIDrivers().List(context.Background(), options) + return client.OperatorV1().ClusterCSIDrivers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ClusterCSIDrivers().Watch(context.Background(), options) + return client.OperatorV1().ClusterCSIDrivers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ClusterCSIDrivers().List(ctx, options) + return client.OperatorV1().ClusterCSIDrivers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ClusterCSIDrivers().Watch(ctx, options) + return client.OperatorV1().ClusterCSIDrivers().Watch(ctx, opts) }, }, client), &apioperatorv1.ClusterCSIDriver{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterCSIDriverInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterCSIDriverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterCSIDriverInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/config.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/config.go index d8b12b3ad4..04ecf5cb57 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/config.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/config.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type configInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredConfigInformer(client, resyncPeriod, indexers, nil) + return NewConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredConfigInformer constructs a new informer for Config type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewConfigInformerWithOptions constructs a new informer for Config type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConfigInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "configs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Configs().List(context.Background(), options) + return client.OperatorV1().Configs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Configs().Watch(context.Background(), options) + return client.OperatorV1().Configs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Configs().List(ctx, options) + return client.OperatorV1().Configs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Configs().Watch(ctx, options) + return client.OperatorV1().Configs().Watch(ctx, opts) }, }, client), &apioperatorv1.Config{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *configInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewConfigInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *configInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/console.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/console.go index 17752bfc4b..0233906c49 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/console.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/console.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type consoleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewConsoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredConsoleInformer(client, resyncPeriod, indexers, nil) + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredConsoleInformer constructs a new informer for Console type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredConsoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewConsoleInformerWithOptions constructs a new informer for Console type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConsoleInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "consoles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Consoles().List(context.Background(), options) + return client.OperatorV1().Consoles().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Consoles().Watch(context.Background(), options) + return client.OperatorV1().Consoles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Consoles().List(ctx, options) + return client.OperatorV1().Consoles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Consoles().Watch(ctx, options) + return client.OperatorV1().Consoles().Watch(ctx, opts) }, }, client), &apioperatorv1.Console{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *consoleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredConsoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewConsoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *consoleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/csisnapshotcontroller.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/csisnapshotcontroller.go index b6f7881bb6..59a719280e 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/csisnapshotcontroller.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/csisnapshotcontroller.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type cSISnapshotControllerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSISnapshotControllerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSISnapshotControllerInformer(client, resyncPeriod, indexers, nil) + return NewCSISnapshotControllerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSISnapshotControllerInformer constructs a new informer for CSISnapshotController type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSISnapshotControllerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSISnapshotControllerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSISnapshotControllerInformerWithOptions constructs a new informer for CSISnapshotController type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSISnapshotControllerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "csisnapshotcontrollers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CSISnapshotControllers().List(context.Background(), options) + return client.OperatorV1().CSISnapshotControllers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CSISnapshotControllers().Watch(context.Background(), options) + return client.OperatorV1().CSISnapshotControllers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CSISnapshotControllers().List(ctx, options) + return client.OperatorV1().CSISnapshotControllers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().CSISnapshotControllers().Watch(ctx, options) + return client.OperatorV1().CSISnapshotControllers().Watch(ctx, opts) }, }, client), &apioperatorv1.CSISnapshotController{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSISnapshotControllerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSISnapshotControllerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSISnapshotControllerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSISnapshotControllerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/dns.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/dns.go index 6459b2ae44..9a21310a52 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/dns.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/dns.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type dNSInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDNSInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDNSInformer(client, resyncPeriod, indexers, nil) + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDNSInformer constructs a new informer for DNS type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDNSInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDNSInformerWithOptions constructs a new informer for DNS type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDNSInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "dnss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().DNSes().List(context.Background(), options) + return client.OperatorV1().DNSes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().DNSes().Watch(context.Background(), options) + return client.OperatorV1().DNSes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().DNSes().List(ctx, options) + return client.OperatorV1().DNSes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().DNSes().Watch(ctx, options) + return client.OperatorV1().DNSes().Watch(ctx, opts) }, }, client), &apioperatorv1.DNS{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *dNSInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDNSInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDNSInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *dNSInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/etcd.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/etcd.go index d68ca3a1b5..b8481922ef 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/etcd.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/etcd.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type etcdInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEtcdInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEtcdInformer(client, resyncPeriod, indexers, nil) + return NewEtcdInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEtcdInformer constructs a new informer for Etcd type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEtcdInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEtcdInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEtcdInformerWithOptions constructs a new informer for Etcd type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEtcdInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "etcds"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Etcds().List(context.Background(), options) + return client.OperatorV1().Etcds().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Etcds().Watch(context.Background(), options) + return client.OperatorV1().Etcds().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Etcds().List(ctx, options) + return client.OperatorV1().Etcds().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Etcds().Watch(ctx, options) + return client.OperatorV1().Etcds().Watch(ctx, opts) }, }, client), &apioperatorv1.Etcd{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *etcdInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEtcdInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEtcdInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *etcdInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/ingresscontroller.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/ingresscontroller.go index 4fc4b106ac..423907ea46 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/ingresscontroller.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/ingresscontroller.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type ingressControllerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressControllerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressControllerInformer(client, namespace, resyncPeriod, indexers, nil) + return NewIngressControllerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressControllerInformer constructs a new informer for IngressController type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressControllerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressControllerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressControllerInformerWithOptions constructs a new informer for IngressController type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressControllerInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "ingresscontrollers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().IngressControllers(namespace).List(context.Background(), options) + return client.OperatorV1().IngressControllers(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().IngressControllers(namespace).Watch(context.Background(), options) + return client.OperatorV1().IngressControllers(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().IngressControllers(namespace).List(ctx, options) + return client.OperatorV1().IngressControllers(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().IngressControllers(namespace).Watch(ctx, options) + return client.OperatorV1().IngressControllers(namespace).Watch(ctx, opts) }, }, client), &apioperatorv1.IngressController{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressControllerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressControllerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressControllerInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressControllerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/insightsoperator.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/insightsoperator.go index c3a0fa480d..b7fb76bf19 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/insightsoperator.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/insightsoperator.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type insightsOperatorInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewInsightsOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredInsightsOperatorInformer(client, resyncPeriod, indexers, nil) + return NewInsightsOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredInsightsOperatorInformer constructs a new informer for InsightsOperator type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredInsightsOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewInsightsOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewInsightsOperatorInformerWithOptions constructs a new informer for InsightsOperator type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInsightsOperatorInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "insightsoperators"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().InsightsOperators().List(context.Background(), options) + return client.OperatorV1().InsightsOperators().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().InsightsOperators().Watch(context.Background(), options) + return client.OperatorV1().InsightsOperators().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().InsightsOperators().List(ctx, options) + return client.OperatorV1().InsightsOperators().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().InsightsOperators().Watch(ctx, options) + return client.OperatorV1().InsightsOperators().Watch(ctx, opts) }, }, client), &apioperatorv1.InsightsOperator{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *insightsOperatorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredInsightsOperatorInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewInsightsOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *insightsOperatorInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubeapiserver.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubeapiserver.go index 07991798e1..3c2ec8a91b 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubeapiserver.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubeapiserver.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type kubeAPIServerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewKubeAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredKubeAPIServerInformer(client, resyncPeriod, indexers, nil) + return NewKubeAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredKubeAPIServerInformer constructs a new informer for KubeAPIServer type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredKubeAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewKubeAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewKubeAPIServerInformerWithOptions constructs a new informer for KubeAPIServer type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKubeAPIServerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "kubeapiservers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeAPIServers().List(context.Background(), options) + return client.OperatorV1().KubeAPIServers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeAPIServers().Watch(context.Background(), options) + return client.OperatorV1().KubeAPIServers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeAPIServers().List(ctx, options) + return client.OperatorV1().KubeAPIServers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeAPIServers().Watch(ctx, options) + return client.OperatorV1().KubeAPIServers().Watch(ctx, opts) }, }, client), &apioperatorv1.KubeAPIServer{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *kubeAPIServerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredKubeAPIServerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewKubeAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *kubeAPIServerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubecontrollermanager.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubecontrollermanager.go index d876f60c5d..b872d2cb00 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubecontrollermanager.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubecontrollermanager.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type kubeControllerManagerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewKubeControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredKubeControllerManagerInformer(client, resyncPeriod, indexers, nil) + return NewKubeControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredKubeControllerManagerInformer constructs a new informer for KubeControllerManager type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredKubeControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewKubeControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewKubeControllerManagerInformerWithOptions constructs a new informer for KubeControllerManager type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKubeControllerManagerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "kubecontrollermanagers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeControllerManagers().List(context.Background(), options) + return client.OperatorV1().KubeControllerManagers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeControllerManagers().Watch(context.Background(), options) + return client.OperatorV1().KubeControllerManagers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeControllerManagers().List(ctx, options) + return client.OperatorV1().KubeControllerManagers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeControllerManagers().Watch(ctx, options) + return client.OperatorV1().KubeControllerManagers().Watch(ctx, opts) }, }, client), &apioperatorv1.KubeControllerManager{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *kubeControllerManagerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredKubeControllerManagerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewKubeControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *kubeControllerManagerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubescheduler.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubescheduler.go index f8a455a175..a882c19c07 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubescheduler.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubescheduler.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type kubeSchedulerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewKubeSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredKubeSchedulerInformer(client, resyncPeriod, indexers, nil) + return NewKubeSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredKubeSchedulerInformer constructs a new informer for KubeScheduler type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredKubeSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewKubeSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewKubeSchedulerInformerWithOptions constructs a new informer for KubeScheduler type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKubeSchedulerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "kubeschedulers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeSchedulers().List(context.Background(), options) + return client.OperatorV1().KubeSchedulers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeSchedulers().Watch(context.Background(), options) + return client.OperatorV1().KubeSchedulers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeSchedulers().List(ctx, options) + return client.OperatorV1().KubeSchedulers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeSchedulers().Watch(ctx, options) + return client.OperatorV1().KubeSchedulers().Watch(ctx, opts) }, }, client), &apioperatorv1.KubeScheduler{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *kubeSchedulerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredKubeSchedulerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewKubeSchedulerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *kubeSchedulerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubestorageversionmigrator.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubestorageversionmigrator.go index fdd3b27a8e..55b40f7494 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubestorageversionmigrator.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/kubestorageversionmigrator.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type kubeStorageVersionMigratorInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewKubeStorageVersionMigratorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredKubeStorageVersionMigratorInformer(client, resyncPeriod, indexers, nil) + return NewKubeStorageVersionMigratorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredKubeStorageVersionMigratorInformer constructs a new informer for KubeStorageVersionMigrator type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredKubeStorageVersionMigratorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewKubeStorageVersionMigratorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewKubeStorageVersionMigratorInformerWithOptions constructs a new informer for KubeStorageVersionMigrator type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewKubeStorageVersionMigratorInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "kubestorageversionmigrators"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeStorageVersionMigrators().List(context.Background(), options) + return client.OperatorV1().KubeStorageVersionMigrators().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeStorageVersionMigrators().Watch(context.Background(), options) + return client.OperatorV1().KubeStorageVersionMigrators().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeStorageVersionMigrators().List(ctx, options) + return client.OperatorV1().KubeStorageVersionMigrators().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().KubeStorageVersionMigrators().Watch(ctx, options) + return client.OperatorV1().KubeStorageVersionMigrators().Watch(ctx, opts) }, }, client), &apioperatorv1.KubeStorageVersionMigrator{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *kubeStorageVersionMigratorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredKubeStorageVersionMigratorInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewKubeStorageVersionMigratorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *kubeStorageVersionMigratorInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/machineconfiguration.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/machineconfiguration.go index a88cdc8dd0..3895f81327 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/machineconfiguration.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/machineconfiguration.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type machineConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMachineConfigurationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMachineConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewMachineConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMachineConfigurationInformer constructs a new informer for MachineConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMachineConfigurationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMachineConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMachineConfigurationInformerWithOptions constructs a new informer for MachineConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMachineConfigurationInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "machineconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().MachineConfigurations().List(context.Background(), options) + return client.OperatorV1().MachineConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().MachineConfigurations().Watch(context.Background(), options) + return client.OperatorV1().MachineConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().MachineConfigurations().List(ctx, options) + return client.OperatorV1().MachineConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().MachineConfigurations().Watch(ctx, options) + return client.OperatorV1().MachineConfigurations().Watch(ctx, opts) }, }, client), &apioperatorv1.MachineConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *machineConfigurationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMachineConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMachineConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *machineConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/network.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/network.go index a076e969ac..d26b9e2e5b 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/network.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/network.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type networkInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNetworkInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNetworkInformer(client, resyncPeriod, indexers, nil) + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNetworkInformer constructs a new informer for Network type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNetworkInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNetworkInformerWithOptions constructs a new informer for Network type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "networks"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Networks().List(context.Background(), options) + return client.OperatorV1().Networks().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Networks().Watch(context.Background(), options) + return client.OperatorV1().Networks().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Networks().List(ctx, options) + return client.OperatorV1().Networks().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Networks().Watch(ctx, options) + return client.OperatorV1().Networks().Watch(ctx, opts) }, }, client), &apioperatorv1.Network{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *networkInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNetworkInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNetworkInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *networkInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/olm.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/olm.go index 0e3ab4c07f..ad2a46c083 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/olm.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/olm.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type oLMInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOLMInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOLMInformer(client, resyncPeriod, indexers, nil) + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOLMInformer constructs a new informer for OLM type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOLMInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOLMInformerWithOptions constructs a new informer for OLM type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOLMInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "olms"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OLMs().List(context.Background(), options) + return client.OperatorV1().OLMs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OLMs().Watch(context.Background(), options) + return client.OperatorV1().OLMs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OLMs().List(ctx, options) + return client.OperatorV1().OLMs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OLMs().Watch(ctx, options) + return client.OperatorV1().OLMs().Watch(ctx, opts) }, }, client), &apioperatorv1.OLM{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *oLMInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOLMInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *oLMInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftapiserver.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftapiserver.go index 00d95d1ff5..e87994a048 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftapiserver.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftapiserver.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type openShiftAPIServerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOpenShiftAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOpenShiftAPIServerInformer(client, resyncPeriod, indexers, nil) + return NewOpenShiftAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOpenShiftAPIServerInformer constructs a new informer for OpenShiftAPIServer type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOpenShiftAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOpenShiftAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOpenShiftAPIServerInformerWithOptions constructs a new informer for OpenShiftAPIServer type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOpenShiftAPIServerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "openshiftapiservers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftAPIServers().List(context.Background(), options) + return client.OperatorV1().OpenShiftAPIServers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftAPIServers().Watch(context.Background(), options) + return client.OperatorV1().OpenShiftAPIServers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftAPIServers().List(ctx, options) + return client.OperatorV1().OpenShiftAPIServers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftAPIServers().Watch(ctx, options) + return client.OperatorV1().OpenShiftAPIServers().Watch(ctx, opts) }, }, client), &apioperatorv1.OpenShiftAPIServer{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *openShiftAPIServerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOpenShiftAPIServerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOpenShiftAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *openShiftAPIServerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftcontrollermanager.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftcontrollermanager.go index f94c4e7d1b..6d6221764e 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftcontrollermanager.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/openshiftcontrollermanager.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type openShiftControllerManagerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOpenShiftControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOpenShiftControllerManagerInformer(client, resyncPeriod, indexers, nil) + return NewOpenShiftControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOpenShiftControllerManagerInformer constructs a new informer for OpenShiftControllerManager type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOpenShiftControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOpenShiftControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOpenShiftControllerManagerInformerWithOptions constructs a new informer for OpenShiftControllerManager type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOpenShiftControllerManagerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "openshiftcontrollermanagers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftControllerManagers().List(context.Background(), options) + return client.OperatorV1().OpenShiftControllerManagers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftControllerManagers().Watch(context.Background(), options) + return client.OperatorV1().OpenShiftControllerManagers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftControllerManagers().List(ctx, options) + return client.OperatorV1().OpenShiftControllerManagers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().OpenShiftControllerManagers().Watch(ctx, options) + return client.OperatorV1().OpenShiftControllerManagers().Watch(ctx, opts) }, }, client), &apioperatorv1.OpenShiftControllerManager{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *openShiftControllerManagerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOpenShiftControllerManagerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOpenShiftControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *openShiftControllerManagerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/serviceca.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/serviceca.go index e3f8870298..bd11c17ba4 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/serviceca.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/serviceca.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type serviceCAInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceCAInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceCAInformer(client, resyncPeriod, indexers, nil) + return NewServiceCAInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceCAInformer constructs a new informer for ServiceCA type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceCAInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceCAInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceCAInformerWithOptions constructs a new informer for ServiceCA type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceCAInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "servicecas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCAs().List(context.Background(), options) + return client.OperatorV1().ServiceCAs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCAs().Watch(context.Background(), options) + return client.OperatorV1().ServiceCAs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCAs().List(ctx, options) + return client.OperatorV1().ServiceCAs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCAs().Watch(ctx, options) + return client.OperatorV1().ServiceCAs().Watch(ctx, opts) }, }, client), &apioperatorv1.ServiceCA{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceCAInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceCAInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceCAInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceCAInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogapiserver.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogapiserver.go index 98b0722d48..b99cbca68f 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogapiserver.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogapiserver.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type serviceCatalogAPIServerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceCatalogAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceCatalogAPIServerInformer(client, resyncPeriod, indexers, nil) + return NewServiceCatalogAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceCatalogAPIServerInformer constructs a new informer for ServiceCatalogAPIServer type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceCatalogAPIServerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceCatalogAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceCatalogAPIServerInformerWithOptions constructs a new informer for ServiceCatalogAPIServer type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceCatalogAPIServerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "servicecatalogapiservers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogAPIServers().List(context.Background(), options) + return client.OperatorV1().ServiceCatalogAPIServers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogAPIServers().Watch(context.Background(), options) + return client.OperatorV1().ServiceCatalogAPIServers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogAPIServers().List(ctx, options) + return client.OperatorV1().ServiceCatalogAPIServers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogAPIServers().Watch(ctx, options) + return client.OperatorV1().ServiceCatalogAPIServers().Watch(ctx, opts) }, }, client), &apioperatorv1.ServiceCatalogAPIServer{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceCatalogAPIServerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceCatalogAPIServerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceCatalogAPIServerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceCatalogAPIServerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogcontrollermanager.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogcontrollermanager.go index a80ad9c33c..049e099f75 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogcontrollermanager.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/servicecatalogcontrollermanager.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type serviceCatalogControllerManagerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceCatalogControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceCatalogControllerManagerInformer(client, resyncPeriod, indexers, nil) + return NewServiceCatalogControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceCatalogControllerManagerInformer constructs a new informer for ServiceCatalogControllerManager type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceCatalogControllerManagerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceCatalogControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceCatalogControllerManagerInformerWithOptions constructs a new informer for ServiceCatalogControllerManager type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceCatalogControllerManagerInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "servicecatalogcontrollermanagers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogControllerManagers().List(context.Background(), options) + return client.OperatorV1().ServiceCatalogControllerManagers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogControllerManagers().Watch(context.Background(), options) + return client.OperatorV1().ServiceCatalogControllerManagers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogControllerManagers().List(ctx, options) + return client.OperatorV1().ServiceCatalogControllerManagers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().ServiceCatalogControllerManagers().Watch(ctx, options) + return client.OperatorV1().ServiceCatalogControllerManagers().Watch(ctx, opts) }, }, client), &apioperatorv1.ServiceCatalogControllerManager{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceCatalogControllerManagerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceCatalogControllerManagerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceCatalogControllerManagerInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceCatalogControllerManagerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/storage.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/storage.go index 570fb4ebca..f11dc38096 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/storage.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1/storage.go @@ -12,6 +12,7 @@ import ( operatorv1 "github.com/openshift/client-go/operator/listers/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type storageInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStorageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageInformer(client, resyncPeriod, indexers, nil) + return NewStorageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStorageInformer constructs a new informer for Storage type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStorageInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStorageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStorageInformerWithOptions constructs a new informer for Storage type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1", Resource: "storages"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Storages().List(context.Background(), options) + return client.OperatorV1().Storages().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Storages().Watch(context.Background(), options) + return client.OperatorV1().Storages().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Storages().List(ctx, options) + return client.OperatorV1().Storages().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1().Storages().Watch(ctx, options) + return client.OperatorV1().Storages().Watch(ctx, opts) }, }, client), &apioperatorv1.Storage{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *storageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStorageInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *storageInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterapi.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterapi.go index 2b61949c1b..b5accc851d 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterapi.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterapi.go @@ -12,6 +12,7 @@ import ( operatorv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterAPIInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterAPIInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterAPIInformer(client, resyncPeriod, indexers, nil) + return NewClusterAPIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterAPIInformer constructs a new informer for ClusterAPI type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterAPIInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterAPIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterAPIInformerWithOptions constructs a new informer for ClusterAPI type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterAPIInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1alpha1", Resource: "clusterapis"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterAPIs().List(context.Background(), options) + return client.OperatorV1alpha1().ClusterAPIs().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterAPIs().Watch(context.Background(), options) + return client.OperatorV1alpha1().ClusterAPIs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterAPIs().List(ctx, options) + return client.OperatorV1alpha1().ClusterAPIs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterAPIs().Watch(ctx, options) + return client.OperatorV1alpha1().ClusterAPIs().Watch(ctx, opts) }, }, client), &apioperatorv1alpha1.ClusterAPI{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterAPIInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterAPIInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterAPIInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterAPIInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterversionoperator.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterversionoperator.go index 001b92c885..19b14b84fa 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterversionoperator.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/clusterversionoperator.go @@ -12,6 +12,7 @@ import ( operatorv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type clusterVersionOperatorInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterVersionOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterVersionOperatorInformer(client, resyncPeriod, indexers, nil) + return NewClusterVersionOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterVersionOperatorInformer constructs a new informer for ClusterVersionOperator type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterVersionOperatorInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterVersionOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterVersionOperatorInformerWithOptions constructs a new informer for ClusterVersionOperator type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterVersionOperatorInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1alpha1", Resource: "clusterversionoperators"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterVersionOperators().List(context.Background(), options) + return client.OperatorV1alpha1().ClusterVersionOperators().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterVersionOperators().Watch(context.Background(), options) + return client.OperatorV1alpha1().ClusterVersionOperators().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterVersionOperators().List(ctx, options) + return client.OperatorV1alpha1().ClusterVersionOperators().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ClusterVersionOperators().Watch(ctx, options) + return client.OperatorV1alpha1().ClusterVersionOperators().Watch(ctx, opts) }, }, client), &apioperatorv1alpha1.ClusterVersionOperator{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterVersionOperatorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterVersionOperatorInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterVersionOperatorInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterVersionOperatorInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/etcdbackup.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/etcdbackup.go index d7094f67d8..3a00de22eb 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/etcdbackup.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/etcdbackup.go @@ -12,6 +12,7 @@ import ( operatorv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type etcdBackupInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEtcdBackupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEtcdBackupInformer(client, resyncPeriod, indexers, nil) + return NewEtcdBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEtcdBackupInformer constructs a new informer for EtcdBackup type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEtcdBackupInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEtcdBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEtcdBackupInformerWithOptions constructs a new informer for EtcdBackup type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEtcdBackupInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1alpha1", Resource: "etcdbackups"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().EtcdBackups().List(context.Background(), options) + return client.OperatorV1alpha1().EtcdBackups().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().EtcdBackups().Watch(context.Background(), options) + return client.OperatorV1alpha1().EtcdBackups().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().EtcdBackups().List(ctx, options) + return client.OperatorV1alpha1().EtcdBackups().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().EtcdBackups().Watch(ctx, options) + return client.OperatorV1alpha1().EtcdBackups().Watch(ctx, opts) }, }, client), &apioperatorv1alpha1.EtcdBackup{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *etcdBackupInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEtcdBackupInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEtcdBackupInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *etcdBackupInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/imagecontentsourcepolicy.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/imagecontentsourcepolicy.go index ccdac78ab9..d3d89018bc 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/imagecontentsourcepolicy.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/imagecontentsourcepolicy.go @@ -12,6 +12,7 @@ import ( operatorv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type imageContentSourcePolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewImageContentSourcePolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredImageContentSourcePolicyInformer(client, resyncPeriod, indexers, nil) + return NewImageContentSourcePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredImageContentSourcePolicyInformer constructs a new informer for ImageContentSourcePolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredImageContentSourcePolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewImageContentSourcePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewImageContentSourcePolicyInformerWithOptions constructs a new informer for ImageContentSourcePolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewImageContentSourcePolicyInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1alpha1", Resource: "imagecontentsourcepolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ImageContentSourcePolicies().List(context.Background(), options) + return client.OperatorV1alpha1().ImageContentSourcePolicies().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ImageContentSourcePolicies().Watch(context.Background(), options) + return client.OperatorV1alpha1().ImageContentSourcePolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ImageContentSourcePolicies().List(ctx, options) + return client.OperatorV1alpha1().ImageContentSourcePolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().ImageContentSourcePolicies().Watch(ctx, options) + return client.OperatorV1alpha1().ImageContentSourcePolicies().Watch(ctx, opts) }, }, client), &apioperatorv1alpha1.ImageContentSourcePolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *imageContentSourcePolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredImageContentSourcePolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewImageContentSourcePolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *imageContentSourcePolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/olm.go b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/olm.go index 2c4da12db0..cb4a0cb01f 100644 --- a/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/olm.go +++ b/vendor/github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1/olm.go @@ -12,6 +12,7 @@ import ( operatorv1alpha1 "github.com/openshift/client-go/operator/listers/operator/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -32,48 +33,61 @@ type oLMInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewOLMInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredOLMInformer(client, resyncPeriod, indexers, nil) + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredOLMInformer constructs a new informer for OLM type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredOLMInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewOLMInformerWithOptions constructs a new informer for OLM type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewOLMInformerWithOptions(client versioned.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "operator.openshift.io", Version: "v1alpha1", Resource: "olms"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().OLMs().List(context.Background(), options) + return client.OperatorV1alpha1().OLMs().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().OLMs().Watch(context.Background(), options) + return client.OperatorV1alpha1().OLMs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().OLMs().List(ctx, options) + return client.OperatorV1alpha1().OLMs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.OperatorV1alpha1().OLMs().Watch(ctx, options) + return client.OperatorV1alpha1().OLMs().Watch(ctx, opts) }, }, client), &apioperatorv1alpha1.OLM{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *oLMInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredOLMInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewOLMInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *oLMInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/client-go/route/clientset/versioned/fake/clientset_generated.go b/vendor/github.com/openshift/client-go/route/clientset/versioned/fake/clientset_generated.go index bf285a7272..10ac867e54 100644 --- a/vendor/github.com/openshift/client-go/route/clientset/versioned/fake/clientset_generated.go +++ b/vendor/github.com/openshift/client-go/route/clientset/versioned/fake/clientset_generated.go @@ -19,10 +19,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -68,7 +64,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -83,6 +79,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, diff --git a/vendor/github.com/openshift/client-go/route/informers/externalversions/factory.go b/vendor/github.com/openshift/client-go/route/informers/externalversions/factory.go index 9897b77885..7ffbc540ae 100644 --- a/vendor/github.com/openshift/client-go/route/informers/externalversions/factory.go +++ b/vendor/github.com/openshift/client-go/route/informers/externalversions/factory.go @@ -3,6 +3,7 @@ package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -13,6 +14,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -27,6 +29,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -73,6 +76,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -107,6 +125,10 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -116,15 +138,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -137,9 +153,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -153,10 +175,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -178,7 +221,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -195,27 +240,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -230,8 +294,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/github.com/openshift/client-go/route/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/github.com/openshift/client-go/route/informers/externalversions/internalinterfaces/factory_interfaces.go index 1f807bab67..e971aac7a7 100644 --- a/vendor/github.com/openshift/client-go/route/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/github.com/openshift/client-go/route/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -18,7 +18,26 @@ type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/github.com/openshift/client-go/route/informers/externalversions/route/v1/route.go b/vendor/github.com/openshift/client-go/route/informers/externalversions/route/v1/route.go index f6b2e2065c..66432c73a8 100644 --- a/vendor/github.com/openshift/client-go/route/informers/externalversions/route/v1/route.go +++ b/vendor/github.com/openshift/client-go/route/informers/externalversions/route/v1/route.go @@ -12,6 +12,7 @@ import ( routev1 "github.com/openshift/client-go/route/listers/route/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -33,48 +34,61 @@ type routeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRouteInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRouteInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRouteInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRouteInformer constructs a new informer for Route type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRouteInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRouteInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRouteInformerWithOptions constructs a new informer for Route type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRouteInformerWithOptions(client versioned.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "route.openshift.io", Version: "v1", Resource: "routes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RouteV1().Routes(namespace).List(context.Background(), options) + return client.RouteV1().Routes(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RouteV1().Routes(namespace).Watch(context.Background(), options) + return client.RouteV1().Routes(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RouteV1().Routes(namespace).List(ctx, options) + return client.RouteV1().Routes(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RouteV1().Routes(namespace).Watch(ctx, options) + return client.RouteV1().Routes(namespace).Watch(ctx, opts) }, }, client), &apiroutev1.Route{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *routeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRouteInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRouteInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *routeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index be0337b900..c5ab62e6b7 100644 --- a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -34,17 +34,29 @@ import ( configv1 "github.com/openshift/api/config/v1" ) -// TLS versions that are known to golang. Go 1.13 adds support for -// TLS 1.3 that's opt-out with a build flag. -var versions = map[string]uint16{ +// TLS configuration +// +// The OpenShift API defines TLS profiles using OpenSSL cipher suite names. +// Go's crypto/tls uses IANA-standard cipher suite names (which happen to +// match the Go constant names). This package bridges the two naming schemes: +// OpenSSLToIANACipherSuites translates API-level OpenSSL names into the IANA +// names that Go understands, silently dropping any cipher that Go's crypto/tls +// cannot negotiate. This silent narrowing is by design: Go literally cannot +// serve those ciphers, so listing them would be misleading. + +// goTLSVersions lists all TLS versions that Go's crypto/tls can negotiate. +// Kept in sync with the crypto/tls package by TestConstantMaps. +var goTLSVersions = map[string]uint16{ "VersionTLS10": tls.VersionTLS10, "VersionTLS11": tls.VersionTLS11, "VersionTLS12": tls.VersionTLS12, "VersionTLS13": tls.VersionTLS13, } -// TLS versions that are enabled. -var supportedVersions = map[string]uint16{ +// enabledTLSVersions is the subset of goTLSVersions that OpenShift allows +// in TLS configurations. Remove an entry here (not from goTLSVersions) to +// phase out a version while still being able to parse legacy references. +var enabledTLSVersions = map[string]uint16{ "VersionTLS10": tls.VersionTLS10, "VersionTLS11": tls.VersionTLS11, "VersionTLS12": tls.VersionTLS12, @@ -54,7 +66,7 @@ var supportedVersions = map[string]uint16{ // TLSVersionToNameOrDie given a tls version as an int, return its readable name func TLSVersionToNameOrDie(intVal uint16) string { matches := []string{} - for key, version := range versions { + for key, version := range goTLSVersions { if version == intVal { matches = append(matches, key) } @@ -73,7 +85,7 @@ func TLSVersion(versionName string) (uint16, error) { if len(versionName) == 0 { return DefaultTLSVersion(), nil } - if version, ok := versions[versionName]; ok { + if version, ok := goTLSVersions[versionName]; ok { return version, nil } return 0, fmt.Errorf("unknown tls version %q", versionName) @@ -86,20 +98,22 @@ func TLSVersionOrDie(versionName string) uint16 { return version } -// TLS versions that are known to golang, but may not necessarily be enabled. +// GolangTLSVersions returns all TLS versions known to this Go build. +// +// Deprecated: Use ValidTLSVersions instead. func GolangTLSVersions() []string { supported := []string{} - for k := range versions { + for k := range goTLSVersions { supported = append(supported, k) } sort.Strings(supported) return supported } -// Returns the build enabled TLS versions. +// ValidTLSVersions returns the TLS versions that OpenShift allows in configurations. func ValidTLSVersions() []string { validVersions := []string{} - for k := range supportedVersions { + for k := range enabledTLSVersions { validVersions = append(validVersions, k) } sort.Strings(validVersions) @@ -112,7 +126,9 @@ func DefaultTLSVersion() uint16 { return tls.VersionTLS12 } -var ciphers = map[string]uint16{ +// goCipherSuites lists all cipher suites recognized by Go's crypto/tls, keyed +// by IANA name. Kept in sync with the crypto/tls package by TestConstantMaps. +var goCipherSuites = map[string]uint16{ "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, @@ -142,14 +158,13 @@ var ciphers = map[string]uint16{ "TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256, } -// openSSLToIANACiphersMap maps OpenSSL cipher suite names to IANA names +// openSSLToIANACiphers maps OpenSSL cipher suite names to IANA names for +// every cipher that Go's crypto/tls can negotiate. // Ref: https://www.iana.org/assignments/tls-parameters/tls-parameters.xml -// This must hold a 1:1 mapping for each OpenSSL cipher defined in openshift/api TLSSecurityProfiles, -// so it can be used to translate OpenSSL ciphers to IANA ciphers, which is what go's crypto/tls understands. -// Ciphers in this map must also be compatible with go's crypto/tls ciphers: -// https://github.com/golang/go/blob/d4febb45179fa99ee1d5783bcb693ed7ba14115c/src/crypto/tls/cipher_suites.go#L682-L724 -var openSSLToIANACiphersMap = map[string]string{ - // TLS 1.3 ciphers - not configurable in go 1.13, all of them are used in TLSv1.3 flows +// Ciphers defined in the API but absent from Go are tracked in +// ciphersUnsupportedByGo (below) so tests detect when Go gains support. +var openSSLToIANACiphers = map[string]string{ + // TLS 1.3 ciphers - always negotiated by Go; not individually configurable. "TLS_AES_128_GCM_SHA256": "TLS_AES_128_GCM_SHA256", // 0x13,0x01 "TLS_AES_256_GCM_SHA384": "TLS_AES_256_GCM_SHA384", // 0x13,0x02 "TLS_CHACHA20_POLY1305_SHA256": "TLS_CHACHA20_POLY1305_SHA256", // 0x13,0x03 @@ -167,20 +182,8 @@ var openSSLToIANACiphersMap = map[string]string{ "AES256-GCM-SHA384": "TLS_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9D "AES128-SHA256": "TLS_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x3C - // Go's crypto/tls does not support CBC mode and DHE ciphers, so we don't want to include them here. - // See: - // - https://github.com/golang/go/issues/26652 - // - https://github.com/golang/go/issues/7758 - // - https://redhat-internal.slack.com/archives/C098FU5MRAB/p1770309657097269 - // - // "ECDHE-ECDSA-AES256-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", // 0xC0,0x24 - // "ECDHE-RSA-AES256-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", // 0xC0,0x28 - // "AES256-SHA256": "TLS_RSA_WITH_AES_256_CBC_SHA256", // 0x00,0x3D - // "DHE-RSA-AES128-GCM-SHA256": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", // 0x00,0x9E - // "DHE-RSA-AES256-GCM-SHA384": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9F - // "DHE-RSA-CHACHA20-POLY1305": "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xAA - // "DHE-RSA-AES128-SHA256": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x67 - // "DHE-RSA-AES256-SHA256": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", // 0x00,0x6B + // Ciphers defined in the API but not supported by Go are listed in + // ciphersUnsupportedByGo below. // TLS 1 "ECDHE-ECDSA-AES128-SHA": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", // 0xC0,0x09 @@ -195,6 +198,19 @@ var openSSLToIANACiphersMap = map[string]string{ "ECDHE-RSA-DES-CBC3-SHA": "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", // 0xC0,0x12 } +// ciphersUnsupportedByGo lists cipher suites that are defined in the OpenShift API +// TLS profiles (from the Mozilla guidelines) but are not supported by Go's crypto/tls. +// These are intentionally excluded from openSSLToIANACiphers and silently filtered +// out during profile translation. The IANA names come from the IANA TLS Cipher Suite +// Registry (https://www.iana.org/assignments/tls-parameters/) and are retained so +// TestCiphersUnsupportedByGoAreActuallyUnsupported can detect if a future Go +// release adds support. +var ciphersUnsupportedByGo = map[string]string{ + "ECDHE-ECDSA-AES256-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "ECDHE-RSA-AES256-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "AES256-SHA256": "TLS_RSA_WITH_AES_256_CBC_SHA256", +} + // CipherSuitesToNamesOrDie given a list of cipher suites as ints, return their readable names func CipherSuitesToNamesOrDie(intVals []uint16) []string { ret := []string{} @@ -219,7 +235,7 @@ func CipherSuiteToNameOrDie(intVal uint16) string { } matches := []string{} - for key, version := range ciphers { + for key, version := range goCipherSuites { if version == intVal { matches = append(matches, key) } @@ -235,7 +251,7 @@ func CipherSuiteToNameOrDie(intVal uint16) string { } func CipherSuite(cipherName string) (uint16, error) { - if cipher, ok := ciphers[cipherName]; ok { + if cipher, ok := goCipherSuites[cipherName]; ok { return cipher, nil } @@ -258,7 +274,7 @@ func CipherSuitesOrDie(cipherNames []string) []uint16 { } func ValidCipherSuites() []string { validCipherSuites := []string{} - for k := range ciphers { + for k := range goCipherSuites { validCipherSuites = append(validCipherSuites, k) } sort.Strings(validCipherSuites) @@ -323,14 +339,17 @@ func SecureTLSConfig(config *tls.Config) *tls.Config { // OpenSSLToIANACipherSuites maps input OpenSSL Cipher Suite names to their // IANA counterparts. -// Unknown ciphers are left out. +// Ciphers that Go's crypto/tls cannot negotiate are silently dropped and +// logged at V(4). func OpenSSLToIANACipherSuites(ciphers []string) []string { ianaCiphers := make([]string, 0, len(ciphers)) for _, c := range ciphers { - ianaCipher, found := openSSLToIANACiphersMap[c] + ianaCipher, found := openSSLToIANACiphers[c] if found { ianaCiphers = append(ianaCiphers, ianaCipher) + } else { + klog.V(4).Infof("Dropping cipher %q: not supported by Go's crypto/tls", c) } } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/client_cert_rotation_controller.go b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/client_cert_rotation_controller.go index dbacb066e9..efb4d3c954 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/client_cert_rotation_controller.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/client_cert_rotation_controller.go @@ -126,7 +126,7 @@ func (c CertRotationController) Sync(ctx context.Context, syncCtx factory.SyncCo return updateErr } if updated && syncErr != nil { - syncCtx.Recorder().Warningf("RotationError", syncErr.Error()) + syncCtx.Recorder().Warningf("RotationError", "%s", syncErr.Error()) } return syncErr diff --git a/vendor/github.com/openshift/library-go/pkg/operator/v1helpers/test_helpers.go b/vendor/github.com/openshift/library-go/pkg/operator/v1helpers/test_helpers.go index ec67f6dd97..66a7b6d89c 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/v1helpers/test_helpers.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/v1helpers/test_helpers.go @@ -24,10 +24,18 @@ import ( // NewFakeSharedIndexInformer returns a fake shared index informer, suitable to use in static pod controller unit tests. func NewFakeSharedIndexInformer() cache.SharedIndexInformer { - return &fakeSharedIndexInformer{} + return &fakeSharedIndexInformer{synced: newFakeSyncedChan()} } -type fakeSharedIndexInformer struct{} +type fakeSharedIndexInformer struct { + synced chan struct{} +} + +func newFakeSyncedChan() chan struct{} { + ch := make(chan struct{}) + close(ch) + return ch +} func (i fakeSharedIndexInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) { return nil, nil @@ -65,8 +73,29 @@ func (fakeSharedIndexInformer) RunWithContext(ctx context.Context) { panic("implement me") } -func (fakeSharedIndexInformer) HasSynced() bool { - return true +func (f fakeSharedIndexInformer) HasSynced() bool { + select { + case <-f.synced: + return true + default: + return false + } +} + +type fakeSharedIndexInformerDone struct { + synced chan struct{} +} + +func (fd *fakeSharedIndexInformerDone) Name() string { + return "FakeSharedIndexInformer" +} + +func (fd *fakeSharedIndexInformerDone) Done() <-chan struct{} { + return fd.synced +} + +func (f fakeSharedIndexInformer) HasSyncedChecker() cache.DoneChecker { + return &fakeSharedIndexInformerDone{synced: f.synced} } func (fakeSharedIndexInformer) LastSyncResourceVersion() string { @@ -118,7 +147,7 @@ type fakeStaticPodOperatorClient struct { } func (c *fakeStaticPodOperatorClient) Informer() cache.SharedIndexInformer { - return &fakeSharedIndexInformer{} + return NewFakeSharedIndexInformer() } func (c *fakeStaticPodOperatorClient) GetObjectMeta() (*metav1.ObjectMeta, error) { @@ -301,7 +330,7 @@ type fakeOperatorClient struct { } func (c *fakeOperatorClient) Informer() cache.SharedIndexInformer { - return &fakeSharedIndexInformer{} + return NewFakeSharedIndexInformer() } func (c *fakeOperatorClient) GetObjectMeta() (*metav1.ObjectMeta, error) { diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index 7b762370e2..8f8dc65d38 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -220,7 +220,7 @@ func extractSamples(f *dto.MetricFamily, o *DecodeOptions) (model.Vector, error) return extractSummary(o, f), nil case dto.MetricType_UNTYPED: return extractUntyped(o, f), nil - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: return extractHistogram(o, f), nil } return nil, fmt.Errorf("expfmt.extractSamples: unknown metric family type %v", f.GetType()) @@ -403,9 +403,13 @@ func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector { infSeen = true } + v := q.GetCumulativeCountFloat() + if v <= 0 { + v = float64(q.GetCumulativeCount()) + } samples = append(samples, &model.Sample{ Metric: model.Metric(lset), - Value: model.SampleValue(q.GetCumulativeCount()), + Value: model.SampleValue(v), Timestamp: timestamp, }) } @@ -428,9 +432,13 @@ func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector { } lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") + v := m.Histogram.GetSampleCountFloat() + if v <= 0 { + v = float64(m.Histogram.GetSampleCount()) + } count := &model.Sample{ Metric: model.Metric(lset), - Value: model.SampleValue(m.Histogram.GetSampleCount()), + Value: model.SampleValue(v), Timestamp: timestamp, } samples = append(samples, count) diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go index c34c7de432..4e4c13e724 100644 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -45,6 +45,7 @@ const ( // The Content-Type values for the different wire protocols. Do not do direct // comparisons to these constants, instead use the comparison functions. + // // Deprecated: Use expfmt.NewFormat(expfmt.TypeUnknown) instead. FmtUnknown Format = `` // Deprecated: Use expfmt.NewFormat(expfmt.TypeTextPlain) instead. diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index 0290f6abc4..872c0c15b4 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -13,7 +13,6 @@ // Build only when actually fuzzing //go:build gofuzz -// +build gofuzz package expfmt diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go index 8dbf6d04ed..21b93bca36 100644 --- a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go @@ -160,38 +160,38 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E n, err = w.WriteString("# HELP ") written += n if err != nil { - return + return written, err } n, err = writeName(w, compliantName) written += n if err != nil { - return + return written, err } err = w.WriteByte(' ') written++ if err != nil { - return + return written, err } n, err = writeEscapedString(w, *in.Help, true) written += n if err != nil { - return + return written, err } err = w.WriteByte('\n') written++ if err != nil { - return + return written, err } } n, err = w.WriteString("# TYPE ") written += n if err != nil { - return + return written, err } n, err = writeName(w, compliantName) written += n if err != nil { - return + return written, err } switch metricType { case dto.MetricType_COUNTER: @@ -208,39 +208,41 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E n, err = w.WriteString(" unknown\n") case dto.MetricType_HISTOGRAM: n, err = w.WriteString(" histogram\n") + case dto.MetricType_GAUGE_HISTOGRAM: + n, err = w.WriteString(" gaugehistogram\n") default: return written, fmt.Errorf("unknown metric type %s", metricType.String()) } written += n if err != nil { - return + return written, err } if toOM.withUnit && in.Unit != nil { n, err = w.WriteString("# UNIT ") written += n if err != nil { - return + return written, err } n, err = writeName(w, compliantName) written += n if err != nil { - return + return written, err } err = w.WriteByte(' ') written++ if err != nil { - return + return written, err } n, err = writeEscapedString(w, *in.Unit, true) written += n if err != nil { - return + return written, err } err = w.WriteByte('\n') written++ if err != nil { - return + return written, err } } @@ -304,7 +306,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E ) written += n if err != nil { - return + return written, err } } n, err = writeOpenMetricsSample( @@ -314,7 +316,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E ) written += n if err != nil { - return + return written, err } n, err = writeOpenMetricsSample( w, compliantName, "_count", metric, "", 0, @@ -325,7 +327,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E createdTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, "", metric, "", 0, metric.Summary.GetCreatedTimestamp()) n += createdTsBytesWritten } - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: if metric.Histogram == nil { return written, fmt.Errorf( "expected histogram in metric %s %s", compliantName, metric, @@ -333,6 +335,12 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E } infSeen := false for _, b := range metric.Histogram.Bucket { + if b.GetCumulativeCountFloat() > 0 { + return written, fmt.Errorf( + "OpenMetrics v1.0 does not support float histogram %s %s", + compliantName, metric, + ) + } n, err = writeOpenMetricsSample( w, compliantName, "_bucket", metric, model.BucketLabel, b.GetUpperBound(), @@ -341,7 +349,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E ) written += n if err != nil { - return + return written, err } if math.IsInf(b.GetUpperBound(), +1) { infSeen = true @@ -354,9 +362,12 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E 0, metric.Histogram.GetSampleCount(), true, nil, ) + // We do not check for a float sample count here + // because we will check for it below (and error + // out if needed). written += n if err != nil { - return + return written, err } } n, err = writeOpenMetricsSample( @@ -366,7 +377,13 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E ) written += n if err != nil { - return + return written, err + } + if metric.Histogram.GetSampleCountFloat() > 0 { + return written, fmt.Errorf( + "OpenMetrics v1.0 does not support float histogram %s %s", + compliantName, metric, + ) } n, err = writeOpenMetricsSample( w, compliantName, "_count", metric, "", 0, @@ -384,10 +401,10 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E } written += n if err != nil { - return + return written, err } } - return + return written, err } // FinalizeOpenMetrics writes the final `# EOF\n` line required by OpenMetrics. diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go index c4e9c1bbc3..6b89781456 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_create.go +++ b/vendor/github.com/prometheus/common/expfmt/text_create.go @@ -108,38 +108,38 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e n, err = w.WriteString("# HELP ") written += n if err != nil { - return + return written, err } n, err = writeName(w, name) written += n if err != nil { - return + return written, err } err = w.WriteByte(' ') written++ if err != nil { - return + return written, err } n, err = writeEscapedString(w, *in.Help, false) written += n if err != nil { - return + return written, err } err = w.WriteByte('\n') written++ if err != nil { - return + return written, err } } n, err = w.WriteString("# TYPE ") written += n if err != nil { - return + return written, err } n, err = writeName(w, name) written += n if err != nil { - return + return written, err } metricType := in.GetType() switch metricType { @@ -151,14 +151,17 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e n, err = w.WriteString(" summary\n") case dto.MetricType_UNTYPED: n, err = w.WriteString(" untyped\n") - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: + // The classic Prometheus text format has no notion of a gauge + // histogram. We render a gauge histogram in the same way as a + // regular histogram. n, err = w.WriteString(" histogram\n") default: return written, fmt.Errorf("unknown metric type %s", metricType.String()) } written += n if err != nil { - return + return written, err } // Finally the samples, one line for each. @@ -208,7 +211,7 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e ) written += n if err != nil { - return + return written, err } } n, err = writeSample( @@ -217,13 +220,13 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e ) written += n if err != nil { - return + return written, err } n, err = writeSample( w, name, "_count", metric, "", 0, float64(metric.Summary.GetSampleCount()), ) - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: if metric.Histogram == nil { return written, fmt.Errorf( "expected histogram in metric %s %s", name, metric, @@ -231,28 +234,36 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e } infSeen := false for _, b := range metric.Histogram.Bucket { + v := b.GetCumulativeCountFloat() + if v == 0 { + v = float64(b.GetCumulativeCount()) + } n, err = writeSample( w, name, "_bucket", metric, model.BucketLabel, b.GetUpperBound(), - float64(b.GetCumulativeCount()), + v, ) written += n if err != nil { - return + return written, err } if math.IsInf(b.GetUpperBound(), +1) { infSeen = true } } if !infSeen { + v := metric.Histogram.GetSampleCountFloat() + if v == 0 { + v = float64(metric.Histogram.GetSampleCount()) + } n, err = writeSample( w, name, "_bucket", metric, model.BucketLabel, math.Inf(+1), - float64(metric.Histogram.GetSampleCount()), + v, ) written += n if err != nil { - return + return written, err } } n, err = writeSample( @@ -261,12 +272,13 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e ) written += n if err != nil { - return + return written, err } - n, err = writeSample( - w, name, "_count", metric, "", 0, - float64(metric.Histogram.GetSampleCount()), - ) + v := metric.Histogram.GetSampleCountFloat() + if v == 0 { + v = float64(metric.Histogram.GetSampleCount()) + } + n, err = writeSample(w, name, "_count", metric, "", 0, v) default: return written, fmt.Errorf( "unexpected type in metric %s %s", name, metric, @@ -274,10 +286,10 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err e } written += n if err != nil { - return + return written, err } } - return + return written, err } // writeSample writes a single sample in text format to w, given the metric diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index 8f2edde324..00c8841a10 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -48,8 +48,10 @@ func (e ParseError) Error() string { return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg) } -// TextParser is used to parse the simple and flat text-based exchange format. Its -// zero value is ready to use. +// TextParser is used to parse the simple and flat text-based exchange format. +// +// TextParser instances must be created with NewTextParser, the zero value of +// TextParser is invalid. type TextParser struct { metricFamiliesByName map[string]*dto.MetricFamily buf *bufio.Reader // Where the parsed input is read through. @@ -129,9 +131,44 @@ func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricF if p.err != nil && errors.Is(p.err, io.EOF) { p.parseError("unexpected end of input stream") } + for _, histogramMetric := range p.histograms { + normalizeHistogram(histogramMetric.GetHistogram()) + } return p.metricFamiliesByName, p.err } +// normalizeHistogram makes sure that all the buckets and the count in each +// histogram is either completely float or completely integer. +func normalizeHistogram(histogram *dto.Histogram) { + if histogram == nil { + return + } + anyFloats := false + if histogram.GetSampleCountFloat() != 0 { + anyFloats = true + } else { + for _, b := range histogram.GetBucket() { + if b.GetCumulativeCountFloat() != 0 { + anyFloats = true + break + } + } + } + if !anyFloats { + return + } + if histogram.GetSampleCountFloat() == 0 { + histogram.SampleCountFloat = proto.Float64(float64(histogram.GetSampleCount())) + histogram.SampleCount = nil + } + for _, b := range histogram.GetBucket() { + if b.GetCumulativeCountFloat() == 0 { + b.CumulativeCountFloat = proto.Float64(float64(b.GetCumulativeCount())) + b.CumulativeCount = nil + } + } +} + func (p *TextParser) reset(in io.Reader) { p.metricFamiliesByName = map[string]*dto.MetricFamily{} p.currentLabelPairs = nil @@ -281,7 +318,9 @@ func (p *TextParser) readingLabels() stateFn { // Summaries/histograms are special. We have to reset the // currentLabels map, currentQuantile and currentBucket before starting to // read labels. - if p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + if p.currentMF.GetType() == dto.MetricType_SUMMARY || + p.currentMF.GetType() == dto.MetricType_HISTOGRAM || + p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { p.currentLabels = map[string]string{} p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName() p.currentQuantile = math.NaN() @@ -374,7 +413,9 @@ func (p *TextParser) startLabelName() stateFn { // Special summary/histogram treatment. Don't add 'quantile' and 'le' // labels to 'real' labels. if (p.currentMF.GetType() != dto.MetricType_SUMMARY || p.currentLabelPair.GetName() != model.QuantileLabel) && - (p.currentMF.GetType() != dto.MetricType_HISTOGRAM || p.currentLabelPair.GetName() != model.BucketLabel) { + ((p.currentMF.GetType() != dto.MetricType_HISTOGRAM && + p.currentMF.GetType() != dto.MetricType_GAUGE_HISTOGRAM) || + p.currentLabelPair.GetName() != model.BucketLabel) { p.currentLabelPairs = append(p.currentLabelPairs, p.currentLabelPair) } // Check for duplicate label names. @@ -425,7 +466,7 @@ func (p *TextParser) startLabelValue() stateFn { } } // Similar special treatment of histograms. - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + if p.currentMF.GetType() == dto.MetricType_HISTOGRAM || p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { if p.currentLabelPair.GetName() == model.BucketLabel { if p.currentBucket, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil { // Create a more helpful error message. @@ -476,7 +517,7 @@ func (p *TextParser) readingValue() stateFn { p.summaries[signature] = p.currentMetric p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) } - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: signature := model.LabelsToSignature(p.currentLabels) if histogram := p.histograms[signature]; histogram != nil { p.currentMetric = histogram @@ -522,24 +563,38 @@ func (p *TextParser) readingValue() stateFn { }, ) } - case dto.MetricType_HISTOGRAM: + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: // *sigh* if p.currentMetric.Histogram == nil { p.currentMetric.Histogram = &dto.Histogram{} } switch { case p.currentIsHistogramCount: - p.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value)) + if uintValue := uint64(value); value == float64(uintValue) { + p.currentMetric.Histogram.SampleCount = proto.Uint64(uintValue) + } else { + if value < 0 { + p.parseError(fmt.Sprintf("negative count for histogram %q", p.currentMF.GetName())) + return nil + } + p.currentMetric.Histogram.SampleCountFloat = proto.Float64(value) + } case p.currentIsHistogramSum: p.currentMetric.Histogram.SampleSum = proto.Float64(value) case !math.IsNaN(p.currentBucket): - p.currentMetric.Histogram.Bucket = append( - p.currentMetric.Histogram.Bucket, - &dto.Bucket{ - UpperBound: proto.Float64(p.currentBucket), - CumulativeCount: proto.Uint64(uint64(value)), - }, - ) + b := &dto.Bucket{ + UpperBound: proto.Float64(p.currentBucket), + } + if uintValue := uint64(value); value == float64(uintValue) { + b.CumulativeCount = proto.Uint64(uintValue) + } else { + if value < 0 { + p.parseError(fmt.Sprintf("negative bucket population for histogram %q", p.currentMF.GetName())) + return nil + } + b.CumulativeCountFloat = proto.Float64(value) + } + p.currentMetric.Histogram.Bucket = append(p.currentMetric.Histogram.Bucket, b) } default: p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName()) @@ -602,10 +657,18 @@ func (p *TextParser) readingType() stateFn { if p.readTokenUntilNewline(false); p.err != nil { return nil // Unexpected end of input. } - metricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())] + typ := strings.ToUpper(p.currentToken.String()) // Tolerate any combination of upper and lower case. + metricType, ok := dto.MetricType_value[typ] // Tolerate "gauge_histogram" (not originally part of the text format). if !ok { - p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String())) - return nil + // We also want to tolerate "gaugehistogram" to mark a gauge + // histogram, because that string is used in OpenMetrics. Note, + // however, that gauge histograms do not officially exist in the + // classic text format. + if typ != "GAUGEHISTOGRAM" { + p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String())) + return nil + } + metricType = int32(dto.MetricType_GAUGE_HISTOGRAM) } p.currentMF.Type = dto.MetricType(metricType).Enum() return p.startOfLine @@ -855,7 +918,8 @@ func (p *TextParser) setOrCreateCurrentMF() { } histogramName := histogramMetricName(name) if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil { - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM { + if p.currentMF.GetType() == dto.MetricType_HISTOGRAM || + p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { if isCount(name) { p.currentIsHistogramCount = true } diff --git a/vendor/github.com/prometheus/procfs/.golangci.yml b/vendor/github.com/prometheus/procfs/.golangci.yml index 3c3bf910fd..23ecd4505b 100644 --- a/vendor/github.com/prometheus/procfs/.golangci.yml +++ b/vendor/github.com/prometheus/procfs/.golangci.yml @@ -1,7 +1,9 @@ version: "2" linters: enable: + - errorlint - forbidigo + - gocritic - godot - misspell - revive @@ -11,6 +13,20 @@ linters: forbid: - pattern: ^fmt\.Print.*$ msg: Do not commit print statements. + gocritic: + enable-all: true + disabled-checks: + - commentFormatting + - commentedOutCode + - deferInLoop + - filepathJoin + - hugeParam + - importShadow + - paramTypeCombine + - rangeValCopy + - tooManyResultsChecker + - unnamedResult + - whyNoLint godot: exclude: # Ignore "See: URL". @@ -19,16 +35,12 @@ linters: misspell: locale: US exclusions: - generated: lax presets: - comments - common-false-positives - legacy - std-error-handling - paths: - - third_party$ - - builtin$ - - examples$ + warn-unused: true formatters: enable: - gofmt @@ -37,9 +49,3 @@ formatters: goimports: local-prefixes: - github.com/prometheus/procfs - exclusions: - generated: lax - paths: - - third_party$ - - builtin$ - - examples$ diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile index 7edfe4d093..bce50a19c5 100644 --- a/vendor/github.com/prometheus/procfs/Makefile +++ b/vendor/github.com/prometheus/procfs/Makefile @@ -1,4 +1,4 @@ -# Copyright 2018 The Prometheus Authors +# Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index 4de21512ff..6f61bec48f 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -139,7 +139,7 @@ common-deps: update-go-deps: @echo ">> updating Go dependencies" @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ - $(GO) get -d $$m; \ + $(GO) get $$m; \ done $(GO) mod tidy diff --git a/vendor/github.com/prometheus/procfs/arp.go b/vendor/github.com/prometheus/procfs/arp.go index 2e53344151..716bdef109 100644 --- a/vendor/github.com/prometheus/procfs/arp.go +++ b/vendor/github.com/prometheus/procfs/arp.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -73,15 +73,16 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) { columns := strings.Fields(line) width := len(columns) - if width == expectedHeaderWidth || width == 0 { + switch width { + case expectedHeaderWidth, 0: continue - } else if width == expectedDataWidth { + case expectedDataWidth: entry, err := parseARPEntry(columns) if err != nil { return []ARPEntry{}, fmt.Errorf("%w: Failed to parse ARP entry: %v: %w", ErrFileParse, entry, err) } entries = append(entries, entry) - } else { + default: return []ARPEntry{}, fmt.Errorf("%w: %d columns found, but expected %d: %w", ErrFileParse, width, expectedDataWidth, err) } diff --git a/vendor/github.com/prometheus/procfs/buddyinfo.go b/vendor/github.com/prometheus/procfs/buddyinfo.go index 8380750090..53243e6875 100644 --- a/vendor/github.com/prometheus/procfs/buddyinfo.go +++ b/vendor/github.com/prometheus/procfs/buddyinfo.go @@ -1,4 +1,4 @@ -// Copyright 2017 The Prometheus Authors +// Copyright The Prometheus 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 @@ -64,14 +64,12 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) { if bucketCount == -1 { bucketCount = arraySize - } else { - if bucketCount != arraySize { - return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize) - } + } else if bucketCount != arraySize { + return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize) } sizes := make([]float64, arraySize) - for i := 0; i < arraySize; i++ { + for i := range arraySize { sizes[i], err = strconv.ParseFloat(parts[i+4], 64) if err != nil { return nil, fmt.Errorf("%w: Invalid valid in buddyinfo: %f: %w", ErrFileParse, sizes[i], err) diff --git a/vendor/github.com/prometheus/procfs/cmdline.go b/vendor/github.com/prometheus/procfs/cmdline.go index bf4f3b48c0..4f1cac1f0a 100644 --- a/vendor/github.com/prometheus/procfs/cmdline.go +++ b/vendor/github.com/prometheus/procfs/cmdline.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go index f0950bb495..5fe6cecd3d 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go index 64cfd534c1..8f155551e5 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go index d88442f0ed..e81a5db949 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go index c11207f3ab..4be2b1cc54 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go index a6b2b3127c..e713bae8df 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_others.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go index 003bc2ad4a..0825aa1a83 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go index 1c9b7313b6..496770b05f 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go index fa3686bc00..b3228ce3d8 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go index a0ef55562e..575eb022eb 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go index 5f2a37a78b..e4a5876eaf 100644 --- a/vendor/github.com/prometheus/procfs/crypto.go +++ b/vendor/github.com/prometheus/procfs/crypto.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/doc.go b/vendor/github.com/prometheus/procfs/doc.go index f9d961e441..26bfea071b 100644 --- a/vendor/github.com/prometheus/procfs/doc.go +++ b/vendor/github.com/prometheus/procfs/doc.go @@ -1,4 +1,4 @@ -// Copyright 2014 Prometheus Team +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go index 9bdaccc7c8..8f27912a13 100644 --- a/vendor/github.com/prometheus/procfs/fs.go +++ b/vendor/github.com/prometheus/procfs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go index 1b5bdbdf84..3c53023c54 100644 --- a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go +++ b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_type.go b/vendor/github.com/prometheus/procfs/fs_statfs_type.go index 80df79c319..80fce48478 100644 --- a/vendor/github.com/prometheus/procfs/fs_statfs_type.go +++ b/vendor/github.com/prometheus/procfs/fs_statfs_type.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/fscache.go b/vendor/github.com/prometheus/procfs/fscache.go index 7db8633077..9dde857073 100644 --- a/vendor/github.com/prometheus/procfs/fscache.go +++ b/vendor/github.com/prometheus/procfs/fscache.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -388,20 +388,21 @@ func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) { } } case "CacheOp:": - if strings.Split(fields[1], "=")[0] == "alo" { + switch strings.Split(fields[1], "=")[0] { + case "alo": err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress, &m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress) if err != nil { return &m, err } - } else if strings.Split(fields[1], "=")[0] == "inv" { + case "inv": err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress, &m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress, &m.CacheopSyncCacheInProgress) if err != nil { return &m, err } - } else { + default: err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress, &m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress, &m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress) diff --git a/vendor/github.com/prometheus/procfs/internal/fs/fs.go b/vendor/github.com/prometheus/procfs/internal/fs/fs.go index 3a43e83915..e7ccad66b2 100644 --- a/vendor/github.com/prometheus/procfs/internal/fs/fs.go +++ b/vendor/github.com/prometheus/procfs/internal/fs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go index 5a7d2df06a..30c5872019 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/parse.go +++ b/vendor/github.com/prometheus/procfs/internal/util/parse.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/internal/util/readfile.go b/vendor/github.com/prometheus/procfs/internal/util/readfile.go index 71b7a70ebd..0e41f71af1 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/readfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/readfile.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go index d5404a6d72..8318d8dfd5 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go index 1d86f5e63f..15bb096ee2 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/internal/util/valueparser.go b/vendor/github.com/prometheus/procfs/internal/util/valueparser.go index fe2355d3c6..e0ed671ea0 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/valueparser.go +++ b/vendor/github.com/prometheus/procfs/internal/util/valueparser.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go index bc3a20c932..5374da9fa8 100644 --- a/vendor/github.com/prometheus/procfs/ipvs.go +++ b/vendor/github.com/prometheus/procfs/ipvs.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/kernel_hung.go b/vendor/github.com/prometheus/procfs/kernel_hung.go new file mode 100644 index 0000000000..539c111514 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/kernel_hung.go @@ -0,0 +1,45 @@ +// Copyright The Prometheus 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. + +//go:build !windows +// +build !windows + +package procfs + +import ( + "os" + "strconv" + "strings" +) + +// KernelHung contains information about to the kernel's hung_task_detect_count number. +type KernelHung struct { + // Indicates the total number of tasks that have been detected as hung since the system boot. + // This file shows up if `CONFIG_DETECT_HUNG_TASK` is enabled. + HungTaskDetectCount *uint64 +} + +// KernelHung returns values from /proc/sys/kernel/hung_task_detect_count. +func (fs FS) KernelHung() (KernelHung, error) { + data, err := os.ReadFile(fs.proc.Path("sys", "kernel", "hung_task_detect_count")) + if err != nil { + return KernelHung{}, err + } + val, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) + if err != nil { + return KernelHung{}, err + } + return KernelHung{ + HungTaskDetectCount: &val, + }, nil +} diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go index db88566bdf..b66565a104 100644 --- a/vendor/github.com/prometheus/procfs/kernel_random.go +++ b/vendor/github.com/prometheus/procfs/kernel_random.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/loadavg.go b/vendor/github.com/prometheus/procfs/loadavg.go index 332e76c17f..c8c78a65ed 100644 --- a/vendor/github.com/prometheus/procfs/loadavg.go +++ b/vendor/github.com/prometheus/procfs/loadavg.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go index 1fd4381b22..d66eeda82a 100644 --- a/vendor/github.com/prometheus/procfs/mdstat.go +++ b/vendor/github.com/prometheus/procfs/mdstat.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -27,13 +27,34 @@ var ( recoveryLinePctRE = regexp.MustCompile(`= (.+)%`) recoveryLineFinishRE = regexp.MustCompile(`finish=(.+)min`) recoveryLineSpeedRE = regexp.MustCompile(`speed=(.+)[A-Z]`) - componentDeviceRE = regexp.MustCompile(`(.*)\[\d+\]`) + componentDeviceRE = regexp.MustCompile(`(.*)\[(\d+)\](\([SF]+\))?`) + personalitiesPrefix = "Personalities : " ) +type MDStatComponent struct { + // Name of the component device. + Name string + // DescriptorIndex number of component device, e.g. the order in the superblock. + DescriptorIndex int32 + // Flags per Linux drivers/md/md.[ch] as of v6.12-rc1 + // Subset that are exposed in mdstat + WriteMostly bool + Journal bool + Faulty bool // "Faulty" is what kernel source uses for "(F)" + Spare bool + Replacement bool + // Some additional flags that are NOT exposed in procfs today; they may + // be available via sysfs. + // In_sync, Bitmap_sync, Blocked, WriteErrorSeen, FaultRecorded, + // BlockedBadBlocks, WantReplacement, Candidate, ... +} + // MDStat holds info parsed from /proc/mdstat. type MDStat struct { // Name of the device. Name string + // raid type of the device. + Type string // activity-state of the device. ActivityState string // Number of active disks. @@ -58,8 +79,8 @@ type MDStat struct { BlocksSyncedFinishTime float64 // current sync speed (in Kilobytes/sec) BlocksSyncedSpeed float64 - // Name of md component devices - Devices []string + // component devices + Devices []MDStatComponent } // MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of @@ -80,28 +101,52 @@ func (fs FS) MDStat() ([]MDStat, error) { // parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of // structs containing the relevant info. func parseMDStat(mdStatData []byte) ([]MDStat, error) { + // TODO: + // - parse global hotspares from the "unused devices" line. mdStats := []MDStat{} lines := strings.Split(string(mdStatData), "\n") + knownRaidTypes := make(map[string]bool) for i, line := range lines { if strings.TrimSpace(line) == "" || line[0] == ' ' || - strings.HasPrefix(line, "Personalities") || strings.HasPrefix(line, "unused") { continue } + // Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] + if len(knownRaidTypes) == 0 && strings.HasPrefix(line, personalitiesPrefix) { + personalities := strings.Fields(line[len(personalitiesPrefix):]) + for _, word := range personalities { + word := word[1 : len(word)-1] + knownRaidTypes[word] = true + } + continue + } deviceFields := strings.Fields(line) if len(deviceFields) < 3 { return nil, fmt.Errorf("%w: Expected 3+ lines, got %q", ErrFileParse, line) } mdName := deviceFields[0] // mdx - state := deviceFields[2] // active or inactive + state := deviceFields[2] // active, inactive, broken + + mdType := "unknown" // raid1, raid5, etc. + var deviceStartIndex int + if len(deviceFields) > 3 { // mdType may be in the 3rd or 4th field + if isRaidType(deviceFields[3], knownRaidTypes) { + mdType = deviceFields[3] + deviceStartIndex = 4 + } else if len(deviceFields) > 4 && isRaidType(deviceFields[4], knownRaidTypes) { + // if the 3rd field is (...), the 4th field is the mdType + mdType = deviceFields[4] + deviceStartIndex = 5 + } + } if len(lines) <= i+3 { return nil, fmt.Errorf("%w: Too few lines for md device: %q", ErrFileParse, mdName) } - // Failed disks have the suffix (F) & Spare disks have the suffix (S). + // Failed (Faulty) disks have the suffix (F) & Spare disks have the suffix (S). fail := int64(strings.Count(line, "(F)")) spare := int64(strings.Count(line, "(S)")) active, total, down, size, err := evalStatusLine(lines[i], lines[i+1]) @@ -129,13 +174,14 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { // Append recovery and resyncing state info. if recovering || resyncing || checking || reshaping { - if recovering { + switch { + case recovering: state = "recovering" - } else if reshaping { + case reshaping: state = "reshaping" - } else if checking { + case checking: state = "checking" - } else { + default: state = "resyncing" } @@ -151,8 +197,14 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { } } + devices, err := evalComponentDevices(deviceFields[deviceStartIndex:]) + if err != nil { + return nil, fmt.Errorf("error parsing components in md device %q: %w", mdName, err) + } + mdStats = append(mdStats, MDStat{ Name: mdName, + Type: mdType, ActivityState: state, DisksActive: active, DisksFailed: fail, @@ -165,14 +217,24 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { BlocksSyncedPct: pct, BlocksSyncedFinishTime: finish, BlocksSyncedSpeed: speed, - Devices: evalComponentDevices(deviceFields), + Devices: devices, }) } return mdStats, nil } +// check if a string's format is like the mdType +// Rule 1: mdType should not be like (...) +// Rule 2: mdType should not be like sda[0] +// . +func isRaidType(mdType string, knownRaidTypes map[string]bool) bool { + _, ok := knownRaidTypes[mdType] + return !strings.ContainsAny(mdType, "([") && ok +} + func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { + // e.g. 523968 blocks super 1.2 [4/4] [UUUU] statusFields := strings.Fields(statusLine) if len(statusFields) < 1 { return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err) @@ -263,17 +325,29 @@ func evalRecoveryLine(recoveryLine string) (blocksSynced int64, blocksToBeSynced return blocksSynced, blocksToBeSynced, pct, finish, speed, nil } -func evalComponentDevices(deviceFields []string) []string { - mdComponentDevices := make([]string, 0) - if len(deviceFields) > 3 { - for _, field := range deviceFields[4:] { - match := componentDeviceRE.FindStringSubmatch(field) - if match == nil { - continue - } - mdComponentDevices = append(mdComponentDevices, match[1]) +func evalComponentDevices(deviceFields []string) ([]MDStatComponent, error) { + mdComponentDevices := make([]MDStatComponent, 0) + for _, field := range deviceFields { + match := componentDeviceRE.FindStringSubmatch(field) + if match == nil { + continue + } + descriptorIndex, err := strconv.ParseInt(match[2], 10, 32) + if err != nil { + return mdComponentDevices, fmt.Errorf("error parsing int from device %q: %w", match[2], err) } + mdComponentDevices = append(mdComponentDevices, MDStatComponent{ + Name: match[1], + DescriptorIndex: int32(descriptorIndex), + // match may contain one or more of these + // https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/md/md.c#L8376-L8392 + Faulty: strings.Contains(match[3], "(F)"), + Spare: strings.Contains(match[3], "(S)"), + Journal: strings.Contains(match[3], "(J)"), + Replacement: strings.Contains(match[3], "(R)"), + WriteMostly: strings.Contains(match[3], "(W)"), + }) } - return mdComponentDevices + return mdComponentDevices, nil } diff --git a/vendor/github.com/prometheus/procfs/meminfo.go b/vendor/github.com/prometheus/procfs/meminfo.go index 937e1f9606..3420383187 100644 --- a/vendor/github.com/prometheus/procfs/meminfo.go +++ b/vendor/github.com/prometheus/procfs/meminfo.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -307,7 +307,7 @@ func parseMemInfo(r io.Reader) (*Meminfo, error) { m.ZswapBytes = &valBytes case "Zswapped:": m.Zswapped = &val - m.ZswapBytes = &valBytes + m.ZswappedBytes = &valBytes case "Dirty:": m.Dirty = &val m.DirtyBytes = &valBytes diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go index a704c5e735..9414a12f42 100644 --- a/vendor/github.com/prometheus/procfs/mountinfo.go +++ b/vendor/github.com/prometheus/procfs/mountinfo.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -147,8 +147,7 @@ func mountOptionsParseOptionalFields(o []string) (map[string]string, error) { // mountOptionsParser parses the mount options, superblock options. func mountOptionsParser(mountOptions string) map[string]string { opts := make(map[string]string) - options := strings.Split(mountOptions, ",") - for _, opt := range options { + for opt := range strings.SplitSeq(mountOptions, ",") { splitOption := strings.Split(opt, "=") if len(splitOption) < 2 { key := splitOption[0] @@ -178,3 +177,21 @@ func GetProcMounts(pid int) ([]*MountInfo, error) { } return parseMountInfo(data) } + +// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. +func (fs FS) GetMounts() ([]*MountInfo, error) { + data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo")) + if err != nil { + return nil, err + } + return parseMountInfo(data) +} + +// GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. +func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) { + data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) + if err != nil { + return nil, err + } + return parseMountInfo(data) +} diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go index 50caa73274..e503cb3a6c 100644 --- a/vendor/github.com/prometheus/procfs/mountstats.go +++ b/vendor/github.com/prometheus/procfs/mountstats.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -383,7 +383,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e if stats.Opts == nil { stats.Opts = map[string]string{} } - for _, opt := range strings.Split(ss[1], ",") { + for opt := range strings.SplitSeq(ss[1], ",") { split := strings.Split(opt, "=") if len(split) == 2 { stats.Opts[split[0]] = split[1] diff --git a/vendor/github.com/prometheus/procfs/net_conntrackstat.go b/vendor/github.com/prometheus/procfs/net_conntrackstat.go index 316df5fbb7..e9ca357079 100644 --- a/vendor/github.com/prometheus/procfs/net_conntrackstat.go +++ b/vendor/github.com/prometheus/procfs/net_conntrackstat.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go index e66208aa05..7b3e1d61c9 100644 --- a/vendor/github.com/prometheus/procfs/net_dev.go +++ b/vendor/github.com/prometheus/procfs/net_dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_dev_snmp6.go b/vendor/github.com/prometheus/procfs/net_dev_snmp6.go index f50b38e352..2a0f60f29f 100644 --- a/vendor/github.com/prometheus/procfs/net_dev_snmp6.go +++ b/vendor/github.com/prometheus/procfs/net_dev_snmp6.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -18,6 +18,7 @@ import ( "errors" "io" "os" + "path/filepath" "strconv" "strings" ) @@ -56,7 +57,9 @@ func newNetDevSNMP6(dir string) (NetDevSNMP6, error) { } for _, iFaceFile := range ifaceFiles { - f, err := os.Open(dir + "/" + iFaceFile.Name()) + filePath := filepath.Join(dir, iFaceFile.Name()) + + f, err := os.Open(filePath) if err != nil { return netDevSNMP6, err } diff --git a/vendor/github.com/prometheus/procfs/net_ip_socket.go b/vendor/github.com/prometheus/procfs/net_ip_socket.go index 19e3378f72..9291f8cd4c 100644 --- a/vendor/github.com/prometheus/procfs/net_ip_socket.go +++ b/vendor/github.com/prometheus/procfs/net_ip_socket.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_protocols.go b/vendor/github.com/prometheus/procfs/net_protocols.go index 8d4b1ac05b..eaa996cbcf 100644 --- a/vendor/github.com/prometheus/procfs/net_protocols.go +++ b/vendor/github.com/prometheus/procfs/net_protocols.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 @@ -169,7 +169,7 @@ func (pc *NetProtocolCapabilities) parseCapabilities(capabilities []string) erro &pc.EnterMemoryPressure, } - for i := 0; i < len(capabilities); i++ { + for i := range capabilities { switch capabilities[i] { case "y": *capabilityFields[i] = true diff --git a/vendor/github.com/prometheus/procfs/net_route.go b/vendor/github.com/prometheus/procfs/net_route.go index deb7029fe1..fa3812d9d0 100644 --- a/vendor/github.com/prometheus/procfs/net_route.go +++ b/vendor/github.com/prometheus/procfs/net_route.go @@ -1,4 +1,4 @@ -// Copyright 2023 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_sockstat.go b/vendor/github.com/prometheus/procfs/net_sockstat.go index fae62b13d9..8b221ebfff 100644 --- a/vendor/github.com/prometheus/procfs/net_sockstat.go +++ b/vendor/github.com/prometheus/procfs/net_sockstat.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -139,9 +139,6 @@ func parseSockstatKVs(kvs []string) (map[string]int, error) { func parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol { var nsp NetSockstatProtocol for k, v := range kvs { - // Capture the range variable to ensure we get unique pointers for - // each of the optional fields. - v := v switch k { case "inuse": nsp.InUse = v diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go index 71c8059f4d..4a2dfa18fd 100644 --- a/vendor/github.com/prometheus/procfs/net_softnet.go +++ b/vendor/github.com/prometheus/procfs/net_softnet.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_tcp.go b/vendor/github.com/prometheus/procfs/net_tcp.go index 0396d72015..610ea78e56 100644 --- a/vendor/github.com/prometheus/procfs/net_tcp.go +++ b/vendor/github.com/prometheus/procfs/net_tcp.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_tls_stat.go b/vendor/github.com/prometheus/procfs/net_tls_stat.go index 13994c1782..b1b3f6a6a2 100644 --- a/vendor/github.com/prometheus/procfs/net_tls_stat.go +++ b/vendor/github.com/prometheus/procfs/net_tls_stat.go @@ -1,4 +1,4 @@ -// Copyright 2023 Prometheus Team +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_udp.go b/vendor/github.com/prometheus/procfs/net_udp.go index 9ac3daf2d4..8a32779102 100644 --- a/vendor/github.com/prometheus/procfs/net_udp.go +++ b/vendor/github.com/prometheus/procfs/net_udp.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_unix.go b/vendor/github.com/prometheus/procfs/net_unix.go index d7e0cacb4c..e4d6359236 100644 --- a/vendor/github.com/prometheus/procfs/net_unix.go +++ b/vendor/github.com/prometheus/procfs/net_unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go index 7c597bc870..69d0794451 100644 --- a/vendor/github.com/prometheus/procfs/net_wireless.go +++ b/vendor/github.com/prometheus/procfs/net_wireless.go @@ -1,4 +1,4 @@ -// Copyright 2023 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/net_xfrm.go b/vendor/github.com/prometheus/procfs/net_xfrm.go index 932ef20468..5a9f497d19 100644 --- a/vendor/github.com/prometheus/procfs/net_xfrm.go +++ b/vendor/github.com/prometheus/procfs/net_xfrm.go @@ -1,4 +1,4 @@ -// Copyright 2017 Prometheus Team +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/netstat.go b/vendor/github.com/prometheus/procfs/netstat.go index 742dff453b..dbdae47392 100644 --- a/vendor/github.com/prometheus/procfs/netstat.go +++ b/vendor/github.com/prometheus/procfs/netstat.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/nfnetlink_queue.go b/vendor/github.com/prometheus/procfs/nfnetlink_queue.go new file mode 100644 index 0000000000..b0a73b11e9 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/nfnetlink_queue.go @@ -0,0 +1,85 @@ +// Copyright The Prometheus 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 procfs + +import ( + "bufio" + "bytes" + "fmt" + + "github.com/prometheus/procfs/internal/util" +) + +const nfNetLinkQueueFormat = "%d %d %d %d %d %d %d %d %d" + +// NFNetLinkQueue contains general information about netfilter queues found in /proc/net/netfilter/nfnetlink_queue. +type NFNetLinkQueue struct { + // id of the queue + QueueID uint + // pid of process handling the queue + PeerPID uint + // number of packets waiting for a decision + QueueTotal uint + // indicate how userspace receive packets + CopyMode uint + // size of copy + CopyRange uint + // number of items dropped by the kernel because too many packets were waiting a decision. + // It queue_total is superior to queue_max_len (1024 per default) the packets are dropped. + QueueDropped uint + // number of packets dropped by userspace (due to kernel send failure on the netlink socket) + QueueUserDropped uint + // sequence number of packets queued. It gives a correct approximation of the number of queued packets. + SequenceID uint + // internal value (number of entity using the queue) + Use uint +} + +// NFNetLinkQueue returns information about current state of netfilter queues. +func (fs FS) NFNetLinkQueue() ([]NFNetLinkQueue, error) { + data, err := util.ReadFileNoStat(fs.proc.Path("net/netfilter/nfnetlink_queue")) + if err != nil { + return nil, err + } + + queue := []NFNetLinkQueue{} + if len(data) == 0 { + return queue, nil + } + + scanner := bufio.NewScanner(bytes.NewReader(data)) + for scanner.Scan() { + line := scanner.Text() + nFNetLinkQueue, err := parseNFNetLinkQueueLine(line) + if err != nil { + return nil, err + } + queue = append(queue, *nFNetLinkQueue) + } + return queue, nil +} + +// parseNFNetLinkQueueLine parses each line of the /proc/net/netfilter/nfnetlink_queue file. +func parseNFNetLinkQueueLine(line string) (*NFNetLinkQueue, error) { + nFNetLinkQueue := NFNetLinkQueue{} + _, err := fmt.Sscanf( + line, nfNetLinkQueueFormat, + &nFNetLinkQueue.QueueID, &nFNetLinkQueue.PeerPID, &nFNetLinkQueue.QueueTotal, &nFNetLinkQueue.CopyMode, + &nFNetLinkQueue.CopyRange, &nFNetLinkQueue.QueueDropped, &nFNetLinkQueue.QueueUserDropped, &nFNetLinkQueue.SequenceID, &nFNetLinkQueue.Use, + ) + if err != nil { + return nil, err + } + return &nFNetLinkQueue, nil +} diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index 368187fa88..39c14aa55e 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -49,7 +49,7 @@ func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID } // Self returns a process for the current process read via /proc/self. func Self() (Proc, error) { fs, err := NewFS(DefaultMountPoint) - if err != nil || errors.Unwrap(err) == ErrMountPoint { + if err != nil || errors.Is(err, ErrMountPoint) { return Proc{}, err } return fs.Self() diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index 4a64347c03..535c08d6fc 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_cgroups.go b/vendor/github.com/prometheus/procfs/proc_cgroups.go index 5dd4938999..0b275c3b1f 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroups.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroups.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Prometheus Authors +// Copyright The Prometheus 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 @@ -40,13 +40,13 @@ type CgroupSummary struct { // parseCgroupSummary parses each line of the /proc/cgroup file // Line format is `subsys_name hierarchy num_cgroups enabled`. -func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) { +func parseCgroupSummaryString(cgroupSummaryStr string) (*CgroupSummary, error) { var err error - fields := strings.Fields(CgroupSummaryStr) + fields := strings.Fields(cgroupSummaryStr) // require at least 4 fields if len(fields) < 4 { - return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), CgroupSummaryStr) + return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), cgroupSummaryStr) } CgroupSummary := &CgroupSummary{ diff --git a/vendor/github.com/prometheus/procfs/proc_environ.go b/vendor/github.com/prometheus/procfs/proc_environ.go index 57a89895d6..5b941de047 100644 --- a/vendor/github.com/prometheus/procfs/proc_environ.go +++ b/vendor/github.com/prometheus/procfs/proc_environ.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_fdinfo.go b/vendor/github.com/prometheus/procfs/proc_fdinfo.go index fa761b3529..fa57761dbe 100644 --- a/vendor/github.com/prometheus/procfs/proc_fdinfo.go +++ b/vendor/github.com/prometheus/procfs/proc_fdinfo.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -60,15 +60,16 @@ func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) { scanner := bufio.NewScanner(bytes.NewReader(data)) for scanner.Scan() { text = scanner.Text() - if rPos.MatchString(text) { + switch { + case rPos.MatchString(text): pos = rPos.FindStringSubmatch(text)[1] - } else if rFlags.MatchString(text) { + case rFlags.MatchString(text): flags = rFlags.FindStringSubmatch(text)[1] - } else if rMntID.MatchString(text) { + case rMntID.MatchString(text): mntid = rMntID.FindStringSubmatch(text)[1] - } else if rIno.MatchString(text) { + case rIno.MatchString(text): ino = rIno.FindStringSubmatch(text)[1] - } else if rInotify.MatchString(text) { + case rInotify.MatchString(text): newInotify, err := parseInotifyInfo(text) if err != nil { return nil, err diff --git a/vendor/github.com/prometheus/procfs/proc_interrupts.go b/vendor/github.com/prometheus/procfs/proc_interrupts.go index 86b4b45246..b942c50723 100644 --- a/vendor/github.com/prometheus/procfs/proc_interrupts.go +++ b/vendor/github.com/prometheus/procfs/proc_interrupts.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go index d15b66ddb6..dd8086ba2e 100644 --- a/vendor/github.com/prometheus/procfs/proc_io.go +++ b/vendor/github.com/prometheus/procfs/proc_io.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go index 9530b14bc6..4b7d337847 100644 --- a/vendor/github.com/prometheus/procfs/proc_limits.go +++ b/vendor/github.com/prometheus/procfs/proc_limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -19,6 +19,7 @@ import ( "os" "regexp" "strconv" + "strings" ) // ProcLimits represents the soft limits for each of the process's resource @@ -74,7 +75,7 @@ const ( ) var ( - limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`) + limitsMatch = regexp.MustCompile(`(Max \w+\s??\w*\s?\w*)\s{2,}(\w+)\s+(\w+)`) ) // NewLimits returns the current soft limits of the process. @@ -106,7 +107,7 @@ func (p Proc) Limits() (ProcLimits, error) { return ProcLimits{}, fmt.Errorf("%w: couldn't parse %q line %q", ErrFileParse, f.Name(), s.Text()) } - switch fields[1] { + switch strings.TrimSpace(fields[1]) { case "Max cpu time": l.CPUTime, err = parseUint(fields[2]) case "Max file size": diff --git a/vendor/github.com/prometheus/procfs/proc_maps.go b/vendor/github.com/prometheus/procfs/proc_maps.go index 7e75c286b5..cc519f92f9 100644 --- a/vendor/github.com/prometheus/procfs/proc_maps.go +++ b/vendor/github.com/prometheus/procfs/proc_maps.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_netstat.go b/vendor/github.com/prometheus/procfs/proc_netstat.go index 4248c1716e..7f94cc8914 100644 --- a/vendor/github.com/prometheus/procfs/proc_netstat.go +++ b/vendor/github.com/prometheus/procfs/proc_netstat.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_ns.go b/vendor/github.com/prometheus/procfs/proc_ns.go index 0f8f847f95..5fc0eb9e2f 100644 --- a/vendor/github.com/prometheus/procfs/proc_ns.go +++ b/vendor/github.com/prometheus/procfs/proc_ns.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_psi.go b/vendor/github.com/prometheus/procfs/proc_psi.go index ccd35f153a..cc2c5de873 100644 --- a/vendor/github.com/prometheus/procfs/proc_psi.go +++ b/vendor/github.com/prometheus/procfs/proc_psi.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go index 9a297afcf8..3e48afd1d3 100644 --- a/vendor/github.com/prometheus/procfs/proc_smaps.go +++ b/vendor/github.com/prometheus/procfs/proc_smaps.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_snmp.go b/vendor/github.com/prometheus/procfs/proc_snmp.go index 4bdc90b07e..8d9a9bcd67 100644 --- a/vendor/github.com/prometheus/procfs/proc_snmp.go +++ b/vendor/github.com/prometheus/procfs/proc_snmp.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_snmp6.go b/vendor/github.com/prometheus/procfs/proc_snmp6.go index fb7fd3995b..841fef4649 100644 --- a/vendor/github.com/prometheus/procfs/proc_snmp6.go +++ b/vendor/github.com/prometheus/procfs/proc_snmp6.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go index 3328556bdc..02e3f9e316 100644 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ b/vendor/github.com/prometheus/procfs/proc_stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/proc_statm.go b/vendor/github.com/prometheus/procfs/proc_statm.go index ed57984243..b0a9360167 100644 --- a/vendor/github.com/prometheus/procfs/proc_statm.go +++ b/vendor/github.com/prometheus/procfs/proc_statm.go @@ -1,4 +1,4 @@ -// Copyright 2025 The Prometheus Authors +// Copyright The Prometheus 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 @@ -80,7 +80,7 @@ func (p Proc) Statm() (ProcStatm, error) { func parseStatm(data []byte) ([]uint64, error) { var statmSlice []uint64 statmItems := strings.Fields(string(data)) - for i := 0; i < len(statmItems); i++ { + for i := range statmItems { statmItem, err := strconv.ParseUint(statmItems[i], 10, 64) if err != nil { return nil, err diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go index dd8aa56885..1ed2bced41 100644 --- a/vendor/github.com/prometheus/procfs/proc_status.go +++ b/vendor/github.com/prometheus/procfs/proc_status.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -16,7 +16,7 @@ package procfs import ( "bytes" "math/bits" - "sort" + "slices" "strconv" "strings" @@ -94,8 +94,7 @@ func (p Proc) NewStatus() (ProcStatus, error) { s := ProcStatus{PID: p.PID} - lines := strings.Split(string(data), "\n") - for _, line := range lines { + for line := range strings.SplitSeq(string(data), "\n") { if !bytes.Contains([]byte(line), []byte(":")) { continue } @@ -222,7 +221,7 @@ func calcCpusAllowedList(cpuString string) []uint64 { } - sort.Slice(g, func(i, j int) bool { return g[i] < g[j] }) + slices.Sort(g) return g } diff --git a/vendor/github.com/prometheus/procfs/proc_sys.go b/vendor/github.com/prometheus/procfs/proc_sys.go index 3810d1ac99..52658a4d52 100644 --- a/vendor/github.com/prometheus/procfs/proc_sys.go +++ b/vendor/github.com/prometheus/procfs/proc_sys.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/schedstat.go b/vendor/github.com/prometheus/procfs/schedstat.go index 5f7f32dc83..fafd8dff74 100644 --- a/vendor/github.com/prometheus/procfs/schedstat.go +++ b/vendor/github.com/prometheus/procfs/schedstat.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/slab.go b/vendor/github.com/prometheus/procfs/slab.go index 8611c90177..32a04678ad 100644 --- a/vendor/github.com/prometheus/procfs/slab.go +++ b/vendor/github.com/prometheus/procfs/slab.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/softirqs.go b/vendor/github.com/prometheus/procfs/softirqs.go index 403e6ae708..47b73a7297 100644 --- a/vendor/github.com/prometheus/procfs/softirqs.go +++ b/vendor/github.com/prometheus/procfs/softirqs.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go index e36b41c18a..593ad0f62f 100644 --- a/vendor/github.com/prometheus/procfs/stat.go +++ b/vendor/github.com/prometheus/procfs/stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Prometheus Authors +// Copyright The Prometheus 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 @@ -16,6 +16,7 @@ package procfs import ( "bufio" "bytes" + "errors" "fmt" "io" "strconv" @@ -92,7 +93,7 @@ func parseCPUStat(line string) (CPUStat, int64, error) { &cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal, &cpuStat.Guest, &cpuStat.GuestNice) - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu): %w", ErrFileParse, line, err) } if count == 0 { diff --git a/vendor/github.com/prometheus/procfs/swaps.go b/vendor/github.com/prometheus/procfs/swaps.go index 65fec834bf..ee17bf4888 100644 --- a/vendor/github.com/prometheus/procfs/swaps.go +++ b/vendor/github.com/prometheus/procfs/swaps.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/thread.go b/vendor/github.com/prometheus/procfs/thread.go index 80e0e947be..0cfbb54184 100644 --- a/vendor/github.com/prometheus/procfs/thread.go +++ b/vendor/github.com/prometheus/procfs/thread.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go index 51c49d89e8..2a8d763909 100644 --- a/vendor/github.com/prometheus/procfs/vm.go +++ b/vendor/github.com/prometheus/procfs/vm.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go index e54d94b090..806e171147 100644 --- a/vendor/github.com/prometheus/procfs/zoneinfo.go +++ b/vendor/github.com/prometheus/procfs/zoneinfo.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright The Prometheus 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 @@ -88,11 +88,9 @@ func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) { zoneinfo := []Zoneinfo{} - zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode")) - for _, block := range zoneinfoBlocks { + for block := range bytes.SplitSeq(zoneinfoData, []byte("\nNode")) { var zoneinfoElement Zoneinfo - lines := strings.Split(string(block), "\n") - for _, line := range lines { + for line := range strings.SplitSeq(string(block), "\n") { if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil { zoneinfoElement.Node = nodeZone[1] diff --git a/vendor/go.etcd.io/etcd/api/v3/version/version.go b/vendor/go.etcd.io/etcd/api/v3/version/version.go index 9e7bc64c17..cd0b63ea67 100644 --- a/vendor/go.etcd.io/etcd/api/v3/version/version.go +++ b/vendor/go.etcd.io/etcd/api/v3/version/version.go @@ -26,7 +26,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "3.0.0" - Version = "3.6.5" + Version = "3.6.8" APIVersion = "unknown" // Git SHA Value will be set during build diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/LICENSE b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/LICENSE index 261eeb9e9f..f1aee0f110 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/LICENSE +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/LICENSE @@ -199,3 +199,33 @@ 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. + +-------------------------------------------------------------------------------- + +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 +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +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 LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/config.go index 2451d2d387..870fdbbf3e 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/config.go @@ -1,16 +1,5 @@ // Copyright The OpenTelemetry 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. +// SPDX-License-Identifier: Apache-2.0 package otelrestful // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful" @@ -70,7 +59,7 @@ func WithTracerProvider(provider oteltrace.TracerProvider) Option { }) } -// WithPublicEndpointFn runs with every request, and allows conditionnally +// WithPublicEndpointFn runs with every request, and allows conditionally // configuring the Handler to link the span with an incoming span context. If // this option is not provided or returns false, then the association is a // child association instead of a link. diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/doc.go index 8e5d99d80f..1662a4199e 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/doc.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/doc.go @@ -1,16 +1,5 @@ // Copyright The OpenTelemetry 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. +// SPDX-License-Identifier: Apache-2.0 // Package otelrestful instruments github.com/emicklei/go-restful. // diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/client.go new file mode 100644 index 0000000000..afd99287b7 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/client.go @@ -0,0 +1,287 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconv/client.go.tmpl + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package semconv provides OpenTelemetry semantic convention types and +// functionality. +package semconv // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv" + +import ( + "context" + "fmt" + "net/http" + "slices" + "strconv" + "strings" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv" +) + +type HTTPClient struct{ + requestBodySize httpconv.ClientRequestBodySize + requestDuration httpconv.ClientRequestDuration +} + +func NewHTTPClient(meter metric.Meter) HTTPClient { + client := HTTPClient{} + + var err error + client.requestBodySize, err = httpconv.NewClientRequestBodySize(meter) + handleErr(err) + + client.requestDuration, err = httpconv.NewClientRequestDuration( + meter, + metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10), + ) + handleErr(err) + + return client +} + +func (n HTTPClient) Status(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 400 { + return codes.Error, "" + } + return codes.Unset, "" +} + +// RequestTraceAttrs returns trace attributes for an HTTP request made by a client. +func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { + /* + below attributes are returned: + - http.request.method + - http.request.method.original + - url.full + - server.address + - server.port + - network.protocol.name + - network.protocol.version + */ + numOfAttributes := 3 // URL, server address, proto, and method. + + var urlHost string + if req.URL != nil { + urlHost = req.URL.Host + } + var requestHost string + var requestPort int + for _, hostport := range []string{urlHost, req.Header.Get("Host")} { + requestHost, requestPort = SplitHostPort(hostport) + if requestHost != "" || requestPort > 0 { + break + } + } + + eligiblePort := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) + if eligiblePort > 0 { + numOfAttributes++ + } + useragent := req.UserAgent() + if useragent != "" { + numOfAttributes++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" && protoName != "http" { + numOfAttributes++ + } + if protoVersion != "" { + numOfAttributes++ + } + + method, originalMethod := n.method(req.Method) + if originalMethod != (attribute.KeyValue{}) { + numOfAttributes++ + } + + attrs := make([]attribute.KeyValue, 0, numOfAttributes) + + attrs = append(attrs, method) + if originalMethod != (attribute.KeyValue{}) { + attrs = append(attrs, originalMethod) + } + + var u string + if req.URL != nil { + // Remove any username/password info that may be in the URL. + userinfo := req.URL.User + req.URL.User = nil + u = req.URL.String() + // Restore any username/password info that was removed. + req.URL.User = userinfo + } + attrs = append(attrs, semconv.URLFull(u)) + + attrs = append(attrs, semconv.ServerAddress(requestHost)) + if eligiblePort > 0 { + attrs = append(attrs, semconv.ServerPort(eligiblePort)) + } + + if protoName != "" && protoName != "http" { + attrs = append(attrs, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attrs = append(attrs, semconv.NetworkProtocolVersion(protoVersion)) + } + + return attrs +} + +// ResponseTraceAttrs returns trace attributes for an HTTP response made by a client. +func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { + /* + below attributes are returned: + - http.response.status_code + - error.type + */ + var count int + if resp.StatusCode > 0 { + count++ + } + + if isErrorStatusCode(resp.StatusCode) { + count++ + } + + attrs := make([]attribute.KeyValue, 0, count) + if resp.StatusCode > 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(resp.StatusCode)) + } + + if isErrorStatusCode(resp.StatusCode) { + errorType := strconv.Itoa(resp.StatusCode) + attrs = append(attrs, semconv.ErrorTypeKey.String(errorType)) + } + return attrs +} + +func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) { + if method == "" { + return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + } + if attr, ok := methodLookup[method]; ok { + return attr, attribute.KeyValue{} + } + + orig := semconv.HTTPRequestMethodOriginal(method) + if attr, ok := methodLookup[strings.ToUpper(method)]; ok { + return attr, orig + } + return semconv.HTTPRequestMethodGet, orig +} + +func (n HTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { + num := len(additionalAttributes) + 2 + var h string + if req.URL != nil { + h = req.URL.Host + } + var requestHost string + var requestPort int + for _, hostport := range []string{h, req.Header.Get("Host")} { + requestHost, requestPort = SplitHostPort(hostport) + if requestHost != "" || requestPort > 0 { + break + } + } + + port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) + if port > 0 { + num++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" { + num++ + } + if protoVersion != "" { + num++ + } + + if statusCode > 0 { + num++ + } + + attributes := slices.Grow(additionalAttributes, num) + attributes = append(attributes, + semconv.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), + semconv.ServerAddress(requestHost), + n.scheme(req), + ) + + if port > 0 { + attributes = append(attributes, semconv.ServerPort(port)) + } + if protoName != "" { + attributes = append(attributes, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attributes = append(attributes, semconv.NetworkProtocolVersion(protoVersion)) + } + + if statusCode > 0 { + attributes = append(attributes, semconv.HTTPResponseStatusCode(statusCode)) + } + return attributes +} + +type MetricOpts struct { + measurement metric.MeasurementOption + addOptions metric.AddOption +} + +func (o MetricOpts) MeasurementOption() metric.MeasurementOption { + return o.measurement +} + +func (o MetricOpts) AddOptions() metric.AddOption { + return o.addOptions +} + +func (n HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts { + opts := map[string]MetricOpts{} + + attributes := n.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) + set := metric.WithAttributeSet(attribute.NewSet(attributes...)) + opts["new"] = MetricOpts{ + measurement: set, + addOptions: set, + } + + return opts +} + +func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) { + n.requestBodySize.Inst().Record(ctx, md.RequestSize, opts["new"].MeasurementOption()) + n.requestDuration.Inst().Record(ctx, md.ElapsedTime/1000, opts["new"].MeasurementOption()) +} + +// TraceAttributes returns attributes for httptrace. +func (n HTTPClient) TraceAttributes(host string) []attribute.KeyValue { + return []attribute.KeyValue{ + semconv.ServerAddress(host), + } +} + +func (n HTTPClient) scheme(req *http.Request) attribute.KeyValue { + if req.URL != nil && req.URL.Scheme != "" { + return semconv.URLScheme(req.URL.Scheme) + } + if req.TLS != nil { + return semconv.URLScheme("https") + } + return semconv.URLScheme("http") +} + +func isErrorStatusCode(code int) bool { + return code >= 400 || code < 100 +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/gen.go new file mode 100644 index 0000000000..28276a037e --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/gen.go @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package semconv // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv" + +// Generate semconv package: +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful\" }" --out=bench_test.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/common_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful\" }" --out=common_test.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/server.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=server.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/server_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=server_test.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/client.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=client.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/client_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=client_test.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/httpconvtest_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful\" }" --out=httpconvtest_test.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/util.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful\" }" --out=util.go +//go:generate gotmpl --body=../../../../../../../internal/shared/semconv/util_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful\" }" --out=util_test.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/server.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/server.go new file mode 100644 index 0000000000..fb3375aa1e --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/server.go @@ -0,0 +1,403 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconv/server.go.tmpl + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package semconv provides OpenTelemetry semantic convention types and +// functionality. +package semconv // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv" + +import ( + "context" + "fmt" + "net/http" + "slices" + "strings" + "sync" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv" +) + +type RequestTraceAttrsOpts struct { + // If set, this is used as value for the "http.client_ip" attribute. + HTTPClientIP string +} + +type ResponseTelemetry struct { + StatusCode int + ReadBytes int64 + ReadError error + WriteBytes int64 + WriteError error +} + +type HTTPServer struct{ + requestBodySizeHistogram httpconv.ServerRequestBodySize + responseBodySizeHistogram httpconv.ServerResponseBodySize + requestDurationHistogram httpconv.ServerRequestDuration +} + +func NewHTTPServer(meter metric.Meter) HTTPServer { + server := HTTPServer{} + + var err error + server.requestBodySizeHistogram, err = httpconv.NewServerRequestBodySize(meter) + handleErr(err) + + server.responseBodySizeHistogram, err = httpconv.NewServerResponseBodySize(meter) + handleErr(err) + + server.requestDurationHistogram, err = httpconv.NewServerRequestDuration( + meter, + metric.WithExplicitBucketBoundaries( + 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, + 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10, + ), + ) + handleErr(err) + return server +} + +// Status returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func (n HTTPServer) Status(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 500 { + return codes.Error, "" + } + return codes.Unset, "" +} + +// RequestTraceAttrs returns trace attributes for an HTTP request received by a +// server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +func (n HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { + count := 3 // ServerAddress, Method, Scheme + + var host string + var p int + if server == "" { + host, p = SplitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = SplitHostPort(server) + if p < 0 { + _, p = SplitHostPort(req.Host) + } + } + + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + count++ + } + + method, methodOriginal := n.method(req.Method) + if methodOriginal != (attribute.KeyValue{}) { + count++ + } + + scheme := n.scheme(req.TLS != nil) + + peer, peerPort := SplitHostPort(req.RemoteAddr) + if peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + count++ + if peerPort > 0 { + count++ + } + } + + useragent := req.UserAgent() + if useragent != "" { + count++ + } + + // For client IP, use, in order: + // 1. The value passed in the options + // 2. The value in the X-Forwarded-For header + // 3. The peer address + clientIP := opts.HTTPClientIP + if clientIP == "" { + clientIP = serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP == "" { + clientIP = peer + } + } + if clientIP != "" { + count++ + } + + if req.URL != nil && req.URL.Path != "" { + count++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" && protoName != "http" { + count++ + } + if protoVersion != "" { + count++ + } + + route := httpRoute(req.Pattern) + if route != "" { + count++ + } + + attrs := make([]attribute.KeyValue, 0, count) + attrs = append(attrs, + semconv.ServerAddress(host), + method, + scheme, + ) + + if hostPort > 0 { + attrs = append(attrs, semconv.ServerPort(hostPort)) + } + if methodOriginal != (attribute.KeyValue{}) { + attrs = append(attrs, methodOriginal) + } + + if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + attrs = append(attrs, semconv.NetworkPeerAddress(peer)) + if peerPort > 0 { + attrs = append(attrs, semconv.NetworkPeerPort(peerPort)) + } + } + + if useragent != "" { + attrs = append(attrs, semconv.UserAgentOriginal(useragent)) + } + + if clientIP != "" { + attrs = append(attrs, semconv.ClientAddress(clientIP)) + } + + if req.URL != nil && req.URL.Path != "" { + attrs = append(attrs, semconv.URLPath(req.URL.Path)) + } + + if protoName != "" && protoName != "http" { + attrs = append(attrs, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attrs = append(attrs, semconv.NetworkProtocolVersion(protoVersion)) + } + + if route != "" { + attrs = append(attrs, n.Route(route)) + } + + return attrs +} + +func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { + attr := semconv.NetworkTransportPipe + switch network { + case "tcp", "tcp4", "tcp6": + attr = semconv.NetworkTransportTCP + case "udp", "udp4", "udp6": + attr = semconv.NetworkTransportUDP + case "unix", "unixgram", "unixpacket": + attr = semconv.NetworkTransportUnix + } + + return []attribute.KeyValue{attr} +} + +type ServerMetricData struct { + ServerName string + ResponseSize int64 + + MetricData + MetricAttributes +} + +type MetricAttributes struct { + Req *http.Request + StatusCode int + Route string + AdditionalAttributes []attribute.KeyValue +} + +type MetricData struct { + RequestSize int64 + + // The request duration, in milliseconds + ElapsedTime float64 +} + +var ( + metricAddOptionPool = &sync.Pool{ + New: func() any { + return &[]metric.AddOption{} + }, + } + + metricRecordOptionPool = &sync.Pool{ + New: func() any { + return &[]metric.RecordOption{} + }, + } +) + +func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { + attributes := n.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.Route, md.AdditionalAttributes) + o := metric.WithAttributeSet(attribute.NewSet(attributes...)) + recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) + *recordOpts = append(*recordOpts, o) + n.requestBodySizeHistogram.Inst().Record(ctx, md.RequestSize, *recordOpts...) + n.responseBodySizeHistogram.Inst().Record(ctx, md.ResponseSize, *recordOpts...) + n.requestDurationHistogram.Inst().Record(ctx, md.ElapsedTime/1000.0, o) + *recordOpts = (*recordOpts)[:0] + metricRecordOptionPool.Put(recordOpts) +} + +func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { + if method == "" { + return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + } + if attr, ok := methodLookup[method]; ok { + return attr, attribute.KeyValue{} + } + + orig := semconv.HTTPRequestMethodOriginal(method) + if attr, ok := methodLookup[strings.ToUpper(method)]; ok { + return attr, orig + } + return semconv.HTTPRequestMethodGet, orig +} + +func (n HTTPServer) scheme(https bool) attribute.KeyValue { //nolint:revive // ignore linter + if https { + return semconv.URLScheme("https") + } + return semconv.URLScheme("http") +} + +// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP +// response. +// +// If any of the fields in the ResponseTelemetry are not set the attribute will +// be omitted. +func (n HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { + var count int + + if resp.ReadBytes > 0 { + count++ + } + if resp.WriteBytes > 0 { + count++ + } + if resp.StatusCode > 0 { + count++ + } + + attributes := make([]attribute.KeyValue, 0, count) + + if resp.ReadBytes > 0 { + attributes = append(attributes, + semconv.HTTPRequestBodySize(int(resp.ReadBytes)), + ) + } + if resp.WriteBytes > 0 { + attributes = append(attributes, + semconv.HTTPResponseBodySize(int(resp.WriteBytes)), + ) + } + if resp.StatusCode > 0 { + attributes = append(attributes, + semconv.HTTPResponseStatusCode(resp.StatusCode), + ) + } + + return attributes +} + +// Route returns the attribute for the route. +func (n HTTPServer) Route(route string) attribute.KeyValue { + return semconv.HTTPRoute(route) +} + +func (n HTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, route string, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { + num := len(additionalAttributes) + 3 + var host string + var p int + if server == "" { + host, p = SplitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = SplitHostPort(server) + if p < 0 { + _, p = SplitHostPort(req.Host) + } + } + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + num++ + } + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" { + num++ + } + if protoVersion != "" { + num++ + } + + if statusCode > 0 { + num++ + } + + if route != "" { + num++ + } + + attributes := slices.Grow(additionalAttributes, num) + attributes = append(attributes, + semconv.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), + n.scheme(req.TLS != nil), + semconv.ServerAddress(host)) + + if hostPort > 0 { + attributes = append(attributes, semconv.ServerPort(hostPort)) + } + if protoName != "" { + attributes = append(attributes, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attributes = append(attributes, semconv.NetworkProtocolVersion(protoVersion)) + } + + if statusCode > 0 { + attributes = append(attributes, semconv.HTTPResponseStatusCode(statusCode)) + } + + if route != "" { + attributes = append(attributes, semconv.HTTPRoute(route)) + } + return attributes +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/util.go new file mode 100644 index 0000000000..5ffa4e0ba8 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv/util.go @@ -0,0 +1,127 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconv/util.go.tmpl + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package semconv // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv" + +import ( + "net" + "net/http" + "strconv" + "strings" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + semconvNew "go.opentelemetry.io/otel/semconv/v1.39.0" +) + +// SplitHostPort splits a network address hostport of the form "host", +// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port", +// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and +// port. +// +// An empty host is returned if it is not provided or unparsable. A negative +// port is returned if it is not provided or unparsable. +func SplitHostPort(hostport string) (host string, port int) { + port = -1 + + if strings.HasPrefix(hostport, "[") { + addrEnd := strings.LastIndexByte(hostport, ']') + if addrEnd < 0 { + // Invalid hostport. + return + } + if i := strings.LastIndexByte(hostport[addrEnd:], ':'); i < 0 { + host = hostport[1:addrEnd] + return + } + } else { + if i := strings.LastIndexByte(hostport, ':'); i < 0 { + host = hostport + return + } + } + + host, pStr, err := net.SplitHostPort(hostport) + if err != nil { + return + } + + p, err := strconv.ParseUint(pStr, 10, 16) + if err != nil { + return + } + return host, int(p) //nolint:gosec // Byte size checked 16 above. +} + +func requiredHTTPPort(https bool, port int) int { //nolint:revive // ignore linter + if https { + if port > 0 && port != 443 { + return port + } + } else { + if port > 0 && port != 80 { + return port + } + } + return -1 +} + +func serverClientIP(xForwardedFor string) string { + if idx := strings.IndexByte(xForwardedFor, ','); idx >= 0 { + xForwardedFor = xForwardedFor[:idx] + } + return xForwardedFor +} + +func httpRoute(pattern string) string { + if idx := strings.IndexByte(pattern, '/'); idx >= 0 { + return pattern[idx:] + } + return "" +} + +func netProtocol(proto string) (name string, version string) { + name, version, _ = strings.Cut(proto, "/") + switch name { + case "HTTP": + name = "http" + case "QUIC": + name = "quic" + case "SPDY": + name = "spdy" + default: + name = strings.ToLower(name) + } + return name, version +} + +var methodLookup = map[string]attribute.KeyValue{ + http.MethodConnect: semconvNew.HTTPRequestMethodConnect, + http.MethodDelete: semconvNew.HTTPRequestMethodDelete, + http.MethodGet: semconvNew.HTTPRequestMethodGet, + http.MethodHead: semconvNew.HTTPRequestMethodHead, + http.MethodOptions: semconvNew.HTTPRequestMethodOptions, + http.MethodPatch: semconvNew.HTTPRequestMethodPatch, + http.MethodPost: semconvNew.HTTPRequestMethodPost, + http.MethodPut: semconvNew.HTTPRequestMethodPut, + http.MethodTrace: semconvNew.HTTPRequestMethodTrace, +} + +func handleErr(err error) { + if err != nil { + otel.Handle(err) + } +} + +func standardizeHTTPMethod(method string) string { + method = strings.ToUpper(method) + switch method { + case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace: + default: + method = "_OTHER" + } + return method +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/gen.go deleted file mode 100644 index cb58065a97..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/gen.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright The OpenTelemetry 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 semconvutil // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil" - -// Generate semconvutil package: -//go:generate gotmpl --body=../../../../../../../internal/shared/semconvutil/httpconv_test.go.tmpl "--data={}" --out=httpconv_test.go -//go:generate gotmpl --body=../../../../../../../internal/shared/semconvutil/httpconv.go.tmpl "--data={}" --out=httpconv.go -//go:generate gotmpl --body=../../../../../../../internal/shared/semconvutil/netconv_test.go.tmpl "--data={}" --out=netconv_test.go -//go:generate gotmpl --body=../../../../../../../internal/shared/semconvutil/netconv.go.tmpl "--data={}" --out=netconv.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/httpconv.go deleted file mode 100644 index 011d80e324..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/httpconv.go +++ /dev/null @@ -1,552 +0,0 @@ -// Code created by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconvutil/httpconv.go.tmpl - -// Copyright The OpenTelemetry 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 semconvutil // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil" - -import ( - "fmt" - "net/http" - "strings" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.17.0" -) - -// HTTPClientResponse returns trace attributes for an HTTP response received by a -// client from a server. It will return the following attributes if the related -// values are defined in resp: "http.status.code", -// "http.response_content_length". -// -// This does not add all OpenTelemetry required attributes for an HTTP event, -// it assumes ClientRequest was used to create the span with a complete set of -// attributes. If a complete set of attributes can be generated using the -// request contained in resp. For example: -// -// append(HTTPClientResponse(resp), ClientRequest(resp.Request)...) -func HTTPClientResponse(resp *http.Response) []attribute.KeyValue { - return hc.ClientResponse(resp) -} - -// HTTPClientRequest returns trace attributes for an HTTP request made by a client. -// The following attributes are always returned: "http.url", "http.flavor", -// "http.method", "net.peer.name". The following attributes are returned if the -// related values are defined in req: "net.peer.port", "http.user_agent", -// "http.request_content_length", "enduser.id". -func HTTPClientRequest(req *http.Request) []attribute.KeyValue { - return hc.ClientRequest(req) -} - -// HTTPClientStatus returns a span status code and message for an HTTP status code -// value received by a client. -func HTTPClientStatus(code int) (codes.Code, string) { - return hc.ClientStatus(code) -} - -// HTTPServerRequest returns trace attributes for an HTTP request received by a -// server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -// -// The following attributes are always returned: "http.method", "http.scheme", -// "http.flavor", "http.target", "net.host.name". The following attributes are -// returned if they related values are defined in req: "net.host.port", -// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", -// "http.client_ip". -func HTTPServerRequest(server string, req *http.Request) []attribute.KeyValue { - return hc.ServerRequest(server, req) -} - -// HTTPServerRequestMetrics returns metric attributes for an HTTP request received by a -// server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -// -// The following attributes are always returned: "http.method", "http.scheme", -// "http.flavor", "net.host.name". The following attributes are -// returned if they related values are defined in req: "net.host.port". -func HTTPServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue { - return hc.ServerRequestMetrics(server, req) -} - -// HTTPServerStatus returns a span status code and message for an HTTP status code -// value returned by a server. Status codes in the 400-499 range are not -// returned as errors. -func HTTPServerStatus(code int) (codes.Code, string) { - return hc.ServerStatus(code) -} - -// HTTPRequestHeader returns the contents of h as attributes. -// -// Instrumentation should require an explicit configuration of which headers to -// captured and then prune what they pass here. Including all headers can be a -// security risk - explicit configuration helps avoid leaking sensitive -// information. -// -// The User-Agent header is already captured in the http.user_agent attribute -// from ClientRequest and ServerRequest. Instrumentation may provide an option -// to capture that header here even though it is not recommended. Otherwise, -// instrumentation should filter that out of what is passed. -func HTTPRequestHeader(h http.Header) []attribute.KeyValue { - return hc.RequestHeader(h) -} - -// HTTPResponseHeader returns the contents of h as attributes. -// -// Instrumentation should require an explicit configuration of which headers to -// captured and then prune what they pass here. Including all headers can be a -// security risk - explicit configuration helps avoid leaking sensitive -// information. -// -// The User-Agent header is already captured in the http.user_agent attribute -// from ClientRequest and ServerRequest. Instrumentation may provide an option -// to capture that header here even though it is not recommended. Otherwise, -// instrumentation should filter that out of what is passed. -func HTTPResponseHeader(h http.Header) []attribute.KeyValue { - return hc.ResponseHeader(h) -} - -// httpConv are the HTTP semantic convention attributes defined for a version -// of the OpenTelemetry specification. -type httpConv struct { - NetConv *netConv - - EnduserIDKey attribute.Key - HTTPClientIPKey attribute.Key - HTTPFlavorKey attribute.Key - HTTPMethodKey attribute.Key - HTTPRequestContentLengthKey attribute.Key - HTTPResponseContentLengthKey attribute.Key - HTTPRouteKey attribute.Key - HTTPSchemeHTTP attribute.KeyValue - HTTPSchemeHTTPS attribute.KeyValue - HTTPStatusCodeKey attribute.Key - HTTPTargetKey attribute.Key - HTTPURLKey attribute.Key - HTTPUserAgentKey attribute.Key -} - -var hc = &httpConv{ - NetConv: nc, - - EnduserIDKey: semconv.EnduserIDKey, - HTTPClientIPKey: semconv.HTTPClientIPKey, - HTTPFlavorKey: semconv.HTTPFlavorKey, - HTTPMethodKey: semconv.HTTPMethodKey, - HTTPRequestContentLengthKey: semconv.HTTPRequestContentLengthKey, - HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey, - HTTPRouteKey: semconv.HTTPRouteKey, - HTTPSchemeHTTP: semconv.HTTPSchemeHTTP, - HTTPSchemeHTTPS: semconv.HTTPSchemeHTTPS, - HTTPStatusCodeKey: semconv.HTTPStatusCodeKey, - HTTPTargetKey: semconv.HTTPTargetKey, - HTTPURLKey: semconv.HTTPURLKey, - HTTPUserAgentKey: semconv.HTTPUserAgentKey, -} - -// ClientResponse returns attributes for an HTTP response received by a client -// from a server. The following attributes are returned if the related values -// are defined in resp: "http.status.code", "http.response_content_length". -// -// This does not add all OpenTelemetry required attributes for an HTTP event, -// it assumes ClientRequest was used to create the span with a complete set of -// attributes. If a complete set of attributes can be generated using the -// request contained in resp. For example: -// -// append(ClientResponse(resp), ClientRequest(resp.Request)...) -func (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue { - var n int - if resp.StatusCode > 0 { - n++ - } - if resp.ContentLength > 0 { - n++ - } - - attrs := make([]attribute.KeyValue, 0, n) - if resp.StatusCode > 0 { - attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode)) - } - if resp.ContentLength > 0 { - attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength))) - } - return attrs -} - -// ClientRequest returns attributes for an HTTP request made by a client. The -// following attributes are always returned: "http.url", "http.flavor", -// "http.method", "net.peer.name". The following attributes are returned if the -// related values are defined in req: "net.peer.port", "http.user_agent", -// "http.request_content_length", "enduser.id". -func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue { - n := 3 // URL, peer name, proto, and method. - var h string - if req.URL != nil { - h = req.URL.Host - } - peer, p := firstHostPort(h, req.Header.Get("Host")) - port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p) - if port > 0 { - n++ - } - useragent := req.UserAgent() - if useragent != "" { - n++ - } - if req.ContentLength > 0 { - n++ - } - userID, _, hasUserID := req.BasicAuth() - if hasUserID { - n++ - } - attrs := make([]attribute.KeyValue, 0, n) - - attrs = append(attrs, c.method(req.Method)) - attrs = append(attrs, c.flavor(req.Proto)) - - var u string - if req.URL != nil { - // Remove any username/password info that may be in the URL. - userinfo := req.URL.User - req.URL.User = nil - u = req.URL.String() - // Restore any username/password info that was removed. - req.URL.User = userinfo - } - attrs = append(attrs, c.HTTPURLKey.String(u)) - - attrs = append(attrs, c.NetConv.PeerName(peer)) - if port > 0 { - attrs = append(attrs, c.NetConv.PeerPort(port)) - } - - if useragent != "" { - attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) - } - - if l := req.ContentLength; l > 0 { - attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l)) - } - - if hasUserID { - attrs = append(attrs, c.EnduserIDKey.String(userID)) - } - - return attrs -} - -// ServerRequest returns attributes for an HTTP request received by a server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -// -// The following attributes are always returned: "http.method", "http.scheme", -// "http.flavor", "http.target", "net.host.name". The following attributes are -// returned if they related values are defined in req: "net.host.port", -// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id", -// "http.client_ip". -func (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue { - // TODO: This currently does not add the specification required - // `http.target` attribute. It has too high of a cardinality to safely be - // added. An alternate should be added, or this comment removed, when it is - // addressed by the specification. If it is ultimately decided to continue - // not including the attribute, the HTTPTargetKey field of the httpConv - // should be removed as well. - - n := 4 // Method, scheme, proto, and host name. - var host string - var p int - if server == "" { - host, p = splitHostPort(req.Host) - } else { - // Prioritize the primary server name. - host, p = splitHostPort(server) - if p < 0 { - _, p = splitHostPort(req.Host) - } - } - hostPort := requiredHTTPPort(req.TLS != nil, p) - if hostPort > 0 { - n++ - } - peer, peerPort := splitHostPort(req.RemoteAddr) - if peer != "" { - n++ - if peerPort > 0 { - n++ - } - } - useragent := req.UserAgent() - if useragent != "" { - n++ - } - userID, _, hasUserID := req.BasicAuth() - if hasUserID { - n++ - } - clientIP := serverClientIP(req.Header.Get("X-Forwarded-For")) - if clientIP != "" { - n++ - } - attrs := make([]attribute.KeyValue, 0, n) - - attrs = append(attrs, c.method(req.Method)) - attrs = append(attrs, c.scheme(req.TLS != nil)) - attrs = append(attrs, c.flavor(req.Proto)) - attrs = append(attrs, c.NetConv.HostName(host)) - - if hostPort > 0 { - attrs = append(attrs, c.NetConv.HostPort(hostPort)) - } - - if peer != "" { - // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a - // file-path that would be interpreted with a sock family. - attrs = append(attrs, c.NetConv.SockPeerAddr(peer)) - if peerPort > 0 { - attrs = append(attrs, c.NetConv.SockPeerPort(peerPort)) - } - } - - if useragent != "" { - attrs = append(attrs, c.HTTPUserAgentKey.String(useragent)) - } - - if hasUserID { - attrs = append(attrs, c.EnduserIDKey.String(userID)) - } - - if clientIP != "" { - attrs = append(attrs, c.HTTPClientIPKey.String(clientIP)) - } - - return attrs -} - -// ServerRequestMetrics returns metric attributes for an HTTP request received -// by a server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -// -// The following attributes are always returned: "http.method", "http.scheme", -// "http.flavor", "net.host.name". The following attributes are -// returned if they related values are defined in req: "net.host.port". -func (c *httpConv) ServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue { - // TODO: This currently does not add the specification required - // `http.target` attribute. It has too high of a cardinality to safely be - // added. An alternate should be added, or this comment removed, when it is - // addressed by the specification. If it is ultimately decided to continue - // not including the attribute, the HTTPTargetKey field of the httpConv - // should be removed as well. - - n := 4 // Method, scheme, proto, and host name. - var host string - var p int - if server == "" { - host, p = splitHostPort(req.Host) - } else { - // Prioritize the primary server name. - host, p = splitHostPort(server) - if p < 0 { - _, p = splitHostPort(req.Host) - } - } - hostPort := requiredHTTPPort(req.TLS != nil, p) - if hostPort > 0 { - n++ - } - attrs := make([]attribute.KeyValue, 0, n) - - attrs = append(attrs, c.methodMetric(req.Method)) - attrs = append(attrs, c.scheme(req.TLS != nil)) - attrs = append(attrs, c.flavor(req.Proto)) - attrs = append(attrs, c.NetConv.HostName(host)) - - if hostPort > 0 { - attrs = append(attrs, c.NetConv.HostPort(hostPort)) - } - - return attrs -} - -func (c *httpConv) method(method string) attribute.KeyValue { - if method == "" { - return c.HTTPMethodKey.String(http.MethodGet) - } - return c.HTTPMethodKey.String(method) -} - -func (c *httpConv) methodMetric(method string) attribute.KeyValue { - method = strings.ToUpper(method) - switch method { - case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace: - default: - method = "_OTHER" - } - return c.HTTPMethodKey.String(method) -} - -func (c *httpConv) scheme(https bool) attribute.KeyValue { // nolint:revive - if https { - return c.HTTPSchemeHTTPS - } - return c.HTTPSchemeHTTP -} - -func (c *httpConv) flavor(proto string) attribute.KeyValue { - switch proto { - case "HTTP/1.0": - return c.HTTPFlavorKey.String("1.0") - case "HTTP/1.1": - return c.HTTPFlavorKey.String("1.1") - case "HTTP/2": - return c.HTTPFlavorKey.String("2.0") - case "HTTP/3": - return c.HTTPFlavorKey.String("3.0") - default: - return c.HTTPFlavorKey.String(proto) - } -} - -func serverClientIP(xForwardedFor string) string { - if idx := strings.Index(xForwardedFor, ","); idx >= 0 { - xForwardedFor = xForwardedFor[:idx] - } - return xForwardedFor -} - -func requiredHTTPPort(https bool, port int) int { // nolint:revive - if https { - if port > 0 && port != 443 { - return port - } - } else { - if port > 0 && port != 80 { - return port - } - } - return -1 -} - -// Return the request host and port from the first non-empty source. -func firstHostPort(source ...string) (host string, port int) { - for _, hostport := range source { - host, port = splitHostPort(hostport) - if host != "" || port > 0 { - break - } - } - return -} - -// RequestHeader returns the contents of h as OpenTelemetry attributes. -func (c *httpConv) RequestHeader(h http.Header) []attribute.KeyValue { - return c.header("http.request.header", h) -} - -// ResponseHeader returns the contents of h as OpenTelemetry attributes. -func (c *httpConv) ResponseHeader(h http.Header) []attribute.KeyValue { - return c.header("http.response.header", h) -} - -func (c *httpConv) header(prefix string, h http.Header) []attribute.KeyValue { - key := func(k string) attribute.Key { - k = strings.ToLower(k) - k = strings.ReplaceAll(k, "-", "_") - k = fmt.Sprintf("%s.%s", prefix, k) - return attribute.Key(k) - } - - attrs := make([]attribute.KeyValue, 0, len(h)) - for k, v := range h { - attrs = append(attrs, key(k).StringSlice(v)) - } - return attrs -} - -// ClientStatus returns a span status code and message for an HTTP status code -// value received by a client. -func (c *httpConv) ClientStatus(code int) (codes.Code, string) { - if code < 100 || code >= 600 { - return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) - } - if code >= 400 { - return codes.Error, "" - } - return codes.Unset, "" -} - -// ServerStatus returns a span status code and message for an HTTP status code -// value returned by a server. Status codes in the 400-499 range are not -// returned as errors. -func (c *httpConv) ServerStatus(code int) (codes.Code, string) { - if code < 100 || code >= 600 { - return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) - } - if code >= 500 { - return codes.Error, "" - } - return codes.Unset, "" -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/netconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/netconv.go deleted file mode 100644 index 914556f485..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil/netconv.go +++ /dev/null @@ -1,368 +0,0 @@ -// Code created by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconvutil/netconv.go.tmpl - -// Copyright The OpenTelemetry 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 semconvutil // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil" - -import ( - "net" - "strconv" - "strings" - - "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.17.0" -) - -// NetTransport returns a trace attribute describing the transport protocol of the -// passed network. See the net.Dial for information about acceptable network -// values. -func NetTransport(network string) attribute.KeyValue { - return nc.Transport(network) -} - -// NetClient returns trace attributes for a client network connection to address. -// See net.Dial for information about acceptable address values, address should -// be the same as the one used to create conn. If conn is nil, only network -// peer attributes will be returned that describe address. Otherwise, the -// socket level information about conn will also be included. -func NetClient(address string, conn net.Conn) []attribute.KeyValue { - return nc.Client(address, conn) -} - -// NetServer returns trace attributes for a network listener listening at address. -// See net.Listen for information about acceptable address values, address -// should be the same as the one used to create ln. If ln is nil, only network -// host attributes will be returned that describe address. Otherwise, the -// socket level information about ln will also be included. -func NetServer(address string, ln net.Listener) []attribute.KeyValue { - return nc.Server(address, ln) -} - -// netConv are the network semantic convention attributes defined for a version -// of the OpenTelemetry specification. -type netConv struct { - NetHostNameKey attribute.Key - NetHostPortKey attribute.Key - NetPeerNameKey attribute.Key - NetPeerPortKey attribute.Key - NetSockFamilyKey attribute.Key - NetSockPeerAddrKey attribute.Key - NetSockPeerPortKey attribute.Key - NetSockHostAddrKey attribute.Key - NetSockHostPortKey attribute.Key - NetTransportOther attribute.KeyValue - NetTransportTCP attribute.KeyValue - NetTransportUDP attribute.KeyValue - NetTransportInProc attribute.KeyValue -} - -var nc = &netConv{ - NetHostNameKey: semconv.NetHostNameKey, - NetHostPortKey: semconv.NetHostPortKey, - NetPeerNameKey: semconv.NetPeerNameKey, - NetPeerPortKey: semconv.NetPeerPortKey, - NetSockFamilyKey: semconv.NetSockFamilyKey, - NetSockPeerAddrKey: semconv.NetSockPeerAddrKey, - NetSockPeerPortKey: semconv.NetSockPeerPortKey, - NetSockHostAddrKey: semconv.NetSockHostAddrKey, - NetSockHostPortKey: semconv.NetSockHostPortKey, - NetTransportOther: semconv.NetTransportOther, - NetTransportTCP: semconv.NetTransportTCP, - NetTransportUDP: semconv.NetTransportUDP, - NetTransportInProc: semconv.NetTransportInProc, -} - -func (c *netConv) Transport(network string) attribute.KeyValue { - switch network { - case "tcp", "tcp4", "tcp6": - return c.NetTransportTCP - case "udp", "udp4", "udp6": - return c.NetTransportUDP - case "unix", "unixgram", "unixpacket": - return c.NetTransportInProc - default: - // "ip:*", "ip4:*", and "ip6:*" all are considered other. - return c.NetTransportOther - } -} - -// Host returns attributes for a network host address. -func (c *netConv) Host(address string) []attribute.KeyValue { - h, p := splitHostPort(address) - var n int - if h != "" { - n++ - if p > 0 { - n++ - } - } - - if n == 0 { - return nil - } - - attrs := make([]attribute.KeyValue, 0, n) - attrs = append(attrs, c.HostName(h)) - if p > 0 { - attrs = append(attrs, c.HostPort(int(p))) - } - return attrs -} - -// Server returns attributes for a network listener listening at address. See -// net.Listen for information about acceptable address values, address should -// be the same as the one used to create ln. If ln is nil, only network host -// attributes will be returned that describe address. Otherwise, the socket -// level information about ln will also be included. -func (c *netConv) Server(address string, ln net.Listener) []attribute.KeyValue { - if ln == nil { - return c.Host(address) - } - - lAddr := ln.Addr() - if lAddr == nil { - return c.Host(address) - } - - hostName, hostPort := splitHostPort(address) - sockHostAddr, sockHostPort := splitHostPort(lAddr.String()) - network := lAddr.Network() - sockFamily := family(network, sockHostAddr) - - n := nonZeroStr(hostName, network, sockHostAddr, sockFamily) - n += positiveInt(hostPort, sockHostPort) - attr := make([]attribute.KeyValue, 0, n) - if hostName != "" { - attr = append(attr, c.HostName(hostName)) - if hostPort > 0 { - // Only if net.host.name is set should net.host.port be. - attr = append(attr, c.HostPort(hostPort)) - } - } - if network != "" { - attr = append(attr, c.Transport(network)) - } - if sockFamily != "" { - attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) - } - if sockHostAddr != "" { - attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) - if sockHostPort > 0 { - // Only if net.sock.host.addr is set should net.sock.host.port be. - attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) - } - } - return attr -} - -func (c *netConv) HostName(name string) attribute.KeyValue { - return c.NetHostNameKey.String(name) -} - -func (c *netConv) HostPort(port int) attribute.KeyValue { - return c.NetHostPortKey.Int(port) -} - -// Client returns attributes for a client network connection to address. See -// net.Dial for information about acceptable address values, address should be -// the same as the one used to create conn. If conn is nil, only network peer -// attributes will be returned that describe address. Otherwise, the socket -// level information about conn will also be included. -func (c *netConv) Client(address string, conn net.Conn) []attribute.KeyValue { - if conn == nil { - return c.Peer(address) - } - - lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr() - - var network string - switch { - case lAddr != nil: - network = lAddr.Network() - case rAddr != nil: - network = rAddr.Network() - default: - return c.Peer(address) - } - - peerName, peerPort := splitHostPort(address) - var ( - sockFamily string - sockPeerAddr string - sockPeerPort int - sockHostAddr string - sockHostPort int - ) - - if lAddr != nil { - sockHostAddr, sockHostPort = splitHostPort(lAddr.String()) - } - - if rAddr != nil { - sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String()) - } - - switch { - case sockHostAddr != "": - sockFamily = family(network, sockHostAddr) - case sockPeerAddr != "": - sockFamily = family(network, sockPeerAddr) - } - - n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily) - n += positiveInt(peerPort, sockPeerPort, sockHostPort) - attr := make([]attribute.KeyValue, 0, n) - if peerName != "" { - attr = append(attr, c.PeerName(peerName)) - if peerPort > 0 { - // Only if net.peer.name is set should net.peer.port be. - attr = append(attr, c.PeerPort(peerPort)) - } - } - if network != "" { - attr = append(attr, c.Transport(network)) - } - if sockFamily != "" { - attr = append(attr, c.NetSockFamilyKey.String(sockFamily)) - } - if sockPeerAddr != "" { - attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr)) - if sockPeerPort > 0 { - // Only if net.sock.peer.addr is set should net.sock.peer.port be. - attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort)) - } - } - if sockHostAddr != "" { - attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr)) - if sockHostPort > 0 { - // Only if net.sock.host.addr is set should net.sock.host.port be. - attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort)) - } - } - return attr -} - -func family(network, address string) string { - switch network { - case "unix", "unixgram", "unixpacket": - return "unix" - default: - if ip := net.ParseIP(address); ip != nil { - if ip.To4() == nil { - return "inet6" - } - return "inet" - } - } - return "" -} - -func nonZeroStr(strs ...string) int { - var n int - for _, str := range strs { - if str != "" { - n++ - } - } - return n -} - -func positiveInt(ints ...int) int { - var n int - for _, i := range ints { - if i > 0 { - n++ - } - } - return n -} - -// Peer returns attributes for a network peer address. -func (c *netConv) Peer(address string) []attribute.KeyValue { - h, p := splitHostPort(address) - var n int - if h != "" { - n++ - if p > 0 { - n++ - } - } - - if n == 0 { - return nil - } - - attrs := make([]attribute.KeyValue, 0, n) - attrs = append(attrs, c.PeerName(h)) - if p > 0 { - attrs = append(attrs, c.PeerPort(int(p))) - } - return attrs -} - -func (c *netConv) PeerName(name string) attribute.KeyValue { - return c.NetPeerNameKey.String(name) -} - -func (c *netConv) PeerPort(port int) attribute.KeyValue { - return c.NetPeerPortKey.Int(port) -} - -func (c *netConv) SockPeerAddr(addr string) attribute.KeyValue { - return c.NetSockPeerAddrKey.String(addr) -} - -func (c *netConv) SockPeerPort(port int) attribute.KeyValue { - return c.NetSockPeerPortKey.Int(port) -} - -// splitHostPort splits a network address hostport of the form "host", -// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port", -// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and -// port. -// -// An empty host is returned if it is not provided or unparsable. A negative -// port is returned if it is not provided or unparsable. -func splitHostPort(hostport string) (host string, port int) { - port = -1 - - if strings.HasPrefix(hostport, "[") { - addrEnd := strings.LastIndex(hostport, "]") - if addrEnd < 0 { - // Invalid hostport. - return - } - if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 { - host = hostport[1:addrEnd] - return - } - } else { - if i := strings.LastIndex(hostport, ":"); i < 0 { - host = hostport - return - } - } - - host, pStr, err := net.SplitHostPort(hostport) - if err != nil { - return - } - - p, err := strconv.ParseUint(pStr, 10, 16) - if err != nil { - return - } - return host, int(p) -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/restful.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/restful.go index 4325368fa3..a38e99455d 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/restful.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/restful.go @@ -1,30 +1,19 @@ // Copyright The OpenTelemetry 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. +// SPDX-License-Identifier: Apache-2.0 package otelrestful // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful" import ( "github.com/emicklei/go-restful/v3" - - "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" - semconv "go.opentelemetry.io/otel/semconv/v1.17.0" oteltrace "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv" ) -const tracerName = "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful" +// ScopeName is the instrumentation scope name. +const ScopeName = "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful" // OTelFilter returns a restful.FilterFunction which will trace an incoming request. // @@ -40,12 +29,14 @@ func OTelFilter(service string, opts ...Option) restful.FilterFunction { cfg.TracerProvider = otel.GetTracerProvider() } tracer := cfg.TracerProvider.Tracer( - tracerName, - oteltrace.WithInstrumentationVersion(Version()), + ScopeName, + oteltrace.WithInstrumentationVersion(Version), ) if cfg.Propagators == nil { cfg.Propagators = otel.GetTextMapPropagator() } + semconvServer := semconv.NewHTTPServer(nil) + return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { r := req.Request ctx := cfg.Propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) @@ -53,11 +44,11 @@ func OTelFilter(service string, opts ...Option) restful.FilterFunction { spanName := route opts := []oteltrace.SpanStartOption{ - oteltrace.WithAttributes(semconvutil.HTTPServerRequest(service, r)...), + oteltrace.WithAttributes(semconvServer.RequestTraceAttrs(service, r, semconv.RequestTraceAttrsOpts{})...), oteltrace.WithSpanKind(oteltrace.SpanKindServer), } if route != "" { - rAttr := semconv.HTTPRoute(route) + rAttr := semconvServer.Route(route) opts = append(opts, oteltrace.WithAttributes(rAttr)) } @@ -78,9 +69,9 @@ func OTelFilter(service string, opts ...Option) restful.FilterFunction { chain.ProcessFilter(req, resp) status := resp.StatusCode() - span.SetStatus(semconvutil.HTTPServerStatus(status)) - if status > 0 { - span.SetAttributes(semconv.HTTPStatusCode(status)) - } + span.SetStatus(semconvServer.Status(status)) + span.SetAttributes(semconvServer.ResponseTraceAttrs(semconv.ResponseTelemetry{ + StatusCode: status, + })...) } } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/version.go index 089f3b00f6..f0a5ed5b63 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/version.go @@ -1,28 +1,7 @@ // Copyright The OpenTelemetry 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. +// SPDX-License-Identifier: Apache-2.0 package otelrestful // import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful" // Version is the current release version of the go-restful instrumentation. -func Version() string { - return "0.44.0" - // This string is updated by the pre_release.sh script during release -} - -// SemVersion is the semantic version to be supplied to tracer/meter creation. -// -// Deprecated: Use [Version] instead. -func SemVersion() string { - return Version() -} +const Version = "0.65.0" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go index e65c4907c9..0018e2d45f 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go @@ -31,14 +31,15 @@ type Filter func(*stats.RPCTagInfo) bool // config is a group of options for this instrumentation. type config struct { - Filter Filter - InterceptorFilter InterceptorFilter - Propagators propagation.TextMapPropagator - TracerProvider trace.TracerProvider - MeterProvider metric.MeterProvider - SpanStartOptions []trace.SpanStartOption - SpanAttributes []attribute.KeyValue - MetricAttributes []attribute.KeyValue + Filter Filter + InterceptorFilter InterceptorFilter + Propagators propagation.TextMapPropagator + TracerProvider trace.TracerProvider + MeterProvider metric.MeterProvider + SpanStartOptions []trace.SpanStartOption + SpanAttributes []attribute.KeyValue + MetricAttributes []attribute.KeyValue + MetricAttributesFn func(ctx context.Context) []attribute.KeyValue PublicEndpoint bool PublicEndpointFn func(ctx context.Context, info *stats.RPCTagInfo) bool @@ -52,6 +53,12 @@ type Option interface { apply(*config) } +type optionFunc func(*config) + +func (f optionFunc) apply(c *config) { + f(c) +} + // newConfig returns a config configured with all the passed Options. func newConfig(opts []Option) *config { c := &config{ @@ -65,27 +72,13 @@ func newConfig(opts []Option) *config { return c } -type publicEndpointOption struct{ p bool } - -func (o publicEndpointOption) apply(c *config) { - c.PublicEndpoint = o.p -} - // WithPublicEndpoint configures the Handler to link the span with an incoming // span context. If this option is not provided, then the association is a child // association instead of a link. func WithPublicEndpoint() Option { - return publicEndpointOption{p: true} -} - -type publicEndpointFnOption struct { - fn func(context.Context, *stats.RPCTagInfo) bool -} - -func (o publicEndpointFnOption) apply(c *config) { - if o.fn != nil { - c.PublicEndpointFn = o.fn - } + return optionFunc(func(c *config) { + c.PublicEndpoint = true + }) } // WithPublicEndpointFn runs with every request, and allows conditionally @@ -94,81 +87,59 @@ func (o publicEndpointFnOption) apply(c *config) { // child association instead of a link. // Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn. func WithPublicEndpointFn(fn func(context.Context, *stats.RPCTagInfo) bool) Option { - return publicEndpointFnOption{fn: fn} -} - -type propagatorsOption struct{ p propagation.TextMapPropagator } - -func (o propagatorsOption) apply(c *config) { - if o.p != nil { - c.Propagators = o.p - } + return optionFunc(func(c *config) { + c.PublicEndpointFn = fn + }) } // WithPropagators returns an Option to use the Propagators when extracting // and injecting trace context from requests. func WithPropagators(p propagation.TextMapPropagator) Option { - return propagatorsOption{p: p} -} - -type tracerProviderOption struct{ tp trace.TracerProvider } - -func (o tracerProviderOption) apply(c *config) { - if o.tp != nil { - c.TracerProvider = o.tp - } + return optionFunc(func(c *config) { + if p != nil { + c.Propagators = p + } + }) } // WithInterceptorFilter returns an Option to use the request filter. // // Deprecated: Use stats handlers instead. func WithInterceptorFilter(f InterceptorFilter) Option { - return interceptorFilterOption{f: f} -} - -type interceptorFilterOption struct { - f InterceptorFilter -} - -func (o interceptorFilterOption) apply(c *config) { - if o.f != nil { - c.InterceptorFilter = o.f - } + return optionFunc(func(c *config) { + if f != nil { + c.InterceptorFilter = f + } + }) } // WithFilter returns an Option to use the request filter. func WithFilter(f Filter) Option { - return filterOption{f: f} -} - -type filterOption struct { - f Filter -} - -func (o filterOption) apply(c *config) { - if o.f != nil { - c.Filter = o.f - } + return optionFunc(func(c *config) { + if f != nil { + c.Filter = f + } + }) } // WithTracerProvider returns an Option to use the TracerProvider when // creating a Tracer. func WithTracerProvider(tp trace.TracerProvider) Option { - return tracerProviderOption{tp: tp} -} - -type meterProviderOption struct{ mp metric.MeterProvider } - -func (o meterProviderOption) apply(c *config) { - if o.mp != nil { - c.MeterProvider = o.mp - } + return optionFunc(func(c *config) { + if tp != nil { + c.TracerProvider = tp + } + }) } // WithMeterProvider returns an Option to use the MeterProvider when // creating a Meter. If this option is not provide the global MeterProvider will be used. func WithMeterProvider(mp metric.MeterProvider) Option { - return meterProviderOption{mp: mp} + return optionFunc(func(c *config) { + if mp != nil { + c.MeterProvider = mp + } + }) } // Event type that can be recorded, see WithMessageEvents. @@ -180,21 +151,6 @@ const ( SentEvents ) -type messageEventsProviderOption struct { - events []Event -} - -func (m messageEventsProviderOption) apply(c *config) { - for _, e := range m.events { - switch e { - case ReceivedEvents: - c.ReceivedEvent = true - case SentEvents: - c.SentEvent = true - } - } -} - // WithMessageEvents configures the Handler to record the specified events // (span.AddEvent) on spans. By default only summary attributes are added at the // end of the request. @@ -203,13 +159,16 @@ func (m messageEventsProviderOption) apply(c *config) { // - ReceivedEvents: Record the number of bytes read after every gRPC read operation. // - SentEvents: Record the number of bytes written after every gRPC write operation. func WithMessageEvents(events ...Event) Option { - return messageEventsProviderOption{events: events} -} - -type spanStartOption struct{ opts []trace.SpanStartOption } - -func (o spanStartOption) apply(c *config) { - c.SpanStartOptions = append(c.SpanStartOptions, o.opts...) + return optionFunc(func(c *config) { + for _, e := range events { + switch e { + case ReceivedEvents: + c.ReceivedEvent = true + case SentEvents: + c.SentEvent = true + } + } + }) } // WithSpanOptions configures an additional set of @@ -217,31 +176,37 @@ func (o spanStartOption) apply(c *config) { // // Deprecated: It is only used by the deprecated interceptor, and is unused by [NewClientHandler] and [NewServerHandler]. func WithSpanOptions(opts ...trace.SpanStartOption) Option { - return spanStartOption{opts} -} - -type spanAttributesOption struct{ a []attribute.KeyValue } - -func (o spanAttributesOption) apply(c *config) { - if o.a != nil { - c.SpanAttributes = o.a - } + return optionFunc(func(c *config) { + c.SpanStartOptions = append(c.SpanStartOptions, opts...) + }) } // WithSpanAttributes returns an Option to add custom attributes to the spans. func WithSpanAttributes(a ...attribute.KeyValue) Option { - return spanAttributesOption{a: a} -} - -type metricAttributesOption struct{ a []attribute.KeyValue } - -func (o metricAttributesOption) apply(c *config) { - if o.a != nil { - c.MetricAttributes = o.a - } + return optionFunc(func(c *config) { + if a != nil { + c.SpanAttributes = a + } + }) } // WithMetricAttributes returns an Option to add custom attributes to the metrics. func WithMetricAttributes(a ...attribute.KeyValue) Option { - return metricAttributesOption{a: a} + return optionFunc(func(c *config) { + if a != nil { + c.MetricAttributes = append(c.MetricAttributes, a...) + } + }) +} + +// WithMetricAttributesFn returns an Option to add dynamic custom attributes to the handler's metrics. +// The function is called once per RPC and the returned attributes are applied to all metrics recorded by this handler. +// +// The context parameter is the standard gRPC request context and provides access to request-scoped data. +func WithMetricAttributesFn(fn func(ctx context.Context) []attribute.KeyValue) Option { + return optionFunc(func(c *config) { + if fn != nil { + c.MetricAttributesFn = fn + } + }) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go index 99f88ec3b9..24053927ca 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go @@ -11,7 +11,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.37.0" + semconv "go.opentelemetry.io/otel/semconv/v1.39.0" grpc_codes "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go index e46185e0b1..2ab085031a 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go @@ -8,7 +8,7 @@ import ( "strings" "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.37.0" + semconv "go.opentelemetry.io/otel/semconv/v1.39.0" ) // ParseFullMethod returns a span name following the OpenTelemetry semantic @@ -23,19 +23,5 @@ func ParseFullMethod(fullMethod string) (string, []attribute.KeyValue) { return fullMethod, nil } name := fullMethod[1:] - pos := strings.LastIndex(name, "/") - if pos < 0 { - // Invalid format, does not follow `/package.service/method`. - return name, nil - } - service, method := name[:pos], name[pos+1:] - - var attrs []attribute.KeyValue - if service != "" { - attrs = append(attrs, semconv.RPCService(service)) - } - if method != "" { - attrs = append(attrs, semconv.RPCMethod(method)) - } - return name, attrs + return name, []attribute.KeyValue{semconv.RPCMethod(name)} } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go index b427e17247..4c62341d66 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go @@ -6,9 +6,7 @@ package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.g import ( "context" - "go.opentelemetry.io/otel/baggage" "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/metadata" ) @@ -17,9 +15,9 @@ type metadataSupplier struct { } // assert that metadataSupplier implements the TextMapCarrier interface. -var _ propagation.TextMapCarrier = &metadataSupplier{} +var _ propagation.TextMapCarrier = metadataSupplier{} -func (s *metadataSupplier) Get(key string) string { +func (s metadataSupplier) Get(key string) string { values := s.metadata.Get(key) if len(values) == 0 { return "" @@ -27,11 +25,11 @@ func (s *metadataSupplier) Get(key string) string { return values[0] } -func (s *metadataSupplier) Set(key, value string) { +func (s metadataSupplier) Set(key, value string) { s.metadata.Set(key, value) } -func (s *metadataSupplier) Keys() []string { +func (s metadataSupplier) Keys() []string { out := make([]string, 0, len(s.metadata)) for key := range s.metadata { out = append(out, key) @@ -39,50 +37,24 @@ func (s *metadataSupplier) Keys() []string { return out } -// Inject injects correlation context and span context into the gRPC -// metadata object. This function is meant to be used on outgoing -// requests. -// -// Deprecated: Unnecessary public func. -func Inject(ctx context.Context, md *metadata.MD, opts ...Option) { - c := newConfig(opts) - c.Propagators.Inject(ctx, &metadataSupplier{ - metadata: *md, - }) -} - func inject(ctx context.Context, propagators propagation.TextMapPropagator) context.Context { md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.MD{} } - propagators.Inject(ctx, &metadataSupplier{ + propagators.Inject(ctx, metadataSupplier{ metadata: md, }) return metadata.NewOutgoingContext(ctx, md) } -// Extract returns the correlation context and span context that -// another service encoded in the gRPC metadata object with Inject. -// This function is meant to be used on incoming requests. -// -// Deprecated: Unnecessary public func. -func Extract(ctx context.Context, md *metadata.MD, opts ...Option) (baggage.Baggage, trace.SpanContext) { - c := newConfig(opts) - ctx = c.Propagators.Extract(ctx, &metadataSupplier{ - metadata: *md, - }) - - return baggage.FromContext(ctx), trace.SpanContextFromContext(ctx) -} - func extract(ctx context.Context, propagators propagation.TextMapPropagator) context.Context { md, ok := metadata.FromIncomingContext(ctx) if !ok { md = metadata.MD{} } - return propagators.Extract(ctx, &metadataSupplier{ + return propagators.Extract(ctx, metadataSupplier{ metadata: md, }) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go index 29d7ab2bda..0340ca7766 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go @@ -12,8 +12,8 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" - semconv "go.opentelemetry.io/otel/semconv/v1.37.0" - "go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv" + semconv "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv" "go.opentelemetry.io/otel/trace" grpc_codes "google.golang.org/grpc/codes" "google.golang.org/grpc/peer" @@ -26,10 +26,11 @@ import ( type gRPCContextKey struct{} type gRPCContext struct { - inMessages int64 - outMessages int64 - metricAttrs []attribute.KeyValue - record bool + inMessages int64 + outMessages int64 + metricAttrs []attribute.KeyValue + metricAttrSet attribute.Set + record bool } type serverHandler struct { @@ -37,11 +38,9 @@ type serverHandler struct { tracer trace.Tracer - duration rpcconv.ServerDuration - inSize rpcconv.ServerRequestSize - outSize rpcconv.ServerResponseSize - inMsg rpcconv.ServerRequestsPerRPC - outMsg rpcconv.ServerResponsesPerRPC + duration rpcconv.ServerCallDuration + inSize int64Hist + outSize int64Hist } // NewServerHandler creates a stats.Handler for a gRPC server. @@ -51,17 +50,17 @@ func NewServerHandler(opts ...Option) stats.Handler { h.tracer = c.TracerProvider.Tracer( ScopeName, - trace.WithInstrumentationVersion(Version()), + trace.WithInstrumentationVersion(Version), ) meter := c.MeterProvider.Meter( ScopeName, - metric.WithInstrumentationVersion(Version()), + metric.WithInstrumentationVersion(Version), metric.WithSchemaURL(semconv.SchemaURL), ) var err error - h.duration, err = rpcconv.NewServerDuration(meter) + h.duration, err = rpcconv.NewServerCallDuration(meter) if err != nil { otel.Handle(err) } @@ -76,16 +75,6 @@ func NewServerHandler(opts ...Option) stats.Handler { otel.Handle(err) } - h.inMsg, err = rpcconv.NewServerRequestsPerRPC(meter) - if err != nil { - otel.Handle(err) - } - - h.outMsg, err = rpcconv.NewServerResponsesPerRPC(meter) - if err != nil { - otel.Handle(err) - } - return h } @@ -103,7 +92,7 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont ctx = extract(ctx, h.Propagators) name, attrs := internal.ParseFullMethod(info.FullMethodName) - attrs = append(attrs, semconv.RPCSystemGRPC) + attrs = append(attrs, semconv.RPCSystemNameGRPC) record := true if h.Filter != nil { @@ -111,9 +100,12 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont } if record { + // Make a new slice to avoid aliasing into the same attrs slice used by metrics. + spanAttributes := make([]attribute.KeyValue, 0, len(attrs)+len(h.SpanAttributes)) + spanAttributes = append(append(spanAttributes, attrs...), h.SpanAttributes...) opts := []trace.SpanStartOption{ trace.WithSpanKind(trace.SpanKindServer), - trace.WithAttributes(append(attrs, h.SpanAttributes...)...), + trace.WithAttributes(spanAttributes...), } if h.PublicEndpoint || (h.PublicEndpointFn != nil && h.PublicEndpointFn(ctx, info)) { opts = append(opts, trace.WithNewRoot()) @@ -134,6 +126,13 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont record: record, } + if h.MetricAttributesFn != nil { + extraAttrs := h.MetricAttributesFn(ctx) + gctx.metricAttrs = append(gctx.metricAttrs, extraAttrs...) + } + + gctx.metricAttrSet = attribute.NewSet(gctx.metricAttrs...) + return context.WithValue(ctx, gRPCContextKey{}, &gctx) } @@ -145,8 +144,6 @@ func (h *serverHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { h.duration.Inst(), h.inSize, h.outSize, - h.inMsg.Inst(), - h.outMsg.Inst(), serverStatus, ) } @@ -156,11 +153,9 @@ type clientHandler struct { tracer trace.Tracer - duration rpcconv.ClientDuration - inSize rpcconv.ClientResponseSize - outSize rpcconv.ClientRequestSize - inMsg rpcconv.ClientResponsesPerRPC - outMsg rpcconv.ClientRequestsPerRPC + duration rpcconv.ClientCallDuration + inSize int64Hist + outSize int64Hist } // NewClientHandler creates a stats.Handler for a gRPC client. @@ -170,17 +165,17 @@ func NewClientHandler(opts ...Option) stats.Handler { h.tracer = c.TracerProvider.Tracer( ScopeName, - trace.WithInstrumentationVersion(Version()), + trace.WithInstrumentationVersion(Version), ) meter := c.MeterProvider.Meter( ScopeName, - metric.WithInstrumentationVersion(Version()), + metric.WithInstrumentationVersion(Version), metric.WithSchemaURL(semconv.SchemaURL), ) var err error - h.duration, err = rpcconv.NewClientDuration(meter) + h.duration, err = rpcconv.NewClientCallDuration(meter) if err != nil { otel.Handle(err) } @@ -195,23 +190,13 @@ func NewClientHandler(opts ...Option) stats.Handler { otel.Handle(err) } - h.inMsg, err = rpcconv.NewClientResponsesPerRPC(meter) - if err != nil { - otel.Handle(err) - } - - h.outMsg, err = rpcconv.NewClientRequestsPerRPC(meter) - if err != nil { - otel.Handle(err) - } - return h } // TagRPC can attach some information to the given context. func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { name, attrs := internal.ParseFullMethod(info.FullMethodName) - attrs = append(attrs, semconv.RPCSystemGRPC) + attrs = append(attrs, semconv.RPCSystemNameGRPC) record := true if h.Filter != nil { @@ -219,11 +204,14 @@ func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont } if record { + // Make a new slice to avoid aliasing into the same attrs slice used by metrics. + spanAttributes := make([]attribute.KeyValue, 0, len(attrs)+len(h.SpanAttributes)) + spanAttributes = append(append(spanAttributes, attrs...), h.SpanAttributes...) ctx, _ = h.tracer.Start( ctx, name, trace.WithSpanKind(trace.SpanKindClient), - trace.WithAttributes(append(attrs, h.SpanAttributes...)...), + trace.WithAttributes(spanAttributes...), ) } @@ -232,6 +220,13 @@ func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont record: record, } + if h.MetricAttributesFn != nil { + extraAttrs := h.MetricAttributesFn(ctx) + gctx.metricAttrs = append(gctx.metricAttrs, extraAttrs...) + } + + gctx.metricAttrSet = attribute.NewSet(gctx.metricAttrs...) + return inject(context.WithValue(ctx, gRPCContextKey{}, &gctx), h.Propagators) } @@ -243,8 +238,6 @@ func (h *clientHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { h.duration.Inst(), h.inSize, h.outSize, - h.inMsg.Inst(), - h.outMsg.Inst(), func(s *status.Status) (codes.Code, string) { return codes.Error, s.Message() }, @@ -262,7 +255,7 @@ func (*clientHandler) HandleConn(context.Context, stats.ConnStats) { } type int64Hist interface { - Record(context.Context, int64, ...attribute.KeyValue) + RecordSet(context.Context, int64, attribute.Set) } func (c *config) handleRPC( @@ -270,7 +263,6 @@ func (c *config) handleRPC( rs stats.RPCStats, duration metric.Float64Histogram, inSize, outSize int64Hist, - inMsg, outMsg metric.Int64Histogram, recordStatus func(*status.Status) (codes.Code, string), ) { gctx, _ := ctx.Value(gRPCContextKey{}).(*gRPCContext) @@ -286,7 +278,7 @@ func (c *config) handleRPC( case *stats.InPayload: if gctx != nil { messageId = atomic.AddInt64(&gctx.inMessages, 1) - inSize.Record(ctx, int64(rs.Length), gctx.metricAttrs...) + inSize.RecordSet(ctx, int64(rs.Length), gctx.metricAttrSet) } if c.ReceivedEvent && span.IsRecording() { @@ -302,7 +294,7 @@ func (c *config) handleRPC( case *stats.OutPayload: if gctx != nil { messageId = atomic.AddInt64(&gctx.outMessages, 1) - outSize.Record(ctx, int64(rs.Length), gctx.metricAttrs...) + outSize.RecordSet(ctx, int64(rs.Length), gctx.metricAttrSet) } if c.SentEvent && span.IsRecording() { @@ -328,9 +320,9 @@ func (c *config) handleRPC( var s *status.Status if rs.Error != nil { s, _ = status.FromError(rs.Error) - rpcStatusAttr = semconv.RPCGRPCStatusCodeKey.Int(int(s.Code())) + rpcStatusAttr = semconv.RPCResponseStatusCode(s.Code().String()) } else { - rpcStatusAttr = semconv.RPCGRPCStatusCodeKey.Int(int(grpc_codes.OK)) + rpcStatusAttr = semconv.RPCResponseStatusCode(grpc_codes.OK.String()) } if span.IsRecording() { if s != nil { @@ -343,6 +335,9 @@ func (c *config) handleRPC( var metricAttrs []attribute.KeyValue if gctx != nil { + // Don't use gctx.metricAttrSet here, because it requires passing + // multiple RecordOptions, which would call metric.mergeSets and + // allocate a new set for each Record call. metricAttrs = make([]attribute.KeyValue, 0, len(gctx.metricAttrs)+1) metricAttrs = append(metricAttrs, gctx.metricAttrs...) } @@ -355,10 +350,6 @@ func (c *config) handleRPC( elapsedTime := float64(rs.EndTime.Sub(rs.BeginTime)) / float64(time.Millisecond) duration.Record(ctx, elapsedTime, recordOpts...) - if gctx != nil { - inMsg.Record(ctx, atomic.LoadInt64(&gctx.inMessages), recordOpts...) - outMsg.Record(ctx, atomic.LoadInt64(&gctx.outMessages), recordOpts...) - } default: return } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go index aa4f4e2129..f9f963fdd9 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go @@ -4,7 +4,4 @@ package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" // Version is the current release version of the gRPC instrumentation. -func Version() string { - return "0.63.0" - // This string is updated by the pre_release.sh script during release -} +const Version = "0.65.0" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go deleted file mode 100644 index 521daa25db..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - -import ( - "context" - "io" - "net/http" - "net/url" - "strings" -) - -// DefaultClient is the default Client and is used by Get, Head, Post and PostForm. -// Please be careful of initialization order - for example, if you change -// the global propagator, the DefaultClient might still be using the old one. -var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} - -// Get is a convenient replacement for http.Get that adds a span around the request. -func Get(ctx context.Context, targetURL string) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, http.NoBody) - if err != nil { - return nil, err - } - return DefaultClient.Do(req) -} - -// Head is a convenient replacement for http.Head that adds a span around the request. -func Head(ctx context.Context, targetURL string) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, http.MethodHead, targetURL, http.NoBody) - if err != nil { - return nil, err - } - return DefaultClient.Do(req) -} - -// Post is a convenient replacement for http.Post that adds a span around the request. -func Post(ctx context.Context, targetURL, contentType string, body io.Reader) (resp *http.Response, err error) { - req, err := http.NewRequestWithContext(ctx, http.MethodPost, targetURL, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", contentType) - return DefaultClient.Do(req) -} - -// PostForm is a convenient replacement for http.PostForm that adds a span around the request. -func PostForm(ctx context.Context, targetURL string, data url.Values) (resp *http.Response, err error) { - return Post(ctx, targetURL, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go index a83a026274..3ae0824344 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go @@ -23,5 +23,5 @@ const ( type Filter func(*http.Request) bool func newTracer(tp trace.TracerProvider) trace.Tracer { - return tp.Tracer(ScopeName, trace.WithInstrumentationVersion(Version())) + return tp.Tracer(ScopeName, trace.WithInstrumentationVersion(Version)) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go index 38fb79c032..f7338b7e52 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go @@ -26,7 +26,6 @@ type config struct { Meter metric.Meter Propagators propagation.TextMapPropagator SpanStartOptions []trace.SpanStartOption - PublicEndpoint bool PublicEndpointFn func(*http.Request) bool ReadEvent bool WriteEvent bool @@ -67,7 +66,7 @@ func newConfig(opts ...Option) *config { c.Meter = c.MeterProvider.Meter( ScopeName, - metric.WithInstrumentationVersion(Version()), + metric.WithInstrumentationVersion(Version), ) return c @@ -93,20 +92,10 @@ func WithMeterProvider(provider metric.MeterProvider) Option { }) } -// WithPublicEndpoint configures the Handler to link the span with an incoming -// span context. If this option is not provided, then the association is a child -// association instead of a link. -func WithPublicEndpoint() Option { - return optionFunc(func(c *config) { - c.PublicEndpoint = true - }) -} - // WithPublicEndpointFn runs with every request, and allows conditionally // configuring the Handler to link the span with an incoming span context. If // this option is not provided or returns false, then the association is a // child association instead of a link. -// Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn. func WithPublicEndpointFn(fn func(*http.Request) bool) Option { return optionFunc(func(c *config) { c.PublicEndpointFn = fn @@ -143,11 +132,13 @@ func WithFilter(f Filter) Option { }) } -type event int +// Event represents message event types for [WithMessageEvents]. +type Event int // Different types of events that can be recorded, see WithMessageEvents. const ( - ReadEvents event = iota + unspecifiedEvents Event = iota + ReadEvents WriteEvents ) @@ -160,7 +151,7 @@ const ( // using the ReadBytesKey // - WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write // using the WriteBytesKey -func WithMessageEvents(events ...event) Option { +func WithMessageEvents(events ...Event) Option { return optionFunc(func(c *config) { for _, e := range events { switch e { diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go index 56b24b982a..1c9aa3ff42 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go @@ -2,6 +2,5 @@ // SPDX-License-Identifier: Apache-2.0 // Package otelhttp provides an http.Handler and functions that are intended -// to be used to add tracing by wrapping existing handlers (with Handler) and -// routes WithRouteTag. +// to be used to add tracing by wrapping existing handlers. package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go index fef83b42fe..1ecd4be2dd 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go @@ -29,7 +29,6 @@ type middleware struct { writeEvent bool filters []Filter spanNameFormatter func(string, *http.Request) string - publicEndpoint bool publicEndpointFn func(*http.Request) bool metricAttributesFn func(*http.Request) []attribute.KeyValue @@ -77,7 +76,6 @@ func (h *middleware) configure(c *config) { h.writeEvent = c.WriteEvent h.filters = c.Filters h.spanNameFormatter = c.SpanNameFormatter - h.publicEndpoint = c.PublicEndpoint h.publicEndpointFn = c.PublicEndpointFn h.server = c.ServerName h.semconv = semconv.NewHTTPServer(c.Meter) @@ -102,7 +100,7 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http } opts = append(opts, h.spanStartOptions...) - if h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) { + if h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx)) { opts = append(opts, trace.WithNewRoot()) // Linking incoming span context if any for public endpoint. if s := trace.SpanContextFromContext(ctx); s.IsValid() && s.IsRemote() { @@ -221,18 +219,3 @@ func (h *middleware) metricAttributesFromRequest(r *http.Request) []attribute.Ke } return attributeForRequest } - -// WithRouteTag annotates spans and metrics with the provided route name -// with HTTP route attribute. -func WithRouteTag(route string, h http.Handler) http.Handler { - attr := semconv.NewHTTPServer(nil).Route(route) - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - span := trace.SpanFromContext(r.Context()) - span.SetAttributes(attr) - - labeler, _ := LabelerFromContext(r.Context()) - labeler.Add(attr) - - h.ServeHTTP(w, r) - }) -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go new file mode 100644 index 0000000000..29d6f508c1 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go @@ -0,0 +1,287 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconv/client.go.tmpl + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package semconv provides OpenTelemetry semantic convention types and +// functionality. +package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" + +import ( + "context" + "fmt" + "net/http" + "slices" + "strconv" + "strings" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv" +) + +type HTTPClient struct{ + requestBodySize httpconv.ClientRequestBodySize + requestDuration httpconv.ClientRequestDuration +} + +func NewHTTPClient(meter metric.Meter) HTTPClient { + client := HTTPClient{} + + var err error + client.requestBodySize, err = httpconv.NewClientRequestBodySize(meter) + handleErr(err) + + client.requestDuration, err = httpconv.NewClientRequestDuration( + meter, + metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10), + ) + handleErr(err) + + return client +} + +func (n HTTPClient) Status(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 400 { + return codes.Error, "" + } + return codes.Unset, "" +} + +// RequestTraceAttrs returns trace attributes for an HTTP request made by a client. +func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { + /* + below attributes are returned: + - http.request.method + - http.request.method.original + - url.full + - server.address + - server.port + - network.protocol.name + - network.protocol.version + */ + numOfAttributes := 3 // URL, server address, proto, and method. + + var urlHost string + if req.URL != nil { + urlHost = req.URL.Host + } + var requestHost string + var requestPort int + for _, hostport := range []string{urlHost, req.Header.Get("Host")} { + requestHost, requestPort = SplitHostPort(hostport) + if requestHost != "" || requestPort > 0 { + break + } + } + + eligiblePort := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) + if eligiblePort > 0 { + numOfAttributes++ + } + useragent := req.UserAgent() + if useragent != "" { + numOfAttributes++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" && protoName != "http" { + numOfAttributes++ + } + if protoVersion != "" { + numOfAttributes++ + } + + method, originalMethod := n.method(req.Method) + if originalMethod != (attribute.KeyValue{}) { + numOfAttributes++ + } + + attrs := make([]attribute.KeyValue, 0, numOfAttributes) + + attrs = append(attrs, method) + if originalMethod != (attribute.KeyValue{}) { + attrs = append(attrs, originalMethod) + } + + var u string + if req.URL != nil { + // Remove any username/password info that may be in the URL. + userinfo := req.URL.User + req.URL.User = nil + u = req.URL.String() + // Restore any username/password info that was removed. + req.URL.User = userinfo + } + attrs = append(attrs, semconv.URLFull(u)) + + attrs = append(attrs, semconv.ServerAddress(requestHost)) + if eligiblePort > 0 { + attrs = append(attrs, semconv.ServerPort(eligiblePort)) + } + + if protoName != "" && protoName != "http" { + attrs = append(attrs, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attrs = append(attrs, semconv.NetworkProtocolVersion(protoVersion)) + } + + return attrs +} + +// ResponseTraceAttrs returns trace attributes for an HTTP response made by a client. +func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { + /* + below attributes are returned: + - http.response.status_code + - error.type + */ + var count int + if resp.StatusCode > 0 { + count++ + } + + if isErrorStatusCode(resp.StatusCode) { + count++ + } + + attrs := make([]attribute.KeyValue, 0, count) + if resp.StatusCode > 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(resp.StatusCode)) + } + + if isErrorStatusCode(resp.StatusCode) { + errorType := strconv.Itoa(resp.StatusCode) + attrs = append(attrs, semconv.ErrorTypeKey.String(errorType)) + } + return attrs +} + +func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) { + if method == "" { + return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + } + if attr, ok := methodLookup[method]; ok { + return attr, attribute.KeyValue{} + } + + orig := semconv.HTTPRequestMethodOriginal(method) + if attr, ok := methodLookup[strings.ToUpper(method)]; ok { + return attr, orig + } + return semconv.HTTPRequestMethodGet, orig +} + +func (n HTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { + num := len(additionalAttributes) + 2 + var h string + if req.URL != nil { + h = req.URL.Host + } + var requestHost string + var requestPort int + for _, hostport := range []string{h, req.Header.Get("Host")} { + requestHost, requestPort = SplitHostPort(hostport) + if requestHost != "" || requestPort > 0 { + break + } + } + + port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) + if port > 0 { + num++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" { + num++ + } + if protoVersion != "" { + num++ + } + + if statusCode > 0 { + num++ + } + + attributes := slices.Grow(additionalAttributes, num) + attributes = append(attributes, + semconv.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), + semconv.ServerAddress(requestHost), + n.scheme(req), + ) + + if port > 0 { + attributes = append(attributes, semconv.ServerPort(port)) + } + if protoName != "" { + attributes = append(attributes, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attributes = append(attributes, semconv.NetworkProtocolVersion(protoVersion)) + } + + if statusCode > 0 { + attributes = append(attributes, semconv.HTTPResponseStatusCode(statusCode)) + } + return attributes +} + +type MetricOpts struct { + measurement metric.MeasurementOption + addOptions metric.AddOption +} + +func (o MetricOpts) MeasurementOption() metric.MeasurementOption { + return o.measurement +} + +func (o MetricOpts) AddOptions() metric.AddOption { + return o.addOptions +} + +func (n HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts { + opts := map[string]MetricOpts{} + + attributes := n.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) + set := metric.WithAttributeSet(attribute.NewSet(attributes...)) + opts["new"] = MetricOpts{ + measurement: set, + addOptions: set, + } + + return opts +} + +func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) { + n.requestBodySize.Inst().Record(ctx, md.RequestSize, opts["new"].MeasurementOption()) + n.requestDuration.Inst().Record(ctx, md.ElapsedTime/1000, opts["new"].MeasurementOption()) +} + +// TraceAttributes returns attributes for httptrace. +func (n HTTPClient) TraceAttributes(host string) []attribute.KeyValue { + return []attribute.KeyValue{ + semconv.ServerAddress(host), + } +} + +func (n HTTPClient) scheme(req *http.Request) attribute.KeyValue { + if req.URL != nil && req.URL.Scheme != "" { + return semconv.URLScheme(req.URL.Scheme) + } + if req.TLS != nil { + return semconv.URLScheme("https") + } + return semconv.URLScheme("http") +} + +func isErrorStatusCode(code int) bool { + return code >= 400 || code < 100 +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go deleted file mode 100644 index 821b80ec41..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go +++ /dev/null @@ -1,248 +0,0 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconv/env.go.tmpl - -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" - -import ( - "context" - "fmt" - "net/http" - "strings" - "sync" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/semconv/v1.37.0/httpconv" -) - -// OTelSemConvStabilityOptIn is an environment variable. -// That can be set to "http/dup" to keep getting the old HTTP semantic conventions. -const OTelSemConvStabilityOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN" - -type ResponseTelemetry struct { - StatusCode int - ReadBytes int64 - ReadError error - WriteBytes int64 - WriteError error -} - -type HTTPServer struct { - requestBodySizeHistogram httpconv.ServerRequestBodySize - responseBodySizeHistogram httpconv.ServerResponseBodySize - requestDurationHistogram httpconv.ServerRequestDuration -} - -// RequestTraceAttrs returns trace attributes for an HTTP request received by a -// server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -func (s HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { - return CurrentHTTPServer{}.RequestTraceAttrs(server, req, opts) -} - -func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { - return []attribute.KeyValue{ - CurrentHTTPServer{}.NetworkTransportAttr(network), - } -} - -// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response. -// -// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted. -func (s HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { - return CurrentHTTPServer{}.ResponseTraceAttrs(resp) -} - -// Route returns the attribute for the route. -func (s HTTPServer) Route(route string) attribute.KeyValue { - return CurrentHTTPServer{}.Route(route) -} - -// Status returns a span status code and message for an HTTP status code -// value returned by a server. Status codes in the 400-499 range are not -// returned as errors. -func (s HTTPServer) Status(code int) (codes.Code, string) { - if code < 100 || code >= 600 { - return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) - } - if code >= 500 { - return codes.Error, "" - } - return codes.Unset, "" -} - -type ServerMetricData struct { - ServerName string - ResponseSize int64 - - MetricData - MetricAttributes -} - -type MetricAttributes struct { - Req *http.Request - StatusCode int - AdditionalAttributes []attribute.KeyValue -} - -type MetricData struct { - RequestSize int64 - - // The request duration, in milliseconds - ElapsedTime float64 -} - -var ( - metricAddOptionPool = &sync.Pool{ - New: func() any { - return &[]metric.AddOption{} - }, - } - - metricRecordOptionPool = &sync.Pool{ - New: func() any { - return &[]metric.RecordOption{} - }, - } -) - -func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { - attributes := CurrentHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes) - o := metric.WithAttributeSet(attribute.NewSet(attributes...)) - recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) - *recordOpts = append(*recordOpts, o) - s.requestBodySizeHistogram.Inst().Record(ctx, md.RequestSize, *recordOpts...) - s.responseBodySizeHistogram.Inst().Record(ctx, md.ResponseSize, *recordOpts...) - s.requestDurationHistogram.Inst().Record(ctx, md.ElapsedTime/1000.0, o) - *recordOpts = (*recordOpts)[:0] - metricRecordOptionPool.Put(recordOpts) -} - -// hasOptIn returns true if the comma-separated version string contains the -// exact optIn value. -func hasOptIn(version, optIn string) bool { - for _, v := range strings.Split(version, ",") { - if strings.TrimSpace(v) == optIn { - return true - } - } - return false -} - -func NewHTTPServer(meter metric.Meter) HTTPServer { - server := HTTPServer{} - - var err error - server.requestBodySizeHistogram, err = httpconv.NewServerRequestBodySize(meter) - handleErr(err) - - server.responseBodySizeHistogram, err = httpconv.NewServerResponseBodySize(meter) - handleErr(err) - - server.requestDurationHistogram, err = httpconv.NewServerRequestDuration( - meter, - metric.WithExplicitBucketBoundaries( - 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, - 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10, - ), - ) - handleErr(err) - return server -} - -type HTTPClient struct { - requestBodySize httpconv.ClientRequestBodySize - requestDuration httpconv.ClientRequestDuration -} - -func NewHTTPClient(meter metric.Meter) HTTPClient { - client := HTTPClient{} - - var err error - client.requestBodySize, err = httpconv.NewClientRequestBodySize(meter) - handleErr(err) - - client.requestDuration, err = httpconv.NewClientRequestDuration( - meter, - metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10), - ) - handleErr(err) - - return client -} - -// RequestTraceAttrs returns attributes for an HTTP request made by a client. -func (c HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { - return CurrentHTTPClient{}.RequestTraceAttrs(req) -} - -// ResponseTraceAttrs returns metric attributes for an HTTP request made by a client. -func (c HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { - return CurrentHTTPClient{}.ResponseTraceAttrs(resp) -} - -func (c HTTPClient) Status(code int) (codes.Code, string) { - if code < 100 || code >= 600 { - return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) - } - if code >= 400 { - return codes.Error, "" - } - return codes.Unset, "" -} - -func (c HTTPClient) ErrorType(err error) attribute.KeyValue { - return CurrentHTTPClient{}.ErrorType(err) -} - -type MetricOpts struct { - measurement metric.MeasurementOption - addOptions metric.AddOption -} - -func (o MetricOpts) MeasurementOption() metric.MeasurementOption { - return o.measurement -} - -func (o MetricOpts) AddOptions() metric.AddOption { - return o.addOptions -} - -func (c HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts { - opts := map[string]MetricOpts{} - - attributes := CurrentHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) - set := metric.WithAttributeSet(attribute.NewSet(attributes...)) - opts["new"] = MetricOpts{ - measurement: set, - addOptions: set, - } - - return opts -} - -func (s HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) { - s.requestBodySize.Inst().Record(ctx, md.RequestSize, opts["new"].MeasurementOption()) - s.requestDuration.Inst().Record(ctx, md.ElapsedTime/1000, opts["new"].MeasurementOption()) -} - -func (s HTTPClient) TraceAttributes(host string) []attribute.KeyValue { - return CurrentHTTPClient{}.TraceAttributes(host) -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go index 1bb207b809..a8a0d58df3 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go @@ -6,10 +6,10 @@ package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/ // Generate semconv package: //go:generate gotmpl --body=../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=bench_test.go //go:generate gotmpl --body=../../../../../../internal/shared/semconv/common_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=common_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env_test.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv.go -//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/server.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=server.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/server_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=server_test.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/client.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=client.go +//go:generate gotmpl --body=../../../../../../internal/shared/semconv/client_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=client_test.go //go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconvtest_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconvtest_test.go //go:generate gotmpl --body=../../../../../../internal/shared/semconv/util.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util.go //go:generate gotmpl --body=../../../../../../internal/shared/semconv/util_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util_test.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go deleted file mode 100644 index 28c51a3b38..0000000000 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go +++ /dev/null @@ -1,517 +0,0 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconv/httpconv.go.tmpl - -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Package semconv provides OpenTelemetry semantic convention types and -// functionality. -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" - -import ( - "fmt" - "net/http" - "reflect" - "slices" - "strconv" - "strings" - - "go.opentelemetry.io/otel/attribute" - semconvNew "go.opentelemetry.io/otel/semconv/v1.37.0" -) - -type RequestTraceAttrsOpts struct { - // If set, this is used as value for the "http.client_ip" attribute. - HTTPClientIP string -} - -type CurrentHTTPServer struct{} - -// RequestTraceAttrs returns trace attributes for an HTTP request received by a -// server. -// -// The server must be the primary server name if it is known. For example this -// would be the ServerName directive -// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache -// server, and the server_name directive -// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an -// nginx server. More generically, the primary server name would be the host -// header value that matches the default virtual host of an HTTP server. It -// should include the host identifier and if a port is used to route to the -// server that port identifier should be included as an appropriate port -// suffix. -// -// If the primary server name is not known, server should be an empty string. -// The req Host will be used to determine the server instead. -func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { - count := 3 // ServerAddress, Method, Scheme - - var host string - var p int - if server == "" { - host, p = SplitHostPort(req.Host) - } else { - // Prioritize the primary server name. - host, p = SplitHostPort(server) - if p < 0 { - _, p = SplitHostPort(req.Host) - } - } - - hostPort := requiredHTTPPort(req.TLS != nil, p) - if hostPort > 0 { - count++ - } - - method, methodOriginal := n.method(req.Method) - if methodOriginal != (attribute.KeyValue{}) { - count++ - } - - scheme := n.scheme(req.TLS != nil) - - peer, peerPort := SplitHostPort(req.RemoteAddr) - if peer != "" { - // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a - // file-path that would be interpreted with a sock family. - count++ - if peerPort > 0 { - count++ - } - } - - useragent := req.UserAgent() - if useragent != "" { - count++ - } - - // For client IP, use, in order: - // 1. The value passed in the options - // 2. The value in the X-Forwarded-For header - // 3. The peer address - clientIP := opts.HTTPClientIP - if clientIP == "" { - clientIP = serverClientIP(req.Header.Get("X-Forwarded-For")) - if clientIP == "" { - clientIP = peer - } - } - if clientIP != "" { - count++ - } - - if req.URL != nil && req.URL.Path != "" { - count++ - } - - protoName, protoVersion := netProtocol(req.Proto) - if protoName != "" && protoName != "http" { - count++ - } - if protoVersion != "" { - count++ - } - - route := httpRoute(req.Pattern) - if route != "" { - count++ - } - - attrs := make([]attribute.KeyValue, 0, count) - attrs = append(attrs, - semconvNew.ServerAddress(host), - method, - scheme, - ) - - if hostPort > 0 { - attrs = append(attrs, semconvNew.ServerPort(hostPort)) - } - if methodOriginal != (attribute.KeyValue{}) { - attrs = append(attrs, methodOriginal) - } - - if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" { - // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a - // file-path that would be interpreted with a sock family. - attrs = append(attrs, semconvNew.NetworkPeerAddress(peer)) - if peerPort > 0 { - attrs = append(attrs, semconvNew.NetworkPeerPort(peerPort)) - } - } - - if useragent != "" { - attrs = append(attrs, semconvNew.UserAgentOriginal(useragent)) - } - - if clientIP != "" { - attrs = append(attrs, semconvNew.ClientAddress(clientIP)) - } - - if req.URL != nil && req.URL.Path != "" { - attrs = append(attrs, semconvNew.URLPath(req.URL.Path)) - } - - if protoName != "" && protoName != "http" { - attrs = append(attrs, semconvNew.NetworkProtocolName(protoName)) - } - if protoVersion != "" { - attrs = append(attrs, semconvNew.NetworkProtocolVersion(protoVersion)) - } - - if route != "" { - attrs = append(attrs, n.Route(route)) - } - - return attrs -} - -func (n CurrentHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue { - switch network { - case "tcp", "tcp4", "tcp6": - return semconvNew.NetworkTransportTCP - case "udp", "udp4", "udp6": - return semconvNew.NetworkTransportUDP - case "unix", "unixgram", "unixpacket": - return semconvNew.NetworkTransportUnix - default: - return semconvNew.NetworkTransportPipe - } -} - -func (n CurrentHTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { - if method == "" { - return semconvNew.HTTPRequestMethodGet, attribute.KeyValue{} - } - if attr, ok := methodLookup[method]; ok { - return attr, attribute.KeyValue{} - } - - orig := semconvNew.HTTPRequestMethodOriginal(method) - if attr, ok := methodLookup[strings.ToUpper(method)]; ok { - return attr, orig - } - return semconvNew.HTTPRequestMethodGet, orig -} - -func (n CurrentHTTPServer) scheme(https bool) attribute.KeyValue { //nolint:revive // ignore linter - if https { - return semconvNew.URLScheme("https") - } - return semconvNew.URLScheme("http") -} - -// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP -// response. -// -// If any of the fields in the ResponseTelemetry are not set the attribute will -// be omitted. -func (n CurrentHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { - var count int - - if resp.ReadBytes > 0 { - count++ - } - if resp.WriteBytes > 0 { - count++ - } - if resp.StatusCode > 0 { - count++ - } - - attributes := make([]attribute.KeyValue, 0, count) - - if resp.ReadBytes > 0 { - attributes = append(attributes, - semconvNew.HTTPRequestBodySize(int(resp.ReadBytes)), - ) - } - if resp.WriteBytes > 0 { - attributes = append(attributes, - semconvNew.HTTPResponseBodySize(int(resp.WriteBytes)), - ) - } - if resp.StatusCode > 0 { - attributes = append(attributes, - semconvNew.HTTPResponseStatusCode(resp.StatusCode), - ) - } - - return attributes -} - -// Route returns the attribute for the route. -func (n CurrentHTTPServer) Route(route string) attribute.KeyValue { - return semconvNew.HTTPRoute(route) -} - -func (n CurrentHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { - num := len(additionalAttributes) + 3 - var host string - var p int - if server == "" { - host, p = SplitHostPort(req.Host) - } else { - // Prioritize the primary server name. - host, p = SplitHostPort(server) - if p < 0 { - _, p = SplitHostPort(req.Host) - } - } - hostPort := requiredHTTPPort(req.TLS != nil, p) - if hostPort > 0 { - num++ - } - protoName, protoVersion := netProtocol(req.Proto) - if protoName != "" { - num++ - } - if protoVersion != "" { - num++ - } - - if statusCode > 0 { - num++ - } - - attributes := slices.Grow(additionalAttributes, num) - attributes = append(attributes, - semconvNew.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), - n.scheme(req.TLS != nil), - semconvNew.ServerAddress(host)) - - if hostPort > 0 { - attributes = append(attributes, semconvNew.ServerPort(hostPort)) - } - if protoName != "" { - attributes = append(attributes, semconvNew.NetworkProtocolName(protoName)) - } - if protoVersion != "" { - attributes = append(attributes, semconvNew.NetworkProtocolVersion(protoVersion)) - } - - if statusCode > 0 { - attributes = append(attributes, semconvNew.HTTPResponseStatusCode(statusCode)) - } - return attributes -} - -type CurrentHTTPClient struct{} - -// RequestTraceAttrs returns trace attributes for an HTTP request made by a client. -func (n CurrentHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { - /* - below attributes are returned: - - http.request.method - - http.request.method.original - - url.full - - server.address - - server.port - - network.protocol.name - - network.protocol.version - */ - numOfAttributes := 3 // URL, server address, proto, and method. - - var urlHost string - if req.URL != nil { - urlHost = req.URL.Host - } - var requestHost string - var requestPort int - for _, hostport := range []string{urlHost, req.Header.Get("Host")} { - requestHost, requestPort = SplitHostPort(hostport) - if requestHost != "" || requestPort > 0 { - break - } - } - - eligiblePort := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) - if eligiblePort > 0 { - numOfAttributes++ - } - useragent := req.UserAgent() - if useragent != "" { - numOfAttributes++ - } - - protoName, protoVersion := netProtocol(req.Proto) - if protoName != "" && protoName != "http" { - numOfAttributes++ - } - if protoVersion != "" { - numOfAttributes++ - } - - method, originalMethod := n.method(req.Method) - if originalMethod != (attribute.KeyValue{}) { - numOfAttributes++ - } - - attrs := make([]attribute.KeyValue, 0, numOfAttributes) - - attrs = append(attrs, method) - if originalMethod != (attribute.KeyValue{}) { - attrs = append(attrs, originalMethod) - } - - var u string - if req.URL != nil { - // Remove any username/password info that may be in the URL. - userinfo := req.URL.User - req.URL.User = nil - u = req.URL.String() - // Restore any username/password info that was removed. - req.URL.User = userinfo - } - attrs = append(attrs, semconvNew.URLFull(u)) - - attrs = append(attrs, semconvNew.ServerAddress(requestHost)) - if eligiblePort > 0 { - attrs = append(attrs, semconvNew.ServerPort(eligiblePort)) - } - - if protoName != "" && protoName != "http" { - attrs = append(attrs, semconvNew.NetworkProtocolName(protoName)) - } - if protoVersion != "" { - attrs = append(attrs, semconvNew.NetworkProtocolVersion(protoVersion)) - } - - return attrs -} - -// ResponseTraceAttrs returns trace attributes for an HTTP response made by a client. -func (n CurrentHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { - /* - below attributes are returned: - - http.response.status_code - - error.type - */ - var count int - if resp.StatusCode > 0 { - count++ - } - - if isErrorStatusCode(resp.StatusCode) { - count++ - } - - attrs := make([]attribute.KeyValue, 0, count) - if resp.StatusCode > 0 { - attrs = append(attrs, semconvNew.HTTPResponseStatusCode(resp.StatusCode)) - } - - if isErrorStatusCode(resp.StatusCode) { - errorType := strconv.Itoa(resp.StatusCode) - attrs = append(attrs, semconvNew.ErrorTypeKey.String(errorType)) - } - return attrs -} - -func (n CurrentHTTPClient) ErrorType(err error) attribute.KeyValue { - t := reflect.TypeOf(err) - var value string - if t.PkgPath() == "" && t.Name() == "" { - // Likely a builtin type. - value = t.String() - } else { - value = fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) - } - - if value == "" { - return semconvNew.ErrorTypeOther - } - - return semconvNew.ErrorTypeKey.String(value) -} - -func (n CurrentHTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) { - if method == "" { - return semconvNew.HTTPRequestMethodGet, attribute.KeyValue{} - } - if attr, ok := methodLookup[method]; ok { - return attr, attribute.KeyValue{} - } - - orig := semconvNew.HTTPRequestMethodOriginal(method) - if attr, ok := methodLookup[strings.ToUpper(method)]; ok { - return attr, orig - } - return semconvNew.HTTPRequestMethodGet, orig -} - -func (n CurrentHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { - num := len(additionalAttributes) + 2 - var h string - if req.URL != nil { - h = req.URL.Host - } - var requestHost string - var requestPort int - for _, hostport := range []string{h, req.Header.Get("Host")} { - requestHost, requestPort = SplitHostPort(hostport) - if requestHost != "" || requestPort > 0 { - break - } - } - - port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort) - if port > 0 { - num++ - } - - protoName, protoVersion := netProtocol(req.Proto) - if protoName != "" { - num++ - } - if protoVersion != "" { - num++ - } - - if statusCode > 0 { - num++ - } - - attributes := slices.Grow(additionalAttributes, num) - attributes = append(attributes, - semconvNew.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), - semconvNew.ServerAddress(requestHost), - n.scheme(req), - ) - - if port > 0 { - attributes = append(attributes, semconvNew.ServerPort(port)) - } - if protoName != "" { - attributes = append(attributes, semconvNew.NetworkProtocolName(protoName)) - } - if protoVersion != "" { - attributes = append(attributes, semconvNew.NetworkProtocolVersion(protoVersion)) - } - - if statusCode > 0 { - attributes = append(attributes, semconvNew.HTTPResponseStatusCode(statusCode)) - } - return attributes -} - -// TraceAttributes returns attributes for httptrace. -func (n CurrentHTTPClient) TraceAttributes(host string) []attribute.KeyValue { - return []attribute.KeyValue{ - semconvNew.ServerAddress(host), - } -} - -func (n CurrentHTTPClient) scheme(req *http.Request) attribute.KeyValue { - if req.URL != nil && req.URL.Scheme != "" { - return semconvNew.URLScheme(req.URL.Scheme) - } - if req.TLS != nil { - return semconvNew.URLScheme("https") - } - return semconvNew.URLScheme("http") -} - -func isErrorStatusCode(code int) bool { - return code >= 400 || code < 100 -} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go new file mode 100644 index 0000000000..e0e9ebc05d --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go @@ -0,0 +1,403 @@ +// Code generated by gotmpl. DO NOT MODIFY. +// source: internal/shared/semconv/server.go.tmpl + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package semconv provides OpenTelemetry semantic convention types and +// functionality. +package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" + +import ( + "context" + "fmt" + "net/http" + "slices" + "strings" + "sync" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv" +) + +type RequestTraceAttrsOpts struct { + // If set, this is used as value for the "http.client_ip" attribute. + HTTPClientIP string +} + +type ResponseTelemetry struct { + StatusCode int + ReadBytes int64 + ReadError error + WriteBytes int64 + WriteError error +} + +type HTTPServer struct{ + requestBodySizeHistogram httpconv.ServerRequestBodySize + responseBodySizeHistogram httpconv.ServerResponseBodySize + requestDurationHistogram httpconv.ServerRequestDuration +} + +func NewHTTPServer(meter metric.Meter) HTTPServer { + server := HTTPServer{} + + var err error + server.requestBodySizeHistogram, err = httpconv.NewServerRequestBodySize(meter) + handleErr(err) + + server.responseBodySizeHistogram, err = httpconv.NewServerResponseBodySize(meter) + handleErr(err) + + server.requestDurationHistogram, err = httpconv.NewServerRequestDuration( + meter, + metric.WithExplicitBucketBoundaries( + 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, + 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10, + ), + ) + handleErr(err) + return server +} + +// Status returns a span status code and message for an HTTP status code +// value returned by a server. Status codes in the 400-499 range are not +// returned as errors. +func (n HTTPServer) Status(code int) (codes.Code, string) { + if code < 100 || code >= 600 { + return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) + } + if code >= 500 { + return codes.Error, "" + } + return codes.Unset, "" +} + +// RequestTraceAttrs returns trace attributes for an HTTP request received by a +// server. +// +// The server must be the primary server name if it is known. For example this +// would be the ServerName directive +// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache +// server, and the server_name directive +// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an +// nginx server. More generically, the primary server name would be the host +// header value that matches the default virtual host of an HTTP server. It +// should include the host identifier and if a port is used to route to the +// server that port identifier should be included as an appropriate port +// suffix. +// +// If the primary server name is not known, server should be an empty string. +// The req Host will be used to determine the server instead. +func (n HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts RequestTraceAttrsOpts) []attribute.KeyValue { + count := 3 // ServerAddress, Method, Scheme + + var host string + var p int + if server == "" { + host, p = SplitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = SplitHostPort(server) + if p < 0 { + _, p = SplitHostPort(req.Host) + } + } + + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + count++ + } + + method, methodOriginal := n.method(req.Method) + if methodOriginal != (attribute.KeyValue{}) { + count++ + } + + scheme := n.scheme(req.TLS != nil) + + peer, peerPort := SplitHostPort(req.RemoteAddr) + if peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + count++ + if peerPort > 0 { + count++ + } + } + + useragent := req.UserAgent() + if useragent != "" { + count++ + } + + // For client IP, use, in order: + // 1. The value passed in the options + // 2. The value in the X-Forwarded-For header + // 3. The peer address + clientIP := opts.HTTPClientIP + if clientIP == "" { + clientIP = serverClientIP(req.Header.Get("X-Forwarded-For")) + if clientIP == "" { + clientIP = peer + } + } + if clientIP != "" { + count++ + } + + if req.URL != nil && req.URL.Path != "" { + count++ + } + + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" && protoName != "http" { + count++ + } + if protoVersion != "" { + count++ + } + + route := httpRoute(req.Pattern) + if route != "" { + count++ + } + + attrs := make([]attribute.KeyValue, 0, count) + attrs = append(attrs, + semconv.ServerAddress(host), + method, + scheme, + ) + + if hostPort > 0 { + attrs = append(attrs, semconv.ServerPort(hostPort)) + } + if methodOriginal != (attribute.KeyValue{}) { + attrs = append(attrs, methodOriginal) + } + + if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" { + // The Go HTTP server sets RemoteAddr to "IP:port", this will not be a + // file-path that would be interpreted with a sock family. + attrs = append(attrs, semconv.NetworkPeerAddress(peer)) + if peerPort > 0 { + attrs = append(attrs, semconv.NetworkPeerPort(peerPort)) + } + } + + if useragent != "" { + attrs = append(attrs, semconv.UserAgentOriginal(useragent)) + } + + if clientIP != "" { + attrs = append(attrs, semconv.ClientAddress(clientIP)) + } + + if req.URL != nil && req.URL.Path != "" { + attrs = append(attrs, semconv.URLPath(req.URL.Path)) + } + + if protoName != "" && protoName != "http" { + attrs = append(attrs, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attrs = append(attrs, semconv.NetworkProtocolVersion(protoVersion)) + } + + if route != "" { + attrs = append(attrs, n.Route(route)) + } + + return attrs +} + +func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { + attr := semconv.NetworkTransportPipe + switch network { + case "tcp", "tcp4", "tcp6": + attr = semconv.NetworkTransportTCP + case "udp", "udp4", "udp6": + attr = semconv.NetworkTransportUDP + case "unix", "unixgram", "unixpacket": + attr = semconv.NetworkTransportUnix + } + + return []attribute.KeyValue{attr} +} + +type ServerMetricData struct { + ServerName string + ResponseSize int64 + + MetricData + MetricAttributes +} + +type MetricAttributes struct { + Req *http.Request + StatusCode int + Route string + AdditionalAttributes []attribute.KeyValue +} + +type MetricData struct { + RequestSize int64 + + // The request duration, in milliseconds + ElapsedTime float64 +} + +var ( + metricAddOptionPool = &sync.Pool{ + New: func() any { + return &[]metric.AddOption{} + }, + } + + metricRecordOptionPool = &sync.Pool{ + New: func() any { + return &[]metric.RecordOption{} + }, + } +) + +func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { + attributes := n.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.Route, md.AdditionalAttributes) + o := metric.WithAttributeSet(attribute.NewSet(attributes...)) + recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) + *recordOpts = append(*recordOpts, o) + n.requestBodySizeHistogram.Inst().Record(ctx, md.RequestSize, *recordOpts...) + n.responseBodySizeHistogram.Inst().Record(ctx, md.ResponseSize, *recordOpts...) + n.requestDurationHistogram.Inst().Record(ctx, md.ElapsedTime/1000.0, o) + *recordOpts = (*recordOpts)[:0] + metricRecordOptionPool.Put(recordOpts) +} + +func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { + if method == "" { + return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + } + if attr, ok := methodLookup[method]; ok { + return attr, attribute.KeyValue{} + } + + orig := semconv.HTTPRequestMethodOriginal(method) + if attr, ok := methodLookup[strings.ToUpper(method)]; ok { + return attr, orig + } + return semconv.HTTPRequestMethodGet, orig +} + +func (n HTTPServer) scheme(https bool) attribute.KeyValue { //nolint:revive // ignore linter + if https { + return semconv.URLScheme("https") + } + return semconv.URLScheme("http") +} + +// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP +// response. +// +// If any of the fields in the ResponseTelemetry are not set the attribute will +// be omitted. +func (n HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { + var count int + + if resp.ReadBytes > 0 { + count++ + } + if resp.WriteBytes > 0 { + count++ + } + if resp.StatusCode > 0 { + count++ + } + + attributes := make([]attribute.KeyValue, 0, count) + + if resp.ReadBytes > 0 { + attributes = append(attributes, + semconv.HTTPRequestBodySize(int(resp.ReadBytes)), + ) + } + if resp.WriteBytes > 0 { + attributes = append(attributes, + semconv.HTTPResponseBodySize(int(resp.WriteBytes)), + ) + } + if resp.StatusCode > 0 { + attributes = append(attributes, + semconv.HTTPResponseStatusCode(resp.StatusCode), + ) + } + + return attributes +} + +// Route returns the attribute for the route. +func (n HTTPServer) Route(route string) attribute.KeyValue { + return semconv.HTTPRoute(route) +} + +func (n HTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, route string, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { + num := len(additionalAttributes) + 3 + var host string + var p int + if server == "" { + host, p = SplitHostPort(req.Host) + } else { + // Prioritize the primary server name. + host, p = SplitHostPort(server) + if p < 0 { + _, p = SplitHostPort(req.Host) + } + } + hostPort := requiredHTTPPort(req.TLS != nil, p) + if hostPort > 0 { + num++ + } + protoName, protoVersion := netProtocol(req.Proto) + if protoName != "" { + num++ + } + if protoVersion != "" { + num++ + } + + if statusCode > 0 { + num++ + } + + if route != "" { + num++ + } + + attributes := slices.Grow(additionalAttributes, num) + attributes = append(attributes, + semconv.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), + n.scheme(req.TLS != nil), + semconv.ServerAddress(host)) + + if hostPort > 0 { + attributes = append(attributes, semconv.ServerPort(hostPort)) + } + if protoName != "" { + attributes = append(attributes, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attributes = append(attributes, semconv.NetworkProtocolVersion(protoVersion)) + } + + if statusCode > 0 { + attributes = append(attributes, semconv.HTTPResponseStatusCode(statusCode)) + } + + if route != "" { + attributes = append(attributes, semconv.HTTPRoute(route)) + } + return attributes +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go index 96422ad1ed..131fda489b 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go @@ -14,7 +14,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - semconvNew "go.opentelemetry.io/otel/semconv/v1.37.0" + semconvNew "go.opentelemetry.io/otel/semconv/v1.39.0" ) // SplitHostPort splits a network address hostport of the form "host", diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go index 514ae6753b..59b6c5498d 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go @@ -5,6 +5,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http import ( "context" + "fmt" "io" "net/http" "net/http/httptrace" @@ -15,6 +16,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/propagation" + otelsemconv "go.opentelemetry.io/otel/semconv/v1.39.0" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" @@ -83,6 +85,8 @@ func defaultTransportFormatter(_ string, r *http.Request) string { // RoundTrip creates a Span and propagates its context via the provided request's headers // before handing the request to the configured base RoundTripper. The created span will // end when the response body is closed or when a read from the body returns io.EOF. +// If GetBody returns an error, the error is reported via otel.Handle and the request +// continues with the original Body. func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { requestStartTime := time.Now() for _, f := range t.filters { @@ -117,11 +121,22 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { r = r.Clone(ctx) // According to RoundTripper spec, we shouldn't modify the origin request. - // if request body is nil or NoBody, we don't want to mutate the body as it + // GetBody is preferred over direct access to Body if the function is set. + // If the resulting body is nil or is NoBody, we don't want to mutate the body as it // will affect the identity of it in an unforeseeable way because we assert // ReadCloser fulfills a certain interface and it is indeed nil or NoBody. - bw := request.NewBodyWrapper(r.Body, func(int64) {}) - if r.Body != nil && r.Body != http.NoBody { + body := r.Body + if r.GetBody != nil { + b, err := r.GetBody() + if err != nil { + otel.Handle(fmt.Errorf("http.Request GetBody returned an error: %w", err)) + } else { + body = b + } + } + + bw := request.NewBodyWrapper(body, func(int64) {}) + if body != nil && body != http.NoBody { r.Body = bw } @@ -161,15 +176,7 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { }() if err != nil { - // set error type attribute if the error is part of the predefined - // error types. - // otherwise, record it as an exception - if errType := t.semconv.ErrorType(err); errType.Valid() { - span.SetAttributes(errType) - } else { - span.RecordError(err) - } - + span.SetAttributes(otelsemconv.ErrorType(err)) span.SetStatus(codes.Error, err.Error()) span.End() @@ -229,7 +236,7 @@ func (wb *wrappedBody) Write(p []byte) (int, error) { // This will not panic given the guard in newWrappedBody. n, err := wb.body.(io.Writer).Write(p) if err != nil { - wb.span.RecordError(err) + wb.span.SetAttributes(otelsemconv.ErrorType(err)) wb.span.SetStatus(codes.Error, err.Error()) } return n, err @@ -247,7 +254,7 @@ func (wb *wrappedBody) Read(b []byte) (int, error) { wb.recordBytesRead() wb.span.End() default: - wb.span.RecordError(err) + wb.span.SetAttributes(otelsemconv.ErrorType(err)) wb.span.SetStatus(codes.Error, err.Error()) } return n, err diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go index dfb53cf1f3..d0107952e1 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go @@ -4,7 +4,4 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" // Version is the current release version of the otelhttp instrumentation. -func Version() string { - return "0.63.0" - // This string is updated by the pre_release.sh script during release -} +const Version = "0.65.0" diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index d487228759..d12c8920af 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -194,6 +194,7 @@ linters: arguments: - ["ID"] # AllowList - ["Otel", "Aws", "Gcp"] # DenyList + - - skip-package-name-collision-with-go-std: true - name: waitgroup-by-value testifylint: enable-all: true diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index e725282bec..f0595b5e5e 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -8,6 +8,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [1.41.0/0.63.0/0.17.0/0.0.15] 2026-03-02 + +This release is the last to support [Go 1.24]. +The next release will require at least [Go 1.25]. + +### Added + +- Support testing of [Go 1.26]. (#7902) + +### Fixed + +- Update `Baggage` in `go.opentelemetry.io/otel/propagation` and `Parse` and `New` in `go.opentelemetry.io/otel/baggage` to comply with W3C Baggage specification limits. + `New` and `Parse` now return partial baggage along with an error when limits are exceeded. + Errors from baggage extraction are reported to the global error handler. (#7880) +- Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#7914) +- Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#7914) +- Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#7914) + @@ -3535,7 +3553,8 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.41.0...HEAD +[1.41.0/0.63.0/0.17.0/0.0.15]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.41.0 [1.40.0/0.62.0/0.16.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.40.0 [1.39.0/0.61.0/0.15.0/0.0.14]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.39.0 [1.38.0/0.60.0/0.14.0/0.0.13]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.38.0 @@ -3635,6 +3654,7 @@ It contains api and sdk for trace and meter. +[Go 1.26]: https://go.dev/doc/go1.26 [Go 1.25]: https://go.dev/doc/go1.25 [Go 1.24]: https://go.dev/doc/go1.24 [Go 1.23]: https://go.dev/doc/go1.23 diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index 44870248c3..fc4befb227 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -215,7 +215,7 @@ go-mod-tidy/%: crosslink && $(GO) mod tidy -compat=1.21 .PHONY: lint -lint: misspell go-mod-tidy golangci-lint govulncheck +lint: misspell go-mod-tidy golangci-lint .PHONY: vanity-import-check vanity-import-check: $(PORTO) diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index c633595431..6b1e170c4b 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -53,18 +53,25 @@ Currently, this project supports the following environments. | OS | Go Version | Architecture | |----------|------------|--------------| +| Ubuntu | 1.26 | amd64 | | Ubuntu | 1.25 | amd64 | | Ubuntu | 1.24 | amd64 | +| Ubuntu | 1.26 | 386 | | Ubuntu | 1.25 | 386 | | Ubuntu | 1.24 | 386 | +| Ubuntu | 1.26 | arm64 | | Ubuntu | 1.25 | arm64 | | Ubuntu | 1.24 | arm64 | +| macOS | 1.26 | amd64 | | macOS | 1.25 | amd64 | | macOS | 1.24 | amd64 | +| macOS | 1.26 | arm64 | | macOS | 1.25 | arm64 | | macOS | 1.24 | arm64 | +| Windows | 1.26 | amd64 | | Windows | 1.25 | amd64 | | Windows | 1.24 | amd64 | +| Windows | 1.26 | 386 | | Windows | 1.25 | 386 | | Windows | 1.24 | 386 | diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go index c4093e49ae..878ffbe43a 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go @@ -14,8 +14,7 @@ import ( ) const ( - maxMembers = 180 - maxBytesPerMembers = 4096 + maxMembers = 64 maxBytesPerBaggageString = 8192 listDelimiter = "," @@ -29,7 +28,6 @@ var ( errInvalidProperty = errors.New("invalid baggage list-member property") errInvalidMember = errors.New("invalid baggage list-member") errMemberNumber = errors.New("too many list-members in baggage-string") - errMemberBytes = errors.New("list-member too large") errBaggageBytes = errors.New("baggage-string too large") ) @@ -309,10 +307,6 @@ func newInvalidMember() Member { // an error if the input is invalid according to the W3C Baggage // specification. func parseMember(member string) (Member, error) { - if n := len(member); n > maxBytesPerMembers { - return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n) - } - var props properties keyValue, properties, found := strings.Cut(member, propertyDelimiter) if found { @@ -430,6 +424,10 @@ type Baggage struct { //nolint:golint // New returns a new valid Baggage. It returns an error if it results in a // Baggage exceeding limits set in that specification. // +// If the resulting Baggage exceeds the maximum allowed members or bytes, +// members are dropped until the limits are satisfied and an error is returned +// along with the partial result. +// // It expects all the provided members to have already been validated. func New(members ...Member) (Baggage, error) { if len(members) == 0 { @@ -441,7 +439,6 @@ func New(members ...Member) (Baggage, error) { if !m.hasData { return Baggage{}, errInvalidMember } - // OpenTelemetry resolves duplicates by last-one-wins. b[m.key] = baggage.Item{ Value: m.value, @@ -449,17 +446,42 @@ func New(members ...Member) (Baggage, error) { } } - // Check member numbers after deduplication. + var truncateErr error + + // Check member count after deduplication. if len(b) > maxMembers { - return Baggage{}, errMemberNumber + truncateErr = errors.Join(truncateErr, errMemberNumber) + for k := range b { + if len(b) <= maxMembers { + break + } + delete(b, k) + } } - bag := Baggage{b} - if n := len(bag.String()); n > maxBytesPerBaggageString { - return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) + // Check byte size and drop members if necessary. + totalBytes := 0 + first := true + for k := range b { + m := Member{ + key: k, + value: b[k].Value, + properties: fromInternalProperties(b[k].Properties), + } + memberSize := len(m.String()) + if !first { + memberSize++ // comma separator + } + if totalBytes+memberSize > maxBytesPerBaggageString { + truncateErr = errors.Join(truncateErr, fmt.Errorf("%w: %d", errBaggageBytes, totalBytes+memberSize)) + delete(b, k) + continue + } + totalBytes += memberSize + first = false } - return bag, nil + return Baggage{b}, truncateErr } // Parse attempts to decode a baggage-string from the passed string. It @@ -470,36 +492,71 @@ func New(members ...Member) (Baggage, error) { // defined (reading left-to-right) will be the only one kept. This diverges // from the W3C Baggage specification which allows duplicate list-members, but // conforms to the OpenTelemetry Baggage specification. +// +// If the baggage-string exceeds the maximum allowed members (64) or bytes +// (8192), members are dropped until the limits are satisfied and an error is +// returned along with the partial result. +// +// Invalid members are skipped and the error is returned along with the +// partial result containing the valid members. func Parse(bStr string) (Baggage, error) { if bStr == "" { return Baggage{}, nil } - if n := len(bStr); n > maxBytesPerBaggageString { - return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) - } - b := make(baggage.List) + sizes := make(map[string]int) // Track per-key byte sizes + var totalBytes int + var truncateErr error for memberStr := range strings.SplitSeq(bStr, listDelimiter) { + // Check member count limit. + if len(b) >= maxMembers { + truncateErr = errors.Join(truncateErr, errMemberNumber) + break + } + m, err := parseMember(memberStr) if err != nil { - return Baggage{}, err + truncateErr = errors.Join(truncateErr, err) + continue // skip invalid member, keep processing } + + // Check byte size limit. + // Account for comma separator between members. + memberBytes := len(m.String()) + _, existingKey := b[m.key] + if !existingKey && len(b) > 0 { + memberBytes++ // comma separator only for new keys + } + + // Calculate new totalBytes if we add/overwrite this key + var newTotalBytes int + if oldSize, exists := sizes[m.key]; exists { + // Overwriting existing key: subtract old size, add new size + newTotalBytes = totalBytes - oldSize + memberBytes + } else { + // New key + newTotalBytes = totalBytes + memberBytes + } + + if newTotalBytes > maxBytesPerBaggageString { + truncateErr = errors.Join(truncateErr, errBaggageBytes) + break + } + // OpenTelemetry resolves duplicates by last-one-wins. b[m.key] = baggage.Item{ Value: m.value, Properties: m.properties.asInternal(), } + sizes[m.key] = memberBytes + totalBytes = newTotalBytes } - // OpenTelemetry does not allow for duplicate list-members, but the W3C - // specification does. Now that we have deduplicated, ensure the baggage - // does not exceed list-member limits. - if len(b) > maxMembers { - return Baggage{}, errMemberNumber + if len(b) == 0 { + return Baggage{}, truncateErr } - - return Baggage{b}, nil + return Baggage{b}, truncateErr } // Member returns the baggage list-member identified by key. diff --git a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile index 676e79116d..f0cc942bae 100644 --- a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile +++ b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile @@ -1,4 +1,4 @@ # This is a renovate-friendly source of Docker images. FROM python:3.13.6-slim-bullseye@sha256:e98b521460ee75bca92175c16247bdf7275637a8faaeb2bcfa19d879ae5c4b9a AS python -FROM otel/weaver:v0.20.0@sha256:fa4f1c6954ecea78ab1a4e865bd6f5b4aaba80c1896f9f4a11e2c361d04e197e AS weaver +FROM otel/weaver:v0.21.2@sha256:2401de985c38bdb98b43918e2f43aa36b2afed4aa5669ac1c1de0a17301cd36d AS weaver FROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown diff --git a/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go b/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go new file mode 100644 index 0000000000..3f0ab31312 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go @@ -0,0 +1,96 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package errorhandler provides the global error handler for OpenTelemetry. +// +// This package has no OTel dependencies, allowing it to be imported by any +// package in the module without creating import cycles. +package errorhandler // import "go.opentelemetry.io/otel/internal/errorhandler" + +import ( + "errors" + "log" + "sync" + "sync/atomic" +) + +// ErrorHandler handles irremediable events. +type ErrorHandler interface { + // Handle handles any error deemed irremediable by an OpenTelemetry + // component. + Handle(error) +} + +type ErrDelegator struct { + delegate atomic.Pointer[ErrorHandler] +} + +// Compile-time check that delegator implements ErrorHandler. +var _ ErrorHandler = (*ErrDelegator)(nil) + +func (d *ErrDelegator) Handle(err error) { + if eh := d.delegate.Load(); eh != nil { + (*eh).Handle(err) + return + } + log.Print(err) +} + +// setDelegate sets the ErrorHandler delegate. +func (d *ErrDelegator) setDelegate(eh ErrorHandler) { + d.delegate.Store(&eh) +} + +type errorHandlerHolder struct { + eh ErrorHandler +} + +var ( + globalErrorHandler = defaultErrorHandler() + delegateErrorHandlerOnce sync.Once +) + +// GetErrorHandler returns the global ErrorHandler instance. +// +// The default ErrorHandler instance returned will log all errors to STDERR +// until an override ErrorHandler is set with SetErrorHandler. All +// ErrorHandler returned prior to this will automatically forward errors to +// the set instance instead of logging. +// +// Subsequent calls to SetErrorHandler after the first will not forward errors +// to the new ErrorHandler for prior returned instances. +func GetErrorHandler() ErrorHandler { + return globalErrorHandler.Load().(errorHandlerHolder).eh +} + +// SetErrorHandler sets the global ErrorHandler to h. +// +// The first time this is called all ErrorHandler previously returned from +// GetErrorHandler will send errors to h instead of the default logging +// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not +// delegate errors to h. +func SetErrorHandler(h ErrorHandler) { + current := GetErrorHandler() + + if _, cOk := current.(*ErrDelegator); cOk { + if _, ehOk := h.(*ErrDelegator); ehOk && current == h { + // Do not assign to the delegate of the default ErrDelegator to be + // itself. + log.Print(errors.New("no ErrorHandler delegate configured"), " ErrorHandler remains its current value.") + return + } + } + + delegateErrorHandlerOnce.Do(func() { + if def, ok := current.(*ErrDelegator); ok { + def.setDelegate(h) + } + }) + globalErrorHandler.Store(errorHandlerHolder{eh: h}) +} + +func defaultErrorHandler() *atomic.Value { + v := &atomic.Value{} + v.Store(errorHandlerHolder{eh: &ErrDelegator{}}) + return v +} diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go index 2e47b2964c..77d0425f54 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/handler.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go @@ -5,33 +5,13 @@ package global // import "go.opentelemetry.io/otel/internal/global" import ( - "log" - "sync/atomic" + "go.opentelemetry.io/otel/internal/errorhandler" ) -// ErrorHandler handles irremediable events. -type ErrorHandler interface { - // Handle handles any error deemed irremediable by an OpenTelemetry - // component. - Handle(error) -} +// ErrorHandler is an alias for errorhandler.ErrorHandler, kept for backward +// compatibility with existing callers of internal/global. +type ErrorHandler = errorhandler.ErrorHandler -type ErrDelegator struct { - delegate atomic.Pointer[ErrorHandler] -} - -// Compile-time check that delegator implements ErrorHandler. -var _ ErrorHandler = (*ErrDelegator)(nil) - -func (d *ErrDelegator) Handle(err error) { - if eh := d.delegate.Load(); eh != nil { - (*eh).Handle(err) - return - } - log.Print(err) -} - -// setDelegate sets the ErrorHandler delegate. -func (d *ErrDelegator) setDelegate(eh ErrorHandler) { - d.delegate.Store(&eh) -} +// ErrDelegator is an alias for errorhandler.ErrDelegator, kept for backward +// compatibility with existing callers of internal/global. +type ErrDelegator = errorhandler.ErrDelegator diff --git a/vendor/go.opentelemetry.io/otel/internal/global/state.go b/vendor/go.opentelemetry.io/otel/internal/global/state.go index 204ea142a5..225c9e5015 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/state.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/state.go @@ -8,16 +8,13 @@ import ( "sync" "sync/atomic" + "go.opentelemetry.io/otel/internal/errorhandler" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" ) type ( - errorHandlerHolder struct { - eh ErrorHandler - } - tracerProviderHolder struct { tp trace.TracerProvider } @@ -32,12 +29,10 @@ type ( ) var ( - globalErrorHandler = defaultErrorHandler() globalTracer = defaultTracerValue() globalPropagators = defaultPropagatorsValue() globalMeterProvider = defaultMeterProvider() - delegateErrorHandlerOnce sync.Once delegateTraceOnce sync.Once delegateTextMapPropagatorOnce sync.Once delegateMeterOnce sync.Once @@ -53,7 +48,7 @@ var ( // Subsequent calls to SetErrorHandler after the first will not forward errors // to the new ErrorHandler for prior returned instances. func GetErrorHandler() ErrorHandler { - return globalErrorHandler.Load().(errorHandlerHolder).eh + return errorhandler.GetErrorHandler() } // SetErrorHandler sets the global ErrorHandler to h. @@ -63,26 +58,7 @@ func GetErrorHandler() ErrorHandler { // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not // delegate errors to h. func SetErrorHandler(h ErrorHandler) { - current := GetErrorHandler() - - if _, cOk := current.(*ErrDelegator); cOk { - if _, ehOk := h.(*ErrDelegator); ehOk && current == h { - // Do not assign to the delegate of the default ErrDelegator to be - // itself. - Error( - errors.New("no ErrorHandler delegate configured"), - "ErrorHandler remains its current value.", - ) - return - } - } - - delegateErrorHandlerOnce.Do(func() { - if def, ok := current.(*ErrDelegator); ok { - def.setDelegate(h) - } - }) - globalErrorHandler.Store(errorHandlerHolder{eh: h}) + errorhandler.SetErrorHandler(h) } // TracerProvider is the internal implementation for global.TracerProvider. @@ -174,12 +150,6 @@ func SetMeterProvider(mp metric.MeterProvider) { globalMeterProvider.Store(meterProviderHolder{mp: mp}) } -func defaultErrorHandler() *atomic.Value { - v := &atomic.Value{} - v.Store(errorHandlerHolder{eh: &ErrDelegator{}}) - return v -} - func defaultTracerValue() *atomic.Value { v := &atomic.Value{} v.Store(tracerProviderHolder{tp: &tracerProvider{}}) diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go index eb4f5961fd..466812d343 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go @@ -211,6 +211,9 @@ type Float64Observer interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Observe(value float64, options ...ObserveOption) } diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go index 1dfc4b0f25..66c971bd8a 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go @@ -210,6 +210,9 @@ type Int64Observer interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Observe(value int64, options ...ObserveOption) } diff --git a/vendor/go.opentelemetry.io/otel/metric/meter.go b/vendor/go.opentelemetry.io/otel/metric/meter.go index a16c4c0a14..5606ec4bd9 100644 --- a/vendor/go.opentelemetry.io/otel/metric/meter.go +++ b/vendor/go.opentelemetry.io/otel/metric/meter.go @@ -30,6 +30,9 @@ type MeterProvider interface { // // If the name is empty, then an implementation defined default name will // be used instead. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Meter(name string, opts ...MeterOption) Meter } @@ -51,6 +54,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64Counter(name string, options ...Int64CounterOption) (Int64Counter, error) // Int64UpDownCounter returns a new Int64UpDownCounter instrument @@ -61,6 +67,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64UpDownCounter(name string, options ...Int64UpDownCounterOption) (Int64UpDownCounter, error) // Int64Histogram returns a new Int64Histogram instrument identified by @@ -71,6 +80,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64Histogram(name string, options ...Int64HistogramOption) (Int64Histogram, error) // Int64Gauge returns a new Int64Gauge instrument identified by name and @@ -80,6 +92,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64Gauge(name string, options ...Int64GaugeOption) (Int64Gauge, error) // Int64ObservableCounter returns a new Int64ObservableCounter identified @@ -95,6 +110,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64ObservableCounter(name string, options ...Int64ObservableCounterOption) (Int64ObservableCounter, error) // Int64ObservableUpDownCounter returns a new Int64ObservableUpDownCounter @@ -110,6 +128,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64ObservableUpDownCounter( name string, options ...Int64ObservableUpDownCounterOption, @@ -128,6 +149,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Int64ObservableGauge(name string, options ...Int64ObservableGaugeOption) (Int64ObservableGauge, error) // Float64Counter returns a new Float64Counter instrument identified by @@ -148,6 +172,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64UpDownCounter(name string, options ...Float64UpDownCounterOption) (Float64UpDownCounter, error) // Float64Histogram returns a new Float64Histogram instrument identified by @@ -158,6 +185,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64Histogram(name string, options ...Float64HistogramOption) (Float64Histogram, error) // Float64Gauge returns a new Float64Gauge instrument identified by name and @@ -167,6 +197,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64Gauge(name string, options ...Float64GaugeOption) (Float64Gauge, error) // Float64ObservableCounter returns a new Float64ObservableCounter @@ -182,6 +215,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64ObservableCounter(name string, options ...Float64ObservableCounterOption) (Float64ObservableCounter, error) // Float64ObservableUpDownCounter returns a new @@ -197,6 +233,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64ObservableUpDownCounter( name string, options ...Float64ObservableUpDownCounterOption, @@ -215,6 +254,9 @@ type Meter interface { // The name needs to conform to the OpenTelemetry instrument name syntax. // See the Instrument Name section of the package documentation for more // information. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Float64ObservableGauge(name string, options ...Float64ObservableGaugeOption) (Float64ObservableGauge, error) // RegisterCallback registers f to be called during the collection of a @@ -229,6 +271,9 @@ type Meter interface { // If no instruments are passed, f should not be registered nor called // during collection. // + // Implementations of this method need to be safe for a user to call + // concurrently. + // // The function f needs to be concurrent safe. RegisterCallback(f Callback, instruments ...Observable) (Registration, error) } @@ -263,9 +308,15 @@ type Observer interface { embedded.Observer // ObserveFloat64 records the float64 value for obsrv. + // + // Implementations of this method need to be safe for a user to call + // concurrently. ObserveFloat64(obsrv Float64Observable, value float64, opts ...ObserveOption) // ObserveInt64 records the int64 value for obsrv. + // + // Implementations of this method need to be safe for a user to call + // concurrently. ObserveInt64(obsrv Int64Observable, value int64, opts ...ObserveOption) } @@ -283,6 +334,7 @@ type Registration interface { // Unregister removes the callback registration from a Meter. // - // This method needs to be idempotent and concurrent safe. + // Implementations of this method need to be idempotent and safe for a user + // to call concurrently. Unregister() error } diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go index 57a74c5e65..abb3051d7f 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go @@ -24,12 +24,18 @@ type Float64Counter interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Add(ctx context.Context, incr float64, options ...AddOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -83,12 +89,18 @@ type Float64UpDownCounter interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Add(ctx context.Context, incr float64, options ...AddOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -142,12 +154,18 @@ type Float64Histogram interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Record(ctx context.Context, incr float64, options ...RecordOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -206,12 +224,18 @@ type Float64Gauge interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Record(ctx context.Context, value float64, options ...RecordOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go index ac2d033ea6..5bbfaf0397 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go @@ -24,12 +24,18 @@ type Int64Counter interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Add(ctx context.Context, incr int64, options ...AddOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -83,12 +89,18 @@ type Int64UpDownCounter interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Add(ctx context.Context, incr int64, options ...AddOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -142,12 +154,18 @@ type Int64Histogram interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Record(ctx context.Context, incr int64, options ...RecordOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } @@ -206,12 +224,18 @@ type Int64Gauge interface { // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Record(ctx context.Context, value int64, options ...RecordOption) // Enabled reports whether the instrument will process measurements for the given context. // // This function can be used in places where measuring an instrument // would result in computationally expensive operations. + // + // Implementations of this method need to be safe for a user to call + // concurrently. Enabled(context.Context) bool } diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go index 0518826020..2ecca3fed1 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go +++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go @@ -7,9 +7,16 @@ import ( "context" "go.opentelemetry.io/otel/baggage" + "go.opentelemetry.io/otel/internal/errorhandler" ) -const baggageHeader = "baggage" +const ( + baggageHeader = "baggage" + + // W3C Baggage specification limits. + // https://www.w3.org/TR/baggage/#limits + maxMembers = 64 +) // Baggage is a propagator that supports the W3C Baggage format. // @@ -50,6 +57,9 @@ func extractSingleBaggage(parent context.Context, carrier TextMapCarrier) contex bag, err := baggage.Parse(bStr) if err != nil { + errorhandler.GetErrorHandler().Handle(err) + } + if bag.Len() == 0 { return parent } return baggage.ContextWithBaggage(parent, bag) @@ -60,17 +70,27 @@ func extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.C if len(bVals) == 0 { return parent } + var members []baggage.Member for _, bStr := range bVals { currBag, err := baggage.Parse(bStr) if err != nil { + errorhandler.GetErrorHandler().Handle(err) + } + if currBag.Len() == 0 { continue } members = append(members, currBag.Members()...) + if len(members) >= maxMembers { + break + } } b, err := baggage.New(members...) - if err != nil || b.Len() == 0 { + if err != nil { + errorhandler.GetErrorHandler().Handle(err) + } + if b.Len() == 0 { return parent } return baggage.ContextWithBaggage(parent, b) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go deleted file mode 100644 index 089b0c457f..0000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go +++ /dev/null @@ -1,1010 +0,0 @@ -// Code generated from semantic convention specification. DO NOT EDIT. - -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Package rpcconv provides types and functionality for OpenTelemetry semantic -// conventions in the "rpc" namespace. -package rpcconv - -import ( - "context" - "sync" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" -) - -var ( - addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }} - recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }} -) - -// ClientDuration is an instrument used to record metric values conforming to the -// "rpc.client.duration" semantic conventions. It represents the measures the -// duration of outbound RPC. -type ClientDuration struct { - metric.Float64Histogram -} - -var newClientDurationOpts = []metric.Float64HistogramOption{ - metric.WithDescription("Measures the duration of outbound RPC."), - metric.WithUnit("ms"), -} - -// NewClientDuration returns a new ClientDuration instrument. -func NewClientDuration( - m metric.Meter, - opt ...metric.Float64HistogramOption, -) (ClientDuration, error) { - // Check if the meter is nil. - if m == nil { - return ClientDuration{noop.Float64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newClientDurationOpts - } else { - opt = append(opt, newClientDurationOpts...) - } - - i, err := m.Float64Histogram( - "rpc.client.duration", - opt..., - ) - if err != nil { - return ClientDuration{noop.Float64Histogram{}}, err - } - return ClientDuration{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ClientDuration) Inst() metric.Float64Histogram { - return m.Float64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ClientDuration) Name() string { - return "rpc.client.duration" -} - -// Unit returns the semantic convention unit of the instrument -func (ClientDuration) Unit() string { - return "ms" -} - -// Description returns the semantic convention description of the instrument -func (ClientDuration) Description() string { - return "Measures the duration of outbound RPC." -} - -// Record records val to the current distribution for attrs. -// -// While streaming RPCs may record this metric as start-of-batch -// to end-of-batch, it's hard to interpret in practice. -// -// **Streaming**: N/A. -func (m ClientDuration) Record(ctx context.Context, val float64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Float64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Float64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// While streaming RPCs may record this metric as start-of-batch -// to end-of-batch, it's hard to interpret in practice. -// -// **Streaming**: N/A. -func (m ClientDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { - if set.Len() == 0 { - m.Float64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Float64Histogram.Record(ctx, val, *o...) -} - -// ClientRequestSize is an instrument used to record metric values conforming to -// the "rpc.client.request.size" semantic conventions. It represents the measures -// the size of RPC request messages (uncompressed). -type ClientRequestSize struct { - metric.Int64Histogram -} - -var newClientRequestSizeOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), - metric.WithUnit("By"), -} - -// NewClientRequestSize returns a new ClientRequestSize instrument. -func NewClientRequestSize( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ClientRequestSize, error) { - // Check if the meter is nil. - if m == nil { - return ClientRequestSize{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newClientRequestSizeOpts - } else { - opt = append(opt, newClientRequestSizeOpts...) - } - - i, err := m.Int64Histogram( - "rpc.client.request.size", - opt..., - ) - if err != nil { - return ClientRequestSize{noop.Int64Histogram{}}, err - } - return ClientRequestSize{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ClientRequestSize) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ClientRequestSize) Name() string { - return "rpc.client.request.size" -} - -// Unit returns the semantic convention unit of the instrument -func (ClientRequestSize) Unit() string { - return "By" -} - -// Description returns the semantic convention description of the instrument -func (ClientRequestSize) Description() string { - return "Measures the size of RPC request messages (uncompressed)." -} - -// Record records val to the current distribution for attrs. -// -// **Streaming**: Recorded per message in a streaming batch -func (m ClientRequestSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// **Streaming**: Recorded per message in a streaming batch -func (m ClientRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ClientRequestsPerRPC is an instrument used to record metric values conforming -// to the "rpc.client.requests_per_rpc" semantic conventions. It represents the -// measures the number of messages received per RPC. -type ClientRequestsPerRPC struct { - metric.Int64Histogram -} - -var newClientRequestsPerRPCOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the number of messages received per RPC."), - metric.WithUnit("{count}"), -} - -// NewClientRequestsPerRPC returns a new ClientRequestsPerRPC instrument. -func NewClientRequestsPerRPC( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ClientRequestsPerRPC, error) { - // Check if the meter is nil. - if m == nil { - return ClientRequestsPerRPC{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newClientRequestsPerRPCOpts - } else { - opt = append(opt, newClientRequestsPerRPCOpts...) - } - - i, err := m.Int64Histogram( - "rpc.client.requests_per_rpc", - opt..., - ) - if err != nil { - return ClientRequestsPerRPC{noop.Int64Histogram{}}, err - } - return ClientRequestsPerRPC{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ClientRequestsPerRPC) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ClientRequestsPerRPC) Name() string { - return "rpc.client.requests_per_rpc" -} - -// Unit returns the semantic convention unit of the instrument -func (ClientRequestsPerRPC) Unit() string { - return "{count}" -} - -// Description returns the semantic convention description of the instrument -func (ClientRequestsPerRPC) Description() string { - return "Measures the number of messages received per RPC." -} - -// Record records val to the current distribution for attrs. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ClientRequestsPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ClientRequestsPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ClientResponseSize is an instrument used to record metric values conforming to -// the "rpc.client.response.size" semantic conventions. It represents the -// measures the size of RPC response messages (uncompressed). -type ClientResponseSize struct { - metric.Int64Histogram -} - -var newClientResponseSizeOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), - metric.WithUnit("By"), -} - -// NewClientResponseSize returns a new ClientResponseSize instrument. -func NewClientResponseSize( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ClientResponseSize, error) { - // Check if the meter is nil. - if m == nil { - return ClientResponseSize{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newClientResponseSizeOpts - } else { - opt = append(opt, newClientResponseSizeOpts...) - } - - i, err := m.Int64Histogram( - "rpc.client.response.size", - opt..., - ) - if err != nil { - return ClientResponseSize{noop.Int64Histogram{}}, err - } - return ClientResponseSize{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ClientResponseSize) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ClientResponseSize) Name() string { - return "rpc.client.response.size" -} - -// Unit returns the semantic convention unit of the instrument -func (ClientResponseSize) Unit() string { - return "By" -} - -// Description returns the semantic convention description of the instrument -func (ClientResponseSize) Description() string { - return "Measures the size of RPC response messages (uncompressed)." -} - -// Record records val to the current distribution for attrs. -// -// **Streaming**: Recorded per response in a streaming batch -func (m ClientResponseSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// **Streaming**: Recorded per response in a streaming batch -func (m ClientResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ClientResponsesPerRPC is an instrument used to record metric values conforming -// to the "rpc.client.responses_per_rpc" semantic conventions. It represents the -// measures the number of messages sent per RPC. -type ClientResponsesPerRPC struct { - metric.Int64Histogram -} - -var newClientResponsesPerRPCOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the number of messages sent per RPC."), - metric.WithUnit("{count}"), -} - -// NewClientResponsesPerRPC returns a new ClientResponsesPerRPC instrument. -func NewClientResponsesPerRPC( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ClientResponsesPerRPC, error) { - // Check if the meter is nil. - if m == nil { - return ClientResponsesPerRPC{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newClientResponsesPerRPCOpts - } else { - opt = append(opt, newClientResponsesPerRPCOpts...) - } - - i, err := m.Int64Histogram( - "rpc.client.responses_per_rpc", - opt..., - ) - if err != nil { - return ClientResponsesPerRPC{noop.Int64Histogram{}}, err - } - return ClientResponsesPerRPC{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ClientResponsesPerRPC) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ClientResponsesPerRPC) Name() string { - return "rpc.client.responses_per_rpc" -} - -// Unit returns the semantic convention unit of the instrument -func (ClientResponsesPerRPC) Unit() string { - return "{count}" -} - -// Description returns the semantic convention description of the instrument -func (ClientResponsesPerRPC) Description() string { - return "Measures the number of messages sent per RPC." -} - -// Record records val to the current distribution for attrs. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ClientResponsesPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ClientResponsesPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ServerDuration is an instrument used to record metric values conforming to the -// "rpc.server.duration" semantic conventions. It represents the measures the -// duration of inbound RPC. -type ServerDuration struct { - metric.Float64Histogram -} - -var newServerDurationOpts = []metric.Float64HistogramOption{ - metric.WithDescription("Measures the duration of inbound RPC."), - metric.WithUnit("ms"), -} - -// NewServerDuration returns a new ServerDuration instrument. -func NewServerDuration( - m metric.Meter, - opt ...metric.Float64HistogramOption, -) (ServerDuration, error) { - // Check if the meter is nil. - if m == nil { - return ServerDuration{noop.Float64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newServerDurationOpts - } else { - opt = append(opt, newServerDurationOpts...) - } - - i, err := m.Float64Histogram( - "rpc.server.duration", - opt..., - ) - if err != nil { - return ServerDuration{noop.Float64Histogram{}}, err - } - return ServerDuration{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ServerDuration) Inst() metric.Float64Histogram { - return m.Float64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ServerDuration) Name() string { - return "rpc.server.duration" -} - -// Unit returns the semantic convention unit of the instrument -func (ServerDuration) Unit() string { - return "ms" -} - -// Description returns the semantic convention description of the instrument -func (ServerDuration) Description() string { - return "Measures the duration of inbound RPC." -} - -// Record records val to the current distribution for attrs. -// -// While streaming RPCs may record this metric as start-of-batch -// to end-of-batch, it's hard to interpret in practice. -// -// **Streaming**: N/A. -func (m ServerDuration) Record(ctx context.Context, val float64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Float64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Float64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// While streaming RPCs may record this metric as start-of-batch -// to end-of-batch, it's hard to interpret in practice. -// -// **Streaming**: N/A. -func (m ServerDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { - if set.Len() == 0 { - m.Float64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Float64Histogram.Record(ctx, val, *o...) -} - -// ServerRequestSize is an instrument used to record metric values conforming to -// the "rpc.server.request.size" semantic conventions. It represents the measures -// the size of RPC request messages (uncompressed). -type ServerRequestSize struct { - metric.Int64Histogram -} - -var newServerRequestSizeOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), - metric.WithUnit("By"), -} - -// NewServerRequestSize returns a new ServerRequestSize instrument. -func NewServerRequestSize( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ServerRequestSize, error) { - // Check if the meter is nil. - if m == nil { - return ServerRequestSize{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newServerRequestSizeOpts - } else { - opt = append(opt, newServerRequestSizeOpts...) - } - - i, err := m.Int64Histogram( - "rpc.server.request.size", - opt..., - ) - if err != nil { - return ServerRequestSize{noop.Int64Histogram{}}, err - } - return ServerRequestSize{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ServerRequestSize) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ServerRequestSize) Name() string { - return "rpc.server.request.size" -} - -// Unit returns the semantic convention unit of the instrument -func (ServerRequestSize) Unit() string { - return "By" -} - -// Description returns the semantic convention description of the instrument -func (ServerRequestSize) Description() string { - return "Measures the size of RPC request messages (uncompressed)." -} - -// Record records val to the current distribution for attrs. -// -// **Streaming**: Recorded per message in a streaming batch -func (m ServerRequestSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// **Streaming**: Recorded per message in a streaming batch -func (m ServerRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ServerRequestsPerRPC is an instrument used to record metric values conforming -// to the "rpc.server.requests_per_rpc" semantic conventions. It represents the -// measures the number of messages received per RPC. -type ServerRequestsPerRPC struct { - metric.Int64Histogram -} - -var newServerRequestsPerRPCOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the number of messages received per RPC."), - metric.WithUnit("{count}"), -} - -// NewServerRequestsPerRPC returns a new ServerRequestsPerRPC instrument. -func NewServerRequestsPerRPC( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ServerRequestsPerRPC, error) { - // Check if the meter is nil. - if m == nil { - return ServerRequestsPerRPC{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newServerRequestsPerRPCOpts - } else { - opt = append(opt, newServerRequestsPerRPCOpts...) - } - - i, err := m.Int64Histogram( - "rpc.server.requests_per_rpc", - opt..., - ) - if err != nil { - return ServerRequestsPerRPC{noop.Int64Histogram{}}, err - } - return ServerRequestsPerRPC{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ServerRequestsPerRPC) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ServerRequestsPerRPC) Name() string { - return "rpc.server.requests_per_rpc" -} - -// Unit returns the semantic convention unit of the instrument -func (ServerRequestsPerRPC) Unit() string { - return "{count}" -} - -// Description returns the semantic convention description of the instrument -func (ServerRequestsPerRPC) Description() string { - return "Measures the number of messages received per RPC." -} - -// Record records val to the current distribution for attrs. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming** : This metric is required for server and client streaming RPCs -func (m ServerRequestsPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming** : This metric is required for server and client streaming RPCs -func (m ServerRequestsPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ServerResponseSize is an instrument used to record metric values conforming to -// the "rpc.server.response.size" semantic conventions. It represents the -// measures the size of RPC response messages (uncompressed). -type ServerResponseSize struct { - metric.Int64Histogram -} - -var newServerResponseSizeOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), - metric.WithUnit("By"), -} - -// NewServerResponseSize returns a new ServerResponseSize instrument. -func NewServerResponseSize( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ServerResponseSize, error) { - // Check if the meter is nil. - if m == nil { - return ServerResponseSize{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newServerResponseSizeOpts - } else { - opt = append(opt, newServerResponseSizeOpts...) - } - - i, err := m.Int64Histogram( - "rpc.server.response.size", - opt..., - ) - if err != nil { - return ServerResponseSize{noop.Int64Histogram{}}, err - } - return ServerResponseSize{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ServerResponseSize) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ServerResponseSize) Name() string { - return "rpc.server.response.size" -} - -// Unit returns the semantic convention unit of the instrument -func (ServerResponseSize) Unit() string { - return "By" -} - -// Description returns the semantic convention description of the instrument -func (ServerResponseSize) Description() string { - return "Measures the size of RPC response messages (uncompressed)." -} - -// Record records val to the current distribution for attrs. -// -// **Streaming**: Recorded per response in a streaming batch -func (m ServerResponseSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// **Streaming**: Recorded per response in a streaming batch -func (m ServerResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// ServerResponsesPerRPC is an instrument used to record metric values conforming -// to the "rpc.server.responses_per_rpc" semantic conventions. It represents the -// measures the number of messages sent per RPC. -type ServerResponsesPerRPC struct { - metric.Int64Histogram -} - -var newServerResponsesPerRPCOpts = []metric.Int64HistogramOption{ - metric.WithDescription("Measures the number of messages sent per RPC."), - metric.WithUnit("{count}"), -} - -// NewServerResponsesPerRPC returns a new ServerResponsesPerRPC instrument. -func NewServerResponsesPerRPC( - m metric.Meter, - opt ...metric.Int64HistogramOption, -) (ServerResponsesPerRPC, error) { - // Check if the meter is nil. - if m == nil { - return ServerResponsesPerRPC{noop.Int64Histogram{}}, nil - } - - if len(opt) == 0 { - opt = newServerResponsesPerRPCOpts - } else { - opt = append(opt, newServerResponsesPerRPCOpts...) - } - - i, err := m.Int64Histogram( - "rpc.server.responses_per_rpc", - opt..., - ) - if err != nil { - return ServerResponsesPerRPC{noop.Int64Histogram{}}, err - } - return ServerResponsesPerRPC{i}, nil -} - -// Inst returns the underlying metric instrument. -func (m ServerResponsesPerRPC) Inst() metric.Int64Histogram { - return m.Int64Histogram -} - -// Name returns the semantic convention name of the instrument. -func (ServerResponsesPerRPC) Name() string { - return "rpc.server.responses_per_rpc" -} - -// Unit returns the semantic convention unit of the instrument -func (ServerResponsesPerRPC) Unit() string { - return "{count}" -} - -// Description returns the semantic convention description of the instrument -func (ServerResponsesPerRPC) Description() string { - return "Measures the number of messages sent per RPC." -} - -// Record records val to the current distribution for attrs. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ServerResponsesPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { - if len(attrs) == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributes(attrs...)) - m.Int64Histogram.Record(ctx, val, *o...) -} - -// RecordSet records val to the current distribution for set. -// -// Should be 1 for all non-streaming RPCs. -// -// **Streaming**: This metric is required for server and client streaming RPCs -func (m ServerResponsesPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { - if set.Len() == 0 { - m.Int64Histogram.Record(ctx, val) - return - } - - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - *o = (*o)[:0] - recOptPool.Put(o) - }() - - *o = append(*o, metric.WithAttributeSet(set)) - m.Int64Histogram.Record(ctx, val, *o...) -} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/httpconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go similarity index 98% rename from vendor/go.opentelemetry.io/otel/semconv/v1.37.0/httpconv/metric.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go index a0ddf652d3..cb993812a8 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/httpconv/metric.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go @@ -67,6 +67,8 @@ var ( RequestMethodPut RequestMethodAttr = "PUT" // RequestMethodTrace is the TRACE method. RequestMethodTrace RequestMethodAttr = "TRACE" + // RequestMethodQuery is the QUERY method. + RequestMethodQuery RequestMethodAttr = "QUERY" // RequestMethodOther is the any HTTP method that the instrumentation has no // prior knowledge of. RequestMethodOther RequestMethodAttr = "_OTHER" @@ -1318,8 +1320,9 @@ func (ServerRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue } // AttrRoute returns an optional attribute for the "http.route" semantic -// convention. It represents the matched route, that is, the path template in the -// format used by the respective server framework. +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. func (ServerRequestBodySize) AttrRoute(val string) attribute.KeyValue { return attribute.String("http.route", val) } @@ -1494,8 +1497,9 @@ func (ServerRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue } // AttrRoute returns an optional attribute for the "http.route" semantic -// convention. It represents the matched route, that is, the path template in the -// format used by the respective server framework. +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. func (ServerRequestDuration) AttrRoute(val string) attribute.KeyValue { return attribute.String("http.route", val) } @@ -1684,8 +1688,9 @@ func (ServerResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue } // AttrRoute returns an optional attribute for the "http.route" semantic -// convention. It represents the matched route, that is, the path template in the -// format used by the respective server framework. +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. func (ServerResponseBodySize) AttrRoute(val string) attribute.KeyValue { return attribute.String("http.route", val) } diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv/metric.go new file mode 100644 index 0000000000..813782a8de --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv/metric.go @@ -0,0 +1,1131 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package rpcconv provides types and functionality for OpenTelemetry semantic +// conventions in the "rpc" namespace. +package rpcconv + +import ( + "context" + "sync" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" +) + +var ( + addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }} + recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }} +) + +// ErrorTypeAttr is an attribute conforming to the error.type semantic +// conventions. It represents the describes a class of error the operation ended +// with. +type ErrorTypeAttr string + +var ( + // ErrorTypeOther is a fallback error value to be used when the instrumentation + // doesn't define a custom value. + ErrorTypeOther ErrorTypeAttr = "_OTHER" +) + +// NetworkTransportAttr is an attribute conforming to the network.transport +// semantic conventions. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +type NetworkTransportAttr string + +var ( + // NetworkTransportTCP is the TCP. + NetworkTransportTCP NetworkTransportAttr = "tcp" + // NetworkTransportUDP is the UDP. + NetworkTransportUDP NetworkTransportAttr = "udp" + // NetworkTransportPipe is the named or anonymous pipe. + NetworkTransportPipe NetworkTransportAttr = "pipe" + // NetworkTransportUnix is the unix domain socket. + NetworkTransportUnix NetworkTransportAttr = "unix" + // NetworkTransportQUIC is the QUIC. + NetworkTransportQUIC NetworkTransportAttr = "quic" +) + +// SystemNameAttr is an attribute conforming to the rpc.system.name semantic +// conventions. It represents the Remote Procedure Call (RPC) system. +type SystemNameAttr string + +var ( + // SystemNameGRPC is the [gRPC]. + // + // [gRPC]: https://grpc.io/ + SystemNameGRPC SystemNameAttr = "grpc" + // SystemNameDubbo is the [Apache Dubbo]. + // + // [Apache Dubbo]: https://dubbo.apache.org/ + SystemNameDubbo SystemNameAttr = "dubbo" + // SystemNameConnectrpc is the [Connect RPC]. + // + // [Connect RPC]: https://connectrpc.com/ + SystemNameConnectrpc SystemNameAttr = "connectrpc" + // SystemNameJSONRPC is the [JSON-RPC]. + // + // [JSON-RPC]: https://www.jsonrpc.org/ + SystemNameJSONRPC SystemNameAttr = "jsonrpc" +) + +// ClientCallDuration is an instrument used to record metric values conforming to +// the "rpc.client.call.duration" semantic conventions. It represents the +// measures the duration of outbound remote procedure calls (RPC). +type ClientCallDuration struct { + metric.Float64Histogram +} + +var newClientCallDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of outbound remote procedure calls (RPC)."), + metric.WithUnit("s"), +} + +// NewClientCallDuration returns a new ClientCallDuration instrument. +func NewClientCallDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ClientCallDuration, error) { + // Check if the meter is nil. + if m == nil { + return ClientCallDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientCallDurationOpts + } else { + opt = append(opt, newClientCallDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.client.call.duration", + opt..., + ) + if err != nil { + return ClientCallDuration{noop.Float64Histogram{}}, err + } + return ClientCallDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientCallDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientCallDuration) Name() string { + return "rpc.client.call.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientCallDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ClientCallDuration) Description() string { + return "Measures the duration of outbound remote procedure calls (RPC)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// When this metric is reported alongside an RPC client span, the metric value +// SHOULD be the same as the RPC client span duration. +func (m ClientCallDuration) Record( + ctx context.Context, + val float64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// When this metric is reported alongside an RPC client span, the metric value +// SHOULD be the same as the RPC client span duration. +func (m ClientCallDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientCallDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ClientCallDuration) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ClientCallDuration) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ClientCallDuration) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientCallDuration) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientCallDuration) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientCallDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ClientCallDuration) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// ClientRequestSize is an instrument used to record metric values conforming to +// the "rpc.client.request.size" semantic conventions. It represents the measures +// the size of RPC request messages (uncompressed). +type ClientRequestSize struct { + metric.Int64Histogram +} + +var newClientRequestSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewClientRequestSize returns a new ClientRequestSize instrument. +func NewClientRequestSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientRequestSize, error) { + // Check if the meter is nil. + if m == nil { + return ClientRequestSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientRequestSizeOpts + } else { + opt = append(opt, newClientRequestSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.request.size", + opt..., + ) + if err != nil { + return ClientRequestSize{noop.Int64Histogram{}}, err + } + return ClientRequestSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientRequestSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientRequestSize) Name() string { + return "rpc.client.request.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientRequestSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientRequestSize) Description() string { + return "Measures the size of RPC request messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ClientRequestSize) Record( + ctx context.Context, + val int64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ClientRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientRequestSize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ClientRequestSize) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ClientRequestSize) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ClientRequestSize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientRequestSize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientRequestSize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientRequestSize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ClientRequestSize) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// ClientResponseSize is an instrument used to record metric values conforming to +// the "rpc.client.response.size" semantic conventions. It represents the +// measures the size of RPC response messages (uncompressed). +type ClientResponseSize struct { + metric.Int64Histogram +} + +var newClientResponseSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewClientResponseSize returns a new ClientResponseSize instrument. +func NewClientResponseSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientResponseSize, error) { + // Check if the meter is nil. + if m == nil { + return ClientResponseSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientResponseSizeOpts + } else { + opt = append(opt, newClientResponseSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.response.size", + opt..., + ) + if err != nil { + return ClientResponseSize{noop.Int64Histogram{}}, err + } + return ClientResponseSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientResponseSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientResponseSize) Name() string { + return "rpc.client.response.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientResponseSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientResponseSize) Description() string { + return "Measures the size of RPC response messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ClientResponseSize) Record( + ctx context.Context, + val int64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ClientResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientResponseSize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ClientResponseSize) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ClientResponseSize) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ClientResponseSize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientResponseSize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientResponseSize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientResponseSize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ClientResponseSize) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// ServerCallDuration is an instrument used to record metric values conforming to +// the "rpc.server.call.duration" semantic conventions. It represents the +// measures the duration of inbound remote procedure calls (RPC). +type ServerCallDuration struct { + metric.Float64Histogram +} + +var newServerCallDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of inbound remote procedure calls (RPC)."), + metric.WithUnit("s"), +} + +// NewServerCallDuration returns a new ServerCallDuration instrument. +func NewServerCallDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ServerCallDuration, error) { + // Check if the meter is nil. + if m == nil { + return ServerCallDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerCallDurationOpts + } else { + opt = append(opt, newServerCallDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.server.call.duration", + opt..., + ) + if err != nil { + return ServerCallDuration{noop.Float64Histogram{}}, err + } + return ServerCallDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerCallDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerCallDuration) Name() string { + return "rpc.server.call.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerCallDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ServerCallDuration) Description() string { + return "Measures the duration of inbound remote procedure calls (RPC)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// When this metric is reported alongside an RPC server span, the metric value +// SHOULD be the same as the RPC server span duration. +func (m ServerCallDuration) Record( + ctx context.Context, + val float64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// When this metric is reported alongside an RPC server span, the metric value +// SHOULD be the same as the RPC server span duration. +func (m ServerCallDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerCallDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ServerCallDuration) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ServerCallDuration) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerCallDuration) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerCallDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ServerCallDuration) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ServerCallDuration) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ServerCallDuration) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// ServerRequestSize is an instrument used to record metric values conforming to +// the "rpc.server.request.size" semantic conventions. It represents the measures +// the size of RPC request messages (uncompressed). +type ServerRequestSize struct { + metric.Int64Histogram +} + +var newServerRequestSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewServerRequestSize returns a new ServerRequestSize instrument. +func NewServerRequestSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerRequestSize, error) { + // Check if the meter is nil. + if m == nil { + return ServerRequestSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerRequestSizeOpts + } else { + opt = append(opt, newServerRequestSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.request.size", + opt..., + ) + if err != nil { + return ServerRequestSize{noop.Int64Histogram{}}, err + } + return ServerRequestSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerRequestSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerRequestSize) Name() string { + return "rpc.server.request.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerRequestSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerRequestSize) Description() string { + return "Measures the size of RPC request messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ServerRequestSize) Record( + ctx context.Context, + val int64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ServerRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerRequestSize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ServerRequestSize) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ServerRequestSize) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerRequestSize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerRequestSize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ServerRequestSize) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ServerRequestSize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ServerRequestSize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// ServerResponseSize is an instrument used to record metric values conforming to +// the "rpc.server.response.size" semantic conventions. It represents the +// measures the size of RPC response messages (uncompressed). +type ServerResponseSize struct { + metric.Int64Histogram +} + +var newServerResponseSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewServerResponseSize returns a new ServerResponseSize instrument. +func NewServerResponseSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerResponseSize, error) { + // Check if the meter is nil. + if m == nil { + return ServerResponseSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerResponseSizeOpts + } else { + opt = append(opt, newServerResponseSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.response.size", + opt..., + ) + if err != nil { + return ServerResponseSize{noop.Int64Histogram{}}, err + } + return ServerResponseSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerResponseSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerResponseSize) Name() string { + return "rpc.server.response.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerResponseSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerResponseSize) Description() string { + return "Measures the size of RPC response messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ServerResponseSize) Record( + ctx context.Context, + val int64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append( + *o, + metric.WithAttributes( + append( + attrs, + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ServerResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerResponseSize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ServerResponseSize) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ServerResponseSize) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerResponseSize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerResponseSize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkTransport returns an optional attribute for the "network.transport" +// semantic convention. It represents the [OSI transport layer] or +// [inter-process communication method]. +// +// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer +// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication +func (ServerResponseSize) AttrNetworkTransport(val NetworkTransportAttr) attribute.KeyValue { + return attribute.String("network.transport", string(val)) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the RPC server [host name]. +// +// [host name]: https://grpc.github.io/grpc/core/md_doc_naming.html +func (ServerResponseSize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ServerResponseSize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go index 073adae2fa..df65c5cc72 100644 --- a/vendor/go.opentelemetry.io/otel/trace/tracestate.go +++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go @@ -61,6 +61,9 @@ func checkValue(val string) bool { func checkKeyRemain(key string) bool { // ( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) for _, v := range key { + if v > 127 { + return false + } if isAlphaNum(byte(v)) { continue } diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index 7c8f50803f..9004534068 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -5,5 +5,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.40.0" + return "1.41.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index 9daa2df9db..479c747876 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -3,7 +3,7 @@ module-sets: stable-v1: - version: v1.40.0 + version: v1.41.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opencensus @@ -22,11 +22,11 @@ module-sets: - go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.62.0 + version: v0.63.0 modules: - go.opentelemetry.io/otel/exporters/prometheus experimental-logs: - version: v0.16.0 + version: v0.17.0 modules: - go.opentelemetry.io/otel/log - go.opentelemetry.io/otel/log/logtest @@ -36,7 +36,7 @@ module-sets: - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp - go.opentelemetry.io/otel/exporters/stdout/stdoutlog experimental-schema: - version: v0.0.14 + version: v0.0.15 modules: - go.opentelemetry.io/otel/schema excluded-modules: diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go deleted file mode 100644 index 24cea68820..0000000000 --- a/vendor/golang.org/x/net/context/context.go +++ /dev/null @@ -1,118 +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. - -// Package context has been superseded by the standard library [context] package. -// -// Deprecated: Use the standard library context package instead. -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. -// -//go:fix inline -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. -// -//go:fix inline -var Canceled = context.Canceled - -// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled -// due to its deadline passing. -// -//go:fix inline -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, -// initialization, and tests, and as the top-level Context for incoming -// requests. -// -//go:fix inline -func Background() Context { return context.Background() } - -// 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). -// -//go:fix inline -func TODO() Context { return 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. -// -//go:fix inline -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. -// -//go:fix inline -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) -// } -// -//go:fix inline -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. -// -//go:fix inline -func WithValue(parent Context, key, val interface{}) Context { - return context.WithValue(parent, key, val) -} diff --git a/vendor/golang.org/x/net/http2/transport_wrap.go b/vendor/golang.org/x/net/http2/transport_wrap.go index eab2e6b073..534e77ab96 100644 --- a/vendor/golang.org/x/net/http2/transport_wrap.go +++ b/vendor/golang.org/x/net/http2/transport_wrap.go @@ -55,7 +55,7 @@ type transportConfig struct { // Registered is called by net/http.Transport.RegisterProtocol, // to let us know that it understands the registration mechanism we're using. func (t transportConfig) Registered(t1 *http.Transport) { - t.t.t1 = t1 + t.t.lazyt1 = t1 } func (t transportConfig) DisableCompression() bool { @@ -145,29 +145,30 @@ func (t transportConfig) DialFromContext(ctx context.Context, network, address s type transportInternal struct { initOnce sync.Once - t1 *http.Transport + lazyt1 *http.Transport } -func (t *Transport) init() { +func (t *Transport) init() *http.Transport { t.initOnce.Do(func() { - if t.t1 != nil { + if t.lazyt1 != nil { return } t1 := &http.Transport{} t.configure(t1) }) + return t.lazyt1 } func (t *Transport) configure(t1 *http.Transport) { t1.RegisterProtocol("http/2", transportConfig{t}) - // tr2.t1 is set by transportConfig.Registered. - if t.t1 != t1 { + // tr2.lazyt1 is set by transportConfig.Registered. + if t.lazyt1 != t1 { panic("http2: net/http does not support this version of x/net/http2") } } func (t *Transport) roundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { - t.init() + t1 := t.init() if req.URL.Scheme == "http" && !t.AllowHTTP { return nil, errors.New("http2: unencrypted HTTP/2 not enabled") @@ -188,22 +189,23 @@ func (t *Transport) roundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res ctx := context.WithValue(req.Context(), http2TransportContextKey{}, t) req = req.WithContext(ctx) - return t.t1.RoundTrip(req) + return t1.RoundTrip(req) } func (t *Transport) closeIdleConnections() { - t.init() - t.t1.CloseIdleConnections() + t1 := t.init() + t1.CloseIdleConnections() } func (t *Transport) newUserClientConn(c net.Conn) (*ClientConn, error) { + t1 := t.init() // http.Transport's NewClientConn doesn't provide a supported way to create // a connection from a net.Conn. (This might be useful to add in the future?) // We're going to craftily sneak one in via the context key, with the // scheme of "http/2" telling NewClientConn to look for it. ctx := context.WithValue(context.Background(), netConnContextKey{}, c) - nhcc, err := t.t1.NewClientConn(ctx, "http/2", "") + nhcc, err := t1.NewClientConn(ctx, "http/2", "") if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go index 22767125bf..e2f28fed48 100644 --- a/vendor/golang.org/x/net/idna/idna.go +++ b/vendor/golang.org/x/net/idna/idna.go @@ -400,7 +400,11 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { // Spec says keep the old label. continue } - if unicode16 && err == nil && len(u) > 0 && isASCII(u) { + if err == nil && len(u) > 0 && isASCII(u) { + // UTS 43 pre-revision 33 doesn't classify a xn-- label + // which contains only ASCII characters as an error, + // but that's a specification bug and a security issue. + // Always return an error in this case. err = punyError(enc) } isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight diff --git a/vendor/google.golang.org/grpc/reflection/README.md b/vendor/google.golang.org/grpc/reflection/README.md new file mode 100644 index 0000000000..9ace83ccb6 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/README.md @@ -0,0 +1,18 @@ +# Reflection + +Package reflection implements server reflection service. + +The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1/reflection.proto. + +To register server reflection on a gRPC server: +```go +import "google.golang.org/grpc/reflection" + +s := grpc.NewServer() +pb.RegisterYourOwnServer(s, &server{}) + +// Register reflection service on gRPC server. +reflection.Register(s) + +s.Serve(lis) +``` diff --git a/vendor/google.golang.org/grpc/reflection/adapt.go b/vendor/google.golang.org/grpc/reflection/adapt.go new file mode 100644 index 0000000000..6997e47403 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/adapt.go @@ -0,0 +1,57 @@ +/* + * + * Copyright 2023 gRPC 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 reflection + +import ( + "google.golang.org/grpc/reflection/internal" + + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +// asV1Alpha returns an implementation of the v1alpha version of the reflection +// interface that delegates all calls to the given v1 version. +func asV1Alpha(svr v1reflectiongrpc.ServerReflectionServer) v1alphareflectiongrpc.ServerReflectionServer { + return v1AlphaServerImpl{svr: svr} +} + +type v1AlphaServerImpl struct { + svr v1reflectiongrpc.ServerReflectionServer +} + +func (s v1AlphaServerImpl) ServerReflectionInfo(stream v1alphareflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { + return s.svr.ServerReflectionInfo(v1AlphaServerStreamAdapter{stream}) +} + +type v1AlphaServerStreamAdapter struct { + v1alphareflectiongrpc.ServerReflection_ServerReflectionInfoServer +} + +func (s v1AlphaServerStreamAdapter) Send(response *v1reflectionpb.ServerReflectionResponse) error { + return s.ServerReflection_ServerReflectionInfoServer.Send(internal.V1ToV1AlphaResponse(response)) +} + +func (s v1AlphaServerStreamAdapter) Recv() (*v1reflectionpb.ServerReflectionRequest, error) { + resp, err := s.ServerReflection_ServerReflectionInfoServer.Recv() + if err != nil { + return nil, err + } + return internal.V1AlphaToV1Request(resp), nil +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go new file mode 100644 index 0000000000..92fdc3afab --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection.pb.go @@ -0,0 +1,777 @@ +// Copyright 2016 The gRPC 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc v5.27.1 +// source: grpc/reflection/v1/reflection.proto + +package grpc_reflection_v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The message sent by the client when calling ServerReflectionInfo method. +type ServerReflectionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // To use reflection service, the client should set one of the following + // fields in message_request. The server distinguishes requests by their + // defined field and then handles them using corresponding methods. + // + // Types that are valid to be assigned to MessageRequest: + // + // *ServerReflectionRequest_FileByFilename + // *ServerReflectionRequest_FileContainingSymbol + // *ServerReflectionRequest_FileContainingExtension + // *ServerReflectionRequest_AllExtensionNumbersOfType + // *ServerReflectionRequest_ListServices + MessageRequest isServerReflectionRequest_MessageRequest `protobuf_oneof:"message_request"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerReflectionRequest) Reset() { + *x = ServerReflectionRequest{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerReflectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionRequest) ProtoMessage() {} + +func (x *ServerReflectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionRequest.ProtoReflect.Descriptor instead. +func (*ServerReflectionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{0} +} + +func (x *ServerReflectionRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *ServerReflectionRequest) GetMessageRequest() isServerReflectionRequest_MessageRequest { + if x != nil { + return x.MessageRequest + } + return nil +} + +func (x *ServerReflectionRequest) GetFileByFilename() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileByFilename); ok { + return x.FileByFilename + } + } + return "" +} + +func (x *ServerReflectionRequest) GetFileContainingSymbol() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileContainingSymbol); ok { + return x.FileContainingSymbol + } + } + return "" +} + +func (x *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileContainingExtension); ok { + return x.FileContainingExtension + } + } + return nil +} + +func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_AllExtensionNumbersOfType); ok { + return x.AllExtensionNumbersOfType + } + } + return "" +} + +func (x *ServerReflectionRequest) GetListServices() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_ListServices); ok { + return x.ListServices + } + } + return "" +} + +type isServerReflectionRequest_MessageRequest interface { + isServerReflectionRequest_MessageRequest() +} + +type ServerReflectionRequest_FileByFilename struct { + // Find a proto file by the file name. + FileByFilename string `protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingSymbol struct { + // Find the proto file that declares the given fully-qualified symbol name. + // This field should be a fully-qualified symbol name + // (e.g. .[.] or .). + FileContainingSymbol string `protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingExtension struct { + // Find the proto file which defines an extension extending the given + // message type with the given field number. + FileContainingExtension *ExtensionRequest `protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"` +} + +type ServerReflectionRequest_AllExtensionNumbersOfType struct { + // Finds the tag numbers used by all known extensions of the given message + // type, and appends them to ExtensionNumberResponse in an undefined order. + // Its corresponding method is best-effort: it's not guaranteed that the + // reflection service will implement this method, and it's not guaranteed + // that this method will provide all extensions. Returns + // StatusCode::UNIMPLEMENTED if it's not implemented. + // This field should be a fully-qualified type name. The format is + // . + AllExtensionNumbersOfType string `protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"` +} + +type ServerReflectionRequest_ListServices struct { + // List the full names of registered services. The content will not be + // checked. + ListServices string `protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"` +} + +func (*ServerReflectionRequest_FileByFilename) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingSymbol) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingExtension) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_AllExtensionNumbersOfType) isServerReflectionRequest_MessageRequest() { +} + +func (*ServerReflectionRequest_ListServices) isServerReflectionRequest_MessageRequest() {} + +// The type name and extension number sent by the client when requesting +// file_containing_extension. +type ExtensionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Fully-qualified type name. The format should be . + ContainingType string `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"` + ExtensionNumber int32 `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExtensionRequest) Reset() { + *x = ExtensionRequest{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExtensionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionRequest) ProtoMessage() {} + +func (x *ExtensionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionRequest.ProtoReflect.Descriptor instead. +func (*ExtensionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{1} +} + +func (x *ExtensionRequest) GetContainingType() string { + if x != nil { + return x.ContainingType + } + return "" +} + +func (x *ExtensionRequest) GetExtensionNumber() int32 { + if x != nil { + return x.ExtensionNumber + } + return 0 +} + +// The message sent by the server to answer ServerReflectionInfo method. +type ServerReflectionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + ValidHost string `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"` + OriginalRequest *ServerReflectionRequest `protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3" json:"original_request,omitempty"` + // The server sets one of the following fields according to the message_request + // in the request. + // + // Types that are valid to be assigned to MessageResponse: + // + // *ServerReflectionResponse_FileDescriptorResponse + // *ServerReflectionResponse_AllExtensionNumbersResponse + // *ServerReflectionResponse_ListServicesResponse + // *ServerReflectionResponse_ErrorResponse + MessageResponse isServerReflectionResponse_MessageResponse `protobuf_oneof:"message_response"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerReflectionResponse) Reset() { + *x = ServerReflectionResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerReflectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionResponse) ProtoMessage() {} + +func (x *ServerReflectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionResponse.ProtoReflect.Descriptor instead. +func (*ServerReflectionResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{2} +} + +func (x *ServerReflectionResponse) GetValidHost() string { + if x != nil { + return x.ValidHost + } + return "" +} + +func (x *ServerReflectionResponse) GetOriginalRequest() *ServerReflectionRequest { + if x != nil { + return x.OriginalRequest + } + return nil +} + +func (x *ServerReflectionResponse) GetMessageResponse() isServerReflectionResponse_MessageResponse { + if x != nil { + return x.MessageResponse + } + return nil +} + +func (x *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_FileDescriptorResponse); ok { + return x.FileDescriptorResponse + } + } + return nil +} + +func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNumberResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_AllExtensionNumbersResponse); ok { + return x.AllExtensionNumbersResponse + } + } + return nil +} + +func (x *ServerReflectionResponse) GetListServicesResponse() *ListServiceResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_ListServicesResponse); ok { + return x.ListServicesResponse + } + } + return nil +} + +func (x *ServerReflectionResponse) GetErrorResponse() *ErrorResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_ErrorResponse); ok { + return x.ErrorResponse + } + } + return nil +} + +type isServerReflectionResponse_MessageResponse interface { + isServerReflectionResponse_MessageResponse() +} + +type ServerReflectionResponse_FileDescriptorResponse struct { + // This message is used to answer file_by_filename, file_containing_symbol, + // file_containing_extension requests with transitive dependencies. + // As the repeated label is not allowed in oneof fields, we use a + // FileDescriptorResponse message to encapsulate the repeated fields. + // The reflection service is allowed to avoid sending FileDescriptorProtos + // that were previously sent in response to earlier requests in the stream. + FileDescriptorResponse *FileDescriptorResponse `protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"` +} + +type ServerReflectionResponse_AllExtensionNumbersResponse struct { + // This message is used to answer all_extension_numbers_of_type requests. + AllExtensionNumbersResponse *ExtensionNumberResponse `protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ListServicesResponse struct { + // This message is used to answer list_services requests. + ListServicesResponse *ListServiceResponse `protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ErrorResponse struct { + // This message is used when an error occurs. + ErrorResponse *ErrorResponse `protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"` +} + +func (*ServerReflectionResponse_FileDescriptorResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_AllExtensionNumbersResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_ListServicesResponse) isServerReflectionResponse_MessageResponse() {} + +func (*ServerReflectionResponse_ErrorResponse) isServerReflectionResponse_MessageResponse() {} + +// Serialized FileDescriptorProto messages sent by the server answering +// a file_by_filename, file_containing_symbol, or file_containing_extension +// request. +type FileDescriptorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Serialized FileDescriptorProto messages. We avoid taking a dependency on + // descriptor.proto, which uses proto2 only features, by making them opaque + // bytes instead. + FileDescriptorProto [][]byte `protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3" json:"file_descriptor_proto,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FileDescriptorResponse) Reset() { + *x = FileDescriptorResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FileDescriptorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileDescriptorResponse) ProtoMessage() {} + +func (x *FileDescriptorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileDescriptorResponse.ProtoReflect.Descriptor instead. +func (*FileDescriptorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{3} +} + +func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte { + if x != nil { + return x.FileDescriptorProto + } + return nil +} + +// A list of extension numbers sent by the server answering +// all_extension_numbers_of_type request. +type ExtensionNumberResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Full name of the base type, including the package name. The format + // is . + BaseTypeName string `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"` + ExtensionNumber []int32 `protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExtensionNumberResponse) Reset() { + *x = ExtensionNumberResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExtensionNumberResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionNumberResponse) ProtoMessage() {} + +func (x *ExtensionNumberResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionNumberResponse.ProtoReflect.Descriptor instead. +func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{4} +} + +func (x *ExtensionNumberResponse) GetBaseTypeName() string { + if x != nil { + return x.BaseTypeName + } + return "" +} + +func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 { + if x != nil { + return x.ExtensionNumber + } + return nil +} + +// A list of ServiceResponse sent by the server answering list_services request. +type ListServiceResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The information of each service may be expanded in the future, so we use + // ServiceResponse message to encapsulate it. + Service []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3" json:"service,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListServiceResponse) Reset() { + *x = ListServiceResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServiceResponse) ProtoMessage() {} + +func (x *ListServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServiceResponse.ProtoReflect.Descriptor instead. +func (*ListServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{5} +} + +func (x *ListServiceResponse) GetService() []*ServiceResponse { + if x != nil { + return x.Service + } + return nil +} + +// The information of a single service used by ListServiceResponse to answer +// list_services request. +type ServiceResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Full name of a registered service, including its package name. The format + // is . + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServiceResponse) Reset() { + *x = ServiceResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceResponse) ProtoMessage() {} + +func (x *ServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceResponse.ProtoReflect.Descriptor instead. +func (*ServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{6} +} + +func (x *ServiceResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The error code and error message sent by the server when an error occurs. +type ErrorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // This field uses the error codes defined in grpc::StatusCode. + ErrorCode int32 `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ErrorResponse) Reset() { + *x = ErrorResponse{} + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ErrorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ErrorResponse) ProtoMessage() {} + +func (x *ErrorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1_reflection_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead. +func (*ErrorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1_reflection_proto_rawDescGZIP(), []int{7} +} + +func (x *ErrorResponse) GetErrorCode() int32 { + if x != nil { + return x.ErrorCode + } + return 0 +} + +func (x *ErrorResponse) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +var File_grpc_reflection_v1_reflection_proto protoreflect.FileDescriptor + +const file_grpc_reflection_v1_reflection_proto_rawDesc = "" + + "\n" + + "#grpc/reflection/v1/reflection.proto\x12\x12grpc.reflection.v1\"\xf3\x02\n" + + "\x17ServerReflectionRequest\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12*\n" + + "\x10file_by_filename\x18\x03 \x01(\tH\x00R\x0efileByFilename\x126\n" + + "\x16file_containing_symbol\x18\x04 \x01(\tH\x00R\x14fileContainingSymbol\x12b\n" + + "\x19file_containing_extension\x18\x05 \x01(\v2$.grpc.reflection.v1.ExtensionRequestH\x00R\x17fileContainingExtension\x12B\n" + + "\x1dall_extension_numbers_of_type\x18\x06 \x01(\tH\x00R\x19allExtensionNumbersOfType\x12%\n" + + "\rlist_services\x18\a \x01(\tH\x00R\flistServicesB\x11\n" + + "\x0fmessage_request\"f\n" + + "\x10ExtensionRequest\x12'\n" + + "\x0fcontaining_type\x18\x01 \x01(\tR\x0econtainingType\x12)\n" + + "\x10extension_number\x18\x02 \x01(\x05R\x0fextensionNumber\"\xae\x04\n" + + "\x18ServerReflectionResponse\x12\x1d\n" + + "\n" + + "valid_host\x18\x01 \x01(\tR\tvalidHost\x12V\n" + + "\x10original_request\x18\x02 \x01(\v2+.grpc.reflection.v1.ServerReflectionRequestR\x0foriginalRequest\x12f\n" + + "\x18file_descriptor_response\x18\x04 \x01(\v2*.grpc.reflection.v1.FileDescriptorResponseH\x00R\x16fileDescriptorResponse\x12r\n" + + "\x1eall_extension_numbers_response\x18\x05 \x01(\v2+.grpc.reflection.v1.ExtensionNumberResponseH\x00R\x1ballExtensionNumbersResponse\x12_\n" + + "\x16list_services_response\x18\x06 \x01(\v2'.grpc.reflection.v1.ListServiceResponseH\x00R\x14listServicesResponse\x12J\n" + + "\x0eerror_response\x18\a \x01(\v2!.grpc.reflection.v1.ErrorResponseH\x00R\rerrorResponseB\x12\n" + + "\x10message_response\"L\n" + + "\x16FileDescriptorResponse\x122\n" + + "\x15file_descriptor_proto\x18\x01 \x03(\fR\x13fileDescriptorProto\"j\n" + + "\x17ExtensionNumberResponse\x12$\n" + + "\x0ebase_type_name\x18\x01 \x01(\tR\fbaseTypeName\x12)\n" + + "\x10extension_number\x18\x02 \x03(\x05R\x0fextensionNumber\"T\n" + + "\x13ListServiceResponse\x12=\n" + + "\aservice\x18\x01 \x03(\v2#.grpc.reflection.v1.ServiceResponseR\aservice\"%\n" + + "\x0fServiceResponse\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"S\n" + + "\rErrorResponse\x12\x1d\n" + + "\n" + + "error_code\x18\x01 \x01(\x05R\terrorCode\x12#\n" + + "\rerror_message\x18\x02 \x01(\tR\ferrorMessage2\x89\x01\n" + + "\x10ServerReflection\x12u\n" + + "\x14ServerReflectionInfo\x12+.grpc.reflection.v1.ServerReflectionRequest\x1a,.grpc.reflection.v1.ServerReflectionResponse(\x010\x01Bf\n" + + "\x15io.grpc.reflection.v1B\x15ServerReflectionProtoP\x01Z4google.golang.org/grpc/reflection/grpc_reflection_v1b\x06proto3" + +var ( + file_grpc_reflection_v1_reflection_proto_rawDescOnce sync.Once + file_grpc_reflection_v1_reflection_proto_rawDescData []byte +) + +func file_grpc_reflection_v1_reflection_proto_rawDescGZIP() []byte { + file_grpc_reflection_v1_reflection_proto_rawDescOnce.Do(func() { + file_grpc_reflection_v1_reflection_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpc_reflection_v1_reflection_proto_rawDesc), len(file_grpc_reflection_v1_reflection_proto_rawDesc))) + }) + return file_grpc_reflection_v1_reflection_proto_rawDescData +} + +var file_grpc_reflection_v1_reflection_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_grpc_reflection_v1_reflection_proto_goTypes = []any{ + (*ServerReflectionRequest)(nil), // 0: grpc.reflection.v1.ServerReflectionRequest + (*ExtensionRequest)(nil), // 1: grpc.reflection.v1.ExtensionRequest + (*ServerReflectionResponse)(nil), // 2: grpc.reflection.v1.ServerReflectionResponse + (*FileDescriptorResponse)(nil), // 3: grpc.reflection.v1.FileDescriptorResponse + (*ExtensionNumberResponse)(nil), // 4: grpc.reflection.v1.ExtensionNumberResponse + (*ListServiceResponse)(nil), // 5: grpc.reflection.v1.ListServiceResponse + (*ServiceResponse)(nil), // 6: grpc.reflection.v1.ServiceResponse + (*ErrorResponse)(nil), // 7: grpc.reflection.v1.ErrorResponse +} +var file_grpc_reflection_v1_reflection_proto_depIdxs = []int32{ + 1, // 0: grpc.reflection.v1.ServerReflectionRequest.file_containing_extension:type_name -> grpc.reflection.v1.ExtensionRequest + 0, // 1: grpc.reflection.v1.ServerReflectionResponse.original_request:type_name -> grpc.reflection.v1.ServerReflectionRequest + 3, // 2: grpc.reflection.v1.ServerReflectionResponse.file_descriptor_response:type_name -> grpc.reflection.v1.FileDescriptorResponse + 4, // 3: grpc.reflection.v1.ServerReflectionResponse.all_extension_numbers_response:type_name -> grpc.reflection.v1.ExtensionNumberResponse + 5, // 4: grpc.reflection.v1.ServerReflectionResponse.list_services_response:type_name -> grpc.reflection.v1.ListServiceResponse + 7, // 5: grpc.reflection.v1.ServerReflectionResponse.error_response:type_name -> grpc.reflection.v1.ErrorResponse + 6, // 6: grpc.reflection.v1.ListServiceResponse.service:type_name -> grpc.reflection.v1.ServiceResponse + 0, // 7: grpc.reflection.v1.ServerReflection.ServerReflectionInfo:input_type -> grpc.reflection.v1.ServerReflectionRequest + 2, // 8: grpc.reflection.v1.ServerReflection.ServerReflectionInfo:output_type -> grpc.reflection.v1.ServerReflectionResponse + 8, // [8:9] is the sub-list for method output_type + 7, // [7:8] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_grpc_reflection_v1_reflection_proto_init() } +func file_grpc_reflection_v1_reflection_proto_init() { + if File_grpc_reflection_v1_reflection_proto != nil { + return + } + file_grpc_reflection_v1_reflection_proto_msgTypes[0].OneofWrappers = []any{ + (*ServerReflectionRequest_FileByFilename)(nil), + (*ServerReflectionRequest_FileContainingSymbol)(nil), + (*ServerReflectionRequest_FileContainingExtension)(nil), + (*ServerReflectionRequest_AllExtensionNumbersOfType)(nil), + (*ServerReflectionRequest_ListServices)(nil), + } + file_grpc_reflection_v1_reflection_proto_msgTypes[2].OneofWrappers = []any{ + (*ServerReflectionResponse_FileDescriptorResponse)(nil), + (*ServerReflectionResponse_AllExtensionNumbersResponse)(nil), + (*ServerReflectionResponse_ListServicesResponse)(nil), + (*ServerReflectionResponse_ErrorResponse)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpc_reflection_v1_reflection_proto_rawDesc), len(file_grpc_reflection_v1_reflection_proto_rawDesc)), + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_grpc_reflection_v1_reflection_proto_goTypes, + DependencyIndexes: file_grpc_reflection_v1_reflection_proto_depIdxs, + MessageInfos: file_grpc_reflection_v1_reflection_proto_msgTypes, + }.Build() + File_grpc_reflection_v1_reflection_proto = out.File + file_grpc_reflection_v1_reflection_proto_goTypes = nil + file_grpc_reflection_v1_reflection_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go new file mode 100644 index 0000000000..93a243631c --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1/reflection_grpc.pb.go @@ -0,0 +1,138 @@ +// Copyright 2016 The gRPC 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc v5.27.1 +// source: grpc/reflection/v1/reflection.proto + +package grpc_reflection_v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + ServerReflection_ServerReflectionInfo_FullMethodName = "/grpc.reflection.v1.ServerReflection/ServerReflectionInfo" +) + +// ServerReflectionClient is the client API for ServerReflection service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ServerReflectionClient interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse], error) +} + +type serverReflectionClient struct { + cc grpc.ClientConnInterface +} + +func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClient { + return &serverReflectionClient{cc} +} + +func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[ServerReflectionRequest, ServerReflectionResponse]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ServerReflection_ServerReflectionInfoClient = grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse] + +// ServerReflectionServer is the server API for ServerReflection service. +// All implementations should embed UnimplementedServerReflectionServer +// for forward compatibility. +type ServerReflectionServer interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse]) error +} + +// UnimplementedServerReflectionServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedServerReflectionServer struct{} + +func (UnimplementedServerReflectionServer) ServerReflectionInfo(grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse]) error { + return status.Error(codes.Unimplemented, "method ServerReflectionInfo not implemented") +} +func (UnimplementedServerReflectionServer) testEmbeddedByValue() {} + +// UnsafeServerReflectionServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ServerReflectionServer will +// result in compilation errors. +type UnsafeServerReflectionServer interface { + mustEmbedUnimplementedServerReflectionServer() +} + +func RegisterServerReflectionServer(s grpc.ServiceRegistrar, srv ServerReflectionServer) { + // If the following call panics, it indicates UnimplementedServerReflectionServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&ServerReflection_ServiceDesc, srv) +} + +func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ServerReflectionServer).ServerReflectionInfo(&grpc.GenericServerStream[ServerReflectionRequest, ServerReflectionResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ServerReflection_ServerReflectionInfoServer = grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse] + +// ServerReflection_ServiceDesc is the grpc.ServiceDesc for ServerReflection service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ServerReflection_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.reflection.v1.ServerReflection", + HandlerType: (*ServerReflectionServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerReflectionInfo", + Handler: _ServerReflection_ServerReflectionInfo_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/reflection/v1/reflection.proto", +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go new file mode 100644 index 0000000000..c803cf3ba1 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection.pb.go @@ -0,0 +1,847 @@ +// Copyright 2016 The gRPC 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. +// Service exported by server reflection + +// Warning: this entire file is deprecated. Use this instead: +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc v5.27.1 +// grpc/reflection/v1alpha/reflection.proto is a deprecated file. + +package grpc_reflection_v1alpha + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The message sent by the client when calling ServerReflectionInfo method. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ServerReflectionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // To use reflection service, the client should set one of the following + // fields in message_request. The server distinguishes requests by their + // defined field and then handles them using corresponding methods. + // + // Types that are valid to be assigned to MessageRequest: + // + // *ServerReflectionRequest_FileByFilename + // *ServerReflectionRequest_FileContainingSymbol + // *ServerReflectionRequest_FileContainingExtension + // *ServerReflectionRequest_AllExtensionNumbersOfType + // *ServerReflectionRequest_ListServices + MessageRequest isServerReflectionRequest_MessageRequest `protobuf_oneof:"message_request"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerReflectionRequest) Reset() { + *x = ServerReflectionRequest{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerReflectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionRequest) ProtoMessage() {} + +func (x *ServerReflectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionRequest.ProtoReflect.Descriptor instead. +func (*ServerReflectionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{0} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *ServerReflectionRequest) GetMessageRequest() isServerReflectionRequest_MessageRequest { + if x != nil { + return x.MessageRequest + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetFileByFilename() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileByFilename); ok { + return x.FileByFilename + } + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetFileContainingSymbol() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileContainingSymbol); ok { + return x.FileContainingSymbol + } + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_FileContainingExtension); ok { + return x.FileContainingExtension + } + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_AllExtensionNumbersOfType); ok { + return x.AllExtensionNumbersOfType + } + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionRequest) GetListServices() string { + if x != nil { + if x, ok := x.MessageRequest.(*ServerReflectionRequest_ListServices); ok { + return x.ListServices + } + } + return "" +} + +type isServerReflectionRequest_MessageRequest interface { + isServerReflectionRequest_MessageRequest() +} + +type ServerReflectionRequest_FileByFilename struct { + // Find a proto file by the file name. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + FileByFilename string `protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingSymbol struct { + // Find the proto file that declares the given fully-qualified symbol name. + // This field should be a fully-qualified symbol name + // (e.g. .[.] or .). + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + FileContainingSymbol string `protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"` +} + +type ServerReflectionRequest_FileContainingExtension struct { + // Find the proto file which defines an extension extending the given + // message type with the given field number. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + FileContainingExtension *ExtensionRequest `protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"` +} + +type ServerReflectionRequest_AllExtensionNumbersOfType struct { + // Finds the tag numbers used by all known extensions of extendee_type, and + // appends them to ExtensionNumberResponse in an undefined order. + // Its corresponding method is best-effort: it's not guaranteed that the + // reflection service will implement this method, and it's not guaranteed + // that this method will provide all extensions. Returns + // StatusCode::UNIMPLEMENTED if it's not implemented. + // This field should be a fully-qualified type name. The format is + // . + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + AllExtensionNumbersOfType string `protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"` +} + +type ServerReflectionRequest_ListServices struct { + // List the full names of registered services. The content will not be + // checked. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ListServices string `protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"` +} + +func (*ServerReflectionRequest_FileByFilename) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingSymbol) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_FileContainingExtension) isServerReflectionRequest_MessageRequest() {} + +func (*ServerReflectionRequest_AllExtensionNumbersOfType) isServerReflectionRequest_MessageRequest() { +} + +func (*ServerReflectionRequest_ListServices) isServerReflectionRequest_MessageRequest() {} + +// The type name and extension number sent by the client when requesting +// file_containing_extension. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ExtensionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Fully-qualified type name. The format should be . + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ContainingType string `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ExtensionNumber int32 `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExtensionRequest) Reset() { + *x = ExtensionRequest{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExtensionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionRequest) ProtoMessage() {} + +func (x *ExtensionRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionRequest.ProtoReflect.Descriptor instead. +func (*ExtensionRequest) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{1} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ExtensionRequest) GetContainingType() string { + if x != nil { + return x.ContainingType + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ExtensionRequest) GetExtensionNumber() int32 { + if x != nil { + return x.ExtensionNumber + } + return 0 +} + +// The message sent by the server to answer ServerReflectionInfo method. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ServerReflectionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ValidHost string `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + OriginalRequest *ServerReflectionRequest `protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3" json:"original_request,omitempty"` + // The server set one of the following fields according to the message_request + // in the request. + // + // Types that are valid to be assigned to MessageResponse: + // + // *ServerReflectionResponse_FileDescriptorResponse + // *ServerReflectionResponse_AllExtensionNumbersResponse + // *ServerReflectionResponse_ListServicesResponse + // *ServerReflectionResponse_ErrorResponse + MessageResponse isServerReflectionResponse_MessageResponse `protobuf_oneof:"message_response"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerReflectionResponse) Reset() { + *x = ServerReflectionResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerReflectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerReflectionResponse) ProtoMessage() {} + +func (x *ServerReflectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerReflectionResponse.ProtoReflect.Descriptor instead. +func (*ServerReflectionResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{2} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetValidHost() string { + if x != nil { + return x.ValidHost + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetOriginalRequest() *ServerReflectionRequest { + if x != nil { + return x.OriginalRequest + } + return nil +} + +func (x *ServerReflectionResponse) GetMessageResponse() isServerReflectionResponse_MessageResponse { + if x != nil { + return x.MessageResponse + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_FileDescriptorResponse); ok { + return x.FileDescriptorResponse + } + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNumberResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_AllExtensionNumbersResponse); ok { + return x.AllExtensionNumbersResponse + } + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetListServicesResponse() *ListServiceResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_ListServicesResponse); ok { + return x.ListServicesResponse + } + } + return nil +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServerReflectionResponse) GetErrorResponse() *ErrorResponse { + if x != nil { + if x, ok := x.MessageResponse.(*ServerReflectionResponse_ErrorResponse); ok { + return x.ErrorResponse + } + } + return nil +} + +type isServerReflectionResponse_MessageResponse interface { + isServerReflectionResponse_MessageResponse() +} + +type ServerReflectionResponse_FileDescriptorResponse struct { + // This message is used to answer file_by_filename, file_containing_symbol, + // file_containing_extension requests with transitive dependencies. As + // the repeated label is not allowed in oneof fields, we use a + // FileDescriptorResponse message to encapsulate the repeated fields. + // The reflection service is allowed to avoid sending FileDescriptorProtos + // that were previously sent in response to earlier requests in the stream. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + FileDescriptorResponse *FileDescriptorResponse `protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"` +} + +type ServerReflectionResponse_AllExtensionNumbersResponse struct { + // This message is used to answer all_extension_numbers_of_type request. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + AllExtensionNumbersResponse *ExtensionNumberResponse `protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ListServicesResponse struct { + // This message is used to answer list_services request. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ListServicesResponse *ListServiceResponse `protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"` +} + +type ServerReflectionResponse_ErrorResponse struct { + // This message is used when an error occurs. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ErrorResponse *ErrorResponse `protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"` +} + +func (*ServerReflectionResponse_FileDescriptorResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_AllExtensionNumbersResponse) isServerReflectionResponse_MessageResponse() { +} + +func (*ServerReflectionResponse_ListServicesResponse) isServerReflectionResponse_MessageResponse() {} + +func (*ServerReflectionResponse_ErrorResponse) isServerReflectionResponse_MessageResponse() {} + +// Serialized FileDescriptorProto messages sent by the server answering +// a file_by_filename, file_containing_symbol, or file_containing_extension +// request. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type FileDescriptorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Serialized FileDescriptorProto messages. We avoid taking a dependency on + // descriptor.proto, which uses proto2 only features, by making them opaque + // bytes instead. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + FileDescriptorProto [][]byte `protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3" json:"file_descriptor_proto,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FileDescriptorResponse) Reset() { + *x = FileDescriptorResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FileDescriptorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileDescriptorResponse) ProtoMessage() {} + +func (x *FileDescriptorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileDescriptorResponse.ProtoReflect.Descriptor instead. +func (*FileDescriptorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{3} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte { + if x != nil { + return x.FileDescriptorProto + } + return nil +} + +// A list of extension numbers sent by the server answering +// all_extension_numbers_of_type request. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ExtensionNumberResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Full name of the base type, including the package name. The format + // is . + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + BaseTypeName string `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ExtensionNumber []int32 `protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExtensionNumberResponse) Reset() { + *x = ExtensionNumberResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExtensionNumberResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionNumberResponse) ProtoMessage() {} + +func (x *ExtensionNumberResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionNumberResponse.ProtoReflect.Descriptor instead. +func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{4} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ExtensionNumberResponse) GetBaseTypeName() string { + if x != nil { + return x.BaseTypeName + } + return "" +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 { + if x != nil { + return x.ExtensionNumber + } + return nil +} + +// A list of ServiceResponse sent by the server answering list_services request. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ListServiceResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The information of each service may be expanded in the future, so we use + // ServiceResponse message to encapsulate it. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + Service []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3" json:"service,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListServiceResponse) Reset() { + *x = ListServiceResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServiceResponse) ProtoMessage() {} + +func (x *ListServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServiceResponse.ProtoReflect.Descriptor instead. +func (*ListServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{5} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ListServiceResponse) GetService() []*ServiceResponse { + if x != nil { + return x.Service + } + return nil +} + +// The information of a single service used by ListServiceResponse to answer +// list_services request. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ServiceResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Full name of a registered service, including its package name. The format + // is . + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServiceResponse) Reset() { + *x = ServiceResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceResponse) ProtoMessage() {} + +func (x *ServiceResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceResponse.ProtoReflect.Descriptor instead. +func (*ServiceResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{6} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ServiceResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The error code and error message sent by the server when an error occurs. +// +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +type ErrorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // This field uses the error codes defined in grpc::StatusCode. + // + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ErrorCode int32 `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + // Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ErrorResponse) Reset() { + *x = ErrorResponse{} + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ErrorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ErrorResponse) ProtoMessage() {} + +func (x *ErrorResponse) ProtoReflect() protoreflect.Message { + mi := &file_grpc_reflection_v1alpha_reflection_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead. +func (*ErrorResponse) Descriptor() ([]byte, []int) { + return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{7} +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ErrorResponse) GetErrorCode() int32 { + if x != nil { + return x.ErrorCode + } + return 0 +} + +// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated. +func (x *ErrorResponse) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +var File_grpc_reflection_v1alpha_reflection_proto protoreflect.FileDescriptor + +const file_grpc_reflection_v1alpha_reflection_proto_rawDesc = "" + + "\n" + + "(grpc/reflection/v1alpha/reflection.proto\x12\x17grpc.reflection.v1alpha\"\xf8\x02\n" + + "\x17ServerReflectionRequest\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12*\n" + + "\x10file_by_filename\x18\x03 \x01(\tH\x00R\x0efileByFilename\x126\n" + + "\x16file_containing_symbol\x18\x04 \x01(\tH\x00R\x14fileContainingSymbol\x12g\n" + + "\x19file_containing_extension\x18\x05 \x01(\v2).grpc.reflection.v1alpha.ExtensionRequestH\x00R\x17fileContainingExtension\x12B\n" + + "\x1dall_extension_numbers_of_type\x18\x06 \x01(\tH\x00R\x19allExtensionNumbersOfType\x12%\n" + + "\rlist_services\x18\a \x01(\tH\x00R\flistServicesB\x11\n" + + "\x0fmessage_request\"f\n" + + "\x10ExtensionRequest\x12'\n" + + "\x0fcontaining_type\x18\x01 \x01(\tR\x0econtainingType\x12)\n" + + "\x10extension_number\x18\x02 \x01(\x05R\x0fextensionNumber\"\xc7\x04\n" + + "\x18ServerReflectionResponse\x12\x1d\n" + + "\n" + + "valid_host\x18\x01 \x01(\tR\tvalidHost\x12[\n" + + "\x10original_request\x18\x02 \x01(\v20.grpc.reflection.v1alpha.ServerReflectionRequestR\x0foriginalRequest\x12k\n" + + "\x18file_descriptor_response\x18\x04 \x01(\v2/.grpc.reflection.v1alpha.FileDescriptorResponseH\x00R\x16fileDescriptorResponse\x12w\n" + + "\x1eall_extension_numbers_response\x18\x05 \x01(\v20.grpc.reflection.v1alpha.ExtensionNumberResponseH\x00R\x1ballExtensionNumbersResponse\x12d\n" + + "\x16list_services_response\x18\x06 \x01(\v2,.grpc.reflection.v1alpha.ListServiceResponseH\x00R\x14listServicesResponse\x12O\n" + + "\x0eerror_response\x18\a \x01(\v2&.grpc.reflection.v1alpha.ErrorResponseH\x00R\rerrorResponseB\x12\n" + + "\x10message_response\"L\n" + + "\x16FileDescriptorResponse\x122\n" + + "\x15file_descriptor_proto\x18\x01 \x03(\fR\x13fileDescriptorProto\"j\n" + + "\x17ExtensionNumberResponse\x12$\n" + + "\x0ebase_type_name\x18\x01 \x01(\tR\fbaseTypeName\x12)\n" + + "\x10extension_number\x18\x02 \x03(\x05R\x0fextensionNumber\"Y\n" + + "\x13ListServiceResponse\x12B\n" + + "\aservice\x18\x01 \x03(\v2(.grpc.reflection.v1alpha.ServiceResponseR\aservice\"%\n" + + "\x0fServiceResponse\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"S\n" + + "\rErrorResponse\x12\x1d\n" + + "\n" + + "error_code\x18\x01 \x01(\x05R\terrorCode\x12#\n" + + "\rerror_message\x18\x02 \x01(\tR\ferrorMessage2\x93\x01\n" + + "\x10ServerReflection\x12\x7f\n" + + "\x14ServerReflectionInfo\x120.grpc.reflection.v1alpha.ServerReflectionRequest\x1a1.grpc.reflection.v1alpha.ServerReflectionResponse(\x010\x01Bs\n" + + "\x1aio.grpc.reflection.v1alphaB\x15ServerReflectionProtoP\x01Z9google.golang.org/grpc/reflection/grpc_reflection_v1alpha\xb8\x01\x01b\x06proto3" + +var ( + file_grpc_reflection_v1alpha_reflection_proto_rawDescOnce sync.Once + file_grpc_reflection_v1alpha_reflection_proto_rawDescData []byte +) + +func file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP() []byte { + file_grpc_reflection_v1alpha_reflection_proto_rawDescOnce.Do(func() { + file_grpc_reflection_v1alpha_reflection_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpc_reflection_v1alpha_reflection_proto_rawDesc), len(file_grpc_reflection_v1alpha_reflection_proto_rawDesc))) + }) + return file_grpc_reflection_v1alpha_reflection_proto_rawDescData +} + +var file_grpc_reflection_v1alpha_reflection_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_grpc_reflection_v1alpha_reflection_proto_goTypes = []any{ + (*ServerReflectionRequest)(nil), // 0: grpc.reflection.v1alpha.ServerReflectionRequest + (*ExtensionRequest)(nil), // 1: grpc.reflection.v1alpha.ExtensionRequest + (*ServerReflectionResponse)(nil), // 2: grpc.reflection.v1alpha.ServerReflectionResponse + (*FileDescriptorResponse)(nil), // 3: grpc.reflection.v1alpha.FileDescriptorResponse + (*ExtensionNumberResponse)(nil), // 4: grpc.reflection.v1alpha.ExtensionNumberResponse + (*ListServiceResponse)(nil), // 5: grpc.reflection.v1alpha.ListServiceResponse + (*ServiceResponse)(nil), // 6: grpc.reflection.v1alpha.ServiceResponse + (*ErrorResponse)(nil), // 7: grpc.reflection.v1alpha.ErrorResponse +} +var file_grpc_reflection_v1alpha_reflection_proto_depIdxs = []int32{ + 1, // 0: grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension:type_name -> grpc.reflection.v1alpha.ExtensionRequest + 0, // 1: grpc.reflection.v1alpha.ServerReflectionResponse.original_request:type_name -> grpc.reflection.v1alpha.ServerReflectionRequest + 3, // 2: grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response:type_name -> grpc.reflection.v1alpha.FileDescriptorResponse + 4, // 3: grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response:type_name -> grpc.reflection.v1alpha.ExtensionNumberResponse + 5, // 4: grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response:type_name -> grpc.reflection.v1alpha.ListServiceResponse + 7, // 5: grpc.reflection.v1alpha.ServerReflectionResponse.error_response:type_name -> grpc.reflection.v1alpha.ErrorResponse + 6, // 6: grpc.reflection.v1alpha.ListServiceResponse.service:type_name -> grpc.reflection.v1alpha.ServiceResponse + 0, // 7: grpc.reflection.v1alpha.ServerReflection.ServerReflectionInfo:input_type -> grpc.reflection.v1alpha.ServerReflectionRequest + 2, // 8: grpc.reflection.v1alpha.ServerReflection.ServerReflectionInfo:output_type -> grpc.reflection.v1alpha.ServerReflectionResponse + 8, // [8:9] is the sub-list for method output_type + 7, // [7:8] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_grpc_reflection_v1alpha_reflection_proto_init() } +func file_grpc_reflection_v1alpha_reflection_proto_init() { + if File_grpc_reflection_v1alpha_reflection_proto != nil { + return + } + file_grpc_reflection_v1alpha_reflection_proto_msgTypes[0].OneofWrappers = []any{ + (*ServerReflectionRequest_FileByFilename)(nil), + (*ServerReflectionRequest_FileContainingSymbol)(nil), + (*ServerReflectionRequest_FileContainingExtension)(nil), + (*ServerReflectionRequest_AllExtensionNumbersOfType)(nil), + (*ServerReflectionRequest_ListServices)(nil), + } + file_grpc_reflection_v1alpha_reflection_proto_msgTypes[2].OneofWrappers = []any{ + (*ServerReflectionResponse_FileDescriptorResponse)(nil), + (*ServerReflectionResponse_AllExtensionNumbersResponse)(nil), + (*ServerReflectionResponse_ListServicesResponse)(nil), + (*ServerReflectionResponse_ErrorResponse)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpc_reflection_v1alpha_reflection_proto_rawDesc), len(file_grpc_reflection_v1alpha_reflection_proto_rawDesc)), + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_grpc_reflection_v1alpha_reflection_proto_goTypes, + DependencyIndexes: file_grpc_reflection_v1alpha_reflection_proto_depIdxs, + MessageInfos: file_grpc_reflection_v1alpha_reflection_proto_msgTypes, + }.Build() + File_grpc_reflection_v1alpha_reflection_proto = out.File + file_grpc_reflection_v1alpha_reflection_proto_goTypes = nil + file_grpc_reflection_v1alpha_reflection_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go new file mode 100644 index 0000000000..cee004ab57 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go @@ -0,0 +1,135 @@ +// Copyright 2016 The gRPC 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. +// Service exported by server reflection + +// Warning: this entire file is deprecated. Use this instead: +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc v5.27.1 +// grpc/reflection/v1alpha/reflection.proto is a deprecated file. + +package grpc_reflection_v1alpha + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + ServerReflection_ServerReflectionInfo_FullMethodName = "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo" +) + +// ServerReflectionClient is the client API for ServerReflection service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ServerReflectionClient interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse], error) +} + +type serverReflectionClient struct { + cc grpc.ClientConnInterface +} + +func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClient { + return &serverReflectionClient{cc} +} + +func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ServerReflection_ServiceDesc.Streams[0], ServerReflection_ServerReflectionInfo_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[ServerReflectionRequest, ServerReflectionResponse]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ServerReflection_ServerReflectionInfoClient = grpc.BidiStreamingClient[ServerReflectionRequest, ServerReflectionResponse] + +// ServerReflectionServer is the server API for ServerReflection service. +// All implementations should embed UnimplementedServerReflectionServer +// for forward compatibility. +type ServerReflectionServer interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse]) error +} + +// UnimplementedServerReflectionServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedServerReflectionServer struct{} + +func (UnimplementedServerReflectionServer) ServerReflectionInfo(grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse]) error { + return status.Error(codes.Unimplemented, "method ServerReflectionInfo not implemented") +} +func (UnimplementedServerReflectionServer) testEmbeddedByValue() {} + +// UnsafeServerReflectionServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ServerReflectionServer will +// result in compilation errors. +type UnsafeServerReflectionServer interface { + mustEmbedUnimplementedServerReflectionServer() +} + +func RegisterServerReflectionServer(s grpc.ServiceRegistrar, srv ServerReflectionServer) { + // If the following call panics, it indicates UnimplementedServerReflectionServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&ServerReflection_ServiceDesc, srv) +} + +func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ServerReflectionServer).ServerReflectionInfo(&grpc.GenericServerStream[ServerReflectionRequest, ServerReflectionResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ServerReflection_ServerReflectionInfoServer = grpc.BidiStreamingServer[ServerReflectionRequest, ServerReflectionResponse] + +// ServerReflection_ServiceDesc is the grpc.ServiceDesc for ServerReflection service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ServerReflection_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.reflection.v1alpha.ServerReflection", + HandlerType: (*ServerReflectionServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerReflectionInfo", + Handler: _ServerReflection_ServerReflectionInfo_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/reflection/v1alpha/reflection.proto", +} diff --git a/vendor/google.golang.org/grpc/reflection/internal/internal.go b/vendor/google.golang.org/grpc/reflection/internal/internal.go new file mode 100644 index 0000000000..902fc6d35c --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/internal/internal.go @@ -0,0 +1,436 @@ +/* + * + * Copyright 2024 gRPC 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 internal contains code that is shared by both reflection package and +// the test package. The packages are split in this way inorder to avoid +// dependency to deprecated package github.com/golang/protobuf. +package internal + +import ( + "io" + "sort" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" + v1alphareflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +// ServiceInfoProvider is an interface used to retrieve metadata about the +// services to expose. +type ServiceInfoProvider interface { + GetServiceInfo() map[string]grpc.ServiceInfo +} + +// ExtensionResolver is the interface used to query details about extensions. +// This interface is satisfied by protoregistry.GlobalTypes. +type ExtensionResolver interface { + protoregistry.ExtensionTypeResolver + RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) +} + +// ServerReflectionServer is the server API for ServerReflection service. +type ServerReflectionServer struct { + v1alphareflectiongrpc.UnimplementedServerReflectionServer + S ServiceInfoProvider + DescResolver protodesc.Resolver + ExtResolver ExtensionResolver +} + +// FileDescWithDependencies returns a slice of serialized fileDescriptors in +// wire format ([]byte). The fileDescriptors will include fd and all the +// transitive dependencies of fd with names not in sentFileDescriptors. +func (s *ServerReflectionServer) FileDescWithDependencies(fd protoreflect.FileDescriptor, sentFileDescriptors map[string]bool) ([][]byte, error) { + if fd.IsPlaceholder() { + // If the given root file is a placeholder, treat it + // as missing instead of serializing it. + return nil, protoregistry.NotFound + } + var r [][]byte + queue := []protoreflect.FileDescriptor{fd} + for len(queue) > 0 { + currentfd := queue[0] + queue = queue[1:] + if currentfd.IsPlaceholder() { + // Skip any missing files in the dependency graph. + continue + } + if sent := sentFileDescriptors[currentfd.Path()]; len(r) == 0 || !sent { + sentFileDescriptors[currentfd.Path()] = true + fdProto := protodesc.ToFileDescriptorProto(currentfd) + currentfdEncoded, err := proto.Marshal(fdProto) + if err != nil { + return nil, err + } + r = append(r, currentfdEncoded) + } + for i := 0; i < currentfd.Imports().Len(); i++ { + queue = append(queue, currentfd.Imports().Get(i)) + } + } + return r, nil +} + +// FileDescEncodingContainingSymbol finds the file descriptor containing the +// given symbol, finds all of its previously unsent transitive dependencies, +// does marshalling on them, and returns the marshalled result. The given symbol +// can be a type, a service or a method. +func (s *ServerReflectionServer) FileDescEncodingContainingSymbol(name string, sentFileDescriptors map[string]bool) ([][]byte, error) { + d, err := s.DescResolver.FindDescriptorByName(protoreflect.FullName(name)) + if err != nil { + return nil, err + } + return s.FileDescWithDependencies(d.ParentFile(), sentFileDescriptors) +} + +// FileDescEncodingContainingExtension finds the file descriptor containing +// given extension, finds all of its previously unsent transitive dependencies, +// does marshalling on them, and returns the marshalled result. +func (s *ServerReflectionServer) FileDescEncodingContainingExtension(typeName string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) { + xt, err := s.ExtResolver.FindExtensionByNumber(protoreflect.FullName(typeName), protoreflect.FieldNumber(extNum)) + if err != nil { + return nil, err + } + return s.FileDescWithDependencies(xt.TypeDescriptor().ParentFile(), sentFileDescriptors) +} + +// AllExtensionNumbersForTypeName returns all extension numbers for the given type. +func (s *ServerReflectionServer) AllExtensionNumbersForTypeName(name string) ([]int32, error) { + var numbers []int32 + s.ExtResolver.RangeExtensionsByMessage(protoreflect.FullName(name), func(xt protoreflect.ExtensionType) bool { + numbers = append(numbers, int32(xt.TypeDescriptor().Number())) + return true + }) + sort.Slice(numbers, func(i, j int) bool { + return numbers[i] < numbers[j] + }) + if len(numbers) == 0 { + // maybe return an error if given type name is not known + if _, err := s.DescResolver.FindDescriptorByName(protoreflect.FullName(name)); err != nil { + return nil, err + } + } + return numbers, nil +} + +// ListServices returns the names of services this server exposes. +func (s *ServerReflectionServer) ListServices() []*v1reflectionpb.ServiceResponse { + serviceInfo := s.S.GetServiceInfo() + resp := make([]*v1reflectionpb.ServiceResponse, 0, len(serviceInfo)) + for svc := range serviceInfo { + resp = append(resp, &v1reflectionpb.ServiceResponse{Name: svc}) + } + sort.Slice(resp, func(i, j int) bool { + return resp[i].Name < resp[j].Name + }) + return resp +} + +// ServerReflectionInfo is the reflection service handler. +func (s *ServerReflectionServer) ServerReflectionInfo(stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoServer) error { + sentFileDescriptors := make(map[string]bool) + for { + in, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + out := &v1reflectionpb.ServerReflectionResponse{ + ValidHost: in.Host, + OriginalRequest: in, + } + switch req := in.MessageRequest.(type) { + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: + var b [][]byte + fd, err := s.DescResolver.FindFileByPath(req.FileByFilename) + if err == nil { + b, err = s.FileDescWithDependencies(fd, sentFileDescriptors) + } + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: + b, err := s.FileDescEncodingContainingSymbol(req.FileContainingSymbol, sentFileDescriptors) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: + typeName := req.FileContainingExtension.ContainingType + extNum := req.FileContainingExtension.ExtensionNumber + b, err := s.FileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{FileDescriptorProto: b}, + } + } + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + extNums, err := s.AllExtensionNumbersForTypeName(req.AllExtensionNumbersOfType) + if err != nil { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: int32(codes.NotFound), + ErrorMessage: err.Error(), + }, + } + } else { + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ + BaseTypeName: req.AllExtensionNumbersOfType, + ExtensionNumber: extNums, + }, + } + } + case *v1reflectionpb.ServerReflectionRequest_ListServices: + out.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1reflectionpb.ListServiceResponse{ + Service: s.ListServices(), + }, + } + default: + return status.Errorf(codes.InvalidArgument, "invalid MessageRequest: %v", in.MessageRequest) + } + + if err := stream.Send(out); err != nil { + return err + } + } +} + +// V1ToV1AlphaResponse converts a v1 ServerReflectionResponse to a v1alpha. +func V1ToV1AlphaResponse(v1 *v1reflectionpb.ServerReflectionResponse) *v1alphareflectionpb.ServerReflectionResponse { + var v1alpha v1alphareflectionpb.ServerReflectionResponse + v1alpha.ValidHost = v1.ValidHost + if v1.OriginalRequest != nil { + v1alpha.OriginalRequest = V1ToV1AlphaRequest(v1.OriginalRequest) + } + switch mr := v1.MessageResponse.(type) { + case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1alphareflectionpb.FileDescriptorResponse{ + FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1alphareflectionpb.ExtensionNumberResponse{ + BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), + ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ListServicesResponse: + if mr != nil { + svcs := make([]*v1alphareflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) + for i, svc := range mr.ListServicesResponse.GetService() { + svcs[i] = &v1alphareflectionpb.ServiceResponse{ + Name: svc.GetName(), + } + } + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1alphareflectionpb.ListServiceResponse{ + Service: svcs, + }, + } + } + case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: + if mr != nil { + v1alpha.MessageResponse = &v1alphareflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1alphareflectionpb.ErrorResponse{ + ErrorCode: mr.ErrorResponse.GetErrorCode(), + ErrorMessage: mr.ErrorResponse.GetErrorMessage(), + }, + } + } + default: + // no value set + } + return &v1alpha +} + +// V1AlphaToV1Request converts a v1alpha ServerReflectionRequest to a v1. +func V1AlphaToV1Request(v1alpha *v1alphareflectionpb.ServerReflectionRequest) *v1reflectionpb.ServerReflectionRequest { + var v1 v1reflectionpb.ServerReflectionRequest + v1.Host = v1alpha.Host + switch mr := v1alpha.MessageRequest.(type) { + case *v1alphareflectionpb.ServerReflectionRequest_FileByFilename: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + case *v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr.FileContainingExtension != nil { + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1reflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + case *v1alphareflectionpb.ServerReflectionRequest_ListServices: + v1.MessageRequest = &v1reflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + default: + // no value set + } + return &v1 +} + +// V1ToV1AlphaRequest converts a v1 ServerReflectionRequest to a v1alpha. +func V1ToV1AlphaRequest(v1 *v1reflectionpb.ServerReflectionRequest) *v1alphareflectionpb.ServerReflectionRequest { + var v1alpha v1alphareflectionpb.ServerReflectionRequest + v1alpha.Host = v1.Host + switch mr := v1.MessageRequest.(type) { + case *v1reflectionpb.ServerReflectionRequest_FileByFilename: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileByFilename{ + FileByFilename: mr.FileByFilename, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingSymbol: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingSymbol{ + FileContainingSymbol: mr.FileContainingSymbol, + } + } + case *v1reflectionpb.ServerReflectionRequest_FileContainingExtension: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_FileContainingExtension{ + FileContainingExtension: &v1alphareflectionpb.ExtensionRequest{ + ContainingType: mr.FileContainingExtension.GetContainingType(), + ExtensionNumber: mr.FileContainingExtension.GetExtensionNumber(), + }, + } + } + case *v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ + AllExtensionNumbersOfType: mr.AllExtensionNumbersOfType, + } + } + case *v1reflectionpb.ServerReflectionRequest_ListServices: + if mr != nil { + v1alpha.MessageRequest = &v1alphareflectionpb.ServerReflectionRequest_ListServices{ + ListServices: mr.ListServices, + } + } + default: + // no value set + } + return &v1alpha +} + +// V1AlphaToV1Response converts a v1alpha ServerReflectionResponse to a v1. +func V1AlphaToV1Response(v1alpha *v1alphareflectionpb.ServerReflectionResponse) *v1reflectionpb.ServerReflectionResponse { + var v1 v1reflectionpb.ServerReflectionResponse + v1.ValidHost = v1alpha.ValidHost + if v1alpha.OriginalRequest != nil { + v1.OriginalRequest = V1AlphaToV1Request(v1alpha.OriginalRequest) + } + switch mr := v1alpha.MessageResponse.(type) { + case *v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ + FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{ + FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ + AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ + BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), + ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse: + if mr != nil { + svcs := make([]*v1reflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) + for i, svc := range mr.ListServicesResponse.GetService() { + svcs[i] = &v1reflectionpb.ServiceResponse{ + Name: svc.GetName(), + } + } + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ + ListServicesResponse: &v1reflectionpb.ListServiceResponse{ + Service: svcs, + }, + } + } + case *v1alphareflectionpb.ServerReflectionResponse_ErrorResponse: + if mr != nil { + v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ + ErrorResponse: &v1reflectionpb.ErrorResponse{ + ErrorCode: mr.ErrorResponse.GetErrorCode(), + ErrorMessage: mr.ErrorResponse.GetErrorMessage(), + }, + } + } + default: + // no value set + } + return &v1 +} diff --git a/vendor/google.golang.org/grpc/reflection/serverreflection.go b/vendor/google.golang.org/grpc/reflection/serverreflection.go new file mode 100644 index 0000000000..13a94e2dd2 --- /dev/null +++ b/vendor/google.golang.org/grpc/reflection/serverreflection.go @@ -0,0 +1,160 @@ +/* + * + * Copyright 2016 gRPC 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 reflection implements server reflection service. + +The service implemented is defined in: +https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto. + +To register server reflection on a gRPC server: + + import "google.golang.org/grpc/reflection" + + s := grpc.NewServer() + pb.RegisterYourOwnServer(s, &server{}) + + // Register reflection service on gRPC server. + reflection.Register(s) + + s.Serve(lis) +*/ +package reflection // import "google.golang.org/grpc/reflection" + +import ( + "google.golang.org/grpc" + "google.golang.org/grpc/reflection/internal" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" + v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" +) + +// GRPCServer is the interface provided by a gRPC server. It is implemented by +// *grpc.Server, but could also be implemented by other concrete types. It acts +// as a registry, for accumulating the services exposed by the server. +type GRPCServer interface { + grpc.ServiceRegistrar + ServiceInfoProvider +} + +var _ GRPCServer = (*grpc.Server)(nil) + +// Register registers the server reflection service on the given gRPC server. +// Both the v1 and v1alpha versions are registered. +func Register(s GRPCServer) { + svr := NewServerV1(ServerOptions{Services: s}) + v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr)) + v1reflectiongrpc.RegisterServerReflectionServer(s, svr) +} + +// RegisterV1 registers only the v1 version of the server reflection service +// on the given gRPC server. Many clients may only support v1alpha so most +// users should use Register instead, at least until clients have upgraded. +func RegisterV1(s GRPCServer) { + svr := NewServerV1(ServerOptions{Services: s}) + v1reflectiongrpc.RegisterServerReflectionServer(s, svr) +} + +// ServiceInfoProvider is an interface used to retrieve metadata about the +// services to expose. +// +// The reflection service is only interested in the service names, but the +// signature is this way so that *grpc.Server implements it. So it is okay +// for a custom implementation to return zero values for the +// grpc.ServiceInfo values in the map. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type ServiceInfoProvider interface { + GetServiceInfo() map[string]grpc.ServiceInfo +} + +// ExtensionResolver is the interface used to query details about extensions. +// This interface is satisfied by protoregistry.GlobalTypes. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type ExtensionResolver interface { + protoregistry.ExtensionTypeResolver + RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) +} + +// ServerOptions represents the options used to construct a reflection server. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type ServerOptions struct { + // The source of advertised RPC services. If not specified, the reflection + // server will report an empty list when asked to list services. + // + // This value will typically be a *grpc.Server. But the set of advertised + // services can be customized by wrapping a *grpc.Server or using an + // alternate implementation that returns a custom set of service names. + Services ServiceInfoProvider + // Optional resolver used to load descriptors. If not specified, + // protoregistry.GlobalFiles will be used. + DescriptorResolver protodesc.Resolver + // Optional resolver used to query for known extensions. If not specified, + // protoregistry.GlobalTypes will be used. + ExtensionResolver ExtensionResolver +} + +// NewServer returns a reflection server implementation using the given options. +// This can be used to customize behavior of the reflection service. Most usages +// should prefer to use Register instead. For backwards compatibility reasons, +// this returns the v1alpha version of the reflection server. For a v1 version +// of the reflection server, see NewServerV1. +// +// # Experimental +// +// Notice: This function is EXPERIMENTAL and may be changed or removed in a +// later release. +func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer { + return asV1Alpha(NewServerV1(opts)) +} + +// NewServerV1 returns a reflection server implementation using the given options. +// This can be used to customize behavior of the reflection service. Most usages +// should prefer to use Register instead. +// +// # Experimental +// +// Notice: This function is EXPERIMENTAL and may be changed or removed in a +// later release. +func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer { + if opts.DescriptorResolver == nil { + opts.DescriptorResolver = protoregistry.GlobalFiles + } + if opts.ExtensionResolver == nil { + opts.ExtensionResolver = protoregistry.GlobalTypes + } + return &internal.ServerReflectionServer{ + S: opts.Services, + DescResolver: opts.DescriptorResolver, + ExtResolver: opts.ExtensionResolver, + } +} diff --git a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go index 2ef36bbcf9..ec63689e72 100644 --- a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go +++ b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go @@ -10,6 +10,7 @@ import ( "encoding/binary" "fmt" "io" + "math" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" @@ -117,7 +118,13 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error { if maxSize == 0 { maxSize = defaultMaxSize } - if maxSize != -1 && size > uint64(maxSize) { + if maxSize == -1 { + // No limit specified: Just check that size fits into an integer, + // otherwise the make([]byte, size) call below will panic. + if size > math.MaxInt { + return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: math.MaxInt}, "") + } + } else if size > uint64(maxSize) { return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "") } diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go index 737d6876d5..1d6608dc7d 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go @@ -365,6 +365,10 @@ func unmarshalInt(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getInt(tok, bitSize) } return protoreflect.Value{}, false @@ -397,6 +401,10 @@ func unmarshalUint(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getUint(tok, bitSize) } return protoreflect.Value{}, false @@ -447,6 +455,10 @@ func unmarshalFloat(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getFloat(tok, bitSize) } return protoreflect.Value{}, false diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go index e9fe103943..d2eab46947 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go @@ -52,7 +52,10 @@ func wellKnownTypeMarshaler(name protoreflect.FullName) marshalFunc { case genid.FieldMask_message_name: return encoder.marshalFieldMask case genid.Empty_message_name: - return encoder.marshalEmpty + // The spec explicitly specifies that the Empty message + // is not considered to have any special JSON mapping: + // https://protobuf.dev/programming-guides/json/#any + return nil } } return nil diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index b53805056a..20ec09e194 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -8,6 +8,7 @@ import ( "fmt" "unicode/utf8" + "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" @@ -49,12 +50,19 @@ type UnmarshalOptions struct { protoregistry.MessageTypeResolver protoregistry.ExtensionTypeResolver } + + // RecursionLimit limits how deeply messages may be nested. + // If zero, a default limit is applied. + RecursionLimit int } // Unmarshal reads the given []byte and populates the given [proto.Message] // using options in the UnmarshalOptions object. // The provided message must be mutable (e.g., a non-nil pointer to a message). func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { + if o.RecursionLimit == 0 { + o.RecursionLimit = protowire.DefaultRecursionLimit + } return o.unmarshal(b, m) } @@ -102,8 +110,14 @@ func (d decoder) syntaxError(pos int, f string, x ...any) error { return errors.New(head+f, x...) } +var errRecursionDepth = errors.New("exceeded maximum recursion depth") + // unmarshalMessage unmarshals into the given protoreflect.Message. func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -437,6 +451,10 @@ func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflec // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + // Determine ahead whether map entry is a scalar type or a message type in // order to call the appropriate unmarshalMapValue func inside // unmarshalMapEntry. diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index 87e46bd4df..0b0dfacbe5 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -83,12 +83,13 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { case protoreflect.FileImports: for i := 0; i < vs.Len(); i++ { var rs records - rv := reflect.ValueOf(vs.Get(i)) - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPublic"), "IsPublic"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, + fi := vs.Get(i) + rv := reflect.ValueOf(fi) + rs.Append(rv, []attrAndName{ + {fi.Path(), "Path"}, + {fi.Package(), "Package"}, + {fi.IsPublic, "IsPublic"}, + {fi.IsWeak, "IsWeak"}, }...) ss = append(ss, "{"+rs.Join()+"}") } @@ -104,9 +105,9 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } -type methodAndName struct { - method reflect.Value - name string +type attrAndName struct { + attr any + name string } func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { @@ -126,58 +127,58 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu start = rt.Name() + "{" } - _, isFile := t.(protoreflect.FileDescriptor) + fd, isFile := t.(protoreflect.FileDescriptor) rs := records{ allowMulti: allowMulti, record: record, } if t.IsPlaceholder() { if isFile { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {fd.Path(), "Path"}, + {fd.Package(), "Package"}, + {fd.IsPlaceholder(), "IsPlaceholder"}, }...) } else { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("FullName"), "FullName"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {t.FullName(), "FullName"}, + {t.IsPlaceholder(), "IsPlaceholder"}, }...) } } else { switch { case isFile: - rs.Append(rv, methodAndName{rv.MethodByName("Syntax"), "Syntax"}) + rs.Append(rv, attrAndName{fd.Syntax(), "Syntax"}) case isRoot: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Syntax"), "Syntax"}, - {rv.MethodByName("FullName"), "FullName"}, + rs.Append(rv, []attrAndName{ + {t.Syntax(), "Syntax"}, + {t.FullName(), "FullName"}, }...) default: - rs.Append(rv, methodAndName{rv.MethodByName("Name"), "Name"}) + rs.Append(rv, attrAndName{t.Name(), "Name"}) } switch t := t.(type) { case protoreflect.FieldDescriptor: - accessors := []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - {rv.MethodByName("Cardinality"), "Cardinality"}, - {rv.MethodByName("Kind"), "Kind"}, - {rv.MethodByName("HasJSONName"), "HasJSONName"}, - {rv.MethodByName("JSONName"), "JSONName"}, - {rv.MethodByName("HasPresence"), "HasPresence"}, - {rv.MethodByName("IsExtension"), "IsExtension"}, - {rv.MethodByName("IsPacked"), "IsPacked"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, - {rv.MethodByName("IsList"), "IsList"}, - {rv.MethodByName("IsMap"), "IsMap"}, - {rv.MethodByName("MapKey"), "MapKey"}, - {rv.MethodByName("MapValue"), "MapValue"}, - {rv.MethodByName("HasDefault"), "HasDefault"}, - {rv.MethodByName("Default"), "Default"}, - {rv.MethodByName("ContainingOneof"), "ContainingOneof"}, - {rv.MethodByName("ContainingMessage"), "ContainingMessage"}, - {rv.MethodByName("Message"), "Message"}, - {rv.MethodByName("Enum"), "Enum"}, + accessors := []attrAndName{ + {t.Number(), "Number"}, + {t.Cardinality(), "Cardinality"}, + {t.Kind(), "Kind"}, + {t.HasJSONName(), "HasJSONName"}, + {t.JSONName(), "JSONName"}, + {t.HasPresence(), "HasPresence"}, + {t.IsExtension(), "IsExtension"}, + {t.IsPacked(), "IsPacked"}, + {t.IsWeak(), "IsWeak"}, + {t.IsList(), "IsList"}, + {t.IsMap(), "IsMap"}, + {t.MapKey(), "MapKey"}, + {t.MapValue(), "MapValue"}, + {t.HasDefault(), "HasDefault"}, + {t.Default(), "Default"}, + {t.ContainingOneof(), "ContainingOneof"}, + {t.ContainingMessage(), "ContainingMessage"}, + {t.Message(), "Message"}, + {t.Enum(), "Enum"}, } for _, s := range accessors { switch s.name { @@ -223,58 +224,54 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu } case protoreflect.FileDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("Imports"), "Imports"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, - {rv.MethodByName("Services"), "Services"}, + rs.Append(rv, []attrAndName{ + {t.Path(), "Path"}, + {t.Package(), "Package"}, + {t.Imports(), "Imports"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, + {t.Services(), "Services"}, }...) case protoreflect.MessageDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("IsMapEntry"), "IsMapEntry"}, - {rv.MethodByName("Fields"), "Fields"}, - {rv.MethodByName("Oneofs"), "Oneofs"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("RequiredNumbers"), "RequiredNumbers"}, - {rv.MethodByName("ExtensionRanges"), "ExtensionRanges"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, + rs.Append(rv, []attrAndName{ + {t.IsMapEntry(), "IsMapEntry"}, + {t.Fields(), "Fields"}, + {t.Oneofs(), "Oneofs"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.RequiredNumbers(), "RequiredNumbers"}, + {t.ExtensionRanges(), "ExtensionRanges"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, }...) case protoreflect.EnumDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Values"), "Values"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("IsClosed"), "IsClosed"}, + rs.Append(rv, []attrAndName{ + {t.Values(), "Values"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.IsClosed(), "IsClosed"}, }...) case protoreflect.EnumValueDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - }...) + rs.Append(rv, attrAndName{t.Number(), "Number"}) case protoreflect.ServiceDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Methods"), "Methods"}, - }...) + rs.Append(rv, attrAndName{t.Methods(), "Methods"}) case protoreflect.MethodDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Input"), "Input"}, - {rv.MethodByName("Output"), "Output"}, - {rv.MethodByName("IsStreamingClient"), "IsStreamingClient"}, - {rv.MethodByName("IsStreamingServer"), "IsStreamingServer"}, + rs.Append(rv, []attrAndName{ + {t.Input(), "Input"}, + {t.Output(), "Output"}, + {t.IsStreamingClient(), "IsStreamingClient"}, + {t.IsStreamingServer(), "IsStreamingServer"}, }...) } - if m := rv.MethodByName("GoType"); m.IsValid() { - rs.Append(rv, methodAndName{m, "GoType"}) + if m, ok := t.(interface{ GoType() reflect.Type }); ok { + rs.Append(rv, attrAndName{m.GoType(), "GoType"}) } } return start + rs.Join() + end @@ -297,68 +294,66 @@ func (rs *records) AppendRecs(fieldName string, newRecs [2]string) { rs.recs = append(rs.recs, newRecs) } -func (rs *records) Append(v reflect.Value, accessors ...methodAndName) { - for _, a := range accessors { - if rs.record != nil { - rs.record(a.name) - } - var rv reflect.Value - if a.method.IsValid() { - rv = a.method.Call(nil)[0] - } - if v.Kind() == reflect.Struct && !rv.IsValid() { - rv = v.FieldByName(a.name) - } - if !rv.IsValid() { - panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a.name)) - } - if _, ok := rv.Interface().(protoreflect.Value); ok { - rv = rv.MethodByName("Interface").Call(nil)[0] - if !rv.IsNil() { - rv = rv.Elem() - } - } +func (rs *records) Append(v reflect.Value, results ...attrAndName) { + for _, r := range results { + rs.appendAttribute(v, r.name, r.attr) + } +} - // Ignore zero values. - var isZero bool - switch rv.Kind() { - case reflect.Interface, reflect.Slice: - isZero = rv.IsNil() - case reflect.Bool: - isZero = rv.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - isZero = rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - isZero = rv.Uint() == 0 - case reflect.String: - isZero = rv.String() == "" - } - if n, ok := rv.Interface().(list); ok { - isZero = n.Len() == 0 - } - if isZero { - continue +func (rs *records) appendAttribute(val reflect.Value, name string, attrVal any) { + if rs.record != nil { + rs.record(name) + } + if attrVal == nil { + return + } + rv := reflect.ValueOf(attrVal) + if _, ok := rv.Interface().(protoreflect.Value); ok { + rv = rv.MethodByName("Interface").Call(nil)[0] + if !rv.IsNil() { + rv = rv.Elem() } + } - // Format the value. - var s string - v := rv.Interface() - switch v := v.(type) { - case list: - s = formatListOpt(v, false, rs.allowMulti) - case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: - s = string(v.(protoreflect.Descriptor).Name()) - case protoreflect.Descriptor: - s = string(v.FullName()) - case string: - s = strconv.Quote(v) - case []byte: - s = fmt.Sprintf("%q", v) - default: - s = fmt.Sprint(v) - } - rs.recs = append(rs.recs, [2]string{a.name, s}) + // Ignore zero values. + var isZero bool + switch rv.Kind() { + case reflect.Interface, reflect.Slice: + isZero = rv.IsNil() + case reflect.Bool: + isZero = rv.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + isZero = rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + isZero = rv.Uint() == 0 + case reflect.String: + isZero = rv.String() == "" + } + if n, ok := rv.Interface().(list); ok { + isZero = n.Len() == 0 + } + if isZero { + return + } + + // Format the value. + var s string + v := rv.Interface() + switch v := v.(type) { + case list: + s = formatListOpt(v, false, rs.allowMulti) + case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: + s = string(v.(protoreflect.Descriptor).Name()) + case protoreflect.Descriptor: + s = string(v.FullName()) + case string: + s = strconv.Quote(v) + case []byte: + s = fmt.Sprintf("%q", v) + default: + s = fmt.Sprint(v) } + rs.recs = append(rs.recs, [2]string{name, s}) } func (rs *records) Join() string { diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 763fd82841..bfb2cfdea5 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -53,7 +53,7 @@ const ( Major = 1 Minor = 36 Patch = 11 - PreRelease = "" + PreRelease = "devel" ) // String formats the version string for this module in semver format. diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go index c826ad0430..84a3228edb 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go @@ -201,6 +201,7 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript return nil, err } x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures()) + x.L2.IsProto3Optional = xd.GetProto3Optional() if opts := xd.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.FieldOptions) x.L2.Options = func() protoreflect.ProtoMessage { return opts } diff --git a/vendor/k8s.io/api/admission/v1/generated.proto b/vendor/k8s.io/api/admission/v1/generated.proto index cd5c88badc..38a0fcea60 100644 --- a/vendor/k8s.io/api/admission/v1/generated.proto +++ b/vendor/k8s.io/api/admission/v1/generated.proto @@ -35,12 +35,15 @@ message AdmissionRequest { // otherwise identical (parallel requests, requests when earlier requests did not modify etc) // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + // +optional optional string uid = 1; // kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind kind = 2; // resource is the fully-qualified resource being requested (for example, v1.pods) + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource resource = 3; // subResource is the subresource being requested, if any (for example, "status" or "scale") @@ -90,9 +93,11 @@ message AdmissionRequest { // operation is the operation being performed. This may be different than the operation // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + // +optional optional string operation = 7; // userInfo is information about the requesting user + // +optional optional .k8s.io.api.authentication.v1.UserInfo userInfo = 8; // object is the object from the incoming request. @@ -121,9 +126,11 @@ message AdmissionRequest { message AdmissionResponse { // uid is an identifier for the individual request/response. // This must be copied over from the corresponding AdmissionRequest. + // +optional optional string uid = 1; // allowed indicates whether or not the admission request was permitted. + // +optional optional bool allowed = 2; // status is the result contains extra details into why an admission request was denied. diff --git a/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go deleted file mode 100644 index 4e1ec547d6..0000000000 --- a/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AdmissionRequest) ProtoMessage() {} - -func (*AdmissionResponse) ProtoMessage() {} - -func (*AdmissionReview) ProtoMessage() {} diff --git a/vendor/k8s.io/api/admission/v1/types.go b/vendor/k8s.io/api/admission/v1/types.go index 395672c390..34cbf2f59b 100644 --- a/vendor/k8s.io/api/admission/v1/types.go +++ b/vendor/k8s.io/api/admission/v1/types.go @@ -43,10 +43,13 @@ type AdmissionRequest struct { // otherwise identical (parallel requests, requests when earlier requests did not modify etc) // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + // +optional UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` // kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + // +optional Kind metav1.GroupVersionKind `json:"kind" protobuf:"bytes,2,opt,name=kind"` // resource is the fully-qualified resource being requested (for example, v1.pods) + // +optional Resource metav1.GroupVersionResource `json:"resource" protobuf:"bytes,3,opt,name=resource"` // subResource is the subresource being requested, if any (for example, "status" or "scale") // +optional @@ -91,8 +94,10 @@ type AdmissionRequest struct { Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"` // operation is the operation being performed. This may be different than the operation // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + // +optional Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"` // userInfo is information about the requesting user + // +optional UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"` // object is the object from the incoming request. // +optional @@ -117,9 +122,11 @@ type AdmissionRequest struct { type AdmissionResponse struct { // uid is an identifier for the individual request/response. // This must be copied over from the corresponding AdmissionRequest. + // +optional UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` // allowed indicates whether or not the admission request was permitted. + // +optional Allowed bool `json:"allowed" protobuf:"varint,2,opt,name=allowed"` // status is the result contains extra details into why an admission request was denied. diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.proto b/vendor/k8s.io/api/admission/v1beta1/generated.proto index 5af234993a..9514719baf 100644 --- a/vendor/k8s.io/api/admission/v1beta1/generated.proto +++ b/vendor/k8s.io/api/admission/v1beta1/generated.proto @@ -35,12 +35,15 @@ message AdmissionRequest { // otherwise identical (parallel requests, requests when earlier requests did not modify etc) // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + // +optional optional string uid = 1; // kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind kind = 2; // resource is the fully-qualified resource being requested (for example, v1.pods) + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource resource = 3; // subResource is the subresource being requested, if any (for example, "status" or "scale") @@ -90,9 +93,11 @@ message AdmissionRequest { // operation is the operation being performed. This may be different than the operation // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + // +optional optional string operation = 7; // userInfo is information about the requesting user + // +optional optional .k8s.io.api.authentication.v1.UserInfo userInfo = 8; // object is the object from the incoming request. @@ -121,9 +126,11 @@ message AdmissionRequest { message AdmissionResponse { // uid is an identifier for the individual request/response. // This should be copied over from the corresponding AdmissionRequest. + // +optional optional string uid = 1; // allowed indicates whether or not the admission request was permitted. + // +optional optional bool allowed = 2; // status is the result contains extra details into why an admission request was denied. diff --git a/vendor/k8s.io/api/admission/v1beta1/types.go b/vendor/k8s.io/api/admission/v1beta1/types.go index 81941eb325..015dc8ba3e 100644 --- a/vendor/k8s.io/api/admission/v1beta1/types.go +++ b/vendor/k8s.io/api/admission/v1beta1/types.go @@ -47,10 +47,13 @@ type AdmissionRequest struct { // otherwise identical (parallel requests, requests when earlier requests did not modify etc) // The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. // It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + // +optional UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` // kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + // +optional Kind metav1.GroupVersionKind `json:"kind" protobuf:"bytes,2,opt,name=kind"` // resource is the fully-qualified resource being requested (for example, v1.pods) + // +optional Resource metav1.GroupVersionResource `json:"resource" protobuf:"bytes,3,opt,name=resource"` // subResource is the subresource being requested, if any (for example, "status" or "scale") // +optional @@ -95,8 +98,10 @@ type AdmissionRequest struct { Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"` // operation is the operation being performed. This may be different than the operation // requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + // +optional Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"` // userInfo is information about the requesting user + // +optional UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"` // object is the object from the incoming request. // +optional @@ -121,9 +126,11 @@ type AdmissionRequest struct { type AdmissionResponse struct { // uid is an identifier for the individual request/response. // This should be copied over from the corresponding AdmissionRequest. + // +optional UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"` // allowed indicates whether or not the admission request was permitted. + // +optional Allowed bool `json:"allowed" protobuf:"varint,2,opt,name=allowed"` // status is the result contains extra details into why an admission request was denied. diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go index 91b2f1cbae..e2def5040c 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go @@ -32,20 +32,38 @@ import ( strings "strings" ) +func (m *ApplyConfiguration) Reset() { *m = ApplyConfiguration{} } + func (m *AuditAnnotation) Reset() { *m = AuditAnnotation{} } func (m *ExpressionWarning) Reset() { *m = ExpressionWarning{} } +func (m *JSONPatch) Reset() { *m = JSONPatch{} } + func (m *MatchCondition) Reset() { *m = MatchCondition{} } func (m *MatchResources) Reset() { *m = MatchResources{} } +func (m *MutatingAdmissionPolicy) Reset() { *m = MutatingAdmissionPolicy{} } + +func (m *MutatingAdmissionPolicyBinding) Reset() { *m = MutatingAdmissionPolicyBinding{} } + +func (m *MutatingAdmissionPolicyBindingList) Reset() { *m = MutatingAdmissionPolicyBindingList{} } + +func (m *MutatingAdmissionPolicyBindingSpec) Reset() { *m = MutatingAdmissionPolicyBindingSpec{} } + +func (m *MutatingAdmissionPolicyList) Reset() { *m = MutatingAdmissionPolicyList{} } + +func (m *MutatingAdmissionPolicySpec) Reset() { *m = MutatingAdmissionPolicySpec{} } + func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} } func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} } func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} } +func (m *Mutation) Reset() { *m = Mutation{} } + func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} } func (m *ParamKind) Reset() { *m = ParamKind{} } @@ -86,6 +104,34 @@ func (m *Variable) Reset() { *m = Variable{} } func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } +func (m *ApplyConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ApplyConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplyConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *AuditAnnotation) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -152,6 +198,34 @@ func (m *ExpressionWarning) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *JSONPatch) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *JSONPatch) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *JSONPatch) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *MatchCondition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -267,7 +341,7 @@ func (m *MatchResources) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) { +func (m *MutatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -277,112 +351,18 @@ func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MutatingWebhook) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.MatchConditions) > 0 { - for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x62 - } - } - if m.ObjectSelector != nil { - { - size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x5a - } - if m.ReinvocationPolicy != nil { - i -= len(*m.ReinvocationPolicy) - copy(dAtA[i:], *m.ReinvocationPolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReinvocationPolicy))) - i-- - dAtA[i] = 0x52 - } - if m.MatchPolicy != nil { - i -= len(*m.MatchPolicy) - copy(dAtA[i:], *m.MatchPolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy))) - i-- - dAtA[i] = 0x4a - } - if len(m.AdmissionReviewVersions) > 0 { - for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AdmissionReviewVersions[iNdEx]) - copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx]))) - i-- - dAtA[i] = 0x42 - } - } - if m.TimeoutSeconds != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds)) - i-- - dAtA[i] = 0x38 - } - if m.SideEffects != nil { - i -= len(*m.SideEffects) - copy(dAtA[i:], *m.SideEffects) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects))) - i-- - dAtA[i] = 0x32 - } - if m.NamespaceSelector != nil { - { - size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.FailurePolicy != nil { - i -= len(*m.FailurePolicy) - copy(dAtA[i:], *m.FailurePolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) - i-- - dAtA[i] = 0x22 - } - if len(m.Rules) > 0 { - for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } { - size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -391,15 +371,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { +func (m *MutatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -409,30 +394,26 @@ func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MutatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Webhooks) > 0 { - for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 { size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -446,7 +427,7 @@ func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } -func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) { +func (m *MutatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -456,12 +437,12 @@ func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MutatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -493,7 +474,7 @@ func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } -func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) { +func (m *MutatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -503,39 +484,49 @@ func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *NamedRuleWithOperations) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *NamedRuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.RuleWithOperations.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.MatchResources != nil { + { + size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a } - i-- - dAtA[i] = 0x12 - if len(m.ResourceNames) > 0 { - for iNdEx := len(m.ResourceNames) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ResourceNames[iNdEx]) - copy(dAtA[i:], m.ResourceNames[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceNames[iNdEx]))) - i-- - dAtA[i] = 0xa + if m.ParamRef != nil { + { + size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 } + i -= len(m.PolicyName) + copy(dAtA[i:], m.PolicyName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName))) + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ParamKind) Marshal() (dAtA []byte, err error) { +func (m *MutatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -545,31 +536,45 @@ func (m *ParamKind) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ParamKind) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ParamKind) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.Kind) - copy(dAtA[i:], m.Kind) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i-- - dAtA[i] = 0x12 - i -= len(m.APIVersion) - copy(dAtA[i:], m.APIVersion) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ParamRef) Marshal() (dAtA []byte, err error) { - size := m.Size() + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MutatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) { + size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) if err != nil { @@ -578,26 +583,73 @@ func (m *ParamRef) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ParamRef) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.ParameterNotFoundAction != nil { - i -= len(*m.ParameterNotFoundAction) - copy(dAtA[i:], *m.ParameterNotFoundAction) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ParameterNotFoundAction))) + i -= len(m.ReinvocationPolicy) + copy(dAtA[i:], m.ReinvocationPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ReinvocationPolicy))) + i-- + dAtA[i] = 0x3a + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if m.FailurePolicy != nil { + i -= len(*m.FailurePolicy) + copy(dAtA[i:], *m.FailurePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a } - if m.Selector != nil { + if len(m.Mutations) > 0 { + for iNdEx := len(m.Mutations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Mutations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Variables) > 0 { + for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.MatchConstraints != nil { { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -605,22 +657,24 @@ func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 + } + if m.ParamKind != nil { + { + size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - i -= len(m.Namespace) - copy(dAtA[i:], m.Namespace) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *Rule) Marshal() (dAtA []byte, err error) { +func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -630,54 +684,129 @@ func (m *Rule) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Rule) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingWebhook) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Rule) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Scope != nil { - i -= len(*m.Scope) - copy(dAtA[i:], *m.Scope) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Scope))) + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + } + if m.ObjectSelector != nil { + { + size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x5a } - if len(m.Resources) > 0 { - for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Resources[iNdEx]) - copy(dAtA[i:], m.Resources[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx]))) + if m.ReinvocationPolicy != nil { + i -= len(*m.ReinvocationPolicy) + copy(dAtA[i:], *m.ReinvocationPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReinvocationPolicy))) + i-- + dAtA[i] = 0x52 + } + if m.MatchPolicy != nil { + i -= len(*m.MatchPolicy) + copy(dAtA[i:], *m.MatchPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy))) + i-- + dAtA[i] = 0x4a + } + if len(m.AdmissionReviewVersions) > 0 { + for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AdmissionReviewVersions[iNdEx]) + copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx]))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x42 } } - if len(m.APIVersions) > 0 { - for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.APIVersions[iNdEx]) - copy(dAtA[i:], m.APIVersions[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx]))) - i-- - dAtA[i] = 0x12 + if m.TimeoutSeconds != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds)) + i-- + dAtA[i] = 0x38 + } + if m.SideEffects != nil { + i -= len(*m.SideEffects) + copy(dAtA[i:], *m.SideEffects) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects))) + i-- + dAtA[i] = 0x32 + } + if m.NamespaceSelector != nil { + { + size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x2a } - if len(m.APIGroups) > 0 { - for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.APIGroups[iNdEx]) - copy(dAtA[i:], m.APIGroups[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx]))) + if m.FailurePolicy != nil { + i -= len(*m.FailurePolicy) + copy(dAtA[i:], *m.FailurePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) + i-- + dAtA[i] = 0x22 + } + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0xa + dAtA[i] = 0x1a + } + } + { + size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) { +func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -687,84 +816,44 @@ func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RuleWithOperations) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Rule.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.Operations) > 0 { - for iNdEx := len(m.Operations) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Operations[iNdEx]) - copy(dAtA[i:], m.Operations[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operations[iNdEx]))) + if len(m.Webhooks) > 0 { + for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 } } - return len(dAtA) - i, nil -} - -func (m *ServiceReference) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ServiceReference) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ServiceReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Port != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.Port)) - i-- - dAtA[i] = 0x20 - } - if m.Path != nil { - i -= len(*m.Path) - copy(dAtA[i:], *m.Path) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Path))) - i-- - dAtA[i] = 0x1a + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - i -= len(m.Namespace) - copy(dAtA[i:], m.Namespace) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *TypeChecking) Marshal() (dAtA []byte, err error) { +func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -774,20 +863,20 @@ func (m *TypeChecking) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *TypeChecking) MarshalTo(dAtA []byte) (int, error) { +func (m *MutatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.ExpressionWarnings) > 0 { - for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- { + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.ExpressionWarnings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -795,13 +884,23 @@ func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { +func (m *Mutation) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -811,50 +910,49 @@ func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) { +func (m *Mutation) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Mutation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.JSONPatch != nil { + { + size, err := m.JSONPatch.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.ApplyConfiguration != nil { + { + size, err := m.ApplyConfiguration.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a } + i -= len(m.PatchType) + copy(dAtA[i:], m.PatchType) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PatchType))) i-- dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) { +func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -864,18 +962,18 @@ func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) { +func (m *NamedRuleWithOperations) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *NamedRuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.RuleWithOperations.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -884,20 +982,19 @@ func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (in } i-- dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.ResourceNames) > 0 { + for iNdEx := len(m.ResourceNames) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ResourceNames[iNdEx]) + copy(dAtA[i:], m.ResourceNames[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceNames[iNdEx]))) + i-- + dAtA[i] = 0xa } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) { +func (m *ParamKind) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -907,44 +1004,30 @@ func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) { +func (m *ParamKind) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ParamKind) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIVersion) + copy(dAtA[i:], m.APIVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) { +func (m *ParamRef) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -954,40 +1037,26 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) { +func (m *ParamRef) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.ValidationActions) > 0 { - for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ValidationActions[iNdEx]) - copy(dAtA[i:], m.ValidationActions[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if m.MatchResources != nil { - { - size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + if m.ParameterNotFoundAction != nil { + i -= len(*m.ParameterNotFoundAction) + copy(dAtA[i:], *m.ParameterNotFoundAction) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ParameterNotFoundAction))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } - if m.ParamRef != nil { + if m.Selector != nil { { - size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -995,17 +1064,22 @@ func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } - i -= len(m.PolicyName) - copy(dAtA[i:], m.PolicyName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName))) + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) { +func (m *Rule) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1015,44 +1089,54 @@ func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) { +func (m *Rule) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Rule) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.Scope != nil { + i -= len(*m.Scope) + copy(dAtA[i:], *m.Scope) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Scope))) + i-- + dAtA[i] = 0x22 + } + if len(m.Resources) > 0 { + for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Resources[iNdEx]) + copy(dAtA[i:], m.Resources[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.APIVersions) > 0 { + for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.APIVersions[iNdEx]) + copy(dAtA[i:], m.APIVersions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.APIGroups) > 0 { + for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.APIGroups[iNdEx]) + copy(dAtA[i:], m.APIGroups[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx]))) + i-- + dAtA[i] = 0xa } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) { +func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1062,107 +1146,84 @@ func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) { +func (m *RuleWithOperations) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Variables) > 0 { - for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - } - if len(m.MatchConditions) > 0 { - for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 + { + size, err := m.Rule.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if len(m.AuditAnnotations) > 0 { - for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i-- + dAtA[i] = 0x12 + if len(m.Operations) > 0 { + for iNdEx := len(m.Operations) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Operations[iNdEx]) + copy(dAtA[i:], m.Operations[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operations[iNdEx]))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0xa } } - if m.FailurePolicy != nil { - i -= len(*m.FailurePolicy) - copy(dAtA[i:], *m.FailurePolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) - i-- - dAtA[i] = 0x22 - } - if len(m.Validations) > 0 { - for iNdEx := len(m.Validations) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Validations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } + return len(dAtA) - i, nil +} + +func (m *ServiceReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - if m.MatchConstraints != nil { - { - size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + return dAtA[:n], nil +} + +func (m *ServiceReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServiceReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Port != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Port)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x20 } - if m.ParamKind != nil { - { - size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + if m.Path != nil { + i -= len(*m.Path) + copy(dAtA[i:], *m.Path) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Path))) i-- - dAtA[i] = 0xa + dAtA[i] = 0x1a } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) { +func (m *TypeChecking) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1172,20 +1233,20 @@ func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) { +func (m *TypeChecking) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Conditions) > 0 { - for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + if len(m.ExpressionWarnings) > 0 { + for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ExpressionWarnings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1193,28 +1254,13 @@ func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - } - } - if m.TypeChecking != nil { - { - size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + dAtA[i] = 0xa } - i-- - dAtA[i] = 0x12 } - i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) - i-- - dAtA[i] = 0x8 return len(dAtA) - i, nil } -func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1224,105 +1270,38 @@ func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingWebhook) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.MatchConditions) > 0 { - for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x5a + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if m.ObjectSelector != nil { - { - size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - } - if m.MatchPolicy != nil { - i -= len(*m.MatchPolicy) - copy(dAtA[i:], *m.MatchPolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy))) - i-- - dAtA[i] = 0x4a - } - if len(m.AdmissionReviewVersions) > 0 { - for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AdmissionReviewVersions[iNdEx]) - copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx]))) - i-- - dAtA[i] = 0x42 - } - } - if m.TimeoutSeconds != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds)) - i-- - dAtA[i] = 0x38 - } - if m.SideEffects != nil { - i -= len(*m.SideEffects) - copy(dAtA[i:], *m.SideEffects) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects))) - i-- - dAtA[i] = 0x32 - } - if m.NamespaceSelector != nil { - { - size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.FailurePolicy != nil { - i -= len(*m.FailurePolicy) - copy(dAtA[i:], *m.FailurePolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) - i-- - dAtA[i] = 0x22 - } - if len(m.Rules) > 0 { - for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 { - size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1330,16 +1309,11 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1349,30 +1323,26 @@ func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ValidatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Webhooks) > 0 { - for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 { size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1386,7 +1356,7 @@ func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1396,12 +1366,12 @@ func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) return dAtA[:n], nil } -func (m *ValidatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1433,7 +1403,7 @@ func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } -func (m *Validation) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1443,42 +1413,58 @@ func (m *Validation) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Validation) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.MessageExpression) - copy(dAtA[i:], m.MessageExpression) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) - i-- - dAtA[i] = 0x22 - if m.Reason != nil { - i -= len(*m.Reason) - copy(dAtA[i:], *m.Reason) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Reason))) + if len(m.ValidationActions) > 0 { + for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValidationActions[iNdEx]) + copy(dAtA[i:], m.ValidationActions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if m.MatchResources != nil { + { + size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0x1a } - i -= len(m.Message) - copy(dAtA[i:], m.Message) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i-- - dAtA[i] = 0x12 - i -= len(m.Expression) - copy(dAtA[i:], m.Expression) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + if m.ParamRef != nil { + { + size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.PolicyName) + copy(dAtA[i:], m.PolicyName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *Variable) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1488,30 +1474,44 @@ func (m *Variable) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Variable) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Variable) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.Expression) - copy(dAtA[i:], m.Expression) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) { +func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1521,355 +1521,610 @@ func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *WebhookClientConfig) MarshalTo(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *WebhookClientConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.URL != nil { - i -= len(*m.URL) - copy(dAtA[i:], *m.URL) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.URL))) - i-- - dAtA[i] = 0x1a + if len(m.Variables) > 0 { + for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } } - if m.CABundle != nil { - i -= len(m.CABundle) - copy(dAtA[i:], m.CABundle) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle))) - i-- - dAtA[i] = 0x12 + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } } - if m.Service != nil { - { - size, err := m.Service.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.AuditAnnotations) > 0 { + for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a } + } + if m.FailurePolicy != nil { + i -= len(*m.FailurePolicy) + copy(dAtA[i:], *m.FailurePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) i-- - dAtA[i] = 0xa + dAtA[i] = 0x22 } - return len(dAtA) - i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ + if len(m.Validations) > 0 { + for iNdEx := len(m.Validations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Validations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } } - dAtA[offset] = uint8(v) - return base -} -func (m *AuditAnnotation) Size() (n int) { - if m == nil { - return 0 + if m.MatchConstraints != nil { + { + size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - var l int - _ = l - l = len(m.Key) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.ValueExpression) - n += 1 + l + sovGenerated(uint64(l)) - return n + if m.ParamKind != nil { + { + size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *ExpressionWarning) Size() (n int) { - if m == nil { - return 0 +func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - l = len(m.FieldRef) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Warning) - n += 1 + l + sovGenerated(uint64(l)) - return n + return dAtA[:n], nil } -func (m *MatchCondition) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Expression) - n += 1 + l + sovGenerated(uint64(l)) - return n +func (m *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MatchResources) Size() (n int) { - if m == nil { - return 0 - } +func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.NamespaceSelector != nil { - l = m.NamespaceSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ObjectSelector != nil { - l = m.ObjectSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.ResourceRules) > 0 { - for _, e := range m.ResourceRules { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } } - if len(m.ExcludeResourceRules) > 0 { - for _, e := range m.ExcludeResourceRules { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.TypeChecking != nil { + { + size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 } - if m.MatchPolicy != nil { - l = len(*m.MatchPolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - return n + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil } -func (m *MutatingWebhook) Size() (n int) { - if m == nil { - return 0 +func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *ValidatingWebhook) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.ClientConfig.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Rules) > 0 { - for _, e := range m.Rules { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a } } - if m.FailurePolicy != nil { - l = len(*m.FailurePolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.NamespaceSelector != nil { - l = m.NamespaceSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.SideEffects != nil { - l = len(*m.SideEffects) - n += 1 + l + sovGenerated(uint64(l)) + if m.ObjectSelector != nil { + { + size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 } - if m.TimeoutSeconds != nil { - n += 1 + sovGenerated(uint64(*m.TimeoutSeconds)) + if m.MatchPolicy != nil { + i -= len(*m.MatchPolicy) + copy(dAtA[i:], *m.MatchPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy))) + i-- + dAtA[i] = 0x4a } if len(m.AdmissionReviewVersions) > 0 { - for _, s := range m.AdmissionReviewVersions { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AdmissionReviewVersions[iNdEx]) + copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx]))) + i-- + dAtA[i] = 0x42 } } - if m.MatchPolicy != nil { - l = len(*m.MatchPolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ReinvocationPolicy != nil { - l = len(*m.ReinvocationPolicy) - n += 1 + l + sovGenerated(uint64(l)) + if m.TimeoutSeconds != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds)) + i-- + dAtA[i] = 0x38 } - if m.ObjectSelector != nil { - l = m.ObjectSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.SideEffects != nil { + i -= len(*m.SideEffects) + copy(dAtA[i:], *m.SideEffects) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects))) + i-- + dAtA[i] = 0x32 } - if len(m.MatchConditions) > 0 { - for _, e := range m.MatchConditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.NamespaceSelector != nil { + { + size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x2a } - return n -} - -func (m *MutatingWebhookConfiguration) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Webhooks) > 0 { - for _, e := range m.Webhooks { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } + if m.FailurePolicy != nil { + i -= len(*m.FailurePolicy) + copy(dAtA[i:], *m.FailurePolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy))) + i-- + dAtA[i] = 0x22 } - return n -} - -func (m *MutatingWebhookConfigurationList) Size() (n int) { - if m == nil { - return 0 + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *NamedRuleWithOperations) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ResourceNames) > 0 { - for _, s := range m.ResourceNames { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } +func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - l = m.RuleWithOperations.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n + return dAtA[:n], nil } -func (m *ParamKind) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.APIVersion) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - return n +func (m *ValidatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ParamRef) Size() (n int) { - if m == nil { - return 0 - } +func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Webhooks) > 0 { + for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } } - if m.ParameterNotFoundAction != nil { - l = len(*m.ParameterNotFoundAction) - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *Rule) Size() (n int) { - if m == nil { - return 0 +func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *ValidatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.APIGroups) > 0 { - for _, s := range m.APIGroups { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.APIVersions) > 0 { - for _, s := range m.APIVersions { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } } - if len(m.Resources) > 0 { - for _, s := range m.Resources { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if m.Scope != nil { - l = len(*m.Scope) - n += 1 + l + sovGenerated(uint64(l)) - } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *RuleWithOperations) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Operations) > 0 { - for _, s := range m.Operations { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } +func (m *Validation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - l = m.Rule.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n + return dAtA[:n], nil } -func (m *ServiceReference) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Namespace) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.Path != nil { - l = len(*m.Path) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Port != nil { - n += 1 + sovGenerated(uint64(*m.Port)) - } - return n +func (m *Validation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *TypeChecking) Size() (n int) { - if m == nil { - return 0 - } +func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.ExpressionWarnings) > 0 { - for _, e := range m.ExpressionWarnings { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x22 + if m.Reason != nil { + i -= len(*m.Reason) + copy(dAtA[i:], *m.Reason) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Reason))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x12 + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Variable) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Variable) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Variable) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WebhookClientConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WebhookClientConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.URL != nil { + i -= len(*m.URL) + copy(dAtA[i:], *m.URL) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.URL))) + i-- + dAtA[i] = 0x1a + } + if m.CABundle != nil { + i -= len(m.CABundle) + copy(dAtA[i:], m.CABundle) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle))) + i-- + dAtA[i] = 0x12 + } + if m.Service != nil { + { + size, err := m.Service.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ApplyConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ValidatingAdmissionPolicy) Size() (n int) { +func (m *AuditAnnotation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.ValueExpression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ExpressionWarning) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FieldRef) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Warning) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *JSONPatch) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MatchResources) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NamespaceSelector != nil { + l = m.NamespaceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ObjectSelector != nil { + l = m.ObjectSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ResourceRules) > 0 { + for _, e := range m.ResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.ExcludeResourceRules) > 0 { + for _, e := range m.ExcludeResourceRules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.MatchPolicy != nil { + l = len(*m.MatchPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *MutatingAdmissionPolicy) Size() (n int) { if m == nil { return 0 } @@ -1879,12 +2134,10 @@ func (m *ValidatingAdmissionPolicy) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Spec.Size() n += 1 + l + sovGenerated(uint64(l)) - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ValidatingAdmissionPolicyBinding) Size() (n int) { +func (m *MutatingAdmissionPolicyBinding) Size() (n int) { if m == nil { return 0 } @@ -1897,7 +2150,7 @@ func (m *ValidatingAdmissionPolicyBinding) Size() (n int) { return n } -func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) { +func (m *MutatingAdmissionPolicyBindingList) Size() (n int) { if m == nil { return 0 } @@ -1914,7 +2167,7 @@ func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) { return n } -func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) { +func (m *MutatingAdmissionPolicyBindingSpec) Size() (n int) { if m == nil { return 0 } @@ -1930,16 +2183,10 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) { l = m.MatchResources.Size() n += 1 + l + sovGenerated(uint64(l)) } - if len(m.ValidationActions) > 0 { - for _, s := range m.ValidationActions { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } return n } -func (m *ValidatingAdmissionPolicyList) Size() (n int) { +func (m *MutatingAdmissionPolicyList) Size() (n int) { if m == nil { return 0 } @@ -1956,7 +2203,7 @@ func (m *ValidatingAdmissionPolicyList) Size() (n int) { return n } -func (m *ValidatingAdmissionPolicySpec) Size() (n int) { +func (m *MutatingAdmissionPolicySpec) Size() (n int) { if m == nil { return 0 } @@ -1970,58 +2217,34 @@ func (m *ValidatingAdmissionPolicySpec) Size() (n int) { l = m.MatchConstraints.Size() n += 1 + l + sovGenerated(uint64(l)) } - if len(m.Validations) > 0 { - for _, e := range m.Validations { + if len(m.Variables) > 0 { + for _, e := range m.Variables { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } - if m.FailurePolicy != nil { - l = len(*m.FailurePolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.AuditAnnotations) > 0 { - for _, e := range m.AuditAnnotations { + if len(m.Mutations) > 0 { + for _, e := range m.Mutations { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } + if m.FailurePolicy != nil { + l = len(*m.FailurePolicy) + n += 1 + l + sovGenerated(uint64(l)) + } if len(m.MatchConditions) > 0 { for _, e := range m.MatchConditions { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } - if len(m.Variables) > 0 { - for _, e := range m.Variables { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } + l = len(m.ReinvocationPolicy) + n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ValidatingAdmissionPolicyStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.ObservedGeneration)) - if m.TypeChecking != nil { - l = m.TypeChecking.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.Conditions) > 0 { - for _, e := range m.Conditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *ValidatingWebhook) Size() (n int) { +func (m *MutatingWebhook) Size() (n int) { if m == nil { return 0 } @@ -2062,6 +2285,10 @@ func (m *ValidatingWebhook) Size() (n int) { l = len(*m.MatchPolicy) n += 1 + l + sovGenerated(uint64(l)) } + if m.ReinvocationPolicy != nil { + l = len(*m.ReinvocationPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } if m.ObjectSelector != nil { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) @@ -2075,7 +2302,7 @@ func (m *ValidatingWebhook) Size() (n int) { return n } -func (m *ValidatingWebhookConfiguration) Size() (n int) { +func (m *MutatingWebhookConfiguration) Size() (n int) { if m == nil { return 0 } @@ -2092,7 +2319,7 @@ func (m *ValidatingWebhookConfiguration) Size() (n int) { return n } -func (m *ValidatingWebhookConfigurationList) Size() (n int) { +func (m *MutatingWebhookConfigurationList) Size() (n int) { if m == nil { return 0 } @@ -2109,500 +2336,1983 @@ func (m *ValidatingWebhookConfigurationList) Size() (n int) { return n } -func (m *Validation) Size() (n int) { +func (m *Mutation) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Expression) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) + l = len(m.PatchType) n += 1 + l + sovGenerated(uint64(l)) - if m.Reason != nil { - l = len(*m.Reason) + if m.ApplyConfiguration != nil { + l = m.ApplyConfiguration.Size() n += 1 + l + sovGenerated(uint64(l)) } - l = len(m.MessageExpression) + if m.JSONPatch != nil { + l = m.JSONPatch.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *NamedRuleWithOperations) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ResourceNames) > 0 { + for _, s := range m.ResourceNames { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = m.RuleWithOperations.Size() n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *Variable) Size() (n int) { +func (m *ParamKind) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Name) + l = len(m.APIVersion) n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Expression) + l = len(m.Kind) n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *WebhookClientConfig) Size() (n int) { +func (m *ParamRef) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Service != nil { - l = m.Service.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.CABundle != nil { - l = len(m.CABundle) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + if m.Selector != nil { + l = m.Selector.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.URL != nil { - l = len(*m.URL) + if m.ParameterNotFoundAction != nil { + l = len(*m.ParameterNotFoundAction) n += 1 + l + sovGenerated(uint64(l)) } return n } -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *AuditAnnotation) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AuditAnnotation{`, - `Key:` + fmt.Sprintf("%v", this.Key) + `,`, - `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`, - `}`, - }, "") - return s -} -func (this *ExpressionWarning) String() string { - if this == nil { - return "nil" +func (m *Rule) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&ExpressionWarning{`, - `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`, - `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`, - `}`, - }, "") - return s -} -func (this *MatchCondition) String() string { - if this == nil { - return "nil" + var l int + _ = l + if len(m.APIGroups) > 0 { + for _, s := range m.APIGroups { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } - s := strings.Join([]string{`&MatchCondition{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, - `}`, - }, "") - return s -} -func (this *MatchResources) String() string { - if this == nil { - return "nil" + if len(m.APIVersions) > 0 { + for _, s := range m.APIVersions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForResourceRules := "[]NamedRuleWithOperations{" - for _, f := range this.ResourceRules { - repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + if len(m.Resources) > 0 { + for _, s := range m.Resources { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForResourceRules += "}" - repeatedStringForExcludeResourceRules := "[]NamedRuleWithOperations{" - for _, f := range this.ExcludeResourceRules { - repeatedStringForExcludeResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + if m.Scope != nil { + l = len(*m.Scope) + n += 1 + l + sovGenerated(uint64(l)) } - repeatedStringForExcludeResourceRules += "}" - s := strings.Join([]string{`&MatchResources{`, - `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `ResourceRules:` + repeatedStringForResourceRules + `,`, - `ExcludeResourceRules:` + repeatedStringForExcludeResourceRules + `,`, - `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, - `}`, - }, "") - return s + return n } -func (this *MutatingWebhook) String() string { - if this == nil { - return "nil" - } - repeatedStringForRules := "[]RuleWithOperations{" - for _, f := range this.Rules { - repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," + +func (m *RuleWithOperations) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForRules += "}" - repeatedStringForMatchConditions := "[]MatchCondition{" - for _, f := range this.MatchConditions { - repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + var l int + _ = l + if len(m.Operations) > 0 { + for _, s := range m.Operations { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForMatchConditions += "}" - s := strings.Join([]string{`&MutatingWebhook{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, - `Rules:` + repeatedStringForRules + `,`, - `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, - `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, - `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, - `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, - `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, - `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, - `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `MatchConditions:` + repeatedStringForMatchConditions + `,`, - `}`, - }, "") - return s + l = m.Rule.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n } -func (this *MutatingWebhookConfiguration) String() string { - if this == nil { - return "nil" + +func (m *ServiceReference) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForWebhooks := "[]MutatingWebhook{" - for _, f := range this.Webhooks { - repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "MutatingWebhook", "MutatingWebhook", 1), `&`, ``, 1) + "," + var l int + _ = l + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.Path != nil { + l = len(*m.Path) + n += 1 + l + sovGenerated(uint64(l)) } - repeatedStringForWebhooks += "}" - s := strings.Join([]string{`&MutatingWebhookConfiguration{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Webhooks:` + repeatedStringForWebhooks + `,`, - `}`, - }, "") - return s + if m.Port != nil { + n += 1 + sovGenerated(uint64(*m.Port)) + } + return n } -func (this *MutatingWebhookConfigurationList) String() string { - if this == nil { - return "nil" + +func (m *TypeChecking) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForItems := "[]MutatingWebhookConfiguration{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingWebhookConfiguration", "MutatingWebhookConfiguration", 1), `&`, ``, 1) + "," + var l int + _ = l + if len(m.ExpressionWarnings) > 0 { + for _, e := range m.ExpressionWarnings { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForItems += "}" - s := strings.Join([]string{`&MutatingWebhookConfigurationList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s + return n } -func (this *NamedRuleWithOperations) String() string { - if this == nil { - return "nil" + +func (m *ValidatingAdmissionPolicy) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&NamedRuleWithOperations{`, - `ResourceNames:` + fmt.Sprintf("%v", this.ResourceNames) + `,`, - `RuleWithOperations:` + strings.Replace(strings.Replace(this.RuleWithOperations.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n } -func (this *ParamKind) String() string { - if this == nil { - return "nil" + +func (m *ValidatingAdmissionPolicyBinding) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&ParamKind{`, - `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `}`, - }, "") - return s + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n } -func (this *ParamRef) String() string { - if this == nil { - return "nil" + +func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&ParamRef{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `ParameterNotFoundAction:` + valueToStringGenerated(this.ParameterNotFoundAction) + `,`, - `}`, - }, "") - return s -} -func (this *Rule) String() string { - if this == nil { - return "nil" + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - s := strings.Join([]string{`&Rule{`, - `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`, - `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, - `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`, - `Scope:` + valueToStringGenerated(this.Scope) + `,`, - `}`, - }, "") - return s + return n } -func (this *RuleWithOperations) String() string { - if this == nil { - return "nil" + +func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&RuleWithOperations{`, - `Operations:` + fmt.Sprintf("%v", this.Operations) + `,`, - `Rule:` + strings.Replace(strings.Replace(this.Rule.String(), "Rule", "Rule", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ServiceReference) String() string { - if this == nil { - return "nil" + var l int + _ = l + l = len(m.PolicyName) + n += 1 + l + sovGenerated(uint64(l)) + if m.ParamRef != nil { + l = m.ParamRef.Size() + n += 1 + l + sovGenerated(uint64(l)) } - s := strings.Join([]string{`&ServiceReference{`, - `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Path:` + valueToStringGenerated(this.Path) + `,`, - `Port:` + valueToStringGenerated(this.Port) + `,`, - `}`, - }, "") - return s -} -func (this *TypeChecking) String() string { - if this == nil { - return "nil" + if m.MatchResources != nil { + l = m.MatchResources.Size() + n += 1 + l + sovGenerated(uint64(l)) } - repeatedStringForExpressionWarnings := "[]ExpressionWarning{" - for _, f := range this.ExpressionWarnings { - repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + "," + if len(m.ValidationActions) > 0 { + for _, s := range m.ValidationActions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForExpressionWarnings += "}" - s := strings.Join([]string{`&TypeChecking{`, - `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`, - `}`, - }, "") - return s + return n } -func (this *ValidatingAdmissionPolicy) String() string { - if this == nil { - return "nil" + +func (m *ValidatingAdmissionPolicyList) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&ValidatingAdmissionPolicy{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ValidatingAdmissionPolicyBinding) String() string { - if this == nil { - return "nil" + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - s := strings.Join([]string{`&ValidatingAdmissionPolicyBinding{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicyBindingSpec", "ValidatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s + return n } -func (this *ValidatingAdmissionPolicyBindingList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]ValidatingAdmissionPolicyBinding{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicyBinding", "ValidatingAdmissionPolicyBinding", 1), `&`, ``, 1) + "," + +func (m *ValidatingAdmissionPolicySpec) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForItems += "}" - s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *ValidatingAdmissionPolicyBindingSpec) String() string { - if this == nil { - return "nil" + var l int + _ = l + if m.ParamKind != nil { + l = m.ParamKind.Size() + n += 1 + l + sovGenerated(uint64(l)) } - s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingSpec{`, - `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`, - `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`, - `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`, - `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`, - `}`, - }, "") - return s -} -func (this *ValidatingAdmissionPolicyList) String() string { - if this == nil { - return "nil" + if m.MatchConstraints != nil { + l = m.MatchConstraints.Size() + n += 1 + l + sovGenerated(uint64(l)) } - repeatedStringForItems := "[]ValidatingAdmissionPolicy{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicy", "ValidatingAdmissionPolicy", 1), `&`, ``, 1) + "," + if len(m.Validations) > 0 { + for _, e := range m.Validations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForItems += "}" - s := strings.Join([]string{`&ValidatingAdmissionPolicyList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *ValidatingAdmissionPolicySpec) String() string { - if this == nil { - return "nil" + if m.FailurePolicy != nil { + l = len(*m.FailurePolicy) + n += 1 + l + sovGenerated(uint64(l)) } - repeatedStringForValidations := "[]Validation{" - for _, f := range this.Validations { - repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + "," + if len(m.AuditAnnotations) > 0 { + for _, e := range m.AuditAnnotations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForValidations += "}" - repeatedStringForAuditAnnotations := "[]AuditAnnotation{" - for _, f := range this.AuditAnnotations { - repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + "," + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForAuditAnnotations += "}" - repeatedStringForMatchConditions := "[]MatchCondition{" - for _, f := range this.MatchConditions { - repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + if len(m.Variables) > 0 { + for _, e := range m.Variables { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForMatchConditions += "}" - repeatedStringForVariables := "[]Variable{" - for _, f := range this.Variables { - repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + "," + return n +} + +func (m *ValidatingAdmissionPolicyStatus) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForVariables += "}" - s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`, - `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`, - `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`, - `Validations:` + repeatedStringForValidations + `,`, - `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, - `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`, - `MatchConditions:` + repeatedStringForMatchConditions + `,`, - `Variables:` + repeatedStringForVariables + `,`, - `}`, - }, "") - return s + var l int + _ = l + n += 1 + sovGenerated(uint64(m.ObservedGeneration)) + if m.TypeChecking != nil { + l = m.TypeChecking.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n } -func (this *ValidatingAdmissionPolicyStatus) String() string { + +func (m *ValidatingWebhook) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = m.ClientConfig.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Rules) > 0 { + for _, e := range m.Rules { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.FailurePolicy != nil { + l = len(*m.FailurePolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.NamespaceSelector != nil { + l = m.NamespaceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.SideEffects != nil { + l = len(*m.SideEffects) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.TimeoutSeconds != nil { + n += 1 + sovGenerated(uint64(*m.TimeoutSeconds)) + } + if len(m.AdmissionReviewVersions) > 0 { + for _, s := range m.AdmissionReviewVersions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.MatchPolicy != nil { + l = len(*m.MatchPolicy) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ObjectSelector != nil { + l = m.ObjectSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingWebhookConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Webhooks) > 0 { + for _, e := range m.Webhooks { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingWebhookConfigurationList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *Validation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) + if m.Reason != nil { + l = len(*m.Reason) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Variable) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *WebhookClientConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Service != nil { + l = m.Service.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.CABundle != nil { + l = len(m.CABundle) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.URL != nil { + l = len(*m.URL) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *ApplyConfiguration) String() string { if this == nil { return "nil" } - repeatedStringForConditions := "[]Condition{" - for _, f := range this.Conditions { - repeatedStringForConditions += fmt.Sprintf("%v", f) + "," - } - repeatedStringForConditions += "}" - s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`, - `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, - `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`, - `Conditions:` + repeatedStringForConditions + `,`, + s := strings.Join([]string{`&ApplyConfiguration{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, `}`, }, "") return s } -func (this *ValidatingWebhook) String() string { +func (this *AuditAnnotation) String() string { if this == nil { return "nil" } - repeatedStringForRules := "[]RuleWithOperations{" - for _, f := range this.Rules { - repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," - } - repeatedStringForRules += "}" - repeatedStringForMatchConditions := "[]MatchCondition{" - for _, f := range this.MatchConditions { - repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," - } - repeatedStringForMatchConditions += "}" - s := strings.Join([]string{`&ValidatingWebhook{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, - `Rules:` + repeatedStringForRules + `,`, - `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, - `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, - `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, - `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, - `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, - `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `MatchConditions:` + repeatedStringForMatchConditions + `,`, + s := strings.Join([]string{`&AuditAnnotation{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`, `}`, }, "") return s } -func (this *ValidatingWebhookConfiguration) String() string { +func (this *ExpressionWarning) String() string { if this == nil { return "nil" } - repeatedStringForWebhooks := "[]ValidatingWebhook{" - for _, f := range this.Webhooks { - repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "ValidatingWebhook", "ValidatingWebhook", 1), `&`, ``, 1) + "," - } - repeatedStringForWebhooks += "}" - s := strings.Join([]string{`&ValidatingWebhookConfiguration{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Webhooks:` + repeatedStringForWebhooks + `,`, + s := strings.Join([]string{`&ExpressionWarning{`, + `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`, + `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`, `}`, }, "") return s } -func (this *ValidatingWebhookConfigurationList) String() string { +func (this *JSONPatch) String() string { if this == nil { return "nil" } - repeatedStringForItems := "[]ValidatingWebhookConfiguration{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingWebhookConfiguration", "ValidatingWebhookConfiguration", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&ValidatingWebhookConfigurationList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, + s := strings.Join([]string{`&JSONPatch{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, `}`, }, "") return s } -func (this *Validation) String() string { +func (this *MatchCondition) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Validation{`, + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `Reason:` + valueToStringGenerated(this.Reason) + `,`, - `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, `}`, }, "") return s } -func (this *Variable) String() string { +func (this *MatchResources) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&Variable{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, - `}`, - }, "") - return s -} -func (this *WebhookClientConfig) String() string { - if this == nil { - return "nil" + repeatedStringForResourceRules := "[]NamedRuleWithOperations{" + for _, f := range this.ResourceRules { + repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceRules += "}" + repeatedStringForExcludeResourceRules := "[]NamedRuleWithOperations{" + for _, f := range this.ExcludeResourceRules { + repeatedStringForExcludeResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForExcludeResourceRules += "}" + s := strings.Join([]string{`&MatchResources{`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ResourceRules:` + repeatedStringForResourceRules + `,`, + `ExcludeResourceRules:` + repeatedStringForExcludeResourceRules + `,`, + `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MutatingAdmissionPolicy{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "MutatingAdmissionPolicySpec", "MutatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicyBinding) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MutatingAdmissionPolicyBinding{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "MutatingAdmissionPolicyBindingSpec", "MutatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicyBindingList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]MutatingAdmissionPolicyBinding{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingAdmissionPolicyBinding", "MutatingAdmissionPolicyBinding", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&MutatingAdmissionPolicyBindingList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicyBindingSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MutatingAdmissionPolicyBindingSpec{`, + `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`, + `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`, + `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicyList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]MutatingAdmissionPolicy{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingAdmissionPolicy", "MutatingAdmissionPolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&MutatingAdmissionPolicyList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *MutatingAdmissionPolicySpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForVariables := "[]Variable{" + for _, f := range this.Variables { + repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + "," + } + repeatedStringForVariables += "}" + repeatedStringForMutations := "[]Mutation{" + for _, f := range this.Mutations { + repeatedStringForMutations += strings.Replace(strings.Replace(f.String(), "Mutation", "Mutation", 1), `&`, ``, 1) + "," + } + repeatedStringForMutations += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" + s := strings.Join([]string{`&MutatingAdmissionPolicySpec{`, + `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`, + `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`, + `Variables:` + repeatedStringForVariables + `,`, + `Mutations:` + repeatedStringForMutations + `,`, + `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `ReinvocationPolicy:` + fmt.Sprintf("%v", this.ReinvocationPolicy) + `,`, + `}`, + }, "") + return s +} +func (this *MutatingWebhook) String() string { + if this == nil { + return "nil" + } + repeatedStringForRules := "[]RuleWithOperations{" + for _, f := range this.Rules { + repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" + s := strings.Join([]string{`&MutatingWebhook{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, + `Rules:` + repeatedStringForRules + `,`, + `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, + `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, + `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, + `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, + `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `}`, + }, "") + return s +} +func (this *MutatingWebhookConfiguration) String() string { + if this == nil { + return "nil" + } + repeatedStringForWebhooks := "[]MutatingWebhook{" + for _, f := range this.Webhooks { + repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "MutatingWebhook", "MutatingWebhook", 1), `&`, ``, 1) + "," + } + repeatedStringForWebhooks += "}" + s := strings.Join([]string{`&MutatingWebhookConfiguration{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Webhooks:` + repeatedStringForWebhooks + `,`, + `}`, + }, "") + return s +} +func (this *MutatingWebhookConfigurationList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]MutatingWebhookConfiguration{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingWebhookConfiguration", "MutatingWebhookConfiguration", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&MutatingWebhookConfigurationList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *Mutation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Mutation{`, + `PatchType:` + fmt.Sprintf("%v", this.PatchType) + `,`, + `ApplyConfiguration:` + strings.Replace(this.ApplyConfiguration.String(), "ApplyConfiguration", "ApplyConfiguration", 1) + `,`, + `JSONPatch:` + strings.Replace(this.JSONPatch.String(), "JSONPatch", "JSONPatch", 1) + `,`, + `}`, + }, "") + return s +} +func (this *NamedRuleWithOperations) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NamedRuleWithOperations{`, + `ResourceNames:` + fmt.Sprintf("%v", this.ResourceNames) + `,`, + `RuleWithOperations:` + strings.Replace(strings.Replace(this.RuleWithOperations.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ParamKind) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParamKind{`, + `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `}`, + }, "") + return s +} +func (this *ParamRef) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParamRef{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `ParameterNotFoundAction:` + valueToStringGenerated(this.ParameterNotFoundAction) + `,`, + `}`, + }, "") + return s +} +func (this *Rule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Rule{`, + `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`, + `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, + `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`, + `Scope:` + valueToStringGenerated(this.Scope) + `,`, + `}`, + }, "") + return s +} +func (this *RuleWithOperations) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RuleWithOperations{`, + `Operations:` + fmt.Sprintf("%v", this.Operations) + `,`, + `Rule:` + strings.Replace(strings.Replace(this.Rule.String(), "Rule", "Rule", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ServiceReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ServiceReference{`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Path:` + valueToStringGenerated(this.Path) + `,`, + `Port:` + valueToStringGenerated(this.Port) + `,`, + `}`, + }, "") + return s +} +func (this *TypeChecking) String() string { + if this == nil { + return "nil" + } + repeatedStringForExpressionWarnings := "[]ExpressionWarning{" + for _, f := range this.ExpressionWarnings { + repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + "," + } + repeatedStringForExpressionWarnings += "}" + s := strings.Join([]string{`&TypeChecking{`, + `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicy{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBinding) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicyBinding{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicyBindingSpec", "ValidatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBindingList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ValidatingAdmissionPolicyBinding{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicyBinding", "ValidatingAdmissionPolicyBinding", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyBindingSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingSpec{`, + `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`, + `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`, + `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`, + `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ValidatingAdmissionPolicy{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicy", "ValidatingAdmissionPolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicySpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForValidations := "[]Validation{" + for _, f := range this.Validations { + repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + "," + } + repeatedStringForValidations += "}" + repeatedStringForAuditAnnotations := "[]AuditAnnotation{" + for _, f := range this.AuditAnnotations { + repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + "," + } + repeatedStringForAuditAnnotations += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" + repeatedStringForVariables := "[]Variable{" + for _, f := range this.Variables { + repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + "," + } + repeatedStringForVariables += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`, + `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`, + `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`, + `Validations:` + repeatedStringForValidations + `,`, + `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `Variables:` + repeatedStringForVariables + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`, + `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, + `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingWebhook) String() string { + if this == nil { + return "nil" + } + repeatedStringForRules := "[]RuleWithOperations{" + for _, f := range this.Rules { + repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," + } + repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" + s := strings.Join([]string{`&ValidatingWebhook{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, + `Rules:` + repeatedStringForRules + `,`, + `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`, + `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`, + `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, + `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, + `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingWebhookConfiguration) String() string { + if this == nil { + return "nil" + } + repeatedStringForWebhooks := "[]ValidatingWebhook{" + for _, f := range this.Webhooks { + repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "ValidatingWebhook", "ValidatingWebhook", 1), `&`, ``, 1) + "," + } + repeatedStringForWebhooks += "}" + s := strings.Join([]string{`&ValidatingWebhookConfiguration{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Webhooks:` + repeatedStringForWebhooks + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingWebhookConfigurationList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ValidatingWebhookConfiguration{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingWebhookConfiguration", "ValidatingWebhookConfiguration", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ValidatingWebhookConfigurationList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *Validation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Validation{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `Reason:` + valueToStringGenerated(this.Reason) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, + `}`, + }, "") + return s +} +func (this *Variable) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Variable{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} +func (this *WebhookClientConfig) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WebhookClientConfig{`, + `Service:` + strings.Replace(this.Service.String(), "ServiceReference", "ServiceReference", 1) + `,`, + `CABundle:` + valueToStringGenerated(this.CABundle) + `,`, + `URL:` + valueToStringGenerated(this.URL) + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *ApplyConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ApplyConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplyConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuditAnnotation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValueExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExpressionWarning: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FieldRef = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Warning", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Warning = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JSONPatch) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JSONPatch: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JSONPatch: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MatchCondition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MatchResources) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MatchResources: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchResources: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamespaceSelector == nil { + m.NamespaceSelector = &v1.LabelSelector{} + } + if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ObjectSelector == nil { + m.ObjectSelector = &v1.LabelSelector{} + } + if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceRules = append(m.ResourceRules, NamedRuleWithOperations{}) + if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExcludeResourceRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExcludeResourceRules = append(m.ExcludeResourceRules, NamedRuleWithOperations{}) + if err := m.ExcludeResourceRules[len(m.ExcludeResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := MatchPolicyType(dAtA[iNdEx:postIndex]) + m.MatchPolicy = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MutatingAdmissionPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MutatingAdmissionPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MutatingAdmissionPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF } - s := strings.Join([]string{`&WebhookClientConfig{`, - `Service:` + strings.Replace(this.Service.String(), "ServiceReference", "ServiceReference", 1) + `,`, - `CABundle:` + valueToStringGenerated(this.CABundle) + `,`, - `URL:` + valueToStringGenerated(this.URL) + `,`, - `}`, - }, "") - return s + return nil } -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" +func (m *MutatingAdmissionPolicyBinding) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MutatingAdmissionPolicyBinding: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MutatingAdmissionPolicyBinding: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { +func (m *MutatingAdmissionPolicyBindingList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2625,17 +4335,17 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuditAnnotation: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingAdmissionPolicyBindingList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingAdmissionPolicyBindingList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2645,29 +4355,30 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = string(dAtA[iNdEx:postIndex]) + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2677,23 +4388,25 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.ValueExpression = string(dAtA[iNdEx:postIndex]) + m.Items = append(m.Items, MutatingAdmissionPolicyBinding{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -2716,7 +4429,7 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error { } return nil } -func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { +func (m *MutatingAdmissionPolicyBindingSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2739,15 +4452,15 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ExpressionWarning: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingAdmissionPolicyBindingSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingAdmissionPolicyBindingSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 2: + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2775,13 +4488,49 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.FieldRef = string(dAtA[iNdEx:postIndex]) + m.PolicyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParamRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ParamRef == nil { + m.ParamRef = &ParamRef{} + } + if err := m.ParamRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Warning", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MatchResources", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2791,23 +4540,27 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Warning = string(dAtA[iNdEx:postIndex]) + if m.MatchResources == nil { + m.MatchResources = &MatchResources{} + } + if err := m.MatchResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -2830,7 +4583,7 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error { } return nil } -func (m *MatchCondition) Unmarshal(dAtA []byte) error { +func (m *MutatingAdmissionPolicyList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2853,17 +4606,17 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingAdmissionPolicyList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingAdmissionPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2873,29 +4626,30 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2905,23 +4659,25 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Expression = string(dAtA[iNdEx:postIndex]) + m.Items = append(m.Items, MutatingAdmissionPolicy{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -2944,7 +4700,7 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error { } return nil } -func (m *MatchResources) Unmarshal(dAtA []byte) error { +func (m *MutatingAdmissionPolicySpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2967,15 +4723,15 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MatchResources: wiretype end group for non-group") + return fmt.Errorf("proto: MutatingAdmissionPolicySpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MatchResources: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutatingAdmissionPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ParamKind", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3002,16 +4758,16 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NamespaceSelector == nil { - m.NamespaceSelector = &v1.LabelSelector{} + if m.ParamKind == nil { + m.ParamKind = &ParamKind{} } - if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ParamKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MatchConstraints", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3038,16 +4794,16 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ObjectSelector == nil { - m.ObjectSelector = &v1.LabelSelector{} + if m.MatchConstraints == nil { + m.MatchConstraints = &MatchResources{} } - if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.MatchConstraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Variables", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3074,14 +4830,14 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ResourceRules = append(m.ResourceRules, NamedRuleWithOperations{}) - if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Variables = append(m.Variables, Variable{}) + if err := m.Variables[len(m.Variables)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExcludeResourceRules", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Mutations", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3108,14 +4864,81 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ExcludeResourceRules = append(m.ExcludeResourceRules, NamedRuleWithOperations{}) - if err := m.ExcludeResourceRules[len(m.ExcludeResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Mutations = append(m.Mutations, Mutation{}) + if err := m.Mutations[len(m.Mutations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FailurePolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := FailurePolicyType(dAtA[iNdEx:postIndex]) + m.FailurePolicy = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MatchPolicy", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ReinvocationPolicy", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3143,8 +4966,7 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := MatchPolicyType(dAtA[iNdEx:postIndex]) - m.MatchPolicy = &s + m.ReinvocationPolicy = ReinvocationPolicyType(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3840,6 +5662,160 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error { } return nil } +func (m *Mutation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Mutation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Mutation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PatchType = PatchType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplyConfiguration", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ApplyConfiguration == nil { + m.ApplyConfiguration = &ApplyConfiguration{} + } + if err := m.ApplyConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JSONPatch", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.JSONPatch == nil { + m.JSONPatch = &JSONPatch{} + } + if err := m.JSONPatch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NamedRuleWithOperations) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1/generated.proto index e856e9eaf2..89c1475b2e 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.proto @@ -28,6 +28,51 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1"; +// ApplyConfiguration defines the desired configuration values of an object. +message ApplyConfiguration { + // expression will be evaluated by CEL to create an apply configuration. + // ref: https://github.com/google/cel-spec + // + // Apply configurations are declared in CEL using object initialization. For example, this CEL expression + // returns an apply configuration to set a single field: + // + // Object{ + // spec: Object.spec{ + // serviceAccountName: "example" + // } + // } + // + // Apply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of + // values not included in the apply configuration. + // + // CEL expressions have access to the object types needed to create apply configurations: + // + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the + // object. No other metadata properties are accessible. + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + optional string expression = 1; +} + // AuditAnnotation describes how to produce an audit annotation for an API request. message AuditAnnotation { // key specifies the audit annotation key. The audit annotation keys of @@ -67,20 +112,89 @@ message AuditAnnotation { // ExpressionWarning is a warning information that targets a specific expression. message ExpressionWarning { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" optional string fieldRef = 2; - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. optional string warning = 3; } +// JSONPatch defines a JSON Patch. +message JSONPatch { + // expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/). + // ref: https://github.com/google/cel-spec + // + // expression must return an array of JSONPatch values. + // + // For example, this CEL expression returns a JSON patch to conditionally modify a value: + // + // [ + // JSONPatch{op: "test", path: "/spec/example", value: "Red"}, + // JSONPatch{op: "replace", path: "/spec/example", value: "Green"} + // ] + // + // To define an object for the patch value, use Object types. For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/spec/selector", + // value: Object.spec.selector{matchLabels: {"environment": "test"}} + // } + // ] + // + // To use strings containing '/' and '~' as JSONPatch path keys, use "jsonpatch.escapeKey". For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"), + // value: "test" + // }, + // ] + // + // CEL expressions have access to the types needed to create JSON patches and objects: + // + // - 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'. + // See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string, + // integer, array, map or object. If set, the 'path' and 'from' fields must be set to a + // [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL + // function may be used to escape path keys containing '/' and '~'. + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // CEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries) + // as well as: + // + // - 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively). + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + optional string expression = 1; +} + // MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. message MatchCondition { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -91,7 +205,7 @@ message MatchCondition { // Required. optional string name = 1; - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. @@ -112,7 +226,7 @@ message MatchCondition { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic message MatchResources { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -158,7 +272,7 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1; - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -172,13 +286,13 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2; - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional repeated NamedRuleWithOperations resourceRules = 3; - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -202,20 +316,187 @@ message MatchResources { optional string matchPolicy = 7; } +// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. +message MutatingAdmissionPolicy { + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec defines the desired behavior of the MutatingAdmissionPolicy. + optional MutatingAdmissionPolicySpec spec = 2; +} + +// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. +// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators +// configure policies for clusters. +// +// For a given admission request, each binding will cause its policy to be +// evaluated N times, where N is 1 for policies/bindings that don't use +// params, otherwise N is the number of parameters selected by the binding. +// Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget). +// +// Adding/removing policies, bindings, or params can not affect whether a +// given (policy, binding, param) combination is within its own CEL budget. +message MutatingAdmissionPolicyBinding { + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. + optional MutatingAdmissionPolicyBindingSpec spec = 2; +} + +// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. +message MutatingAdmissionPolicyBindingList { + // metadata is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // List of PolicyBinding. + repeated MutatingAdmissionPolicyBinding items = 2; +} + +// MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding. +message MutatingAdmissionPolicyBindingSpec { + // policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to. + // If the referenced resource does not exist, this binding is considered invalid and will be ignored + // Required. + optional string policyName = 1; + + // paramRef specifies the parameter resource used to configure the admission control policy. + // It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy. + // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied. + // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. + // +optional + optional ParamRef paramRef = 2; + + // matchResources limits what resources match this binding and may be mutated by it. + // Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and + // matchConditions before the resource may be mutated. + // When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints + // and matchConditions must match for the resource to be mutated. + // Additionally, matchResources.resourceRules are optional and do not constraint matching when unset. + // Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + // +optional + optional MatchResources matchResources = 3; +} + +// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. +message MutatingAdmissionPolicyList { + // metadata is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // List of ValidatingAdmissionPolicy. + repeated MutatingAdmissionPolicy items = 2; +} + +// MutatingAdmissionPolicySpec defines the desired behavior of the admission policy. +message MutatingAdmissionPolicySpec { + // paramKind specifies the kind of resources used to parameterize this policy. + // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. + // If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. + // If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null. + // +optional + optional ParamKind paramKind = 1; + + // matchConstraints specifies what resources this policy is designed to validate. + // The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints. + // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API + // MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + // Required. + optional MatchResources matchConstraints = 2; + + // variables contain definitions of variables that can be used in composition of other expressions. + // Each variable is defined as a named CEL expression. + // The variables defined here will be available under `variables` in other expressions of the policy + // except matchConditions because matchConditions are evaluated before the rest of the policy. + // + // The expression of a variable can refer to other variables defined earlier in the list but not those after. + // Thus, variables must be sorted by the order of first appearance and acyclic. + // +listType=atomic + // +optional + repeated Variable variables = 3; + + // mutations contain operations to perform on matching objects. + // mutations may not be empty; a minimum of one mutation is required. + // mutations are evaluated in order, and are reinvoked according to + // the reinvocationPolicy. + // The mutations of a policy are invoked for each binding of this policy + // and reinvocation of mutations occurs on a per binding basis. + // + // +listType=atomic + // +optional + repeated Mutation mutations = 4; + + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // + // A policy is invalid if paramKind refers to a non-existent Kind. + // A binding is invalid if paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // Allowed values are Ignore or Fail. Defaults to Fail. + // +optional + optional string failurePolicy = 5; + + // matchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the matchConstraints. + // An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + repeated MatchCondition matchConditions = 6; + + // reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding + // as part of a single admission evaluation. + // Allowed values are "Never" and "IfNeeded". + // + // Never: These mutations will not be called more than once per binding in a single admission evaluation. + // + // IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of + // order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only + // reinvoked when mutations change the object after this mutation is invoked. + // Required. + optional string reinvocationPolicy = 7; +} + // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. optional string name = 1; - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required optional WebhookClientConfig clientConfig = 2; - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -224,7 +505,7 @@ message MutatingWebhook { // +listType=atomic repeated RuleWithOperations rules = 3; - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. // +optional optional string failurePolicy = 4; @@ -246,7 +527,7 @@ message MutatingWebhook { // +optional optional string matchPolicy = 9; - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -292,7 +573,7 @@ message MutatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -306,7 +587,7 @@ message MutatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 11; - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -314,7 +595,7 @@ message MutatingWebhook { // sideEffects == Unknown or Some. optional string sideEffects = 6; - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -322,7 +603,7 @@ message MutatingWebhook { // +optional optional int32 timeoutSeconds = 7; - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -350,7 +631,7 @@ message MutatingWebhook { // +optional optional string reinvocationPolicy = 10; - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -372,11 +653,11 @@ message MutatingWebhook { // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. message MutatingWebhookConfiguration { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -387,7 +668,7 @@ message MutatingWebhookConfiguration { // MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration. message MutatingWebhookConfigurationList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -396,10 +677,30 @@ message MutatingWebhookConfigurationList { repeated MutatingWebhookConfiguration items = 2; } +// Mutation specifies the CEL expression which is used to apply the Mutation. +message Mutation { + // patchType indicates the patch strategy used. + // Allowed values are "ApplyConfiguration" and "JSONPatch". + // Required. + // + // +unionDiscriminator + optional string patchType = 2; + + // applyConfiguration defines the desired configuration values of an object. + // The configuration is applied to the admission object using + // [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff). + // A CEL expression is used to create apply configuration. + optional ApplyConfiguration applyConfiguration = 3; + + // jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object. + // A CEL expression is used to create the JSON patch. + optional JSONPatch jsonPatch = 4; +} + // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic message NamedRuleWithOperations { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional repeated string resourceNames = 1; @@ -411,12 +712,12 @@ message NamedRuleWithOperations { // ParamKind is a tuple of Group Kind and Version. // +structType=atomic message ParamKind { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. optional string apiVersion = 1; - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. optional string kind = 2; } @@ -465,7 +766,7 @@ message ParamRef { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3; - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -481,19 +782,19 @@ message ParamRef { // Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended // to make sure that all the tuple expansions are valid. message Rule { - // APIGroups is the API groups the resources belong to. '*' is all groups. + // apiGroups is the API groups the resources belong to. '*' is all groups. // If '*' is present, the length of the slice must be one. // Required. // +listType=atomic repeated string apiGroups = 1; - // APIVersions is the API versions the resources belong to. '*' is all versions. + // apiVersions is the API versions the resources belong to. '*' is all versions. // If '*' is present, the length of the slice must be one. // Required. // +listType=atomic repeated string apiVersions = 2; - // Resources is a list of resources this rule applies to. + // resources is a list of resources this rule applies to. // // For example: // 'pods' means pods. @@ -527,7 +828,7 @@ message Rule { // RuleWithOperations is a tuple of Operations and Resources. It is recommended to make // sure that all the tuple expansions are valid. message RuleWithOperations { - // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * + // operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * // for all of those operations and any future admission operations that are added. // If '*' is present, the length of the slice must be one. // Required. @@ -541,20 +842,20 @@ message RuleWithOperations { // ServiceReference holds a reference to Service.legacy.k8s.io message ServiceReference { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required optional string namespace = 1; - // `name` is the name of the service. + // name is the name of the service. // Required optional string name = 2; - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. // +optional optional string path = 3; - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. // `port` should be a valid port number (1-65535, inclusive). // +optional @@ -564,7 +865,7 @@ message ServiceReference { // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy message TypeChecking { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic repeated ExpressionWarning expressionWarnings = 1; @@ -572,14 +873,14 @@ message TypeChecking { // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. message ValidatingAdmissionPolicy { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. optional ValidatingAdmissionPolicySpec spec = 2; - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -599,17 +900,18 @@ message ValidatingAdmissionPolicy { // Adding/removing policies, bindings, or params can not affect whether a // given (policy, binding, param) combination is within its own CEL budget. message ValidatingAdmissionPolicyBinding { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required optional ValidatingAdmissionPolicyBindingSpec spec = 2; } // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -620,9 +922,11 @@ message ValidatingAdmissionPolicyBindingList { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingSpec { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string policyName = 1; // paramRef specifies the parameter resource used to configure the admission control policy. @@ -632,7 +936,7 @@ message ValidatingAdmissionPolicyBindingSpec { // +optional optional ParamRef paramRef = 2; - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -680,12 +984,14 @@ message ValidatingAdmissionPolicyBindingSpec { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string validationActions = 4; } // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. message ValidatingAdmissionPolicyList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -696,21 +1002,21 @@ message ValidatingAdmissionPolicyList { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. message ValidatingAdmissionPolicySpec { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional optional ParamKind paramKind = 1; - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. optional MatchResources matchConstraints = 2; - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -741,7 +1047,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated AuditAnnotation auditAnnotations = 5; - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -763,7 +1069,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated MatchCondition matchConditions = 6; - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -780,16 +1086,16 @@ message ValidatingAdmissionPolicySpec { // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. message ValidatingAdmissionPolicyStatus { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional optional int64 observedGeneration = 1; - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional optional TypeChecking typeChecking = 2; - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -798,18 +1104,18 @@ message ValidatingAdmissionPolicyStatus { // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. message ValidatingWebhook { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. optional string name = 1; - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required optional WebhookClientConfig clientConfig = 2; - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -818,7 +1124,7 @@ message ValidatingWebhook { // +listType=atomic repeated RuleWithOperations rules = 3; - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. // +optional optional string failurePolicy = 4; @@ -840,7 +1146,7 @@ message ValidatingWebhook { // +optional optional string matchPolicy = 9; - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -886,7 +1192,7 @@ message ValidatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -900,7 +1206,7 @@ message ValidatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 10; - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -908,7 +1214,7 @@ message ValidatingWebhook { // sideEffects == Unknown or Some. optional string sideEffects = 6; - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -916,7 +1222,7 @@ message ValidatingWebhook { // +optional optional int32 timeoutSeconds = 7; - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -926,7 +1232,7 @@ message ValidatingWebhook { // +listType=atomic repeated string admissionReviewVersions = 8; - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -948,11 +1254,11 @@ message ValidatingWebhook { // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. message ValidatingWebhookConfiguration { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -963,7 +1269,7 @@ message ValidatingWebhookConfiguration { // ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration. message ValidatingWebhookConfigurationList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -974,7 +1280,7 @@ message ValidatingWebhookConfigurationList { // Validation specifies the CEL expression which is used to apply the validation. message Validation { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -1017,7 +1323,7 @@ message Validation { // Required. optional string Expression = 1; - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -1027,7 +1333,7 @@ message Validation { // +optional optional string message = 2; - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -1053,12 +1359,12 @@ message Validation { // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. // +structType=atomic message Variable { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` optional string Name = 1; - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. optional string Expression = 2; } @@ -1066,7 +1372,7 @@ message Variable { // WebhookClientConfig contains the information to make a TLS // connection with the webhook message WebhookClientConfig { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -1095,7 +1401,7 @@ message WebhookClientConfig { // +optional optional string url = 3; - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. @@ -1103,7 +1409,7 @@ message WebhookClientConfig { // +optional optional ServiceReference service = 1; - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. // +optional optional bytes caBundle = 2; diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go deleted file mode 100644 index 04a23c597c..0000000000 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AuditAnnotation) ProtoMessage() {} - -func (*ExpressionWarning) ProtoMessage() {} - -func (*MatchCondition) ProtoMessage() {} - -func (*MatchResources) ProtoMessage() {} - -func (*MutatingWebhook) ProtoMessage() {} - -func (*MutatingWebhookConfiguration) ProtoMessage() {} - -func (*MutatingWebhookConfigurationList) ProtoMessage() {} - -func (*NamedRuleWithOperations) ProtoMessage() {} - -func (*ParamKind) ProtoMessage() {} - -func (*ParamRef) ProtoMessage() {} - -func (*Rule) ProtoMessage() {} - -func (*RuleWithOperations) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} - -func (*TypeChecking) ProtoMessage() {} - -func (*ValidatingAdmissionPolicy) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicySpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {} - -func (*ValidatingWebhook) ProtoMessage() {} - -func (*ValidatingWebhookConfiguration) ProtoMessage() {} - -func (*ValidatingWebhookConfigurationList) ProtoMessage() {} - -func (*Validation) ProtoMessage() {} - -func (*Variable) ProtoMessage() {} - -func (*WebhookClientConfig) ProtoMessage() {} diff --git a/vendor/k8s.io/api/admissionregistration/v1/register.go b/vendor/k8s.io/api/admissionregistration/v1/register.go index da74379ce2..c1137d2bd4 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/register.go +++ b/vendor/k8s.io/api/admissionregistration/v1/register.go @@ -54,6 +54,10 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ValidatingAdmissionPolicyList{}, &ValidatingAdmissionPolicyBinding{}, &ValidatingAdmissionPolicyBindingList{}, + &MutatingAdmissionPolicy{}, + &MutatingAdmissionPolicyList{}, + &MutatingAdmissionPolicyBinding{}, + &MutatingAdmissionPolicyBindingList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/vendor/k8s.io/api/admissionregistration/v1/types.go b/vendor/k8s.io/api/admissionregistration/v1/types.go index 311c05c0ff..f7a07b6453 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types.go @@ -23,19 +23,19 @@ import ( // Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended // to make sure that all the tuple expansions are valid. type Rule struct { - // APIGroups is the API groups the resources belong to. '*' is all groups. + // apiGroups is the API groups the resources belong to. '*' is all groups. // If '*' is present, the length of the slice must be one. // Required. // +listType=atomic APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"` - // APIVersions is the API versions the resources belong to. '*' is all versions. + // apiVersions is the API versions the resources belong to. '*' is all versions. // If '*' is present, the length of the slice must be one. // Required. // +listType=atomic APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,2,rep,name=apiVersions"` - // Resources is a list of resources this rule applies to. + // resources is a list of resources this rule applies to. // // For example: // 'pods' means pods. @@ -141,12 +141,12 @@ const ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicy struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -156,14 +156,14 @@ type ValidatingAdmissionPolicy struct { // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. type ValidatingAdmissionPolicyStatus struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -176,7 +176,7 @@ type ValidatingAdmissionPolicyConditionType string // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeChecking struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"` @@ -184,11 +184,11 @@ type TypeChecking struct { // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarning struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"` @@ -200,7 +200,7 @@ type ExpressionWarning struct { // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. type ValidatingAdmissionPolicyList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -210,21 +210,21 @@ type ValidatingAdmissionPolicyList struct { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpec struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -255,7 +255,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -277,7 +277,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -295,19 +295,19 @@ type ValidatingAdmissionPolicySpec struct { // ParamKind is a tuple of Group Kind and Version. // +structType=atomic type ParamKind struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"` } // Validation specifies the CEL expression which is used to apply the validation. type Validation struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -349,7 +349,7 @@ type Validation struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -358,7 +358,7 @@ type Validation struct { // If unset, the message is "failed Expression: {Expression}". // +optional Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -383,12 +383,12 @@ type Validation struct { // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. // +structType=atomic type Variable struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name string `json:"name" protobuf:"bytes,1,opt,name=Name"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"` } @@ -448,10 +448,11 @@ type AuditAnnotation struct { // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBinding struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -461,7 +462,7 @@ type ValidatingAdmissionPolicyBinding struct { // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -471,9 +472,11 @@ type ValidatingAdmissionPolicyBindingList struct { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpec struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"` // paramRef specifies the parameter resource used to configure the admission control policy. @@ -483,7 +486,7 @@ type ValidatingAdmissionPolicyBindingSpec struct { // +optional ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -531,6 +534,8 @@ type ValidatingAdmissionPolicyBindingSpec struct { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"` } @@ -579,7 +584,7 @@ type ParamRef struct { // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -597,7 +602,7 @@ type ParamRef struct { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic type MatchResources struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -642,7 +647,7 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -655,12 +660,12 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"` - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"` - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -704,7 +709,7 @@ const ( // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic type NamedRuleWithOperations struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"` @@ -720,10 +725,10 @@ type NamedRuleWithOperations struct { // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. type ValidatingWebhookConfiguration struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -738,7 +743,7 @@ type ValidatingWebhookConfiguration struct { // ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration. type ValidatingWebhookConfigurationList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -754,10 +759,10 @@ type ValidatingWebhookConfigurationList struct { // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. type MutatingWebhookConfiguration struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -772,7 +777,7 @@ type MutatingWebhookConfiguration struct { // MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration. type MutatingWebhookConfigurationList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -782,18 +787,18 @@ type MutatingWebhookConfigurationList struct { // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. type ValidatingWebhook struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -802,7 +807,7 @@ type ValidatingWebhook struct { // +listType=atomic Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. // +optional FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` @@ -824,7 +829,7 @@ type ValidatingWebhook struct { // +optional MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -870,7 +875,7 @@ type ValidatingWebhook struct { // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -884,7 +889,7 @@ type ValidatingWebhook struct { // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,10,opt,name=objectSelector"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -892,7 +897,7 @@ type ValidatingWebhook struct { // sideEffects == Unknown or Some. SideEffects *SideEffectClass `json:"sideEffects" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -900,7 +905,7 @@ type ValidatingWebhook struct { // +optional TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -910,7 +915,7 @@ type ValidatingWebhook struct { // +listType=atomic AdmissionReviewVersions []string `json:"admissionReviewVersions" protobuf:"bytes,8,rep,name=admissionReviewVersions"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -932,18 +937,18 @@ type ValidatingWebhook struct { // MutatingWebhook describes an admission webhook and the resources and operations it applies to. type MutatingWebhook struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -952,7 +957,7 @@ type MutatingWebhook struct { // +listType=atomic Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. // +optional FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` @@ -974,7 +979,7 @@ type MutatingWebhook struct { // +optional MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -1020,7 +1025,7 @@ type MutatingWebhook struct { // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -1034,7 +1039,7 @@ type MutatingWebhook struct { // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,11,opt,name=objectSelector"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -1042,7 +1047,7 @@ type MutatingWebhook struct { // sideEffects == Unknown or Some. SideEffects *SideEffectClass `json:"sideEffects" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -1050,7 +1055,7 @@ type MutatingWebhook struct { // +optional TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -1078,7 +1083,7 @@ type MutatingWebhook struct { // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -1098,6 +1103,335 @@ type MutatingWebhook struct { MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,opt,name=matchConditions"` } +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. +type MutatingAdmissionPolicy struct { + metav1.TypeMeta `json:",inline"` + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // spec defines the desired behavior of the MutatingAdmissionPolicy. + Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. +type MutatingAdmissionPolicyList struct { + metav1.TypeMeta `json:",inline"` + // metadata is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // List of ValidatingAdmissionPolicy. + Items []MutatingAdmissionPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// MutatingAdmissionPolicySpec defines the desired behavior of the admission policy. +type MutatingAdmissionPolicySpec struct { + // paramKind specifies the kind of resources used to parameterize this policy. + // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. + // If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. + // If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null. + // +optional + ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"` + + // matchConstraints specifies what resources this policy is designed to validate. + // The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints. + // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API + // MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + // Required. + MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` + + // variables contain definitions of variables that can be used in composition of other expressions. + // Each variable is defined as a named CEL expression. + // The variables defined here will be available under `variables` in other expressions of the policy + // except matchConditions because matchConditions are evaluated before the rest of the policy. + // + // The expression of a variable can refer to other variables defined earlier in the list but not those after. + // Thus, variables must be sorted by the order of first appearance and acyclic. + // +listType=atomic + // +optional + Variables []Variable `json:"variables,omitempty" protobuf:"bytes,3,rep,name=variables"` + + // mutations contain operations to perform on matching objects. + // mutations may not be empty; a minimum of one mutation is required. + // mutations are evaluated in order, and are reinvoked according to + // the reinvocationPolicy. + // The mutations of a policy are invoked for each binding of this policy + // and reinvocation of mutations occurs on a per binding basis. + // + // +listType=atomic + // +optional + Mutations []Mutation `json:"mutations,omitempty" protobuf:"bytes,4,rep,name=mutations"` + + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // + // A policy is invalid if paramKind refers to a non-existent Kind. + // A binding is invalid if paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // Allowed values are Ignore or Fail. Defaults to Fail. + // +optional + FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,5,opt,name=failurePolicy,casttype=FailurePolicyType"` + + // matchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the matchConstraints. + // An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` + + // reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding + // as part of a single admission evaluation. + // Allowed values are "Never" and "IfNeeded". + // + // Never: These mutations will not be called more than once per binding in a single admission evaluation. + // + // IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of + // order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only + // reinvoked when mutations change the object after this mutation is invoked. + // Required. + ReinvocationPolicy ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,7,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` +} + +// Mutation specifies the CEL expression which is used to apply the Mutation. +type Mutation struct { + // patchType indicates the patch strategy used. + // Allowed values are "ApplyConfiguration" and "JSONPatch". + // Required. + // + // +unionDiscriminator + PatchType PatchType `json:"patchType" protobuf:"bytes,2,opt,name=patchType,casttype=PatchType"` + + // applyConfiguration defines the desired configuration values of an object. + // The configuration is applied to the admission object using + // [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff). + // A CEL expression is used to create apply configuration. + ApplyConfiguration *ApplyConfiguration `json:"applyConfiguration,omitempty" protobuf:"bytes,3,opt,name=applyConfiguration"` + + // jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object. + // A CEL expression is used to create the JSON patch. + JSONPatch *JSONPatch `json:"jsonPatch,omitempty" protobuf:"bytes,4,opt,name=jsonPatch"` +} + +// PatchType specifies the type of patch operation for a mutation. +// +enum +type PatchType string + +const ( + // ApplyConfiguration indicates that the mutation is using apply configuration to mutate the object. + PatchTypeApplyConfiguration PatchType = "ApplyConfiguration" + // JSONPatch indicates that the object is mutated through JSON Patch. + PatchTypeJSONPatch PatchType = "JSONPatch" +) + +// ApplyConfiguration defines the desired configuration values of an object. +type ApplyConfiguration struct { + // expression will be evaluated by CEL to create an apply configuration. + // ref: https://github.com/google/cel-spec + // + // Apply configurations are declared in CEL using object initialization. For example, this CEL expression + // returns an apply configuration to set a single field: + // + // Object{ + // spec: Object.spec{ + // serviceAccountName: "example" + // } + // } + // + // Apply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of + // values not included in the apply configuration. + // + // CEL expressions have access to the object types needed to create apply configurations: + // + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the + // object. No other metadata properties are accessible. + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + Expression string `json:"expression,omitempty" protobuf:"bytes,1,opt,name=expression"` +} + +// JSONPatch defines a JSON Patch. +type JSONPatch struct { + // expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/). + // ref: https://github.com/google/cel-spec + // + // expression must return an array of JSONPatch values. + // + // For example, this CEL expression returns a JSON patch to conditionally modify a value: + // + // [ + // JSONPatch{op: "test", path: "/spec/example", value: "Red"}, + // JSONPatch{op: "replace", path: "/spec/example", value: "Green"} + // ] + // + // To define an object for the patch value, use Object types. For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/spec/selector", + // value: Object.spec.selector{matchLabels: {"environment": "test"}} + // } + // ] + // + // To use strings containing '/' and '~' as JSONPatch path keys, use "jsonpatch.escapeKey". For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"), + // value: "test" + // }, + // ] + // + // CEL expressions have access to the types needed to create JSON patches and objects: + // + // - 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'. + // See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string, + // integer, array, map or object. If set, the 'path' and 'from' fields must be set to a + // [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL + // function may be used to escape path keys containing '/' and '~'. + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // CEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries) + // as well as: + // + // - 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively). + // + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + Expression string `json:"expression,omitempty" protobuf:"bytes,1,opt,name=expression"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. +// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators +// configure policies for clusters. +// +// For a given admission request, each binding will cause its policy to be +// evaluated N times, where N is 1 for policies/bindings that don't use +// params, otherwise N is the number of parameters selected by the binding. +// Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget). +// +// Adding/removing policies, bindings, or params can not affect whether a +// given (policy, binding, param) combination is within its own CEL budget. +type MutatingAdmissionPolicyBinding struct { + metav1.TypeMeta `json:",inline"` + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. + Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. +type MutatingAdmissionPolicyBindingList struct { + metav1.TypeMeta `json:",inline"` + // metadata is the standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // List of PolicyBinding. + Items []MutatingAdmissionPolicyBinding `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding. +type MutatingAdmissionPolicyBindingSpec struct { + // policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to. + // If the referenced resource does not exist, this binding is considered invalid and will be ignored + // Required. + PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"` + + // paramRef specifies the parameter resource used to configure the admission control policy. + // It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy. + // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied. + // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. + // +optional + ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"` + + // matchResources limits what resources match this binding and may be mutated by it. + // Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and + // matchConditions before the resource may be mutated. + // When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints + // and matchConditions must match for the resource to be mutated. + // Additionally, matchResources.resourceRules are optional and do not constraint matching when unset. + // Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + // +optional + MatchResources *MatchResources `json:"matchResources,omitempty" protobuf:"bytes,3,rep,name=matchResources"` +} + // ReinvocationPolicyType specifies what type of policy is used when other admission plugins also perform // modifications. // +enum @@ -1116,7 +1450,7 @@ const ( // RuleWithOperations is a tuple of Operations and Resources. It is recommended to make // sure that all the tuple expansions are valid. type RuleWithOperations struct { - // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * + // operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * // for all of those operations and any future admission operations that are added. // If '*' is present, the length of the slice must be one. // Required. @@ -1143,7 +1477,7 @@ const ( // WebhookClientConfig contains the information to make a TLS // connection with the webhook type WebhookClientConfig struct { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -1172,7 +1506,7 @@ type WebhookClientConfig struct { // +optional URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"` - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. @@ -1180,7 +1514,7 @@ type WebhookClientConfig struct { // +optional Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"` - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. // +optional CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"` @@ -1188,19 +1522,19 @@ type WebhookClientConfig struct { // ServiceReference holds a reference to Service.legacy.k8s.io type ServiceReference struct { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"` - // `name` is the name of the service. + // name is the name of the service. // Required Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. // +optional Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"` - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. // `port` should be a valid port number (1-65535, inclusive). // +optional @@ -1209,7 +1543,7 @@ type ServiceReference struct { // MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. type MatchCondition struct { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -1220,7 +1554,7 @@ type MatchCondition struct { // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. diff --git a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go index f43139505d..182f8ad0f0 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go @@ -27,6 +27,15 @@ package v1 // Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_ApplyConfiguration = map[string]string{ + "": "ApplyConfiguration defines the desired configuration values of an object.", + "expression": "expression will be evaluated by CEL to create an apply configuration. ref: https://github.com/google/cel-spec\n\nApply configurations are declared in CEL using object initialization. For example, this CEL expression returns an apply configuration to set a single field:\n\n\tObject{\n\t spec: Object.spec{\n\t serviceAccountName: \"example\"\n\t }\n\t}\n\nApply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of values not included in the apply configuration.\n\nCEL expressions have access to the object types needed to create apply configurations:\n\n- 'Object' - CEL type of the resource object. - 'Object.' - CEL type of object field (such as 'Object.spec') - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')\n\nCEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Required.", +} + +func (ApplyConfiguration) SwaggerDoc() map[string]string { + return map_ApplyConfiguration +} + var map_AuditAnnotation = map[string]string{ "": "AuditAnnotation describes how to produce an audit annotation for an API request.", "key": "key specifies the audit annotation key. The audit annotation keys of a ValidatingAdmissionPolicy must be unique. The key must be a qualified name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length.\n\nThe key is combined with the resource name of the ValidatingAdmissionPolicy to construct an audit annotation key: \"{ValidatingAdmissionPolicy name}/{key}\".\n\nIf an admission webhook uses the same resource name as this ValidatingAdmissionPolicy and the same audit annotation key, the annotation key will be identical. In this case, the first annotation written with the key will be included in the audit event and all subsequent annotations with the same key will be discarded.\n\nRequired.", @@ -39,18 +48,27 @@ func (AuditAnnotation) SwaggerDoc() map[string]string { var map_ExpressionWarning = map[string]string{ "": "ExpressionWarning is a warning information that targets a specific expression.", - "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", - "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", + "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", + "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", } func (ExpressionWarning) SwaggerDoc() map[string]string { return map_ExpressionWarning } +var map_JSONPatch = map[string]string{ + "": "JSONPatch defines a JSON Patch.", + "expression": "expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/). ref: https://github.com/google/cel-spec\n\nexpression must return an array of JSONPatch values.\n\nFor example, this CEL expression returns a JSON patch to conditionally modify a value:\n\n\t [\n\t JSONPatch{op: \"test\", path: \"/spec/example\", value: \"Red\"},\n\t JSONPatch{op: \"replace\", path: \"/spec/example\", value: \"Green\"}\n\t ]\n\nTo define an object for the patch value, use Object types. For example:\n\n\t [\n\t JSONPatch{\n\t op: \"add\",\n\t path: \"/spec/selector\",\n\t value: Object.spec.selector{matchLabels: {\"environment\": \"test\"}}\n\t }\n\t ]\n\nTo use strings containing '/' and '~' as JSONPatch path keys, use \"jsonpatch.escapeKey\". For example:\n\n\t [\n\t JSONPatch{\n\t op: \"add\",\n\t path: \"/metadata/labels/\" + jsonpatch.escapeKey(\"example.com/environment\"),\n\t value: \"test\"\n\t },\n\t ]\n\nCEL expressions have access to the types needed to create JSON patches and objects:\n\n- 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'.\n See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string,\n integer, array, map or object. If set, the 'path' and 'from' fields must be set to a\n [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL\n function may be used to escape path keys containing '/' and '~'.\n- 'Object' - CEL type of the resource object. - 'Object.' - CEL type of object field (such as 'Object.spec') - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')\n\nCEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nCEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries) as well as:\n\n- 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively).\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Required.", +} + +func (JSONPatch) SwaggerDoc() map[string]string { + return map_JSONPatch +} + var map_MatchCondition = map[string]string{ "": "MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.", - "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", - "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", + "name": "name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", } func (MatchCondition) SwaggerDoc() map[string]string { @@ -59,10 +77,10 @@ func (MatchCondition) SwaggerDoc() map[string]string { var map_MatchResources = map[string]string{ "": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", - "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", - "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "resourceRules": "resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", + "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"", } @@ -70,20 +88,86 @@ func (MatchResources) SwaggerDoc() map[string]string { return map_MatchResources } +var map_MutatingAdmissionPolicy = map[string]string{ + "": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.", +} + +func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicy +} + +var map_MutatingAdmissionPolicyBinding = map[string]string{ + "": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.", +} + +func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicyBinding +} + +var map_MutatingAdmissionPolicyBindingList = map[string]string{ + "": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "items": "List of PolicyBinding.", +} + +func (MutatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicyBindingList +} + +var map_MutatingAdmissionPolicyBindingSpec = map[string]string{ + "": "MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding.", + "policyName": "policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.", + "matchResources": "matchResources limits what resources match this binding and may be mutated by it. Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and matchConditions before the resource may be mutated. When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints and matchConditions must match for the resource to be mutated. Additionally, matchResources.resourceRules are optional and do not constraint matching when unset. Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required. The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. '*' matches CREATE, UPDATE and CONNECT.", +} + +func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicyBindingSpec +} + +var map_MutatingAdmissionPolicyList = map[string]string{ + "": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "items": "List of ValidatingAdmissionPolicy.", +} + +func (MutatingAdmissionPolicyList) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicyList +} + +var map_MutatingAdmissionPolicySpec = map[string]string{ + "": "MutatingAdmissionPolicySpec defines the desired behavior of the admission policy.", + "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null.", + "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding. The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. '*' matches CREATE, UPDATE and CONNECT. Required.", + "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except matchConditions because matchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, variables must be sorted by the order of first appearance and acyclic.", + "mutations": "mutations contain operations to perform on matching objects. mutations may not be empty; a minimum of one mutation is required. mutations are evaluated in order, and are reinvoked according to the reinvocationPolicy. The mutations of a policy are invoked for each binding of this policy and reinvocation of mutations occurs on a per binding basis.", + "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if paramKind refers to a non-existent Kind. A binding is invalid if paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the matchConstraints. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", + "reinvocationPolicy": "reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: These mutations will not be called more than once per binding in a single admission evaluation.\n\nIfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only reinvoked when mutations change the object after this mutation is invoked. Required.", +} + +func (MutatingAdmissionPolicySpec) SwaggerDoc() map[string]string { + return map_MutatingAdmissionPolicySpec +} + var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", - "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", - "clientConfig": "ClientConfig defines how to communicate with the hook. Required", - "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", - "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.", + "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", + "clientConfig": "clientConfig defines how to communicate with the hook. Required", + "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", + "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.", "matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Equivalent\"", - "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", - "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", - "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", + "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", + "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", + "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -92,8 +176,8 @@ func (MutatingWebhook) SwaggerDoc() map[string]string { var map_MutatingWebhookConfiguration = map[string]string{ "": "MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "webhooks": "webhooks is a list of webhooks and the affected resources and operations.", } func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string { @@ -102,7 +186,7 @@ func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string { var map_MutatingWebhookConfigurationList = map[string]string{ "": "MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of MutatingWebhookConfiguration.", } @@ -110,9 +194,20 @@ func (MutatingWebhookConfigurationList) SwaggerDoc() map[string]string { return map_MutatingWebhookConfigurationList } +var map_Mutation = map[string]string{ + "": "Mutation specifies the CEL expression which is used to apply the Mutation.", + "patchType": "patchType indicates the patch strategy used. Allowed values are \"ApplyConfiguration\" and \"JSONPatch\". Required.", + "applyConfiguration": "applyConfiguration defines the desired configuration values of an object. The configuration is applied to the admission object using [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff). A CEL expression is used to create apply configuration.", + "jsonPatch": "jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object. A CEL expression is used to create the JSON patch.", +} + +func (Mutation) SwaggerDoc() map[string]string { + return map_Mutation +} + var map_NamedRuleWithOperations = map[string]string{ "": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.", - "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", + "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", } func (NamedRuleWithOperations) SwaggerDoc() map[string]string { @@ -121,8 +216,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string { var map_ParamKind = map[string]string{ "": "ParamKind is a tuple of Group Kind and Version.", - "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.", - "kind": "Kind is the API kind the resources belong to. Required.", + "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.", + "kind": "kind is the API kind the resources belong to. Required.", } func (ParamKind) SwaggerDoc() map[string]string { @@ -134,7 +229,7 @@ var map_ParamRef = map[string]string{ "name": "name is the name of the resource being referenced.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.\n\nA single parameter used for all admission requests can be configured by setting the `name` field, leaving `selector` blank, and setting namespace if `paramKind` is namespace-scoped.", "namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.", "selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.", - "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired", + "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired", } func (ParamRef) SwaggerDoc() map[string]string { @@ -143,9 +238,9 @@ func (ParamRef) SwaggerDoc() map[string]string { var map_Rule = map[string]string{ "": "Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended to make sure that all the tuple expansions are valid.", - "apiGroups": "APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.", - "apiVersions": "APIVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.", - "resources": "Resources is a list of resources this rule applies to.\n\nFor example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.\n\nIf wildcard is present, the validation rule will ensure resources do not overlap with each other.\n\nDepending on the enclosing object, subresources might not be allowed. Required.", + "apiGroups": "apiGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.", + "apiVersions": "apiVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.", + "resources": "resources is a list of resources this rule applies to.\n\nFor example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.\n\nIf wildcard is present, the validation rule will ensure resources do not overlap with each other.\n\nDepending on the enclosing object, subresources might not be allowed. Required.", "scope": "scope specifies the scope of this rule. Valid values are \"Cluster\", \"Namespaced\", and \"*\" \"Cluster\" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. \"Namespaced\" means that only namespaced resources will match this rule. \"*\" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is \"*\".", } @@ -155,7 +250,7 @@ func (Rule) SwaggerDoc() map[string]string { var map_RuleWithOperations = map[string]string{ "": "RuleWithOperations is a tuple of Operations and Resources. It is recommended to make sure that all the tuple expansions are valid.", - "operations": "Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.", + "operations": "operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.", } func (RuleWithOperations) SwaggerDoc() map[string]string { @@ -164,10 +259,10 @@ func (RuleWithOperations) SwaggerDoc() map[string]string { var map_ServiceReference = map[string]string{ "": "ServiceReference holds a reference to Service.legacy.k8s.io", - "namespace": "`namespace` is the namespace of the service. Required", - "name": "`name` is the name of the service. Required", - "path": "`path` is an optional URL path which will be sent in any request to this service.", - "port": "If specified, the port on the service that hosting webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).", + "namespace": "namespace is the namespace of the service. Required", + "name": "name is the name of the service. Required", + "path": "path is an optional URL path which will be sent in any request to this service.", + "port": "port is the port on the service that hosts the webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).", } func (ServiceReference) SwaggerDoc() map[string]string { @@ -176,7 +271,7 @@ func (ServiceReference) SwaggerDoc() map[string]string { var map_TypeChecking = map[string]string{ "": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy", - "expressionWarnings": "The type checking warnings for each expression.", + "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.", } func (TypeChecking) SwaggerDoc() map[string]string { @@ -185,9 +280,9 @@ func (TypeChecking) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicy = map[string]string{ "": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.", - "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.", + "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", } func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -196,8 +291,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBinding = map[string]string{ "": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.", } func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { @@ -206,7 +301,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingList = map[string]string{ "": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of PolicyBinding.", } @@ -216,9 +311,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{ "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", - "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", "paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.", - "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", "validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.", } @@ -228,7 +323,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyList = map[string]string{ "": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingAdmissionPolicy.", } @@ -238,13 +333,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicySpec = map[string]string{ "": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.", - "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", - "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", - "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", + "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", + "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", + "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", "auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", - "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", + "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", } func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { @@ -253,9 +348,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyStatus = map[string]string{ "": "ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.", - "observedGeneration": "The generation observed by the controller.", - "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.", - "conditions": "The conditions represent the latest available observations of a policy's current state.", + "observedGeneration": "observedGeneration is the generation observed by the controller.", + "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.", + "conditions": "conditions represent the latest available observations of a policy's current state.", } func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { @@ -264,17 +359,17 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { var map_ValidatingWebhook = map[string]string{ "": "ValidatingWebhook describes an admission webhook and the resources and operations it applies to.", - "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", - "clientConfig": "ClientConfig defines how to communicate with the hook. Required", - "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", - "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.", + "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", + "clientConfig": "clientConfig defines how to communicate with the hook. Required", + "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", + "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.", "matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Equivalent\"", - "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", - "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", - "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", + "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", + "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", + "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (ValidatingWebhook) SwaggerDoc() map[string]string { @@ -283,8 +378,8 @@ func (ValidatingWebhook) SwaggerDoc() map[string]string { var map_ValidatingWebhookConfiguration = map[string]string{ "": "ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "webhooks": "webhooks is a list of webhooks and the affected resources and operations.", } func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string { @@ -293,7 +388,7 @@ func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string { var map_ValidatingWebhookConfigurationList = map[string]string{ "": "ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingWebhookConfiguration.", } @@ -303,9 +398,9 @@ func (ValidatingWebhookConfigurationList) SwaggerDoc() map[string]string { var map_Validation = map[string]string{ "": "Validation specifies the CEL expression which is used to apply the validation.", - "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", - "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", - "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", + "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", + "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", "messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"", } @@ -315,8 +410,8 @@ func (Validation) SwaggerDoc() map[string]string { var map_Variable = map[string]string{ "": "Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.", - "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", - "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", + "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", + "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", } func (Variable) SwaggerDoc() map[string]string { @@ -325,9 +420,9 @@ func (Variable) SwaggerDoc() map[string]string { var map_WebhookClientConfig = map[string]string{ "": "WebhookClientConfig contains the information to make a TLS connection with the webhook", - "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", - "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.", - "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", + "url": "url gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "service": "service is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.", + "caBundle": "caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", } func (WebhookClientConfig) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go index bfe599c1d3..afdbfd9143 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go @@ -26,6 +26,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplyConfiguration) DeepCopyInto(out *ApplyConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplyConfiguration. +func (in *ApplyConfiguration) DeepCopy() *ApplyConfiguration { + if in == nil { + return nil + } + out := new(ApplyConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuditAnnotation) DeepCopyInto(out *AuditAnnotation) { *out = *in @@ -58,6 +74,22 @@ func (in *ExpressionWarning) DeepCopy() *ExpressionWarning { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JSONPatch) DeepCopyInto(out *JSONPatch) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONPatch. +func (in *JSONPatch) DeepCopy() *JSONPatch { + if in == nil { + return nil + } + out := new(JSONPatch) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { *out = *in @@ -119,6 +151,200 @@ func (in *MatchResources) DeepCopy() *MatchResources { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicy) DeepCopyInto(out *MutatingAdmissionPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicy. +func (in *MutatingAdmissionPolicy) DeepCopy() *MutatingAdmissionPolicy { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyBinding) DeepCopyInto(out *MutatingAdmissionPolicyBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBinding. +func (in *MutatingAdmissionPolicyBinding) DeepCopy() *MutatingAdmissionPolicyBinding { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicyBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyBindingList) DeepCopyInto(out *MutatingAdmissionPolicyBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MutatingAdmissionPolicyBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBindingList. +func (in *MutatingAdmissionPolicyBindingList) DeepCopy() *MutatingAdmissionPolicyBindingList { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicyBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyBindingSpec) DeepCopyInto(out *MutatingAdmissionPolicyBindingSpec) { + *out = *in + if in.ParamRef != nil { + in, out := &in.ParamRef, &out.ParamRef + *out = new(ParamRef) + (*in).DeepCopyInto(*out) + } + if in.MatchResources != nil { + in, out := &in.MatchResources, &out.MatchResources + *out = new(MatchResources) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBindingSpec. +func (in *MutatingAdmissionPolicyBindingSpec) DeepCopy() *MutatingAdmissionPolicyBindingSpec { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyBindingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyList) DeepCopyInto(out *MutatingAdmissionPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MutatingAdmissionPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyList. +func (in *MutatingAdmissionPolicyList) DeepCopy() *MutatingAdmissionPolicyList { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicySpec) DeepCopyInto(out *MutatingAdmissionPolicySpec) { + *out = *in + if in.ParamKind != nil { + in, out := &in.ParamKind, &out.ParamKind + *out = new(ParamKind) + **out = **in + } + if in.MatchConstraints != nil { + in, out := &in.MatchConstraints, &out.MatchConstraints + *out = new(MatchResources) + (*in).DeepCopyInto(*out) + } + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + copy(*out, *in) + } + if in.Mutations != nil { + in, out := &in.Mutations, &out.Mutations + *out = make([]Mutation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.FailurePolicy != nil { + in, out := &in.FailurePolicy, &out.FailurePolicy + *out = new(FailurePolicyType) + **out = **in + } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicySpec. +func (in *MutatingAdmissionPolicySpec) DeepCopy() *MutatingAdmissionPolicySpec { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicySpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = *in @@ -254,6 +480,32 @@ func (in *MutatingWebhookConfigurationList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Mutation) DeepCopyInto(out *Mutation) { + *out = *in + if in.ApplyConfiguration != nil { + in, out := &in.ApplyConfiguration, &out.ApplyConfiguration + *out = new(ApplyConfiguration) + **out = **in + } + if in.JSONPatch != nil { + in, out := &in.JSONPatch, &out.JSONPatch + *out = new(JSONPatch) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mutation. +func (in *Mutation) DeepCopy() *Mutation { + if in == nil { + return nil + } + out := new(Mutation) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamedRuleWithOperations) DeepCopyInto(out *NamedRuleWithOperations) { *out = *in diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go index 3264285cd0..b7baac8d1c 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go +++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go @@ -21,6 +21,11 @@ limitations under the License. package v1 +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ApplyConfiguration) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.ApplyConfiguration" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in AuditAnnotation) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.AuditAnnotation" @@ -31,6 +36,11 @@ func (in ExpressionWarning) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.ExpressionWarning" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in JSONPatch) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.JSONPatch" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in MatchCondition) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.MatchCondition" @@ -41,6 +51,36 @@ func (in MatchResources) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.MatchResources" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicy) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicy" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicyBinding) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBinding" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicyBindingList) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicyBindingSpec) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingSpec" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicyList) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in MutatingAdmissionPolicySpec) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicySpec" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in MutatingWebhook) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.MutatingWebhook" @@ -56,6 +96,11 @@ func (in MutatingWebhookConfigurationList) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in Mutation) OpenAPIModelName() string { + return "io.k8s.api.admissionregistration.v1.Mutation" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in NamedRuleWithOperations) OpenAPIModelName() string { return "io.k8s.api.admissionregistration.v1.NamedRuleWithOperations" diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go index 0862bb1f2d..5fde55f151 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go @@ -21,6 +21,30 @@ limitations under the License. package v1 +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *MutatingAdmissionPolicy) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *MutatingAdmissionPolicyBinding) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *MutatingAdmissionPolicyBindingList) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *MutatingAdmissionPolicyList) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *MutatingWebhookConfiguration) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto index d23f21cc84..57c7cd2b1d 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto @@ -113,12 +113,12 @@ message AuditAnnotation { // ExpressionWarning is a warning information that targets a specific expression. message ExpressionWarning { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" optional string fieldRef = 2; - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. optional string warning = 3; @@ -194,7 +194,7 @@ message JSONPatch { } message MatchCondition { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -205,7 +205,7 @@ message MatchCondition { // Required. optional string name = 1; - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. @@ -226,7 +226,7 @@ message MatchCondition { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic message MatchResources { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -272,7 +272,7 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1; - // ObjectSelector decides whether to run the policy based on if the + // objectSelector decides whether to run the policy based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the policy's expression (CEL), and // is considered to match if either object matches the selector. A null @@ -286,13 +286,13 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2; - // ResourceRules describes what operations on what resources/subresources the admission policy matches. + // resourceRules describes what operations on what resources/subresources the admission policy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional repeated NamedRuleWithOperations resourceRules = 3; - // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the policy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -319,11 +319,11 @@ message MatchResources { // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. message MutatingAdmissionPolicy { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. optional MutatingAdmissionPolicySpec spec = 2; } @@ -339,17 +339,17 @@ message MutatingAdmissionPolicy { // Adding/removing policies, bindings, or params can not affect whether a // given (policy, binding, param) combination is within its own CEL budget. message MutatingAdmissionPolicyBinding { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. optional MutatingAdmissionPolicyBindingSpec spec = 2; } // MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. message MutatingAdmissionPolicyBindingList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -387,7 +387,7 @@ message MutatingAdmissionPolicyBindingSpec { // MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. message MutatingAdmissionPolicyList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -507,7 +507,7 @@ message Mutation { // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic message NamedRuleWithOperations { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional repeated string resourceNames = 1; @@ -519,12 +519,12 @@ message NamedRuleWithOperations { // ParamKind is a tuple of Group Kind and Version. // +structType=atomic message ParamKind { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. optional string apiVersion = 1; - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. optional string kind = 2; } @@ -533,7 +533,7 @@ message ParamKind { // expressions of rules applied by a policy binding. // +structType=atomic message ParamRef { - // `name` is the name of the resource being referenced. + // name is the name of the resource being referenced. // // `name` and `selector` are mutually exclusive properties. If one is set, // the other must be unset. @@ -571,7 +571,7 @@ message ParamRef { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3; - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -587,7 +587,7 @@ message ParamRef { // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy message TypeChecking { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic repeated ExpressionWarning expressionWarnings = 1; @@ -595,14 +595,14 @@ message TypeChecking { // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. message ValidatingAdmissionPolicy { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. optional ValidatingAdmissionPolicySpec spec = 2; - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -622,17 +622,18 @@ message ValidatingAdmissionPolicy { // Adding/removing policies, bindings, or params can not affect whether a // given (policy, binding, param) combination is within its own CEL budget. message ValidatingAdmissionPolicyBinding { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required optional ValidatingAdmissionPolicyBindingSpec spec = 2; } // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -643,9 +644,11 @@ message ValidatingAdmissionPolicyBindingList { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingSpec { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string policyName = 1; // paramRef specifies the parameter resource used to configure the admission control policy. @@ -655,7 +658,7 @@ message ValidatingAdmissionPolicyBindingSpec { // +optional optional ParamRef paramRef = 2; - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -703,12 +706,14 @@ message ValidatingAdmissionPolicyBindingSpec { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string validationActions = 4; } // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. message ValidatingAdmissionPolicyList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -719,21 +724,21 @@ message ValidatingAdmissionPolicyList { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. message ValidatingAdmissionPolicySpec { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional optional ParamKind paramKind = 1; - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. optional MatchResources matchConstraints = 2; - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -764,7 +769,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated AuditAnnotation auditAnnotations = 5; - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -786,7 +791,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated MatchCondition matchConditions = 6; - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -803,16 +808,16 @@ message ValidatingAdmissionPolicySpec { // ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. message ValidatingAdmissionPolicyStatus { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional optional int64 observedGeneration = 1; - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional optional TypeChecking typeChecking = 2; - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -821,7 +826,7 @@ message ValidatingAdmissionPolicyStatus { // Validation specifies the CEL expression which is used to apply the validation. message Validation { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -864,7 +869,7 @@ message Validation { // Required. optional string Expression = 1; - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -874,7 +879,7 @@ message Validation { // +optional optional string message = 2; - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -899,12 +904,12 @@ message Validation { // Variable is the definition of a variable that is used for composition. message Variable { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` optional string Name = 1; - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. optional string Expression = 2; } diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index 651a01f0b3..0000000000 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*ApplyConfiguration) ProtoMessage() {} - -func (*AuditAnnotation) ProtoMessage() {} - -func (*ExpressionWarning) ProtoMessage() {} - -func (*JSONPatch) ProtoMessage() {} - -func (*MatchCondition) ProtoMessage() {} - -func (*MatchResources) ProtoMessage() {} - -func (*MutatingAdmissionPolicy) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBinding) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBindingList) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBindingSpec) ProtoMessage() {} - -func (*MutatingAdmissionPolicyList) ProtoMessage() {} - -func (*MutatingAdmissionPolicySpec) ProtoMessage() {} - -func (*Mutation) ProtoMessage() {} - -func (*NamedRuleWithOperations) ProtoMessage() {} - -func (*ParamKind) ProtoMessage() {} - -func (*ParamRef) ProtoMessage() {} - -func (*TypeChecking) ProtoMessage() {} - -func (*ValidatingAdmissionPolicy) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicySpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {} - -func (*Validation) ProtoMessage() {} - -func (*Variable) ProtoMessage() {} diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go index 459f7944c7..6a789b2d7f 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go @@ -83,12 +83,12 @@ const ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicy struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -98,14 +98,14 @@ type ValidatingAdmissionPolicy struct { // ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. type ValidatingAdmissionPolicyStatus struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -115,7 +115,7 @@ type ValidatingAdmissionPolicyStatus struct { // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeChecking struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"` @@ -123,11 +123,11 @@ type TypeChecking struct { // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarning struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"` @@ -139,7 +139,7 @@ type ExpressionWarning struct { // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. type ValidatingAdmissionPolicyList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -149,21 +149,21 @@ type ValidatingAdmissionPolicyList struct { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpec struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -194,7 +194,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -216,7 +216,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -236,19 +236,19 @@ type MatchCondition v1.MatchCondition // ParamKind is a tuple of Group Kind and Version. // +structType=atomic type ParamKind struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"` } // Validation specifies the CEL expression which is used to apply the validation. type Validation struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -290,7 +290,7 @@ type Validation struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -299,7 +299,7 @@ type Validation struct { // If unset, the message is "failed Expression: {Expression}". // +optional Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -323,12 +323,12 @@ type Validation struct { // Variable is the definition of a variable that is used for composition. type Variable struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name string `json:"name" protobuf:"bytes,1,opt,name=Name"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"` } @@ -388,10 +388,11 @@ type AuditAnnotation struct { // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBinding struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -401,7 +402,7 @@ type ValidatingAdmissionPolicyBinding struct { // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -411,9 +412,11 @@ type ValidatingAdmissionPolicyBindingList struct { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpec struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"` // paramRef specifies the parameter resource used to configure the admission control policy. @@ -423,7 +426,7 @@ type ValidatingAdmissionPolicyBindingSpec struct { // +optional ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -471,6 +474,8 @@ type ValidatingAdmissionPolicyBindingSpec struct { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"` } @@ -478,7 +483,7 @@ type ValidatingAdmissionPolicyBindingSpec struct { // expressions of rules applied by a policy binding. // +structType=atomic type ParamRef struct { - // `name` is the name of the resource being referenced. + // name is the name of the resource being referenced. // // `name` and `selector` are mutually exclusive properties. If one is set, // the other must be unset. @@ -516,7 +521,7 @@ type ParamRef struct { // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -534,7 +539,7 @@ type ParamRef struct { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic type MatchResources struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -579,7 +584,7 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the policy based on if the + // objectSelector decides whether to run the policy based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the policy's expression (CEL), and // is considered to match if either object matches the selector. A null @@ -592,12 +597,12 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"` - // ResourceRules describes what operations on what resources/subresources the admission policy matches. + // resourceRules describes what operations on what resources/subresources the admission policy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"` - // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the policy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -642,7 +647,7 @@ const ( // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic type NamedRuleWithOperations struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"` @@ -675,10 +680,10 @@ const ( // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. type MutatingAdmissionPolicy struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -688,7 +693,7 @@ type MutatingAdmissionPolicy struct { // MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. type MutatingAdmissionPolicyList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -963,10 +968,10 @@ const ( // given (policy, binding, param) combination is within its own CEL budget. type MutatingAdmissionPolicyBinding struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -976,7 +981,7 @@ type MutatingAdmissionPolicyBinding struct { // MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. type MutatingAdmissionPolicyBindingList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go index 116e56e065..4b2b13bc4a 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go @@ -48,8 +48,8 @@ func (AuditAnnotation) SwaggerDoc() map[string]string { var map_ExpressionWarning = map[string]string{ "": "ExpressionWarning is a warning information that targets a specific expression.", - "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", - "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", + "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", + "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", } func (ExpressionWarning) SwaggerDoc() map[string]string { @@ -67,10 +67,10 @@ func (JSONPatch) SwaggerDoc() map[string]string { var map_MatchResources = map[string]string{ "": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", - "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "resourceRules": "ResourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.", - "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "resourceRules": "resourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.", + "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 API groups. The API server translates the request to a matched resource API if necessary.\n\nDefaults to \"Equivalent\"", } @@ -80,8 +80,8 @@ func (MatchResources) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicy = map[string]string{ "": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the MutatingAdmissionPolicy.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.", } func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -90,8 +90,8 @@ func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyBinding = map[string]string{ "": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the MutatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.", } func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { @@ -100,7 +100,7 @@ func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyBindingList = map[string]string{ "": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of PolicyBinding.", } @@ -121,7 +121,7 @@ func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyList = map[string]string{ "": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingAdmissionPolicy.", } @@ -157,7 +157,7 @@ func (Mutation) SwaggerDoc() map[string]string { var map_NamedRuleWithOperations = map[string]string{ "": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.", - "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", + "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", } func (NamedRuleWithOperations) SwaggerDoc() map[string]string { @@ -166,8 +166,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string { var map_ParamKind = map[string]string{ "": "ParamKind is a tuple of Group Kind and Version.", - "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.", - "kind": "Kind is the API kind the resources belong to. Required.", + "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.", + "kind": "kind is the API kind the resources belong to. Required.", } func (ParamKind) SwaggerDoc() map[string]string { @@ -176,10 +176,10 @@ func (ParamKind) SwaggerDoc() map[string]string { var map_ParamRef = map[string]string{ "": "ParamRef describes how to locate the params to be used as input to expressions of rules applied by a policy binding.", - "name": "`name` is the name of the resource being referenced.\n\n`name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.", + "name": "name is the name of the resource being referenced.\n\n`name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.", "namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.", "selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.", - "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny` Default to `Deny`", + "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny` Default to `Deny`", } func (ParamRef) SwaggerDoc() map[string]string { @@ -188,7 +188,7 @@ func (ParamRef) SwaggerDoc() map[string]string { var map_TypeChecking = map[string]string{ "": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy", - "expressionWarnings": "The type checking warnings for each expression.", + "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.", } func (TypeChecking) SwaggerDoc() map[string]string { @@ -197,9 +197,9 @@ func (TypeChecking) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicy = map[string]string{ "": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.", - "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.", + "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", } func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -208,8 +208,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBinding = map[string]string{ "": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.", } func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { @@ -218,7 +218,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingList = map[string]string{ "": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of PolicyBinding.", } @@ -228,9 +228,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{ "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", - "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", "paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.", - "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", "validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.", } @@ -240,7 +240,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyList = map[string]string{ "": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingAdmissionPolicy.", } @@ -250,13 +250,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicySpec = map[string]string{ "": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.", - "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", - "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", - "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", + "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", + "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", + "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", "auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", - "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", + "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", } func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { @@ -265,9 +265,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyStatus = map[string]string{ "": "ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.", - "observedGeneration": "The generation observed by the controller.", - "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.", - "conditions": "The conditions represent the latest available observations of a policy's current state.", + "observedGeneration": "observedGeneration is the generation observed by the controller.", + "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.", + "conditions": "conditions represent the latest available observations of a policy's current state.", } func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { @@ -276,9 +276,9 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { var map_Validation = map[string]string{ "": "Validation specifies the CEL expression which is used to apply the validation.", - "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", - "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", - "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", + "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", + "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", "messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"", } @@ -288,8 +288,8 @@ func (Validation) SwaggerDoc() map[string]string { var map_Variable = map[string]string{ "": "Variable is the definition of a variable that is used for composition.", - "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", - "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", + "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", + "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", } func (Variable) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto index d184664e56..5fcb74f8ba 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto @@ -113,12 +113,12 @@ message AuditAnnotation { // ExpressionWarning is a warning information that targets a specific expression. message ExpressionWarning { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" optional string fieldRef = 2; - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. optional string warning = 3; @@ -195,7 +195,7 @@ message JSONPatch { // MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. message MatchCondition { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -206,7 +206,7 @@ message MatchCondition { // Required. optional string name = 1; - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. @@ -227,7 +227,7 @@ message MatchCondition { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic message MatchResources { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -273,7 +273,7 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1; - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -287,13 +287,13 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2; - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional repeated NamedRuleWithOperations resourceRules = 3; - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -319,11 +319,11 @@ message MatchResources { // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. message MutatingAdmissionPolicy { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. optional MutatingAdmissionPolicySpec spec = 2; } @@ -339,17 +339,17 @@ message MutatingAdmissionPolicy { // Adding/removing policies, bindings, or params can not affect whether a // given (policy, binding, param) combination is within its own CEL budget. message MutatingAdmissionPolicyBinding { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. optional MutatingAdmissionPolicyBindingSpec spec = 2; } // MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. message MutatingAdmissionPolicyBindingList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -387,7 +387,7 @@ message MutatingAdmissionPolicyBindingSpec { // MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. message MutatingAdmissionPolicyList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -486,18 +486,18 @@ message MutatingAdmissionPolicySpec { // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. optional string name = 1; - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required optional WebhookClientConfig clientConfig = 2; - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -506,7 +506,7 @@ message MutatingWebhook { // +listType=atomic repeated .k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3; - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. // +optional optional string failurePolicy = 4; @@ -528,7 +528,7 @@ message MutatingWebhook { // +optional optional string matchPolicy = 9; - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -574,7 +574,7 @@ message MutatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -588,7 +588,7 @@ message MutatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 11; - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -597,7 +597,7 @@ message MutatingWebhook { // +optional optional string sideEffects = 6; - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -605,7 +605,7 @@ message MutatingWebhook { // +optional optional int32 timeoutSeconds = 7; - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -635,7 +635,7 @@ message MutatingWebhook { // +optional optional string reinvocationPolicy = 10; - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -658,11 +658,11 @@ message MutatingWebhook { // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead. message MutatingWebhookConfiguration { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -673,7 +673,7 @@ message MutatingWebhookConfiguration { // MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration. message MutatingWebhookConfigurationList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -705,7 +705,7 @@ message Mutation { // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic message NamedRuleWithOperations { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional repeated string resourceNames = 1; @@ -717,12 +717,12 @@ message NamedRuleWithOperations { // ParamKind is a tuple of Group Kind and Version. // +structType=atomic message ParamKind { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. optional string apiVersion = 1; - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. optional string kind = 2; } @@ -771,7 +771,7 @@ message ParamRef { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3; - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -786,22 +786,22 @@ message ParamRef { // ServiceReference holds a reference to Service.legacy.k8s.io message ServiceReference { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required optional string namespace = 1; - // `name` is the name of the service. + // name is the name of the service. // Required optional string name = 2; - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. // +optional optional string path = 3; - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. - // `port` should be a valid port number (1-65535, inclusive). + // port should be a valid port number (1-65535, inclusive). // +optional optional int32 port = 4; } @@ -809,7 +809,7 @@ message ServiceReference { // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy message TypeChecking { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic repeated ExpressionWarning expressionWarnings = 1; @@ -821,14 +821,14 @@ message TypeChecking { // +k8s:prerelease-lifecycle-gen:introduced=1.28 // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. message ValidatingAdmissionPolicy { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. optional ValidatingAdmissionPolicySpec spec = 2; - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -848,17 +848,18 @@ message ValidatingAdmissionPolicy { // Adding/removing policies, bindings, or params can not affect whether a // given (policy, binding, param) combination is within its own CEL budget. message ValidatingAdmissionPolicyBinding { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required optional ValidatingAdmissionPolicyBindingSpec spec = 2; } // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -869,9 +870,11 @@ message ValidatingAdmissionPolicyBindingList { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. message ValidatingAdmissionPolicyBindingSpec { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string policyName = 1; // paramRef specifies the parameter resource used to configure the admission control policy. @@ -881,7 +884,7 @@ message ValidatingAdmissionPolicyBindingSpec { // +optional optional ParamRef paramRef = 2; - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -929,6 +932,8 @@ message ValidatingAdmissionPolicyBindingSpec { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string validationActions = 4; } @@ -936,7 +941,7 @@ message ValidatingAdmissionPolicyBindingSpec { // +k8s:prerelease-lifecycle-gen:introduced=1.28 // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. message ValidatingAdmissionPolicyList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -947,21 +952,21 @@ message ValidatingAdmissionPolicyList { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. message ValidatingAdmissionPolicySpec { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional optional ParamKind paramKind = 1; - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. optional MatchResources matchConstraints = 2; - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -992,7 +997,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated AuditAnnotation auditAnnotations = 5; - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -1014,7 +1019,7 @@ message ValidatingAdmissionPolicySpec { // +optional repeated MatchCondition matchConditions = 6; - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -1031,16 +1036,16 @@ message ValidatingAdmissionPolicySpec { // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. message ValidatingAdmissionPolicyStatus { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional optional int64 observedGeneration = 1; - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional optional TypeChecking typeChecking = 2; - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -1049,18 +1054,18 @@ message ValidatingAdmissionPolicyStatus { // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. message ValidatingWebhook { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. optional string name = 1; - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required optional WebhookClientConfig clientConfig = 2; - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -1069,7 +1074,7 @@ message ValidatingWebhook { // +listType=atomic repeated .k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3; - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. // +optional optional string failurePolicy = 4; @@ -1091,7 +1096,7 @@ message ValidatingWebhook { // +optional optional string matchPolicy = 9; - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -1137,7 +1142,7 @@ message ValidatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5; - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -1151,7 +1156,7 @@ message ValidatingWebhook { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 10; - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -1161,7 +1166,7 @@ message ValidatingWebhook { // +listType=atomic optional string sideEffects = 6; - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -1169,7 +1174,7 @@ message ValidatingWebhook { // +optional optional int32 timeoutSeconds = 7; - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -1181,7 +1186,7 @@ message ValidatingWebhook { // +listType=atomic repeated string admissionReviewVersions = 8; - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -1204,11 +1209,11 @@ message ValidatingWebhook { // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead. message ValidatingWebhookConfiguration { - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -1219,7 +1224,7 @@ message ValidatingWebhookConfiguration { // ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration. message ValidatingWebhookConfigurationList { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; @@ -1230,7 +1235,7 @@ message ValidatingWebhookConfigurationList { // Validation specifies the CEL expression which is used to apply the validation. message Validation { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -1273,7 +1278,7 @@ message Validation { // Required. optional string Expression = 1; - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -1283,7 +1288,7 @@ message Validation { // +optional optional string message = 2; - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -1309,12 +1314,12 @@ message Validation { // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. // +structType=atomic message Variable { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` optional string Name = 1; - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. optional string Expression = 2; } @@ -1322,7 +1327,7 @@ message Variable { // WebhookClientConfig contains the information to make a TLS // connection with the webhook message WebhookClientConfig { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -1351,7 +1356,7 @@ message WebhookClientConfig { // +optional optional string url = 3; - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. @@ -1359,7 +1364,7 @@ message WebhookClientConfig { // +optional optional ServiceReference service = 1; - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. // +optional optional bytes caBundle = 2; diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 67b85ac629..0000000000 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,90 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ApplyConfiguration) ProtoMessage() {} - -func (*AuditAnnotation) ProtoMessage() {} - -func (*ExpressionWarning) ProtoMessage() {} - -func (*JSONPatch) ProtoMessage() {} - -func (*MatchCondition) ProtoMessage() {} - -func (*MatchResources) ProtoMessage() {} - -func (*MutatingAdmissionPolicy) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBinding) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBindingList) ProtoMessage() {} - -func (*MutatingAdmissionPolicyBindingSpec) ProtoMessage() {} - -func (*MutatingAdmissionPolicyList) ProtoMessage() {} - -func (*MutatingAdmissionPolicySpec) ProtoMessage() {} - -func (*MutatingWebhook) ProtoMessage() {} - -func (*MutatingWebhookConfiguration) ProtoMessage() {} - -func (*MutatingWebhookConfigurationList) ProtoMessage() {} - -func (*Mutation) ProtoMessage() {} - -func (*NamedRuleWithOperations) ProtoMessage() {} - -func (*ParamKind) ProtoMessage() {} - -func (*ParamRef) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} - -func (*TypeChecking) ProtoMessage() {} - -func (*ValidatingAdmissionPolicy) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyList) ProtoMessage() {} - -func (*ValidatingAdmissionPolicySpec) ProtoMessage() {} - -func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {} - -func (*ValidatingWebhook) ProtoMessage() {} - -func (*ValidatingWebhookConfiguration) ProtoMessage() {} - -func (*ValidatingWebhookConfigurationList) ProtoMessage() {} - -func (*Validation) ProtoMessage() {} - -func (*Variable) ProtoMessage() {} - -func (*WebhookClientConfig) ProtoMessage() {} diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go index c7259d3d3e..734a606f4b 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go @@ -95,12 +95,12 @@ const ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicy struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. @@ -110,14 +110,14 @@ type ValidatingAdmissionPolicy struct { // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. type ValidatingAdmissionPolicyStatus struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. // +optional TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. // +optional // +listType=map // +listMapKey=type @@ -130,7 +130,7 @@ type ValidatingAdmissionPolicyConditionType string // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeChecking struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. // +optional // +listType=atomic ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"` @@ -138,11 +138,11 @@ type TypeChecking struct { // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarning struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"` @@ -153,7 +153,7 @@ type ExpressionWarning struct { // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. type ValidatingAdmissionPolicyList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -163,21 +163,21 @@ type ValidatingAdmissionPolicyList struct { // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpec struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. // +optional ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. // +listType=atomic @@ -208,7 +208,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -230,7 +230,7 @@ type ValidatingAdmissionPolicySpec struct { // +optional MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. @@ -248,19 +248,19 @@ type ValidatingAdmissionPolicySpec struct { // ParamKind is a tuple of Group Kind and Version. // +structType=atomic type ParamKind struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"` } // Validation specifies the CEL expression which is used to apply the validation. type Validation struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -302,7 +302,7 @@ type Validation struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -311,7 +311,7 @@ type Validation struct { // If unset, the message is "failed Expression: {Expression}". // +optional Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. @@ -336,12 +336,12 @@ type Validation struct { // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. // +structType=atomic type Variable struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name string `json:"name" protobuf:"bytes,1,opt,name=Name"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"` } @@ -401,10 +401,11 @@ type AuditAnnotation struct { // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBinding struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. + // +required Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -414,7 +415,7 @@ type ValidatingAdmissionPolicyBinding struct { // ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -424,9 +425,11 @@ type ValidatingAdmissionPolicyBindingList struct { // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpec struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"` // paramRef specifies the parameter resource used to configure the admission control policy. @@ -436,7 +439,7 @@ type ValidatingAdmissionPolicyBindingSpec struct { // +optional ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. @@ -484,6 +487,8 @@ type ValidatingAdmissionPolicyBindingSpec struct { // // Required. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"` } @@ -532,7 +537,7 @@ type ParamRef struct { // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. @@ -550,7 +555,7 @@ type ParamRef struct { // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +structType=atomic type MatchResources struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -595,7 +600,7 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -608,12 +613,12 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"` - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"` - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -657,7 +662,7 @@ const ( // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic type NamedRuleWithOperations struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. // +listType=atomic // +optional ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"` @@ -677,10 +682,10 @@ type NamedRuleWithOperations struct { // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead. type ValidatingWebhookConfiguration struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -698,7 +703,7 @@ type ValidatingWebhookConfiguration struct { // ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration. type ValidatingWebhookConfigurationList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -718,10 +723,10 @@ type ValidatingWebhookConfigurationList struct { // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead. type MutatingWebhookConfiguration struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. // +optional // +patchMergeKey=name // +patchStrategy=merge @@ -739,7 +744,7 @@ type MutatingWebhookConfiguration struct { // MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration. type MutatingWebhookConfigurationList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -749,18 +754,18 @@ type MutatingWebhookConfigurationList struct { // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. type ValidatingWebhook struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -769,7 +774,7 @@ type ValidatingWebhook struct { // +listType=atomic Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. // +optional FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` @@ -791,7 +796,7 @@ type ValidatingWebhook struct { // +optional MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -837,7 +842,7 @@ type ValidatingWebhook struct { // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -851,7 +856,7 @@ type ValidatingWebhook struct { // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,10,opt,name=objectSelector"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -861,7 +866,7 @@ type ValidatingWebhook struct { // +listType=atomic SideEffects *SideEffectClass `json:"sideEffects,omitempty" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -869,7 +874,7 @@ type ValidatingWebhook struct { // +optional TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -881,7 +886,7 @@ type ValidatingWebhook struct { // +listType=atomic AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -903,18 +908,18 @@ type ValidatingWebhook struct { // MutatingWebhook describes an admission webhook and the resources and operations it applies to. type MutatingWebhook struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely @@ -923,7 +928,7 @@ type MutatingWebhook struct { // +listType=atomic Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. // +optional FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` @@ -945,7 +950,7 @@ type MutatingWebhook struct { // +optional MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -991,7 +996,7 @@ type MutatingWebhook struct { // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -1005,7 +1010,7 @@ type MutatingWebhook struct { // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,11,opt,name=objectSelector"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. @@ -1014,7 +1019,7 @@ type MutatingWebhook struct { // +optional SideEffects *SideEffectClass `json:"sideEffects,omitempty" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. @@ -1022,7 +1027,7 @@ type MutatingWebhook struct { // +optional TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -1052,7 +1057,7 @@ type MutatingWebhook struct { // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -1107,7 +1112,7 @@ const ( // WebhookClientConfig contains the information to make a TLS // connection with the webhook type WebhookClientConfig struct { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -1136,7 +1141,7 @@ type WebhookClientConfig struct { // +optional URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"` - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. @@ -1144,7 +1149,7 @@ type WebhookClientConfig struct { // +optional Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"` - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. // +optional CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"` @@ -1152,28 +1157,28 @@ type WebhookClientConfig struct { // ServiceReference holds a reference to Service.legacy.k8s.io type ServiceReference struct { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"` - // `name` is the name of the service. + // name is the name of the service. // Required Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. // +optional Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"` - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. - // `port` should be a valid port number (1-65535, inclusive). + // port should be a valid port number (1-65535, inclusive). // +optional Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"` } // MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. type MatchCondition struct { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -1184,7 +1189,7 @@ type MatchCondition struct { // Required. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. @@ -1204,24 +1209,26 @@ type MatchCondition struct { // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.34 +// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicy // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. type MutatingAdmissionPolicy struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.34 +// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyList // MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy. type MutatingAdmissionPolicyList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -1467,6 +1474,7 @@ type JSONPatch struct { // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.34 +// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyBinding // MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. // MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators @@ -1481,20 +1489,21 @@ type JSONPatch struct { // given (policy, binding, param) combination is within its own CEL budget. type MutatingAdmissionPolicyBinding struct { metav1.TypeMeta `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.34 +// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyBindingList // MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding. type MutatingAdmissionPolicyBindingList struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go index 1a97c94729..0fcf37aa13 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go @@ -48,8 +48,8 @@ func (AuditAnnotation) SwaggerDoc() map[string]string { var map_ExpressionWarning = map[string]string{ "": "ExpressionWarning is a warning information that targets a specific expression.", - "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", - "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", + "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", + "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", } func (ExpressionWarning) SwaggerDoc() map[string]string { @@ -67,8 +67,8 @@ func (JSONPatch) SwaggerDoc() map[string]string { var map_MatchCondition = map[string]string{ "": "MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.", - "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", - "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", + "name": "name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", } func (MatchCondition) SwaggerDoc() map[string]string { @@ -77,10 +77,10 @@ func (MatchCondition) SwaggerDoc() map[string]string { var map_MatchResources = map[string]string{ "": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", - "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", - "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "resourceRules": "resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", + "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"", } @@ -90,8 +90,8 @@ func (MatchResources) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicy = map[string]string{ "": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the MutatingAdmissionPolicy.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.", } func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -100,8 +100,8 @@ func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyBinding = map[string]string{ "": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the MutatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.", } func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { @@ -110,7 +110,7 @@ func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyBindingList = map[string]string{ "": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of PolicyBinding.", } @@ -131,7 +131,7 @@ func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { var map_MutatingAdmissionPolicyList = map[string]string{ "": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingAdmissionPolicy.", } @@ -156,18 +156,18 @@ func (MutatingAdmissionPolicySpec) SwaggerDoc() map[string]string { var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", - "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", - "clientConfig": "ClientConfig defines how to communicate with the hook. Required", - "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", - "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.", + "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", + "clientConfig": "clientConfig defines how to communicate with the hook. Required", + "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", + "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.", "matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Exact\"", - "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", - "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", - "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", + "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", + "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", + "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -176,8 +176,8 @@ func (MutatingWebhook) SwaggerDoc() map[string]string { var map_MutatingWebhookConfiguration = map[string]string{ "": "MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "webhooks": "webhooks is a list of webhooks and the affected resources and operations.", } func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string { @@ -186,7 +186,7 @@ func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string { var map_MutatingWebhookConfigurationList = map[string]string{ "": "MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of MutatingWebhookConfiguration.", } @@ -207,7 +207,7 @@ func (Mutation) SwaggerDoc() map[string]string { var map_NamedRuleWithOperations = map[string]string{ "": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.", - "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", + "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", } func (NamedRuleWithOperations) SwaggerDoc() map[string]string { @@ -216,8 +216,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string { var map_ParamKind = map[string]string{ "": "ParamKind is a tuple of Group Kind and Version.", - "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.", - "kind": "Kind is the API kind the resources belong to. Required.", + "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.", + "kind": "kind is the API kind the resources belong to. Required.", } func (ParamKind) SwaggerDoc() map[string]string { @@ -229,7 +229,7 @@ var map_ParamRef = map[string]string{ "name": "name is the name of the resource being referenced.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.\n\nA single parameter used for all admission requests can be configured by setting the `name` field, leaving `selector` blank, and setting namespace if `paramKind` is namespace-scoped.", "namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.", "selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.", - "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired", + "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired", } func (ParamRef) SwaggerDoc() map[string]string { @@ -238,10 +238,10 @@ func (ParamRef) SwaggerDoc() map[string]string { var map_ServiceReference = map[string]string{ "": "ServiceReference holds a reference to Service.legacy.k8s.io", - "namespace": "`namespace` is the namespace of the service. Required", - "name": "`name` is the name of the service. Required", - "path": "`path` is an optional URL path which will be sent in any request to this service.", - "port": "If specified, the port on the service that hosting webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).", + "namespace": "namespace is the namespace of the service. Required", + "name": "name is the name of the service. Required", + "path": "path is an optional URL path which will be sent in any request to this service.", + "port": "port is the port on the service that hosts the webhook. Default to 443 for backward compatibility. port should be a valid port number (1-65535, inclusive).", } func (ServiceReference) SwaggerDoc() map[string]string { @@ -250,7 +250,7 @@ func (ServiceReference) SwaggerDoc() map[string]string { var map_TypeChecking = map[string]string{ "": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy", - "expressionWarnings": "The type checking warnings for each expression.", + "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.", } func (TypeChecking) SwaggerDoc() map[string]string { @@ -259,9 +259,9 @@ func (TypeChecking) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicy = map[string]string{ "": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.", - "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.", + "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", } func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -270,8 +270,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBinding = map[string]string{ "": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.", } func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { @@ -280,7 +280,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingList = map[string]string{ "": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of PolicyBinding.", } @@ -290,9 +290,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{ "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", - "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", "paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.", - "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", "validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.", } @@ -302,7 +302,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyList = map[string]string{ "": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingAdmissionPolicy.", } @@ -312,13 +312,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicySpec = map[string]string{ "": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.", - "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", - "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", - "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", + "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", + "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", + "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", "auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", - "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", + "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.", } func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { @@ -327,9 +327,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { var map_ValidatingAdmissionPolicyStatus = map[string]string{ "": "ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.", - "observedGeneration": "The generation observed by the controller.", - "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.", - "conditions": "The conditions represent the latest available observations of a policy's current state.", + "observedGeneration": "observedGeneration is the generation observed by the controller.", + "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.", + "conditions": "conditions represent the latest available observations of a policy's current state.", } func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { @@ -338,17 +338,17 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { var map_ValidatingWebhook = map[string]string{ "": "ValidatingWebhook describes an admission webhook and the resources and operations it applies to.", - "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", - "clientConfig": "ClientConfig defines how to communicate with the hook. Required", - "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", - "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.", + "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", + "clientConfig": "clientConfig defines how to communicate with the hook. Required", + "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.", + "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.", "matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Exact\"", - "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", - "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", - "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", - "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", + "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", + "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", + "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", + "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", + "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped", } func (ValidatingWebhook) SwaggerDoc() map[string]string { @@ -357,8 +357,8 @@ func (ValidatingWebhook) SwaggerDoc() map[string]string { var map_ValidatingWebhookConfiguration = map[string]string{ "": "ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead.", - "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.", + "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", + "webhooks": "webhooks is a list of webhooks and the affected resources and operations.", } func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string { @@ -367,7 +367,7 @@ func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string { var map_ValidatingWebhookConfigurationList = map[string]string{ "": "ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of ValidatingWebhookConfiguration.", } @@ -377,9 +377,9 @@ func (ValidatingWebhookConfigurationList) SwaggerDoc() map[string]string { var map_Validation = map[string]string{ "": "Validation specifies the CEL expression which is used to apply the validation.", - "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", - "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", - "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", + "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", + "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", "messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"", } @@ -389,8 +389,8 @@ func (Validation) SwaggerDoc() map[string]string { var map_Variable = map[string]string{ "": "Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.", - "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", - "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", + "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`", + "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.", } func (Variable) SwaggerDoc() map[string]string { @@ -399,9 +399,9 @@ func (Variable) SwaggerDoc() map[string]string { var map_WebhookClientConfig = map[string]string{ "": "WebhookClientConfig contains the information to make a TLS connection with the webhook", - "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", - "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.", - "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", + "url": "url gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.", + "service": "service is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.", + "caBundle": "caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.", } func (WebhookClientConfig) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go index 4fc0596b34..80064734ee 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go @@ -37,6 +37,12 @@ func (in *MutatingAdmissionPolicy) APILifecycleDeprecated() (major, minor int) { return 1, 37 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *MutatingAdmissionPolicy) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicy"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *MutatingAdmissionPolicy) APILifecycleRemoved() (major, minor int) { @@ -55,6 +61,12 @@ func (in *MutatingAdmissionPolicyBinding) APILifecycleDeprecated() (major, minor return 1, 37 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *MutatingAdmissionPolicyBinding) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBinding"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *MutatingAdmissionPolicyBinding) APILifecycleRemoved() (major, minor int) { @@ -73,6 +85,12 @@ func (in *MutatingAdmissionPolicyBindingList) APILifecycleDeprecated() (major, m return 1, 37 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *MutatingAdmissionPolicyBindingList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBindingList"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *MutatingAdmissionPolicyBindingList) APILifecycleRemoved() (major, minor int) { @@ -91,6 +109,12 @@ func (in *MutatingAdmissionPolicyList) APILifecycleDeprecated() (major, minor in return 1, 37 } +// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. +// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. +func (in *MutatingAdmissionPolicyList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyList"} +} + // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *MutatingAdmissionPolicyList) APILifecycleRemoved() (major, minor int) { diff --git a/vendor/k8s.io/api/apidiscovery/v2/generated.proto b/vendor/k8s.io/api/apidiscovery/v2/generated.proto index 62f2d7f2c1..7f58048e17 100644 --- a/vendor/k8s.io/api/apidiscovery/v2/generated.proto +++ b/vendor/k8s.io/api/apidiscovery/v2/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/apidiscovery/v2"; // It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version. // Versions are in descending order of preference, with the first version being the preferred entry. message APIGroupDiscovery { - // Standard object's metadata. + // metadata is standard object's metadata. // The only field completed will be name. For instance, resourceVersion will be empty. // name is the name of the API group whose discovery information is presented here. // name is allowed to be "" to represent the legacy, ungroupified resources. diff --git a/vendor/k8s.io/api/apidiscovery/v2/types.go b/vendor/k8s.io/api/apidiscovery/v2/types.go index 449679b61d..761bb6990b 100644 --- a/vendor/k8s.io/api/apidiscovery/v2/types.go +++ b/vendor/k8s.io/api/apidiscovery/v2/types.go @@ -45,7 +45,7 @@ type APIGroupDiscoveryList struct { // Versions are in descending order of preference, with the first version being the preferred entry. type APIGroupDiscovery struct { v1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is standard object's metadata. // The only field completed will be name. For instance, resourceVersion will be empty. // name is the name of the API group whose discovery information is presented here. // name is allowed to be "" to represent the legacy, ungroupified resources. diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto index e9ae88072a..f81449e6a9 100644 --- a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/apidiscovery/v2beta1"; // It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version. // Versions are in descending order of preference, with the first version being the preferred entry. message APIGroupDiscovery { - // Standard object's metadata. + // metadata is standard object's metadata. // The only field completed will be name. For instance, resourceVersion will be empty. // name is the name of the API group whose discovery information is presented here. // name is allowed to be "" to represent the legacy, ungroupified resources. diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/types.go b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go index 8342937730..306264da4d 100644 --- a/vendor/k8s.io/api/apidiscovery/v2beta1/types.go +++ b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go @@ -51,7 +51,7 @@ type APIGroupDiscoveryList struct { // Versions are in descending order of preference, with the first version being the preferred entry. type APIGroupDiscovery struct { v1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is standard object's metadata. // The only field completed will be name. For instance, resourceVersion will be empty. // name is the name of the API group whose discovery information is presented here. // name is allowed to be "" to represent the legacy, ungroupified resources. diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto index 8a77860720..e8f8c339df 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto @@ -31,59 +31,69 @@ option go_package = "k8s.io/api/apiserverinternal/v1alpha1"; // An API server instance reports the version it can decode and the version it // encodes objects to when persisting objects in the backend. message ServerStorageVersion { - // The ID of the reporting API server. + // apiServerID is the ID of the reporting API server. + // +required optional string apiServerID = 1; - // The API server encodes the object to this version when persisting it in + // encodingVersion the API server encodes the object to when persisting it in // the backend (e.g., etcd). + // +required optional string encodingVersion = 2; + // decodableVersions are the encoding versions the API server can handle to decode. // The API server can decode objects encoded in these versions. // The encodingVersion must be included in the decodableVersions. // +listType=set + // +required repeated string decodableVersions = 3; - // The API server can serve these versions. + // servedVersions lists all versions the API server can serve. // DecodableVersions must include all ServedVersions. // +listType=set + // +optional repeated string servedVersions = 4; } // Storage version of a specific resource. message StorageVersion { + // metadata is the standard object metadata. // The name is .. + // +required optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is an empty spec. It is here to comply with Kubernetes API style. + // spec is an empty spec. It is here to comply with Kubernetes API style. + // +optional optional StorageVersionSpec spec = 2; - // API server instances report the version they can decode and the version they + // status on the version the API server instance can decode from and // encode objects to when persisting objects in the backend. + // +optional optional StorageVersionStatus status = 3; } // Describes the state of the storageVersion at a certain point. message StorageVersionCondition { - // Type of the condition. + // type of the condition. // +required optional string type = 1; - // Status of the condition, one of True, False, Unknown. + // status of the condition, one of True, False, Unknown. // +required optional string status = 2; - // If set, this represents the .metadata.generation that the condition was set based upon. + // observedGeneration represents the .metadata.generation that the condition was set based upon, if field is set. // +optional optional int64 observedGeneration = 3; - // Last time the condition transitioned from one status to another. + // lastTransitionTime is the last time the condition transitioned from one status to another. + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 4; - // The reason for the condition's last transition. + // reason for the condition's last transition. // +required optional string reason = 5; - // A human readable message indicating details about the transition. + // message is a human readable string indicating details about the transition. // +required optional string message = 6; } @@ -106,20 +116,21 @@ message StorageVersionSpec { // API server instances report the versions they can decode and the version they // encode objects to when persisting objects in the backend. message StorageVersionStatus { - // The reported versions per API server instance. + // storageVersions lists the reported versions per API server instance. // +optional // +listType=map // +listMapKey=apiServerID repeated ServerStorageVersion storageVersions = 1; - // If all API server instances agree on the same encoding storage version, - // then this field is set to that version. Otherwise this field is left empty. + // commonEncodingVersion is set to an encoding storage version if all API server + // instances share that same version. If they don't share one storage version, this + // field is left empty. // API servers should finish updating its storageVersionStatus entry before // serving write operations, so that this field will be in sync with the reality. // +optional optional string commonEncodingVersion = 2; - // The latest available observations of the storageVersion's state. + // conditions lists the latest available observations of the storageVersion's state. // +optional // +listType=map // +listMapKey=type diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index b0839952b2..0000000000 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*ServerStorageVersion) ProtoMessage() {} - -func (*StorageVersion) ProtoMessage() {} - -func (*StorageVersionCondition) ProtoMessage() {} - -func (*StorageVersionList) ProtoMessage() {} - -func (*StorageVersionSpec) ProtoMessage() {} - -func (*StorageVersionStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go index 31a419abf1..69c21fd3c4 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types.go @@ -27,14 +27,18 @@ import ( // Storage version of a specific resource. type StorageVersion struct { metav1.TypeMeta `json:",inline"` + // metadata is the standard object metadata. // The name is .. + // +required metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec is an empty spec. It is here to comply with Kubernetes API style. + // spec is an empty spec. It is here to comply with Kubernetes API style. + // +optional Spec StorageVersionSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // API server instances report the version they can decode and the version they + // status on the version the API server instance can decode from and // encode objects to when persisting objects in the backend. + // +optional Status StorageVersionStatus `json:"status" protobuf:"bytes,3,opt,name=status"` } @@ -44,19 +48,20 @@ type StorageVersionSpec struct{} // API server instances report the versions they can decode and the version they // encode objects to when persisting objects in the backend. type StorageVersionStatus struct { - // The reported versions per API server instance. + // storageVersions lists the reported versions per API server instance. // +optional // +listType=map // +listMapKey=apiServerID StorageVersions []ServerStorageVersion `json:"storageVersions,omitempty" protobuf:"bytes,1,opt,name=storageVersions"` - // If all API server instances agree on the same encoding storage version, - // then this field is set to that version. Otherwise this field is left empty. + // commonEncodingVersion is set to an encoding storage version if all API server + // instances share that same version. If they don't share one storage version, this + // field is left empty. // API servers should finish updating its storageVersionStatus entry before // serving write operations, so that this field will be in sync with the reality. // +optional CommonEncodingVersion *string `json:"commonEncodingVersion,omitempty" protobuf:"bytes,2,opt,name=commonEncodingVersion"` - // The latest available observations of the storageVersion's state. + // conditions lists the latest available observations of the storageVersion's state. // +optional // +listType=map // +listMapKey=type @@ -66,21 +71,26 @@ type StorageVersionStatus struct { // An API server instance reports the version it can decode and the version it // encodes objects to when persisting objects in the backend. type ServerStorageVersion struct { - // The ID of the reporting API server. + // apiServerID is the ID of the reporting API server. + // +required APIServerID string `json:"apiServerID,omitempty" protobuf:"bytes,1,opt,name=apiServerID"` - // The API server encodes the object to this version when persisting it in + // encodingVersion the API server encodes the object to when persisting it in // the backend (e.g., etcd). + // +required EncodingVersion string `json:"encodingVersion,omitempty" protobuf:"bytes,2,opt,name=encodingVersion"` + // decodableVersions are the encoding versions the API server can handle to decode. // The API server can decode objects encoded in these versions. // The encodingVersion must be included in the decodableVersions. // +listType=set + // +required DecodableVersions []string `json:"decodableVersions,omitempty" protobuf:"bytes,3,opt,name=decodableVersions"` - // The API server can serve these versions. + // servedVersions lists all versions the API server can serve. // DecodableVersions must include all ServedVersions. // +listType=set + // +optional ServedVersions []string `json:"servedVersions,omitempty" protobuf:"bytes,4,opt,name=servedVersions"` } @@ -101,21 +111,22 @@ const ( // Describes the state of the storageVersion at a certain point. type StorageVersionCondition struct { - // Type of the condition. + // type of the condition. // +required Type StorageVersionConditionType `json:"type" protobuf:"bytes,1,opt,name=type"` - // Status of the condition, one of True, False, Unknown. + // status of the condition, one of True, False, Unknown. // +required Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status"` - // If set, this represents the .metadata.generation that the condition was set based upon. + // observedGeneration represents the .metadata.generation that the condition was set based upon, if field is set. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` - // Last time the condition transitioned from one status to another. + // lastTransitionTime is the last time the condition transitioned from one status to another. + // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,4,opt,name=lastTransitionTime"` - // The reason for the condition's last transition. + // reason for the condition's last transition. // +required Reason string `json:"reason" protobuf:"bytes,5,opt,name=reason"` - // A human readable message indicating details about the transition. + // message is a human readable string indicating details about the transition. // +required Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"` } diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go index 6fd1c3ebe8..b74035e500 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go @@ -29,10 +29,10 @@ package v1alpha1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ServerStorageVersion = map[string]string{ "": "An API server instance reports the version it can decode and the version it encodes objects to when persisting objects in the backend.", - "apiServerID": "The ID of the reporting API server.", - "encodingVersion": "The API server encodes the object to this version when persisting it in the backend (e.g., etcd).", - "decodableVersions": "The API server can decode objects encoded in these versions. The encodingVersion must be included in the decodableVersions.", - "servedVersions": "The API server can serve these versions. DecodableVersions must include all ServedVersions.", + "apiServerID": "apiServerID is the ID of the reporting API server.", + "encodingVersion": "encodingVersion the API server encodes the object to when persisting it in the backend (e.g., etcd).", + "decodableVersions": "decodableVersions are the encoding versions the API server can handle to decode. The API server can decode objects encoded in these versions. The encodingVersion must be included in the decodableVersions.", + "servedVersions": "servedVersions lists all versions the API server can serve. DecodableVersions must include all ServedVersions.", } func (ServerStorageVersion) SwaggerDoc() map[string]string { @@ -41,9 +41,9 @@ func (ServerStorageVersion) SwaggerDoc() map[string]string { var map_StorageVersion = map[string]string{ "": "Storage version of a specific resource.", - "metadata": "The name is ..", - "spec": "Spec is an empty spec. It is here to comply with Kubernetes API style.", - "status": "API server instances report the version they can decode and the version they encode objects to when persisting objects in the backend.", + "metadata": "metadata is the standard object metadata. The name is ..", + "spec": "spec is an empty spec. It is here to comply with Kubernetes API style.", + "status": "status on the version the API server instance can decode from and encode objects to when persisting objects in the backend.", } func (StorageVersion) SwaggerDoc() map[string]string { @@ -52,12 +52,12 @@ func (StorageVersion) SwaggerDoc() map[string]string { var map_StorageVersionCondition = map[string]string{ "": "Describes the state of the storageVersion at a certain point.", - "type": "Type of the condition.", - "status": "Status of the condition, one of True, False, Unknown.", - "observedGeneration": "If set, this represents the .metadata.generation that the condition was set based upon.", - "lastTransitionTime": "Last time the condition transitioned from one status to another.", - "reason": "The reason for the condition's last transition.", - "message": "A human readable message indicating details about the transition.", + "type": "type of the condition.", + "status": "status of the condition, one of True, False, Unknown.", + "observedGeneration": "observedGeneration represents the .metadata.generation that the condition was set based upon, if field is set.", + "lastTransitionTime": "lastTransitionTime is the last time the condition transitioned from one status to another.", + "reason": "reason for the condition's last transition.", + "message": "message is a human readable string indicating details about the transition.", } func (StorageVersionCondition) SwaggerDoc() map[string]string { @@ -84,9 +84,9 @@ func (StorageVersionSpec) SwaggerDoc() map[string]string { var map_StorageVersionStatus = map[string]string{ "": "API server instances report the versions they can decode and the version they encode objects to when persisting objects in the backend.", - "storageVersions": "The reported versions per API server instance.", - "commonEncodingVersion": "If all API server instances agree on the same encoding storage version, then this field is set to that version. Otherwise this field is left empty. API servers should finish updating its storageVersionStatus entry before serving write operations, so that this field will be in sync with the reality.", - "conditions": "The latest available observations of the storageVersion's state.", + "storageVersions": "storageVersions lists the reported versions per API server instance.", + "commonEncodingVersion": "commonEncodingVersion is set to an encoding storage version if all API server instances share that same version. If they don't share one storage version, this field is left empty. API servers should finish updating its storageVersionStatus entry before serving write operations, so that this field will be in sync with the reality.", + "conditions": "conditions lists the latest available observations of the storageVersion's state.", } func (StorageVersionStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/apps/v1/generated.protomessage.pb.go deleted file mode 100644 index f9faa4e13a..0000000000 --- a/vendor/k8s.io/api/apps/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,82 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*ControllerRevision) ProtoMessage() {} - -func (*ControllerRevisionList) ProtoMessage() {} - -func (*DaemonSet) ProtoMessage() {} - -func (*DaemonSetCondition) ProtoMessage() {} - -func (*DaemonSetList) ProtoMessage() {} - -func (*DaemonSetSpec) ProtoMessage() {} - -func (*DaemonSetStatus) ProtoMessage() {} - -func (*DaemonSetUpdateStrategy) ProtoMessage() {} - -func (*Deployment) ProtoMessage() {} - -func (*DeploymentCondition) ProtoMessage() {} - -func (*DeploymentList) ProtoMessage() {} - -func (*DeploymentSpec) ProtoMessage() {} - -func (*DeploymentStatus) ProtoMessage() {} - -func (*DeploymentStrategy) ProtoMessage() {} - -func (*ReplicaSet) ProtoMessage() {} - -func (*ReplicaSetCondition) ProtoMessage() {} - -func (*ReplicaSetList) ProtoMessage() {} - -func (*ReplicaSetSpec) ProtoMessage() {} - -func (*ReplicaSetStatus) ProtoMessage() {} - -func (*RollingUpdateDaemonSet) ProtoMessage() {} - -func (*RollingUpdateDeployment) ProtoMessage() {} - -func (*RollingUpdateStatefulSetStrategy) ProtoMessage() {} - -func (*StatefulSet) ProtoMessage() {} - -func (*StatefulSetCondition) ProtoMessage() {} - -func (*StatefulSetList) ProtoMessage() {} - -func (*StatefulSetOrdinals) ProtoMessage() {} - -func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} - -func (*StatefulSetSpec) ProtoMessage() {} - -func (*StatefulSetStatus) ProtoMessage() {} - -func (*StatefulSetUpdateStrategy) ProtoMessage() {} diff --git a/vendor/k8s.io/api/apps/v1beta1/generated.proto b/vendor/k8s.io/api/apps/v1beta1/generated.proto index b47d61e209..c6f0628e0c 100644 --- a/vendor/k8s.io/api/apps/v1beta1/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta1/generated.proto @@ -318,9 +318,9 @@ message Scale { message ScaleSpec { // replicas is the number of observed instances of the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 replicas = 1; } diff --git a/vendor/k8s.io/api/apps/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/apps/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 3127ea3cae..0000000000 --- a/vendor/k8s.io/api/apps/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ControllerRevision) ProtoMessage() {} - -func (*ControllerRevisionList) ProtoMessage() {} - -func (*Deployment) ProtoMessage() {} - -func (*DeploymentCondition) ProtoMessage() {} - -func (*DeploymentList) ProtoMessage() {} - -func (*DeploymentRollback) ProtoMessage() {} - -func (*DeploymentSpec) ProtoMessage() {} - -func (*DeploymentStatus) ProtoMessage() {} - -func (*DeploymentStrategy) ProtoMessage() {} - -func (*RollbackConfig) ProtoMessage() {} - -func (*RollingUpdateDeployment) ProtoMessage() {} - -func (*RollingUpdateStatefulSetStrategy) ProtoMessage() {} - -func (*Scale) ProtoMessage() {} - -func (*ScaleSpec) ProtoMessage() {} - -func (*ScaleStatus) ProtoMessage() {} - -func (*StatefulSet) ProtoMessage() {} - -func (*StatefulSetCondition) ProtoMessage() {} - -func (*StatefulSetList) ProtoMessage() {} - -func (*StatefulSetOrdinals) ProtoMessage() {} - -func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} - -func (*StatefulSetSpec) ProtoMessage() {} - -func (*StatefulSetStatus) ProtoMessage() {} - -func (*StatefulSetUpdateStrategy) ProtoMessage() {} diff --git a/vendor/k8s.io/api/apps/v1beta1/types.go b/vendor/k8s.io/api/apps/v1beta1/types.go index b1e6b33683..4e67338e36 100644 --- a/vendor/k8s.io/api/apps/v1beta1/types.go +++ b/vendor/k8s.io/api/apps/v1beta1/types.go @@ -33,9 +33,9 @@ const ( type ScaleSpec struct { // replicas is the number of observed instances of the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } @@ -63,7 +63,7 @@ type ScaleStatus struct { // +k8s:prerelease-lifecycle-gen:deprecated=1.8 // +k8s:prerelease-lifecycle-gen:removed=1.16 // +k8s:prerelease-lifecycle-gen:replacement=autoscaling,v1,Scale -// +k8s:isSubresource=/scale +// +k8s:isSubresource="/scale" // Scale represents a scaling request for a resource. type Scale struct { diff --git a/vendor/k8s.io/api/apps/v1beta2/generated.proto b/vendor/k8s.io/api/apps/v1beta2/generated.proto index 1cdd0a43f7..d680c9663e 100644 --- a/vendor/k8s.io/api/apps/v1beta2/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta2/generated.proto @@ -616,9 +616,9 @@ message Scale { message ScaleSpec { // desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 replicas = 1; } diff --git a/vendor/k8s.io/api/apps/v1beta2/generated.protomessage.pb.go b/vendor/k8s.io/api/apps/v1beta2/generated.protomessage.pb.go deleted file mode 100644 index 18582bf290..0000000000 --- a/vendor/k8s.io/api/apps/v1beta2/generated.protomessage.pb.go +++ /dev/null @@ -1,88 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta2 - -func (*ControllerRevision) ProtoMessage() {} - -func (*ControllerRevisionList) ProtoMessage() {} - -func (*DaemonSet) ProtoMessage() {} - -func (*DaemonSetCondition) ProtoMessage() {} - -func (*DaemonSetList) ProtoMessage() {} - -func (*DaemonSetSpec) ProtoMessage() {} - -func (*DaemonSetStatus) ProtoMessage() {} - -func (*DaemonSetUpdateStrategy) ProtoMessage() {} - -func (*Deployment) ProtoMessage() {} - -func (*DeploymentCondition) ProtoMessage() {} - -func (*DeploymentList) ProtoMessage() {} - -func (*DeploymentSpec) ProtoMessage() {} - -func (*DeploymentStatus) ProtoMessage() {} - -func (*DeploymentStrategy) ProtoMessage() {} - -func (*ReplicaSet) ProtoMessage() {} - -func (*ReplicaSetCondition) ProtoMessage() {} - -func (*ReplicaSetList) ProtoMessage() {} - -func (*ReplicaSetSpec) ProtoMessage() {} - -func (*ReplicaSetStatus) ProtoMessage() {} - -func (*RollingUpdateDaemonSet) ProtoMessage() {} - -func (*RollingUpdateDeployment) ProtoMessage() {} - -func (*RollingUpdateStatefulSetStrategy) ProtoMessage() {} - -func (*Scale) ProtoMessage() {} - -func (*ScaleSpec) ProtoMessage() {} - -func (*ScaleStatus) ProtoMessage() {} - -func (*StatefulSet) ProtoMessage() {} - -func (*StatefulSetCondition) ProtoMessage() {} - -func (*StatefulSetList) ProtoMessage() {} - -func (*StatefulSetOrdinals) ProtoMessage() {} - -func (*StatefulSetPersistentVolumeClaimRetentionPolicy) ProtoMessage() {} - -func (*StatefulSetSpec) ProtoMessage() {} - -func (*StatefulSetStatus) ProtoMessage() {} - -func (*StatefulSetUpdateStrategy) ProtoMessage() {} diff --git a/vendor/k8s.io/api/apps/v1beta2/types.go b/vendor/k8s.io/api/apps/v1beta2/types.go index 18c74a4aa6..d4d4a7e0dc 100644 --- a/vendor/k8s.io/api/apps/v1beta2/types.go +++ b/vendor/k8s.io/api/apps/v1beta2/types.go @@ -35,9 +35,9 @@ const ( type ScaleSpec struct { // desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } @@ -66,7 +66,7 @@ type ScaleStatus struct { // +k8s:prerelease-lifecycle-gen:deprecated=1.9 // +k8s:prerelease-lifecycle-gen:removed=1.16 // +k8s:prerelease-lifecycle-gen:replacement=autoscaling,v1,Scale -// +k8s:isSubresource=/scale +// +k8s:isSubresource="/scale" // Scale represents a scaling request for a resource. type Scale struct { diff --git a/vendor/k8s.io/api/authentication/v1/generated.proto b/vendor/k8s.io/api/authentication/v1/generated.proto index ae9763576c..82ff7c3c51 100644 --- a/vendor/k8s.io/api/authentication/v1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1/generated.proto @@ -30,19 +30,19 @@ option go_package = "k8s.io/api/authentication/v1"; // BoundObjectReference is a reference to an object that a token is bound to. message BoundObjectReference { - // Kind of the referent. Valid kinds are 'Pod' and 'Secret'. + // kind of the referent. Valid kinds are 'Pod' and 'Secret'. // +optional optional string kind = 1; - // API version of the referent. + // apiVersion is API version of the referent. // +optional optional string apiVersion = 2; - // Name of the referent. + // name of the referent. // +optional optional string name = 3; - // UID of the referent. + // uid of the referent. // +optional optional string uID = 4; } @@ -60,55 +60,58 @@ message ExtraValue { // When using impersonation, users will receive the user info of the user being impersonated. If impersonation or // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. message SelfSubjectReview { - // Standard object's metadata. + // metadata is standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional optional SelfSubjectReviewStatus status = 2; } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. message SelfSubjectReviewStatus { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional optional UserInfo userInfo = 1; } // TokenRequest requests a token for a given service account. message TokenRequest { - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +optional optional TokenRequestSpec spec = 2; - // Status is filled in by the server and indicates whether the token can be authenticated. + // status is filled in by the server and indicates whether the token can be authenticated. // +optional optional TokenRequestStatus status = 3; } // TokenRequestSpec contains client provided parameters of a token request. message TokenRequestSpec { - // Audiences are the intendend audiences of the token. A recipient of a + // audiences are the intendend audiences of the token. A recipient of a // token must identify themself with an identifier in the list of // audiences of the token, and otherwise should reject the token. A // token issued for multiple audiences may be used to authenticate // against any of the audiences listed but implies a high degree of // trust between the target audiences. + // +optional // +listType=atomic repeated string audiences = 1; - // ExpirationSeconds is the requested duration of validity of the request. The + // expirationSeconds is the requested duration of validity of the request. The // token issuer may return a token with a different validity duration so a // client needs to check the 'expiration' field in a response. // +optional optional int64 expirationSeconds = 4; - // BoundObjectRef is a reference to an object that the token will be bound to. + // boundObjectRef is a reference to an object that the token will be bound to. // The token will only be valid for as long as the bound object exists. // NOTE: The API server's TokenReview endpoint will validate the // BoundObjectRef, but other audiences may not. Keep ExpirationSeconds @@ -119,10 +122,12 @@ message TokenRequestSpec { // TokenRequestStatus is the result of a token request. message TokenRequestStatus { - // Token is the opaque bearer token. + // token is the opaque bearer token. + // +optional optional string token = 1; - // ExpirationTimestamp is the time of expiration of the returned token. + // expirationTimestamp is the time of expiration of the returned token. + // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time expirationTimestamp = 2; } @@ -130,26 +135,27 @@ message TokenRequestStatus { // Note: TokenReview requests may be cached by the webhook token authenticator // plugin in the kube-apiserver. message TokenReview { - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +required optional TokenReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request can be authenticated. + // status is filled in by the server and indicates whether the request can be authenticated. // +optional optional TokenReviewStatus status = 3; } // TokenReviewSpec is a description of the token authentication request. message TokenReviewSpec { - // Token is the opaque bearer token. - // +optional + // token is the opaque bearer token. + // +required optional string token = 1; - // Audiences is a list of the identifiers that the resource server presented + // audiences is a list of the identifiers that the resource server presented // with the token identifies as. Audience-aware token authenticators will // verify that the token was intended for at least one of the audiences in // this list. If no audiences are provided, the audience will default to the @@ -161,15 +167,15 @@ message TokenReviewSpec { // TokenReviewStatus is the result of the token authentication request. message TokenReviewStatus { - // Authenticated indicates that the token was associated with a known user. + // authenticated indicates that the token was associated with a known user. // +optional optional bool authenticated = 1; - // User is the UserInfo associated with the provided token. + // user is the UserInfo associated with the provided token. // +optional optional UserInfo user = 2; - // Audiences are audience identifiers chosen by the authenticator that are + // audiences are audience identifiers chosen by the authenticator that are // compatible with both the TokenReview and token. An identifier is any // identifier in the intersection of the TokenReviewSpec audiences and the // token's audiences. A client of the TokenReview API that sets the @@ -182,7 +188,7 @@ message TokenReviewStatus { // +listType=atomic repeated string audiences = 4; - // Error indicates that the token couldn't be checked + // error indicates that the token couldn't be checked // +optional optional string error = 3; } @@ -190,22 +196,22 @@ message TokenReviewStatus { // UserInfo holds the information about the user needed to implement the // user.Info interface. message UserInfo { - // The name that uniquely identifies this user among all active users. + // username is the name that uniquely identifies this user among all active users. // +optional optional string username = 1; - // A unique value that identifies this user across time. If this user is + // uid is a unique value that identifies this user across time. If this user is // deleted and another user by the same name is added, they will have // different UIDs. // +optional optional string uid = 2; - // The names of groups this user is a part of. + // groups is the names of groups this user is a part of. // +optional // +listType=atomic repeated string groups = 3; - // Any additional information provided by the authenticator. + // extra is any additional information provided by the authenticator. // +optional map extra = 4; } diff --git a/vendor/k8s.io/api/authentication/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/authentication/v1/generated.protomessage.pb.go deleted file mode 100644 index 7003a80843..0000000000 --- a/vendor/k8s.io/api/authentication/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*BoundObjectReference) ProtoMessage() {} - -func (*ExtraValue) ProtoMessage() {} - -func (*SelfSubjectReview) ProtoMessage() {} - -func (*SelfSubjectReviewStatus) ProtoMessage() {} - -func (*TokenRequest) ProtoMessage() {} - -func (*TokenRequestSpec) ProtoMessage() {} - -func (*TokenRequestStatus) ProtoMessage() {} - -func (*TokenReview) ProtoMessage() {} - -func (*TokenReviewSpec) ProtoMessage() {} - -func (*TokenReviewStatus) ProtoMessage() {} - -func (*UserInfo) ProtoMessage() {} diff --git a/vendor/k8s.io/api/authentication/v1/types.go b/vendor/k8s.io/api/authentication/v1/types.go index 2dc0707c4f..c28bded50a 100644 --- a/vendor/k8s.io/api/authentication/v1/types.go +++ b/vendor/k8s.io/api/authentication/v1/types.go @@ -52,25 +52,26 @@ const ( // plugin in the kube-apiserver. type TokenReview struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +required Spec TokenReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request can be authenticated. + // status is filled in by the server and indicates whether the request can be authenticated. // +optional Status TokenReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // TokenReviewSpec is a description of the token authentication request. type TokenReviewSpec struct { - // Token is the opaque bearer token. - // +optional + // token is the opaque bearer token. + // +required Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"` - // Audiences is a list of the identifiers that the resource server presented + // audiences is a list of the identifiers that the resource server presented // with the token identifies as. Audience-aware token authenticators will // verify that the token was intended for at least one of the audiences in // this list. If no audiences are provided, the audience will default to the @@ -82,13 +83,13 @@ type TokenReviewSpec struct { // TokenReviewStatus is the result of the token authentication request. type TokenReviewStatus struct { - // Authenticated indicates that the token was associated with a known user. + // authenticated indicates that the token was associated with a known user. // +optional Authenticated bool `json:"authenticated,omitempty" protobuf:"varint,1,opt,name=authenticated"` - // User is the UserInfo associated with the provided token. + // user is the UserInfo associated with the provided token. // +optional User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"` - // Audiences are audience identifiers chosen by the authenticator that are + // audiences are audience identifiers chosen by the authenticator that are // compatible with both the TokenReview and token. An identifier is any // identifier in the intersection of the TokenReviewSpec audiences and the // token's audiences. A client of the TokenReview API that sets the @@ -100,7 +101,7 @@ type TokenReviewStatus struct { // +optional // +listType=atomic Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"` - // Error indicates that the token couldn't be checked + // error indicates that the token couldn't be checked // +optional Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"` } @@ -108,19 +109,19 @@ type TokenReviewStatus struct { // UserInfo holds the information about the user needed to implement the // user.Info interface. type UserInfo struct { - // The name that uniquely identifies this user among all active users. + // username is the name that uniquely identifies this user among all active users. // +optional Username string `json:"username,omitempty" protobuf:"bytes,1,opt,name=username"` - // A unique value that identifies this user across time. If this user is + // uid is a unique value that identifies this user across time. If this user is // deleted and another user by the same name is added, they will have // different UIDs. // +optional UID string `json:"uid,omitempty" protobuf:"bytes,2,opt,name=uid"` - // The names of groups this user is a part of. + // groups is the names of groups this user is a part of. // +optional // +listType=atomic Groups []string `json:"groups,omitempty" protobuf:"bytes,3,rep,name=groups"` - // Any additional information provided by the authenticator. + // extra is any additional information provided by the authenticator. // +optional Extra map[string]ExtraValue `json:"extra,omitempty" protobuf:"bytes,4,rep,name=extra"` } @@ -140,37 +141,39 @@ func (t ExtraValue) String() string { // TokenRequest requests a token for a given service account. type TokenRequest struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +optional Spec TokenRequestSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the token can be authenticated. + // status is filled in by the server and indicates whether the token can be authenticated. // +optional Status TokenRequestStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // TokenRequestSpec contains client provided parameters of a token request. type TokenRequestSpec struct { - // Audiences are the intendend audiences of the token. A recipient of a + // audiences are the intendend audiences of the token. A recipient of a // token must identify themself with an identifier in the list of // audiences of the token, and otherwise should reject the token. A // token issued for multiple audiences may be used to authenticate // against any of the audiences listed but implies a high degree of // trust between the target audiences. + // +optional // +listType=atomic Audiences []string `json:"audiences" protobuf:"bytes,1,rep,name=audiences"` - // ExpirationSeconds is the requested duration of validity of the request. The + // expirationSeconds is the requested duration of validity of the request. The // token issuer may return a token with a different validity duration so a // client needs to check the 'expiration' field in a response. // +optional ExpirationSeconds *int64 `json:"expirationSeconds" protobuf:"varint,4,opt,name=expirationSeconds"` - // BoundObjectRef is a reference to an object that the token will be bound to. + // boundObjectRef is a reference to an object that the token will be bound to. // The token will only be valid for as long as the bound object exists. // NOTE: The API server's TokenReview endpoint will validate the // BoundObjectRef, but other audiences may not. Keep ExpirationSeconds @@ -181,25 +184,27 @@ type TokenRequestSpec struct { // TokenRequestStatus is the result of a token request. type TokenRequestStatus struct { - // Token is the opaque bearer token. + // token is the opaque bearer token. + // +optional Token string `json:"token" protobuf:"bytes,1,opt,name=token"` - // ExpirationTimestamp is the time of expiration of the returned token. + // expirationTimestamp is the time of expiration of the returned token. + // +optional ExpirationTimestamp metav1.Time `json:"expirationTimestamp" protobuf:"bytes,2,opt,name=expirationTimestamp"` } // BoundObjectReference is a reference to an object that a token is bound to. type BoundObjectReference struct { - // Kind of the referent. Valid kinds are 'Pod' and 'Secret'. + // kind of the referent. Valid kinds are 'Pod' and 'Secret'. // +optional Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"` - // API version of the referent. + // apiVersion is API version of the referent. // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"` - // Name of the referent. + // name of the referent. // +optional Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` - // UID of the referent. + // uid of the referent. // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,4,opt,name=uID,casttype=k8s.io/apimachinery/pkg/types.UID"` } @@ -215,17 +220,18 @@ type BoundObjectReference struct { // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. type SelfSubjectReview struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. type SelfSubjectReviewStatus struct { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional UserInfo UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` } diff --git a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go index ebfd4852c0..ea3acbb681 100644 --- a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go @@ -29,10 +29,10 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_BoundObjectReference = map[string]string{ "": "BoundObjectReference is a reference to an object that a token is bound to.", - "kind": "Kind of the referent. Valid kinds are 'Pod' and 'Secret'.", - "apiVersion": "API version of the referent.", - "name": "Name of the referent.", - "uid": "UID of the referent.", + "kind": "kind of the referent. Valid kinds are 'Pod' and 'Secret'.", + "apiVersion": "apiVersion is API version of the referent.", + "name": "name of the referent.", + "uid": "uid of the referent.", } func (BoundObjectReference) SwaggerDoc() map[string]string { @@ -41,8 +41,8 @@ func (BoundObjectReference) SwaggerDoc() map[string]string { var map_SelfSubjectReview = map[string]string{ "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "status": "Status is filled in by the server with the user attributes.", + "metadata": "metadata is standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "status is filled in by the server with the user attributes.", } func (SelfSubjectReview) SwaggerDoc() map[string]string { @@ -51,7 +51,7 @@ func (SelfSubjectReview) SwaggerDoc() map[string]string { var map_SelfSubjectReviewStatus = map[string]string{ "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", - "userInfo": "User attributes of the user making this request.", + "userInfo": "userInfo is a set of attributes belonging to the user making this request.", } func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { @@ -60,9 +60,9 @@ func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { var map_TokenRequest = map[string]string{ "": "TokenRequest requests a token for a given service account.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated", - "status": "Status is filled in by the server and indicates whether the token can be authenticated.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated", + "status": "status is filled in by the server and indicates whether the token can be authenticated.", } func (TokenRequest) SwaggerDoc() map[string]string { @@ -71,9 +71,9 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_TokenRequestSpec = map[string]string{ "": "TokenRequestSpec contains client provided parameters of a token request.", - "audiences": "Audiences are the intendend audiences of the token. A recipient of a token must identify themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.", - "expirationSeconds": "ExpirationSeconds is the requested duration of validity of the request. The token issuer may return a token with a different validity duration so a client needs to check the 'expiration' field in a response.", - "boundObjectRef": "BoundObjectRef is a reference to an object that the token will be bound to. The token will only be valid for as long as the bound object exists. NOTE: The API server's TokenReview endpoint will validate the BoundObjectRef, but other audiences may not. Keep ExpirationSeconds small if you want prompt revocation.", + "audiences": "audiences are the intendend audiences of the token. A recipient of a token must identify themself with an identifier in the list of audiences of the token, and otherwise should reject the token. A token issued for multiple audiences may be used to authenticate against any of the audiences listed but implies a high degree of trust between the target audiences.", + "expirationSeconds": "expirationSeconds is the requested duration of validity of the request. The token issuer may return a token with a different validity duration so a client needs to check the 'expiration' field in a response.", + "boundObjectRef": "boundObjectRef is a reference to an object that the token will be bound to. The token will only be valid for as long as the bound object exists. NOTE: The API server's TokenReview endpoint will validate the BoundObjectRef, but other audiences may not. Keep ExpirationSeconds small if you want prompt revocation.", } func (TokenRequestSpec) SwaggerDoc() map[string]string { @@ -82,8 +82,8 @@ func (TokenRequestSpec) SwaggerDoc() map[string]string { var map_TokenRequestStatus = map[string]string{ "": "TokenRequestStatus is the result of a token request.", - "token": "Token is the opaque bearer token.", - "expirationTimestamp": "ExpirationTimestamp is the time of expiration of the returned token.", + "token": "token is the opaque bearer token.", + "expirationTimestamp": "expirationTimestamp is the time of expiration of the returned token.", } func (TokenRequestStatus) SwaggerDoc() map[string]string { @@ -92,9 +92,9 @@ func (TokenRequestStatus) SwaggerDoc() map[string]string { var map_TokenReview = map[string]string{ "": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated", - "status": "Status is filled in by the server and indicates whether the request can be authenticated.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated", + "status": "status is filled in by the server and indicates whether the request can be authenticated.", } func (TokenReview) SwaggerDoc() map[string]string { @@ -103,8 +103,8 @@ func (TokenReview) SwaggerDoc() map[string]string { var map_TokenReviewSpec = map[string]string{ "": "TokenReviewSpec is a description of the token authentication request.", - "token": "Token is the opaque bearer token.", - "audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.", + "token": "token is the opaque bearer token.", + "audiences": "audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.", } func (TokenReviewSpec) SwaggerDoc() map[string]string { @@ -113,10 +113,10 @@ func (TokenReviewSpec) SwaggerDoc() map[string]string { var map_TokenReviewStatus = map[string]string{ "": "TokenReviewStatus is the result of the token authentication request.", - "authenticated": "Authenticated indicates that the token was associated with a known user.", - "user": "User is the UserInfo associated with the provided token.", - "audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.", - "error": "Error indicates that the token couldn't be checked", + "authenticated": "authenticated indicates that the token was associated with a known user.", + "user": "user is the UserInfo associated with the provided token.", + "audiences": "audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.", + "error": "error indicates that the token couldn't be checked", } func (TokenReviewStatus) SwaggerDoc() map[string]string { @@ -125,10 +125,10 @@ func (TokenReviewStatus) SwaggerDoc() map[string]string { var map_UserInfo = map[string]string{ "": "UserInfo holds the information about the user needed to implement the user.Info interface.", - "username": "The name that uniquely identifies this user among all active users.", - "uid": "A unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs.", - "groups": "The names of groups this user is a part of.", - "extra": "Any additional information provided by the authenticator.", + "username": "username is the name that uniquely identifies this user among all active users.", + "uid": "uid is a unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs.", + "groups": "groups is the names of groups this user is a part of.", + "extra": "extra is any additional information provided by the authenticator.", } func (UserInfo) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/authentication/v1alpha1/generated.proto b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto index 4585e5cdd3..2bf836d730 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto @@ -33,18 +33,19 @@ option go_package = "k8s.io/api/authentication/v1alpha1"; // When using impersonation, users will receive the user info of the user being impersonated. If impersonation or // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. message SelfSubjectReview { - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional optional SelfSubjectReviewStatus status = 2; } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. message SelfSubjectReviewStatus { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional optional .k8s.io.api.authentication.v1.UserInfo userInfo = 1; } diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types.go b/vendor/k8s.io/api/authentication/v1alpha1/types.go index 1ee3612fbc..7e02470c96 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/types.go +++ b/vendor/k8s.io/api/authentication/v1alpha1/types.go @@ -32,17 +32,18 @@ import ( // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. type SelfSubjectReview struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. type SelfSubjectReviewStatus struct { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional UserInfo v1.UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` } diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go index 1ffcc99e7d..95ce0287cf 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go @@ -29,8 +29,8 @@ package v1alpha1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_SelfSubjectReview = map[string]string{ "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "status": "Status is filled in by the server with the user attributes.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "status is filled in by the server with the user attributes.", } func (SelfSubjectReview) SwaggerDoc() map[string]string { @@ -39,7 +39,7 @@ func (SelfSubjectReview) SwaggerDoc() map[string]string { var map_SelfSubjectReviewStatus = map[string]string{ "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", - "userInfo": "User attributes of the user making this request.", + "userInfo": "userInfo is a set of attributes belonging to the user making this request.", } func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.proto b/vendor/k8s.io/api/authentication/v1beta1/generated.proto index d0f6fe4402..999c65156d 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1beta1/generated.proto @@ -42,18 +42,19 @@ message ExtraValue { // When using impersonation, users will receive the user info of the user being impersonated. If impersonation or // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. message SelfSubjectReview { - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional optional SelfSubjectReviewStatus status = 2; } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. message SelfSubjectReviewStatus { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional optional .k8s.io.api.authentication.v1.UserInfo userInfo = 1; } @@ -62,26 +63,27 @@ message SelfSubjectReviewStatus { // Note: TokenReview requests may be cached by the webhook token authenticator // plugin in the kube-apiserver. message TokenReview { - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +required optional TokenReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the token can be authenticated. + // status is filled in by the server and indicates whether the token can be authenticated. // +optional optional TokenReviewStatus status = 3; } // TokenReviewSpec is a description of the token authentication request. message TokenReviewSpec { - // Token is the opaque bearer token. - // +optional + // token is the opaque bearer token. + // +required optional string token = 1; - // Audiences is a list of the identifiers that the resource server presented + // audiences is a list of the identifiers that the resource server presented // with the token identifies as. Audience-aware token authenticators will // verify that the token was intended for at least one of the audiences in // this list. If no audiences are provided, the audience will default to the @@ -93,15 +95,15 @@ message TokenReviewSpec { // TokenReviewStatus is the result of the token authentication request. message TokenReviewStatus { - // Authenticated indicates that the token was associated with a known user. + // authenticated indicates that the token was associated with a known user. // +optional optional bool authenticated = 1; - // User is the UserInfo associated with the provided token. + // user is the UserInfo associated with the provided token. // +optional optional UserInfo user = 2; - // Audiences are audience identifiers chosen by the authenticator that are + // audiences are audience identifiers chosen by the authenticator that are // compatible with both the TokenReview and token. An identifier is any // identifier in the intersection of the TokenReviewSpec audiences and the // token's audiences. A client of the TokenReview API that sets the @@ -114,7 +116,7 @@ message TokenReviewStatus { // +listType=atomic repeated string audiences = 4; - // Error indicates that the token couldn't be checked + // error indicates that the token couldn't be checked // +optional optional string error = 3; } @@ -122,22 +124,22 @@ message TokenReviewStatus { // UserInfo holds the information about the user needed to implement the // user.Info interface. message UserInfo { - // The name that uniquely identifies this user among all active users. + // username is the name that uniquely identifies this user among all active users. // +optional optional string username = 1; - // A unique value that identifies this user across time. If this user is + // uid is a unique value that identifies this user across time. If this user is // deleted and another user by the same name is added, they will have // different UIDs. // +optional optional string uid = 2; - // The names of groups this user is a part of. + // groups is the names of groups this user is a part of. // +optional // +listType=atomic repeated string groups = 3; - // Any additional information provided by the authenticator. + // extra is any additional information provided by the authenticator. // +optional map extra = 4; } diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/authentication/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index a55034da99..0000000000 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ExtraValue) ProtoMessage() {} - -func (*SelfSubjectReview) ProtoMessage() {} - -func (*SelfSubjectReviewStatus) ProtoMessage() {} - -func (*TokenReview) ProtoMessage() {} - -func (*TokenReviewSpec) ProtoMessage() {} - -func (*TokenReviewStatus) ProtoMessage() {} - -func (*UserInfo) ProtoMessage() {} diff --git a/vendor/k8s.io/api/authentication/v1beta1/types.go b/vendor/k8s.io/api/authentication/v1beta1/types.go index 8038ef7d34..33dacdb723 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types.go @@ -36,25 +36,26 @@ import ( // plugin in the kube-apiserver. type TokenReview struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated + // +required Spec TokenReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the token can be authenticated. + // status is filled in by the server and indicates whether the token can be authenticated. // +optional Status TokenReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // TokenReviewSpec is a description of the token authentication request. type TokenReviewSpec struct { - // Token is the opaque bearer token. - // +optional + // token is the opaque bearer token. + // +required Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"` - // Audiences is a list of the identifiers that the resource server presented + // audiences is a list of the identifiers that the resource server presented // with the token identifies as. Audience-aware token authenticators will // verify that the token was intended for at least one of the audiences in // this list. If no audiences are provided, the audience will default to the @@ -66,13 +67,13 @@ type TokenReviewSpec struct { // TokenReviewStatus is the result of the token authentication request. type TokenReviewStatus struct { - // Authenticated indicates that the token was associated with a known user. + // authenticated indicates that the token was associated with a known user. // +optional Authenticated bool `json:"authenticated,omitempty" protobuf:"varint,1,opt,name=authenticated"` - // User is the UserInfo associated with the provided token. + // user is the UserInfo associated with the provided token. // +optional User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"` - // Audiences are audience identifiers chosen by the authenticator that are + // audiences are audience identifiers chosen by the authenticator that are // compatible with both the TokenReview and token. An identifier is any // identifier in the intersection of the TokenReviewSpec audiences and the // token's audiences. A client of the TokenReview API that sets the @@ -84,7 +85,7 @@ type TokenReviewStatus struct { // +optional // +listType=atomic Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"` - // Error indicates that the token couldn't be checked + // error indicates that the token couldn't be checked // +optional Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"` } @@ -92,19 +93,19 @@ type TokenReviewStatus struct { // UserInfo holds the information about the user needed to implement the // user.Info interface. type UserInfo struct { - // The name that uniquely identifies this user among all active users. + // username is the name that uniquely identifies this user among all active users. // +optional Username string `json:"username,omitempty" protobuf:"bytes,1,opt,name=username"` - // A unique value that identifies this user across time. If this user is + // uid is a unique value that identifies this user across time. If this user is // deleted and another user by the same name is added, they will have // different UIDs. // +optional UID string `json:"uid,omitempty" protobuf:"bytes,2,opt,name=uid"` - // The names of groups this user is a part of. + // groups is the names of groups this user is a part of. // +optional // +listType=atomic Groups []string `json:"groups,omitempty" protobuf:"bytes,3,rep,name=groups"` - // Any additional information provided by the authenticator. + // extra is any additional information provided by the authenticator. // +optional Extra map[string]ExtraValue `json:"extra,omitempty" protobuf:"bytes,4,rep,name=extra"` } @@ -129,17 +130,18 @@ func (t ExtraValue) String() string { // request header authentication is used, any extra keys will have their case ignored and returned as lowercase. type SelfSubjectReview struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. + // metadata is the standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Status is filled in by the server with the user attributes. + // status is filled in by the server with the user attributes. + // +optional Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` } // SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. type SelfSubjectReviewStatus struct { - // User attributes of the user making this request. + // userInfo is a set of attributes belonging to the user making this request. // +optional UserInfo v1.UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` } diff --git a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go index d6644f2cf9..31dadf968e 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go @@ -29,8 +29,8 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_SelfSubjectReview = map[string]string{ "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "status": "Status is filled in by the server with the user attributes.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "status is filled in by the server with the user attributes.", } func (SelfSubjectReview) SwaggerDoc() map[string]string { @@ -39,7 +39,7 @@ func (SelfSubjectReview) SwaggerDoc() map[string]string { var map_SelfSubjectReviewStatus = map[string]string{ "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", - "userInfo": "User attributes of the user making this request.", + "userInfo": "userInfo is a set of attributes belonging to the user making this request.", } func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { @@ -48,9 +48,9 @@ func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { var map_TokenReview = map[string]string{ "": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated", - "status": "Status is filled in by the server and indicates whether the token can be authenticated.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated", + "status": "status is filled in by the server and indicates whether the token can be authenticated.", } func (TokenReview) SwaggerDoc() map[string]string { @@ -59,8 +59,8 @@ func (TokenReview) SwaggerDoc() map[string]string { var map_TokenReviewSpec = map[string]string{ "": "TokenReviewSpec is a description of the token authentication request.", - "token": "Token is the opaque bearer token.", - "audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.", + "token": "token is the opaque bearer token.", + "audiences": "audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.", } func (TokenReviewSpec) SwaggerDoc() map[string]string { @@ -69,10 +69,10 @@ func (TokenReviewSpec) SwaggerDoc() map[string]string { var map_TokenReviewStatus = map[string]string{ "": "TokenReviewStatus is the result of the token authentication request.", - "authenticated": "Authenticated indicates that the token was associated with a known user.", - "user": "User is the UserInfo associated with the provided token.", - "audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.", - "error": "Error indicates that the token couldn't be checked", + "authenticated": "authenticated indicates that the token was associated with a known user.", + "user": "user is the UserInfo associated with the provided token.", + "audiences": "audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.", + "error": "error indicates that the token couldn't be checked", } func (TokenReviewStatus) SwaggerDoc() map[string]string { @@ -81,10 +81,10 @@ func (TokenReviewStatus) SwaggerDoc() map[string]string { var map_UserInfo = map[string]string{ "": "UserInfo holds the information about the user needed to implement the user.Info interface.", - "username": "The name that uniquely identifies this user among all active users.", - "uid": "A unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs.", - "groups": "The names of groups this user is a part of.", - "extra": "Any additional information provided by the authenticator.", + "username": "username is the name that uniquely identifies this user among all active users.", + "uid": "uid is a unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs.", + "groups": "groups is the names of groups this user is a part of.", + "extra": "extra is any additional information provided by the authenticator.", } func (UserInfo) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/authorization/v1/generated.proto b/vendor/k8s.io/api/authorization/v1/generated.proto index ff529c969e..c47449f911 100644 --- a/vendor/k8s.io/api/authorization/v1/generated.proto +++ b/vendor/k8s.io/api/authorization/v1/generated.proto @@ -95,38 +95,38 @@ message LabelSelectorAttributes { // Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions // checking. message LocalSubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace + // spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // you made the request against. If empty, it is defaulted. optional SubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } // NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface message NonResourceAttributes { - // Path is the URL path of the request + // path is the URL path of the request // +optional optional string path = 1; - // Verb is the standard HTTP verb + // verb is the standard HTTP verb // +optional optional string verb = 2; } // NonResourceRule holds information that describes a rule for the non-resource message NonResourceRule { - // Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. + // verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. // +listType=atomic repeated string verbs = 1; - // NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, + // nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, // final step in the path. "*" means all. // +optional // +listType=atomic @@ -135,34 +135,34 @@ message NonResourceRule { // ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface message ResourceAttributes { - // Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + // namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces // "" (empty) is defaulted for LocalSubjectAccessReviews // "" (empty) is empty for cluster-scoped resources // "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview // +optional optional string namespace = 1; - // Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. // +optional optional string verb = 2; - // Group is the API Group of the Resource. "*" means all. + // group is the API Group of the Resource. "*" means all. // +optional optional string group = 3; - // Version is the API Version of the Resource. "*" means all. + // version is the API Version of the Resource. "*" means all. // +optional optional string version = 4; - // Resource is one of the existing resource types. "*" means all. + // resource is one of the existing resource types. "*" means all. // +optional optional string resource = 5; - // Subresource is one of the existing resource types. "" means none. + // subresource is one of the existing resource types. "" means none. // +optional optional string subresource = 6; - // Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. + // name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. // +optional optional string name = 7; @@ -178,23 +178,23 @@ message ResourceAttributes { // ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, // may contain duplicates, and possibly be incomplete. message ResourceRule { - // Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. // +listType=atomic repeated string verbs = 1; - // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + // apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of // the enumerated resources in any API group will be allowed. "*" means all. // +optional // +listType=atomic repeated string apiGroups = 2; - // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional // +listType=atomic repeated string resources = 3; - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. // +optional // +listType=atomic repeated string resourceNames = 4; @@ -204,27 +204,27 @@ message ResourceRule { // spec.namespace means "in all namespaces". Self is a special case, because users should always be able // to check whether they can perform an action message SelfSubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. user and groups must be empty + // spec holds information about the request being evaluated. user and groups must be empty optional SelfSubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } -// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set message SelfSubjectAccessReviewSpec { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional optional ResourceAttributes resourceAttributes = 1; - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional optional NonResourceAttributes nonResourceAttributes = 2; } @@ -236,88 +236,88 @@ message SelfSubjectAccessReviewSpec { // drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. // SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server. message SelfSubjectRulesReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. + // spec holds information about the request being evaluated. optional SelfSubjectRulesReviewSpec spec = 2; - // Status is filled in by the server and indicates the set of actions a user can perform. + // status is filled in by the server and indicates the set of actions a user can perform. // +optional optional SubjectRulesReviewStatus status = 3; } // SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview. message SelfSubjectRulesReviewSpec { - // Namespace to evaluate rules for. Required. + // namespace to evaluate rules for. Required. optional string namespace = 1; } // SubjectAccessReview checks whether or not a user or group can perform an action. message SubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated optional SubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } -// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set message SubjectAccessReviewSpec { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional optional ResourceAttributes resourceAttributes = 1; - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional optional NonResourceAttributes nonResourceAttributes = 2; - // User is the user you're testing for. + // user is the user you're testing for. // If you specify "User" but not "Groups", then is it interpreted as "What if User were not a member of any groups // +optional optional string user = 3; - // Groups is the groups you're testing for. + // groups is the groups you're testing for. // +optional // +listType=atomic repeated string groups = 4; - // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer + // extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // it needs a reflection here. // +optional map extra = 5; - // UID information about the requesting user. + // uid information about the requesting user. // +optional optional string uid = 6; } // SubjectAccessReviewStatus message SubjectAccessReviewStatus { - // Allowed is required. True if the action would be allowed, false otherwise. + // allowed is required. True if the action would be allowed, false otherwise. optional bool allowed = 1; - // Denied is optional. True if the action would be denied, otherwise + // denied is optional. True if the action would be denied, otherwise // false. If both allowed is false and denied is false, then the // authorizer has no opinion on whether to authorize the action. Denied // may not be true if Allowed is true. // +optional optional bool denied = 4; - // Reason is optional. It indicates why a request was allowed or denied. + // reason is optional. It indicates why a request was allowed or denied. // +optional optional string reason = 2; - // EvaluationError is an indication that some error occurred during the authorization check. + // evaluationError is an indication that some error occurred during the authorization check. // It is entirely possible to get an error and be able to continue determine authorization status in spite of it. // For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request. // +optional @@ -329,21 +329,21 @@ message SubjectAccessReviewStatus { // Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, // even if that list is incomplete. message SubjectRulesReviewStatus { - // ResourceRules is the list of actions the subject is allowed to perform on resources. + // resourceRules is the list of actions the subject is allowed to perform on resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic repeated ResourceRule resourceRules = 1; - // NonResourceRules is the list of actions the subject is allowed to perform on non-resources. + // nonResourceRules is the list of actions the subject is allowed to perform on non-resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic repeated NonResourceRule nonResourceRules = 2; - // Incomplete is true when the rules returned by this call are incomplete. This is most commonly + // incomplete is true when the rules returned by this call are incomplete. This is most commonly // encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation. optional bool incomplete = 3; - // EvaluationError can appear in combination with Rules. It indicates an error occurred during + // evaluationError can appear in combination with Rules. It indicates an error occurred during // rule evaluation, such as an authorizer that doesn't support rule evaluation, and that // ResourceRules and/or NonResourceRules may be incomplete. // +optional diff --git a/vendor/k8s.io/api/authorization/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/authorization/v1/generated.protomessage.pb.go deleted file mode 100644 index dc1e1028c0..0000000000 --- a/vendor/k8s.io/api/authorization/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,54 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*ExtraValue) ProtoMessage() {} - -func (*FieldSelectorAttributes) ProtoMessage() {} - -func (*LabelSelectorAttributes) ProtoMessage() {} - -func (*LocalSubjectAccessReview) ProtoMessage() {} - -func (*NonResourceAttributes) ProtoMessage() {} - -func (*NonResourceRule) ProtoMessage() {} - -func (*ResourceAttributes) ProtoMessage() {} - -func (*ResourceRule) ProtoMessage() {} - -func (*SelfSubjectAccessReview) ProtoMessage() {} - -func (*SelfSubjectAccessReviewSpec) ProtoMessage() {} - -func (*SelfSubjectRulesReview) ProtoMessage() {} - -func (*SelfSubjectRulesReviewSpec) ProtoMessage() {} - -func (*SubjectAccessReview) ProtoMessage() {} - -func (*SubjectAccessReviewSpec) ProtoMessage() {} - -func (*SubjectAccessReviewStatus) ProtoMessage() {} - -func (*SubjectRulesReviewStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/authorization/v1/types.go b/vendor/k8s.io/api/authorization/v1/types.go index 251e776b02..dcc9b0f853 100644 --- a/vendor/k8s.io/api/authorization/v1/types.go +++ b/vendor/k8s.io/api/authorization/v1/types.go @@ -31,15 +31,15 @@ import ( // SubjectAccessReview checks whether or not a user or group can perform an action. type SubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -55,15 +55,15 @@ type SubjectAccessReview struct { // to check whether they can perform an action type SelfSubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. user and groups must be empty + // spec holds information about the request being evaluated. user and groups must be empty Spec SelfSubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -78,44 +78,44 @@ type SelfSubjectAccessReview struct { // checking. type LocalSubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace + // spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // you made the request against. If empty, it is defaulted. Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface type ResourceAttributes struct { - // Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + // namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces // "" (empty) is defaulted for LocalSubjectAccessReviews // "" (empty) is empty for cluster-scoped resources // "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` - // Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. // +optional Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"` - // Group is the API Group of the Resource. "*" means all. + // group is the API Group of the Resource. "*" means all. // +optional Group string `json:"group,omitempty" protobuf:"bytes,3,opt,name=group"` - // Version is the API Version of the Resource. "*" means all. + // version is the API Version of the Resource. "*" means all. // +optional Version string `json:"version,omitempty" protobuf:"bytes,4,opt,name=version"` - // Resource is one of the existing resource types. "*" means all. + // resource is one of the existing resource types. "*" means all. // +optional Resource string `json:"resource,omitempty" protobuf:"bytes,5,opt,name=resource"` - // Subresource is one of the existing resource types. "" means none. + // subresource is one of the existing resource types. "" means none. // +optional Subresource string `json:"subresource,omitempty" protobuf:"bytes,6,opt,name=subresource"` - // Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. + // name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. // +optional Name string `json:"name,omitempty" protobuf:"bytes,7,opt,name=name"` // fieldSelector describes the limitation on access based on field. It can only limit access, not broaden it. @@ -182,37 +182,37 @@ type FieldSelectorAttributes struct { // NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface type NonResourceAttributes struct { - // Path is the URL path of the request + // path is the URL path of the request // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // Verb is the standard HTTP verb + // verb is the standard HTTP verb // +optional Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"` } -// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set type SubjectAccessReviewSpec struct { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"` - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"` - // User is the user you're testing for. + // user is the user you're testing for. // If you specify "User" but not "Groups", then is it interpreted as "What if User were not a member of any groups // +optional User string `json:"user,omitempty" protobuf:"bytes,3,opt,name=user"` - // Groups is the groups you're testing for. + // groups is the groups you're testing for. // +optional // +listType=atomic Groups []string `json:"groups,omitempty" protobuf:"bytes,4,rep,name=groups"` - // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer + // extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // it needs a reflection here. // +optional Extra map[string]ExtraValue `json:"extra,omitempty" protobuf:"bytes,5,rep,name=extra"` - // UID information about the requesting user. + // uid information about the requesting user. // +optional UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"` } @@ -226,31 +226,31 @@ func (t ExtraValue) String() string { return fmt.Sprintf("%v", []string(t)) } -// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set type SelfSubjectAccessReviewSpec struct { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"` - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"` } // SubjectAccessReviewStatus type SubjectAccessReviewStatus struct { - // Allowed is required. True if the action would be allowed, false otherwise. + // allowed is required. True if the action would be allowed, false otherwise. Allowed bool `json:"allowed" protobuf:"varint,1,opt,name=allowed"` - // Denied is optional. True if the action would be denied, otherwise + // denied is optional. True if the action would be denied, otherwise // false. If both allowed is false and denied is false, then the // authorizer has no opinion on whether to authorize the action. Denied // may not be true if Allowed is true. // +optional Denied bool `json:"denied,omitempty" protobuf:"varint,4,opt,name=denied"` - // Reason is optional. It indicates why a request was allowed or denied. + // reason is optional. It indicates why a request was allowed or denied. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,2,opt,name=reason"` - // EvaluationError is an indication that some error occurred during the authorization check. + // evaluationError is an indication that some error occurred during the authorization check. // It is entirely possible to get an error and be able to continue determine authorization status in spite of it. // For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request. // +optional @@ -271,22 +271,22 @@ type SubjectAccessReviewStatus struct { // SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server. type SelfSubjectRulesReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. + // spec holds information about the request being evaluated. Spec SelfSubjectRulesReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates the set of actions a user can perform. + // status is filled in by the server and indicates the set of actions a user can perform. // +optional Status SubjectRulesReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview. type SelfSubjectRulesReviewSpec struct { - // Namespace to evaluate rules for. Required. + // namespace to evaluate rules for. Required. Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` } @@ -295,18 +295,18 @@ type SelfSubjectRulesReviewSpec struct { // Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, // even if that list is incomplete. type SubjectRulesReviewStatus struct { - // ResourceRules is the list of actions the subject is allowed to perform on resources. + // resourceRules is the list of actions the subject is allowed to perform on resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic ResourceRules []ResourceRule `json:"resourceRules" protobuf:"bytes,1,rep,name=resourceRules"` - // NonResourceRules is the list of actions the subject is allowed to perform on non-resources. + // nonResourceRules is the list of actions the subject is allowed to perform on non-resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic NonResourceRules []NonResourceRule `json:"nonResourceRules" protobuf:"bytes,2,rep,name=nonResourceRules"` - // Incomplete is true when the rules returned by this call are incomplete. This is most commonly + // incomplete is true when the rules returned by this call are incomplete. This is most commonly // encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation. Incomplete bool `json:"incomplete" protobuf:"bytes,3,rep,name=incomplete"` - // EvaluationError can appear in combination with Rules. It indicates an error occurred during + // evaluationError can appear in combination with Rules. It indicates an error occurred during // rule evaluation, such as an authorizer that doesn't support rule evaluation, and that // ResourceRules and/or NonResourceRules may be incomplete. // +optional @@ -316,21 +316,21 @@ type SubjectRulesReviewStatus struct { // ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, // may contain duplicates, and possibly be incomplete. type ResourceRule struct { - // Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. // +listType=atomic Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` - // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + // apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of // the enumerated resources in any API group will be allowed. "*" means all. // +optional // +listType=atomic APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` - // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional // +listType=atomic Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. // +optional // +listType=atomic ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,4,rep,name=resourceNames"` @@ -338,11 +338,11 @@ type ResourceRule struct { // NonResourceRule holds information that describes a rule for the non-resource type NonResourceRule struct { - // Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. + // verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. // +listType=atomic Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` - // NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, + // nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, // final step in the path. "*" means all. // +optional // +listType=atomic diff --git a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go index 29d0aa8463..0b3ae19a59 100644 --- a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go @@ -49,9 +49,9 @@ func (LabelSelectorAttributes) SwaggerDoc() map[string]string { var map_LocalSubjectAccessReview = map[string]string{ "": "LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions checking.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (LocalSubjectAccessReview) SwaggerDoc() map[string]string { @@ -60,8 +60,8 @@ func (LocalSubjectAccessReview) SwaggerDoc() map[string]string { var map_NonResourceAttributes = map[string]string{ "": "NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface", - "path": "Path is the URL path of the request", - "verb": "Verb is the standard HTTP verb", + "path": "path is the URL path of the request", + "verb": "verb is the standard HTTP verb", } func (NonResourceAttributes) SwaggerDoc() map[string]string { @@ -70,8 +70,8 @@ func (NonResourceAttributes) SwaggerDoc() map[string]string { var map_NonResourceRule = map[string]string{ "": "NonResourceRule holds information that describes a rule for the non-resource", - "verbs": "Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. \"*\" means all.", - "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path. \"*\" means all.", + "verbs": "verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. \"*\" means all.", + "nonResourceURLs": "nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path. \"*\" means all.", } func (NonResourceRule) SwaggerDoc() map[string]string { @@ -80,13 +80,13 @@ func (NonResourceRule) SwaggerDoc() map[string]string { var map_ResourceAttributes = map[string]string{ "": "ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface", - "namespace": "Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces \"\" (empty) is defaulted for LocalSubjectAccessReviews \"\" (empty) is empty for cluster-scoped resources \"\" (empty) means \"all\" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview", - "verb": "Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", - "group": "Group is the API Group of the Resource. \"*\" means all.", - "version": "Version is the API Version of the Resource. \"*\" means all.", - "resource": "Resource is one of the existing resource types. \"*\" means all.", - "subresource": "Subresource is one of the existing resource types. \"\" means none.", - "name": "Name is the name of the resource being requested for a \"get\" or deleted for a \"delete\". \"\" (empty) means all.", + "namespace": "namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces \"\" (empty) is defaulted for LocalSubjectAccessReviews \"\" (empty) is empty for cluster-scoped resources \"\" (empty) means \"all\" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview", + "verb": "verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", + "group": "group is the API Group of the Resource. \"*\" means all.", + "version": "version is the API Version of the Resource. \"*\" means all.", + "resource": "resource is one of the existing resource types. \"*\" means all.", + "subresource": "subresource is one of the existing resource types. \"\" means none.", + "name": "name is the name of the resource being requested for a \"get\" or deleted for a \"delete\". \"\" (empty) means all.", "fieldSelector": "fieldSelector describes the limitation on access based on field. It can only limit access, not broaden it.", "labelSelector": "labelSelector describes the limitation on access based on labels. It can only limit access, not broaden it.", } @@ -97,10 +97,10 @@ func (ResourceAttributes) SwaggerDoc() map[string]string { var map_ResourceRule = map[string]string{ "": "ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "verbs": "Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", - "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", - "resources": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", - "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", + "verbs": "verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", + "apiGroups": "apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", + "resources": "resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", + "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", } func (ResourceRule) SwaggerDoc() map[string]string { @@ -109,9 +109,9 @@ func (ResourceRule) SwaggerDoc() map[string]string { var map_SelfSubjectAccessReview = map[string]string{ "": "SelfSubjectAccessReview checks whether or the current user can perform an action. Not filling in a spec.namespace means \"in all namespaces\". Self is a special case, because users should always be able to check whether they can perform an action", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated. user and groups must be empty", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated. user and groups must be empty", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (SelfSubjectAccessReview) SwaggerDoc() map[string]string { @@ -119,9 +119,9 @@ func (SelfSubjectAccessReview) SwaggerDoc() map[string]string { } var map_SelfSubjectAccessReviewSpec = map[string]string{ - "": "SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set", - "resourceAttributes": "ResourceAuthorizationAttributes describes information for a resource access request", - "nonResourceAttributes": "NonResourceAttributes describes information for a non-resource access request", + "": "SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes and nonResourceAttributes must be set", + "resourceAttributes": "resourceAttributes describes information for a resource access request", + "nonResourceAttributes": "nonResourceAttributes describes information for a non-resource access request", } func (SelfSubjectAccessReviewSpec) SwaggerDoc() map[string]string { @@ -130,9 +130,9 @@ func (SelfSubjectAccessReviewSpec) SwaggerDoc() map[string]string { var map_SelfSubjectRulesReview = map[string]string{ "": "SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. The returned list of actions may be incomplete depending on the server's authorization mode, and any errors experienced during the evaluation. SelfSubjectRulesReview should be used by UIs to show/hide actions, or to quickly let an end user reason about their permissions. It should NOT Be used by external systems to drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated.", - "status": "Status is filled in by the server and indicates the set of actions a user can perform.", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated.", + "status": "status is filled in by the server and indicates the set of actions a user can perform.", } func (SelfSubjectRulesReview) SwaggerDoc() map[string]string { @@ -141,7 +141,7 @@ func (SelfSubjectRulesReview) SwaggerDoc() map[string]string { var map_SelfSubjectRulesReviewSpec = map[string]string{ "": "SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview.", - "namespace": "Namespace to evaluate rules for. Required.", + "namespace": "namespace to evaluate rules for. Required.", } func (SelfSubjectRulesReviewSpec) SwaggerDoc() map[string]string { @@ -150,9 +150,9 @@ func (SelfSubjectRulesReviewSpec) SwaggerDoc() map[string]string { var map_SubjectAccessReview = map[string]string{ "": "SubjectAccessReview checks whether or not a user or group can perform an action.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (SubjectAccessReview) SwaggerDoc() map[string]string { @@ -160,13 +160,13 @@ func (SubjectAccessReview) SwaggerDoc() map[string]string { } var map_SubjectAccessReviewSpec = map[string]string{ - "": "SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set", - "resourceAttributes": "ResourceAuthorizationAttributes describes information for a resource access request", - "nonResourceAttributes": "NonResourceAttributes describes information for a non-resource access request", - "user": "User is the user you're testing for. If you specify \"User\" but not \"Groups\", then is it interpreted as \"What if User were not a member of any groups", - "groups": "Groups is the groups you're testing for.", - "extra": "Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer it needs a reflection here.", - "uid": "UID information about the requesting user.", + "": "SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes and nonResourceAttributes must be set", + "resourceAttributes": "resourceAttributes describes information for a resource access request", + "nonResourceAttributes": "nonResourceAttributes describes information for a non-resource access request", + "user": "user is the user you're testing for. If you specify \"User\" but not \"Groups\", then is it interpreted as \"What if User were not a member of any groups", + "groups": "groups is the groups you're testing for.", + "extra": "extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer it needs a reflection here.", + "uid": "uid information about the requesting user.", } func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string { @@ -175,10 +175,10 @@ func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string { var map_SubjectAccessReviewStatus = map[string]string{ "": "SubjectAccessReviewStatus", - "allowed": "Allowed is required. True if the action would be allowed, false otherwise.", - "denied": "Denied is optional. True if the action would be denied, otherwise false. If both allowed is false and denied is false, then the authorizer has no opinion on whether to authorize the action. Denied may not be true if Allowed is true.", - "reason": "Reason is optional. It indicates why a request was allowed or denied.", - "evaluationError": "EvaluationError is an indication that some error occurred during the authorization check. It is entirely possible to get an error and be able to continue determine authorization status in spite of it. For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.", + "allowed": "allowed is required. True if the action would be allowed, false otherwise.", + "denied": "denied is optional. True if the action would be denied, otherwise false. If both allowed is false and denied is false, then the authorizer has no opinion on whether to authorize the action. Denied may not be true if Allowed is true.", + "reason": "reason is optional. It indicates why a request was allowed or denied.", + "evaluationError": "evaluationError is an indication that some error occurred during the authorization check. It is entirely possible to get an error and be able to continue determine authorization status in spite of it. For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.", } func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string { @@ -187,10 +187,10 @@ func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string { var map_SubjectRulesReviewStatus = map[string]string{ "": "SubjectRulesReviewStatus contains the result of a rules check. This check can be incomplete depending on the set of authorizers the server is configured with and any errors experienced during evaluation. Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, even if that list is incomplete.", - "resourceRules": "ResourceRules is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "nonResourceRules": "NonResourceRules is the list of actions the subject is allowed to perform on non-resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "incomplete": "Incomplete is true when the rules returned by this call are incomplete. This is most commonly encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation.", - "evaluationError": "EvaluationError can appear in combination with Rules. It indicates an error occurred during rule evaluation, such as an authorizer that doesn't support rule evaluation, and that ResourceRules and/or NonResourceRules may be incomplete.", + "resourceRules": "resourceRules is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", + "nonResourceRules": "nonResourceRules is the list of actions the subject is allowed to perform on non-resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", + "incomplete": "incomplete is true when the rules returned by this call are incomplete. This is most commonly encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation.", + "evaluationError": "evaluationError can appear in combination with Rules. It indicates an error occurred during rule evaluation, such as an authorizer that doesn't support rule evaluation, and that ResourceRules and/or NonResourceRules may be incomplete.", } func (SubjectRulesReviewStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/authorization/v1beta1/generated.proto b/vendor/k8s.io/api/authorization/v1beta1/generated.proto index 8738768b89..8095ab4dbb 100644 --- a/vendor/k8s.io/api/authorization/v1beta1/generated.proto +++ b/vendor/k8s.io/api/authorization/v1beta1/generated.proto @@ -42,38 +42,38 @@ message ExtraValue { // Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions // checking. message LocalSubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace + // spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // you made the request against. If empty, it is defaulted. optional SubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } // NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface message NonResourceAttributes { - // Path is the URL path of the request + // path is the URL path of the request // +optional optional string path = 1; - // Verb is the standard HTTP verb + // verb is the standard HTTP verb // +optional optional string verb = 2; } // NonResourceRule holds information that describes a rule for the non-resource message NonResourceRule { - // Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. + // verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. // +listType=atomic repeated string verbs = 1; - // NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, + // nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, // final step in the path. "*" means all. // +optional // +listType=atomic @@ -82,34 +82,34 @@ message NonResourceRule { // ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface message ResourceAttributes { - // Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + // namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces // "" (empty) is defaulted for LocalSubjectAccessReviews // "" (empty) is empty for cluster-scoped resources // "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview // +optional optional string namespace = 1; - // Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. // +optional optional string verb = 2; - // Group is the API Group of the Resource. "*" means all. + // group is the API Group of the Resource. "*" means all. // +optional optional string group = 3; - // Version is the API Version of the Resource. "*" means all. + // version is the API Version of the Resource. "*" means all. // +optional optional string version = 4; - // Resource is one of the existing resource types. "*" means all. + // resource is one of the existing resource types. "*" means all. // +optional optional string resource = 5; - // Subresource is one of the existing resource types. "" means none. + // subresource is one of the existing resource types. "" means none. // +optional optional string subresource = 6; - // Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. + // name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. // +optional optional string name = 7; @@ -125,23 +125,23 @@ message ResourceAttributes { // ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, // may contain duplicates, and possibly be incomplete. message ResourceRule { - // Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. // +listType=atomic repeated string verbs = 1; - // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + // apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of // the enumerated resources in any API group will be allowed. "*" means all. // +optional // +listType=atomic repeated string apiGroups = 2; - // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional // +listType=atomic repeated string resources = 3; - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. // +optional // +listType=atomic repeated string resourceNames = 4; @@ -151,27 +151,27 @@ message ResourceRule { // spec.namespace means "in all namespaces". Self is a special case, because users should always be able // to check whether they can perform an action message SelfSubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. user and groups must be empty + // spec holds information about the request being evaluated. user and groups must be empty optional SelfSubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } -// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set message SelfSubjectAccessReviewSpec { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional optional ResourceAttributes resourceAttributes = 1; - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional optional NonResourceAttributes nonResourceAttributes = 2; } @@ -183,88 +183,88 @@ message SelfSubjectAccessReviewSpec { // drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. // SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server. message SelfSubjectRulesReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated. + // spec holds information about the request being evaluated. optional SelfSubjectRulesReviewSpec spec = 2; - // Status is filled in by the server and indicates the set of actions a user can perform. + // status is filled in by the server and indicates the set of actions a user can perform. // +optional optional SubjectRulesReviewStatus status = 3; } // SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview. message SelfSubjectRulesReviewSpec { - // Namespace to evaluate rules for. Required. + // namespace to evaluate rules for. Required. optional string namespace = 1; } // SubjectAccessReview checks whether or not a user or group can perform an action. message SubjectAccessReview { - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated optional SubjectAccessReviewSpec spec = 2; - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional optional SubjectAccessReviewStatus status = 3; } -// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set message SubjectAccessReviewSpec { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional optional ResourceAttributes resourceAttributes = 1; - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional optional NonResourceAttributes nonResourceAttributes = 2; - // User is the user you're testing for. + // user is the user you're testing for. // If you specify "User" but not "Group", then is it interpreted as "What if User were not a member of any groups // +optional optional string user = 3; - // Groups is the groups you're testing for. + // group is the groups you're testing for. // +optional // +listType=atomic repeated string group = 4; - // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer + // extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // it needs a reflection here. // +optional map extra = 5; - // UID information about the requesting user. + // uid information about the requesting user. // +optional optional string uid = 6; } // SubjectAccessReviewStatus message SubjectAccessReviewStatus { - // Allowed is required. True if the action would be allowed, false otherwise. + // allowed is required. True if the action would be allowed, false otherwise. optional bool allowed = 1; - // Denied is optional. True if the action would be denied, otherwise + // denied is optional. True if the action would be denied, otherwise // false. If both allowed is false and denied is false, then the // authorizer has no opinion on whether to authorize the action. Denied // may not be true if Allowed is true. // +optional optional bool denied = 4; - // Reason is optional. It indicates why a request was allowed or denied. + // reason is optional. It indicates why a request was allowed or denied. // +optional optional string reason = 2; - // EvaluationError is an indication that some error occurred during the authorization check. + // evaluationError is an indication that some error occurred during the authorization check. // It is entirely possible to get an error and be able to continue determine authorization status in spite of it. // For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request. // +optional @@ -276,21 +276,21 @@ message SubjectAccessReviewStatus { // Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, // even if that list is incomplete. message SubjectRulesReviewStatus { - // ResourceRules is the list of actions the subject is allowed to perform on resources. + // resourceRules is the list of actions the subject is allowed to perform on resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic repeated ResourceRule resourceRules = 1; - // NonResourceRules is the list of actions the subject is allowed to perform on non-resources. + // nonResourceRules is the list of actions the subject is allowed to perform on non-resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic repeated NonResourceRule nonResourceRules = 2; - // Incomplete is true when the rules returned by this call are incomplete. This is most commonly + // incomplete is true when the rules returned by this call are incomplete. This is most commonly // encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation. optional bool incomplete = 3; - // EvaluationError can appear in combination with Rules. It indicates an error occurred during + // evaluationError can appear in combination with Rules. It indicates an error occurred during // rule evaluation, such as an authorizer that doesn't support rule evaluation, and that // ResourceRules and/or NonResourceRules may be incomplete. // +optional diff --git a/vendor/k8s.io/api/authorization/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/authorization/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 69af1b6c93..0000000000 --- a/vendor/k8s.io/api/authorization/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ExtraValue) ProtoMessage() {} - -func (*LocalSubjectAccessReview) ProtoMessage() {} - -func (*NonResourceAttributes) ProtoMessage() {} - -func (*NonResourceRule) ProtoMessage() {} - -func (*ResourceAttributes) ProtoMessage() {} - -func (*ResourceRule) ProtoMessage() {} - -func (*SelfSubjectAccessReview) ProtoMessage() {} - -func (*SelfSubjectAccessReviewSpec) ProtoMessage() {} - -func (*SelfSubjectRulesReview) ProtoMessage() {} - -func (*SelfSubjectRulesReviewSpec) ProtoMessage() {} - -func (*SubjectAccessReview) ProtoMessage() {} - -func (*SubjectAccessReviewSpec) ProtoMessage() {} - -func (*SubjectAccessReviewStatus) ProtoMessage() {} - -func (*SubjectRulesReviewStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/authorization/v1beta1/types.go b/vendor/k8s.io/api/authorization/v1beta1/types.go index 8b8e5a9867..204559fd20 100644 --- a/vendor/k8s.io/api/authorization/v1beta1/types.go +++ b/vendor/k8s.io/api/authorization/v1beta1/types.go @@ -34,15 +34,15 @@ import ( // SubjectAccessReview checks whether or not a user or group can perform an action. type SubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated + // spec holds information about the request being evaluated Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -60,15 +60,15 @@ type SubjectAccessReview struct { // to check whether they can perform an action type SelfSubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. user and groups must be empty + // spec holds information about the request being evaluated. user and groups must be empty Spec SelfSubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -85,44 +85,44 @@ type SelfSubjectAccessReview struct { // checking. type LocalSubjectAccessReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace + // spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // you made the request against. If empty, it is defaulted. Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates whether the request is allowed or not + // status is filled in by the server and indicates whether the request is allowed or not // +optional Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface type ResourceAttributes struct { - // Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + // namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces // "" (empty) is defaulted for LocalSubjectAccessReviews // "" (empty) is empty for cluster-scoped resources // "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` - // Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. // +optional Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"` - // Group is the API Group of the Resource. "*" means all. + // group is the API Group of the Resource. "*" means all. // +optional Group string `json:"group,omitempty" protobuf:"bytes,3,opt,name=group"` - // Version is the API Version of the Resource. "*" means all. + // version is the API Version of the Resource. "*" means all. // +optional Version string `json:"version,omitempty" protobuf:"bytes,4,opt,name=version"` - // Resource is one of the existing resource types. "*" means all. + // resource is one of the existing resource types. "*" means all. // +optional Resource string `json:"resource,omitempty" protobuf:"bytes,5,opt,name=resource"` - // Subresource is one of the existing resource types. "" means none. + // subresource is one of the existing resource types. "" means none. // +optional Subresource string `json:"subresource,omitempty" protobuf:"bytes,6,opt,name=subresource"` - // Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. + // name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. // +optional Name string `json:"name,omitempty" protobuf:"bytes,7,opt,name=name"` // fieldSelector describes the limitation on access based on field. It can only limit access, not broaden it. @@ -135,37 +135,37 @@ type ResourceAttributes struct { // NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface type NonResourceAttributes struct { - // Path is the URL path of the request + // path is the URL path of the request // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // Verb is the standard HTTP verb + // verb is the standard HTTP verb // +optional Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"` } -// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set type SubjectAccessReviewSpec struct { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"` - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"` - // User is the user you're testing for. + // user is the user you're testing for. // If you specify "User" but not "Group", then is it interpreted as "What if User were not a member of any groups // +optional User string `json:"user,omitempty" protobuf:"bytes,3,opt,name=user"` - // Groups is the groups you're testing for. + // group is the groups you're testing for. // +optional // +listType=atomic Groups []string `json:"group,omitempty" protobuf:"bytes,4,rep,name=group"` - // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer + // extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // it needs a reflection here. // +optional Extra map[string]ExtraValue `json:"extra,omitempty" protobuf:"bytes,5,rep,name=extra"` - // UID information about the requesting user. + // uid information about the requesting user. // +optional UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"` } @@ -179,31 +179,31 @@ func (t ExtraValue) String() string { return fmt.Sprintf("%v", []string(t)) } -// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes -// and NonResourceAuthorizationAttributes must be set +// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes +// and nonResourceAttributes must be set type SelfSubjectAccessReviewSpec struct { - // ResourceAuthorizationAttributes describes information for a resource access request + // resourceAttributes describes information for a resource access request // +optional ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"` - // NonResourceAttributes describes information for a non-resource access request + // nonResourceAttributes describes information for a non-resource access request // +optional NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"` } // SubjectAccessReviewStatus type SubjectAccessReviewStatus struct { - // Allowed is required. True if the action would be allowed, false otherwise. + // allowed is required. True if the action would be allowed, false otherwise. Allowed bool `json:"allowed" protobuf:"varint,1,opt,name=allowed"` - // Denied is optional. True if the action would be denied, otherwise + // denied is optional. True if the action would be denied, otherwise // false. If both allowed is false and denied is false, then the // authorizer has no opinion on whether to authorize the action. Denied // may not be true if Allowed is true. // +optional Denied bool `json:"denied,omitempty" protobuf:"varint,4,opt,name=denied"` - // Reason is optional. It indicates why a request was allowed or denied. + // reason is optional. It indicates why a request was allowed or denied. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,2,opt,name=reason"` - // EvaluationError is an indication that some error occurred during the authorization check. + // evaluationError is an indication that some error occurred during the authorization check. // It is entirely possible to get an error and be able to continue determine authorization status in spite of it. // For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request. // +optional @@ -226,22 +226,22 @@ type SubjectAccessReviewStatus struct { // SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server. type SelfSubjectRulesReview struct { metav1.TypeMeta `json:",inline"` - // Standard list metadata. + // metadata is the standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Spec holds information about the request being evaluated. + // spec holds information about the request being evaluated. Spec SelfSubjectRulesReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status is filled in by the server and indicates the set of actions a user can perform. + // status is filled in by the server and indicates the set of actions a user can perform. // +optional Status SubjectRulesReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview. type SelfSubjectRulesReviewSpec struct { - // Namespace to evaluate rules for. Required. + // namespace to evaluate rules for. Required. Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` } @@ -250,18 +250,18 @@ type SelfSubjectRulesReviewSpec struct { // Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, // even if that list is incomplete. type SubjectRulesReviewStatus struct { - // ResourceRules is the list of actions the subject is allowed to perform on resources. + // resourceRules is the list of actions the subject is allowed to perform on resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic ResourceRules []ResourceRule `json:"resourceRules" protobuf:"bytes,1,rep,name=resourceRules"` - // NonResourceRules is the list of actions the subject is allowed to perform on non-resources. + // nonResourceRules is the list of actions the subject is allowed to perform on non-resources. // The list ordering isn't significant, may contain duplicates, and possibly be incomplete. // +listType=atomic NonResourceRules []NonResourceRule `json:"nonResourceRules" protobuf:"bytes,2,rep,name=nonResourceRules"` - // Incomplete is true when the rules returned by this call are incomplete. This is most commonly + // incomplete is true when the rules returned by this call are incomplete. This is most commonly // encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation. Incomplete bool `json:"incomplete" protobuf:"bytes,3,rep,name=incomplete"` - // EvaluationError can appear in combination with Rules. It indicates an error occurred during + // evaluationError can appear in combination with Rules. It indicates an error occurred during // rule evaluation, such as an authorizer that doesn't support rule evaluation, and that // ResourceRules and/or NonResourceRules may be incomplete. // +optional @@ -271,21 +271,21 @@ type SubjectRulesReviewStatus struct { // ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, // may contain duplicates, and possibly be incomplete. type ResourceRule struct { - // Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. + // verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. "*" means all. // +listType=atomic Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` - // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + // apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of // the enumerated resources in any API group will be allowed. "*" means all. // +optional // +listType=atomic APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` - // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional // +listType=atomic Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. // +optional // +listType=atomic ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,4,rep,name=resourceNames"` @@ -293,11 +293,11 @@ type ResourceRule struct { // NonResourceRule holds information that describes a rule for the non-resource type NonResourceRule struct { - // Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. + // verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. "*" means all. // +listType=atomic Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` - // NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, + // nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, // final step in the path. "*" means all. // +optional // +listType=atomic diff --git a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go index bb1352a2d9..5667187c9d 100644 --- a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go @@ -29,9 +29,9 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_LocalSubjectAccessReview = map[string]string{ "": "LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions checking.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated. spec.namespace must be equal to the namespace you made the request against. If empty, it is defaulted.", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (LocalSubjectAccessReview) SwaggerDoc() map[string]string { @@ -40,8 +40,8 @@ func (LocalSubjectAccessReview) SwaggerDoc() map[string]string { var map_NonResourceAttributes = map[string]string{ "": "NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface", - "path": "Path is the URL path of the request", - "verb": "Verb is the standard HTTP verb", + "path": "path is the URL path of the request", + "verb": "verb is the standard HTTP verb", } func (NonResourceAttributes) SwaggerDoc() map[string]string { @@ -50,8 +50,8 @@ func (NonResourceAttributes) SwaggerDoc() map[string]string { var map_NonResourceRule = map[string]string{ "": "NonResourceRule holds information that describes a rule for the non-resource", - "verbs": "Verb is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. \"*\" means all.", - "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path. \"*\" means all.", + "verbs": "verbs is a list of kubernetes non-resource API verbs, like: get, post, put, delete, patch, head, options. \"*\" means all.", + "nonResourceURLs": "nonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path. \"*\" means all.", } func (NonResourceRule) SwaggerDoc() map[string]string { @@ -60,13 +60,13 @@ func (NonResourceRule) SwaggerDoc() map[string]string { var map_ResourceAttributes = map[string]string{ "": "ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface", - "namespace": "Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces \"\" (empty) is defaulted for LocalSubjectAccessReviews \"\" (empty) is empty for cluster-scoped resources \"\" (empty) means \"all\" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview", - "verb": "Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", - "group": "Group is the API Group of the Resource. \"*\" means all.", - "version": "Version is the API Version of the Resource. \"*\" means all.", - "resource": "Resource is one of the existing resource types. \"*\" means all.", - "subresource": "Subresource is one of the existing resource types. \"\" means none.", - "name": "Name is the name of the resource being requested for a \"get\" or deleted for a \"delete\". \"\" (empty) means all.", + "namespace": "namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces \"\" (empty) is defaulted for LocalSubjectAccessReviews \"\" (empty) is empty for cluster-scoped resources \"\" (empty) means \"all\" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview", + "verb": "verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", + "group": "group is the API Group of the Resource. \"*\" means all.", + "version": "version is the API Version of the Resource. \"*\" means all.", + "resource": "resource is one of the existing resource types. \"*\" means all.", + "subresource": "subresource is one of the existing resource types. \"\" means none.", + "name": "name is the name of the resource being requested for a \"get\" or deleted for a \"delete\". \"\" (empty) means all.", "fieldSelector": "fieldSelector describes the limitation on access based on field. It can only limit access, not broaden it.", "labelSelector": "labelSelector describes the limitation on access based on labels. It can only limit access, not broaden it.", } @@ -77,10 +77,10 @@ func (ResourceAttributes) SwaggerDoc() map[string]string { var map_ResourceRule = map[string]string{ "": "ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "verbs": "Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", - "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", - "resources": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", - "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", + "verbs": "verbs is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", + "apiGroups": "apiGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", + "resources": "resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", + "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", } func (ResourceRule) SwaggerDoc() map[string]string { @@ -89,9 +89,9 @@ func (ResourceRule) SwaggerDoc() map[string]string { var map_SelfSubjectAccessReview = map[string]string{ "": "SelfSubjectAccessReview checks whether or the current user can perform an action. Not filling in a spec.namespace means \"in all namespaces\". Self is a special case, because users should always be able to check whether they can perform an action", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated. user and groups must be empty", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated. user and groups must be empty", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (SelfSubjectAccessReview) SwaggerDoc() map[string]string { @@ -99,9 +99,9 @@ func (SelfSubjectAccessReview) SwaggerDoc() map[string]string { } var map_SelfSubjectAccessReviewSpec = map[string]string{ - "": "SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set", - "resourceAttributes": "ResourceAuthorizationAttributes describes information for a resource access request", - "nonResourceAttributes": "NonResourceAttributes describes information for a non-resource access request", + "": "SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes and nonResourceAttributes must be set", + "resourceAttributes": "resourceAttributes describes information for a resource access request", + "nonResourceAttributes": "nonResourceAttributes describes information for a non-resource access request", } func (SelfSubjectAccessReviewSpec) SwaggerDoc() map[string]string { @@ -110,9 +110,9 @@ func (SelfSubjectAccessReviewSpec) SwaggerDoc() map[string]string { var map_SelfSubjectRulesReview = map[string]string{ "": "SelfSubjectRulesReview enumerates the set of actions the current user can perform within a namespace. The returned list of actions may be incomplete depending on the server's authorization mode, and any errors experienced during the evaluation. SelfSubjectRulesReview should be used by UIs to show/hide actions, or to quickly let an end user reason about their permissions. It should NOT Be used by external systems to drive authorization decisions as this raises confused deputy, cache lifetime/revocation, and correctness concerns. SubjectAccessReview, and LocalAccessReview are the correct way to defer authorization decisions to the API server.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated.", - "status": "Status is filled in by the server and indicates the set of actions a user can perform.", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated.", + "status": "status is filled in by the server and indicates the set of actions a user can perform.", } func (SelfSubjectRulesReview) SwaggerDoc() map[string]string { @@ -121,7 +121,7 @@ func (SelfSubjectRulesReview) SwaggerDoc() map[string]string { var map_SelfSubjectRulesReviewSpec = map[string]string{ "": "SelfSubjectRulesReviewSpec defines the specification for SelfSubjectRulesReview.", - "namespace": "Namespace to evaluate rules for. Required.", + "namespace": "namespace to evaluate rules for. Required.", } func (SelfSubjectRulesReviewSpec) SwaggerDoc() map[string]string { @@ -130,9 +130,9 @@ func (SelfSubjectRulesReviewSpec) SwaggerDoc() map[string]string { var map_SubjectAccessReview = map[string]string{ "": "SubjectAccessReview checks whether or not a user or group can perform an action.", - "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Spec holds information about the request being evaluated", - "status": "Status is filled in by the server and indicates whether the request is allowed or not", + "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec holds information about the request being evaluated", + "status": "status is filled in by the server and indicates whether the request is allowed or not", } func (SubjectAccessReview) SwaggerDoc() map[string]string { @@ -140,13 +140,13 @@ func (SubjectAccessReview) SwaggerDoc() map[string]string { } var map_SubjectAccessReviewSpec = map[string]string{ - "": "SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes and NonResourceAuthorizationAttributes must be set", - "resourceAttributes": "ResourceAuthorizationAttributes describes information for a resource access request", - "nonResourceAttributes": "NonResourceAttributes describes information for a non-resource access request", - "user": "User is the user you're testing for. If you specify \"User\" but not \"Group\", then is it interpreted as \"What if User were not a member of any groups", - "group": "Groups is the groups you're testing for.", - "extra": "Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer it needs a reflection here.", - "uid": "UID information about the requesting user.", + "": "SubjectAccessReviewSpec is a description of the access request. Exactly one of resourceAttributes and nonResourceAttributes must be set", + "resourceAttributes": "resourceAttributes describes information for a resource access request", + "nonResourceAttributes": "nonResourceAttributes describes information for a non-resource access request", + "user": "user is the user you're testing for. If you specify \"User\" but not \"Group\", then is it interpreted as \"What if User were not a member of any groups", + "group": "group is the groups you're testing for.", + "extra": "extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer it needs a reflection here.", + "uid": "uid information about the requesting user.", } func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string { @@ -155,10 +155,10 @@ func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string { var map_SubjectAccessReviewStatus = map[string]string{ "": "SubjectAccessReviewStatus", - "allowed": "Allowed is required. True if the action would be allowed, false otherwise.", - "denied": "Denied is optional. True if the action would be denied, otherwise false. If both allowed is false and denied is false, then the authorizer has no opinion on whether to authorize the action. Denied may not be true if Allowed is true.", - "reason": "Reason is optional. It indicates why a request was allowed or denied.", - "evaluationError": "EvaluationError is an indication that some error occurred during the authorization check. It is entirely possible to get an error and be able to continue determine authorization status in spite of it. For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.", + "allowed": "allowed is required. True if the action would be allowed, false otherwise.", + "denied": "denied is optional. True if the action would be denied, otherwise false. If both allowed is false and denied is false, then the authorizer has no opinion on whether to authorize the action. Denied may not be true if Allowed is true.", + "reason": "reason is optional. It indicates why a request was allowed or denied.", + "evaluationError": "evaluationError is an indication that some error occurred during the authorization check. It is entirely possible to get an error and be able to continue determine authorization status in spite of it. For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.", } func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string { @@ -167,10 +167,10 @@ func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string { var map_SubjectRulesReviewStatus = map[string]string{ "": "SubjectRulesReviewStatus contains the result of a rules check. This check can be incomplete depending on the set of authorizers the server is configured with and any errors experienced during evaluation. Because authorization rules are additive, if a rule appears in a list it's safe to assume the subject has that permission, even if that list is incomplete.", - "resourceRules": "ResourceRules is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "nonResourceRules": "NonResourceRules is the list of actions the subject is allowed to perform on non-resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", - "incomplete": "Incomplete is true when the rules returned by this call are incomplete. This is most commonly encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation.", - "evaluationError": "EvaluationError can appear in combination with Rules. It indicates an error occurred during rule evaluation, such as an authorizer that doesn't support rule evaluation, and that ResourceRules and/or NonResourceRules may be incomplete.", + "resourceRules": "resourceRules is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", + "nonResourceRules": "nonResourceRules is the list of actions the subject is allowed to perform on non-resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", + "incomplete": "incomplete is true when the rules returned by this call are incomplete. This is most commonly encountered when an authorizer, such as an external authorizer, doesn't support rules evaluation.", + "evaluationError": "evaluationError can appear in combination with Rules. It indicates an error occurred during rule evaluation, such as an authorizer that doesn't support rule evaluation, and that ResourceRules and/or NonResourceRules may be incomplete.", } func (SubjectRulesReviewStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/autoscaling/v1/generated.proto b/vendor/k8s.io/api/autoscaling/v1/generated.proto index a17d7989db..6ef1facb6a 100644 --- a/vendor/k8s.io/api/autoscaling/v1/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v1/generated.proto @@ -148,7 +148,7 @@ message HorizontalPodAutoscaler { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional + // +required optional HorizontalPodAutoscalerSpec spec = 2; // status is the current information about the autoscaler. @@ -202,9 +202,15 @@ message HorizontalPodAutoscalerSpec { // metric is configured. Scaling is active as long as at least one metric value is // available. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:ifEnabled(HPAScaleToZero)=+k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:ifDisabled(HPAScaleToZero)=+k8s:minimum=1 optional int32 minReplicas = 2; // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:minimum=1 optional int32 maxReplicas = 3; // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; @@ -472,9 +478,9 @@ message Scale { message ScaleSpec { // replicas is the desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 replicas = 1; } diff --git a/vendor/k8s.io/api/autoscaling/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/autoscaling/v1/generated.protomessage.pb.go deleted file mode 100644 index 7b073f92c3..0000000000 --- a/vendor/k8s.io/api/autoscaling/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*ContainerResourceMetricSource) ProtoMessage() {} - -func (*ContainerResourceMetricStatus) ProtoMessage() {} - -func (*CrossVersionObjectReference) ProtoMessage() {} - -func (*ExternalMetricSource) ProtoMessage() {} - -func (*ExternalMetricStatus) ProtoMessage() {} - -func (*HorizontalPodAutoscaler) ProtoMessage() {} - -func (*HorizontalPodAutoscalerCondition) ProtoMessage() {} - -func (*HorizontalPodAutoscalerList) ProtoMessage() {} - -func (*HorizontalPodAutoscalerSpec) ProtoMessage() {} - -func (*HorizontalPodAutoscalerStatus) ProtoMessage() {} - -func (*MetricSpec) ProtoMessage() {} - -func (*MetricStatus) ProtoMessage() {} - -func (*ObjectMetricSource) ProtoMessage() {} - -func (*ObjectMetricStatus) ProtoMessage() {} - -func (*PodsMetricSource) ProtoMessage() {} - -func (*PodsMetricStatus) ProtoMessage() {} - -func (*ResourceMetricSource) ProtoMessage() {} - -func (*ResourceMetricStatus) ProtoMessage() {} - -func (*Scale) ProtoMessage() {} - -func (*ScaleSpec) ProtoMessage() {} - -func (*ScaleStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/autoscaling/v1/types.go b/vendor/k8s.io/api/autoscaling/v1/types.go index e1e8809fe9..97222afc08 100644 --- a/vendor/k8s.io/api/autoscaling/v1/types.go +++ b/vendor/k8s.io/api/autoscaling/v1/types.go @@ -47,9 +47,15 @@ type HorizontalPodAutoscalerSpec struct { // metric is configured. Scaling is active as long as at least one metric value is // available. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:ifEnabled(HPAScaleToZero)=+k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:ifDisabled(HPAScaleToZero)=+k8s:minimum=1 MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:minimum=1 MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; @@ -93,7 +99,7 @@ type HorizontalPodAutoscaler struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional + // +required Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // status is the current information about the autoscaler. @@ -117,7 +123,7 @@ type HorizontalPodAutoscalerList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.2 -// +k8s:isSubresource=/scale +// +k8s:isSubresource="/scale" // Scale represents a scaling request for a resource. type Scale struct { @@ -139,9 +145,9 @@ type Scale struct { type ScaleSpec struct { // replicas is the desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } @@ -408,6 +414,8 @@ const ( // ScalingLimited indicates that the calculated scale based on metrics would be above or // below the range for the HPA, and has thus been capped. ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited" + // ScaledToZero indicates that the HPA controller scaled the workload to zero. + ScaledToZero HorizontalPodAutoscalerConditionType = "ScaledToZero" ) // HorizontalPodAutoscalerCondition describes the state of diff --git a/vendor/k8s.io/api/autoscaling/v2/generated.proto b/vendor/k8s.io/api/autoscaling/v2/generated.proto index a007676a7d..f56b8c749d 100644 --- a/vendor/k8s.io/api/autoscaling/v2/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2/generated.proto @@ -175,7 +175,7 @@ message HorizontalPodAutoscaler { // spec is the specification for the behaviour of the autoscaler. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional + // +required optional HorizontalPodAutoscalerSpec spec = 2; // status is the current information about the autoscaler. @@ -248,10 +248,16 @@ message HorizontalPodAutoscalerSpec { // metric is configured. Scaling is active as long as at least one metric value is // available. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:ifEnabled(HPAScaleToZero)=+k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:ifDisabled(HPAScaleToZero)=+k8s:minimum=1 optional int32 minReplicas = 2; // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:minimum=1 optional int32 maxReplicas = 3; // metrics contains the specifications for which to use to calculate the diff --git a/vendor/k8s.io/api/autoscaling/v2/generated.protomessage.pb.go b/vendor/k8s.io/api/autoscaling/v2/generated.protomessage.pb.go deleted file mode 100644 index 0a73d526bc..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2/generated.protomessage.pb.go +++ /dev/null @@ -1,70 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v2 - -func (*ContainerResourceMetricSource) ProtoMessage() {} - -func (*ContainerResourceMetricStatus) ProtoMessage() {} - -func (*CrossVersionObjectReference) ProtoMessage() {} - -func (*ExternalMetricSource) ProtoMessage() {} - -func (*ExternalMetricStatus) ProtoMessage() {} - -func (*HPAScalingPolicy) ProtoMessage() {} - -func (*HPAScalingRules) ProtoMessage() {} - -func (*HorizontalPodAutoscaler) ProtoMessage() {} - -func (*HorizontalPodAutoscalerBehavior) ProtoMessage() {} - -func (*HorizontalPodAutoscalerCondition) ProtoMessage() {} - -func (*HorizontalPodAutoscalerList) ProtoMessage() {} - -func (*HorizontalPodAutoscalerSpec) ProtoMessage() {} - -func (*HorizontalPodAutoscalerStatus) ProtoMessage() {} - -func (*MetricIdentifier) ProtoMessage() {} - -func (*MetricSpec) ProtoMessage() {} - -func (*MetricStatus) ProtoMessage() {} - -func (*MetricTarget) ProtoMessage() {} - -func (*MetricValueStatus) ProtoMessage() {} - -func (*ObjectMetricSource) ProtoMessage() {} - -func (*ObjectMetricStatus) ProtoMessage() {} - -func (*PodsMetricSource) ProtoMessage() {} - -func (*PodsMetricStatus) ProtoMessage() {} - -func (*ResourceMetricSource) ProtoMessage() {} - -func (*ResourceMetricStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/autoscaling/v2/types.go b/vendor/k8s.io/api/autoscaling/v2/types.go index 03a06dc8b4..ad10169a01 100644 --- a/vendor/k8s.io/api/autoscaling/v2/types.go +++ b/vendor/k8s.io/api/autoscaling/v2/types.go @@ -40,7 +40,7 @@ type HorizontalPodAutoscaler struct { // spec is the specification for the behaviour of the autoscaler. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional + // +required Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // status is the current information about the autoscaler. @@ -59,10 +59,16 @@ type HorizontalPodAutoscalerSpec struct { // metric is configured. Scaling is active as long as at least one metric value is // available. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:ifEnabled(HPAScaleToZero)=+k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:ifDisabled(HPAScaleToZero)=+k8s:minimum=1 MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:minimum=1 MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` // metrics contains the specifications for which to use to calculate the @@ -444,6 +450,8 @@ const ( // ScalingLimited indicates that the calculated scale based on metrics would be above or // below the range for the HPA, and has thus been capped. ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited" + // ScaledToZero indicates that the HPA controller scaled the workload to zero. + ScaledToZero HorizontalPodAutoscalerConditionType = "ScaledToZero" ) // HorizontalPodAutoscalerCondition describes the state of diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go b/vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go deleted file mode 100644 index b3b535adc7..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go +++ /dev/null @@ -1,5106 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: k8s.io/api/autoscaling/v2beta1/generated.proto - -package v2beta1 - -import ( - fmt "fmt" - - io "io" - - k8s_io_api_core_v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - math_bits "math/bits" - reflect "reflect" - strings "strings" -) - -func (m *ContainerResourceMetricSource) Reset() { *m = ContainerResourceMetricSource{} } - -func (m *ContainerResourceMetricStatus) Reset() { *m = ContainerResourceMetricStatus{} } - -func (m *CrossVersionObjectReference) Reset() { *m = CrossVersionObjectReference{} } - -func (m *ExternalMetricSource) Reset() { *m = ExternalMetricSource{} } - -func (m *ExternalMetricStatus) Reset() { *m = ExternalMetricStatus{} } - -func (m *HorizontalPodAutoscaler) Reset() { *m = HorizontalPodAutoscaler{} } - -func (m *HorizontalPodAutoscalerCondition) Reset() { *m = HorizontalPodAutoscalerCondition{} } - -func (m *HorizontalPodAutoscalerList) Reset() { *m = HorizontalPodAutoscalerList{} } - -func (m *HorizontalPodAutoscalerSpec) Reset() { *m = HorizontalPodAutoscalerSpec{} } - -func (m *HorizontalPodAutoscalerStatus) Reset() { *m = HorizontalPodAutoscalerStatus{} } - -func (m *MetricSpec) Reset() { *m = MetricSpec{} } - -func (m *MetricStatus) Reset() { *m = MetricStatus{} } - -func (m *ObjectMetricSource) Reset() { *m = ObjectMetricSource{} } - -func (m *ObjectMetricStatus) Reset() { *m = ObjectMetricStatus{} } - -func (m *PodsMetricSource) Reset() { *m = PodsMetricSource{} } - -func (m *PodsMetricStatus) Reset() { *m = PodsMetricStatus{} } - -func (m *ResourceMetricSource) Reset() { *m = ResourceMetricSource{} } - -func (m *ResourceMetricStatus) Reset() { *m = ResourceMetricStatus{} } - -func (m *ContainerResourceMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ContainerResourceMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContainerResourceMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Container) - copy(dAtA[i:], m.Container) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Container))) - i-- - dAtA[i] = 0x22 - if m.TargetAverageValue != nil { - { - size, err := m.TargetAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.TargetAverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.TargetAverageUtilization)) - i-- - dAtA[i] = 0x10 - } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ContainerResourceMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ContainerResourceMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContainerResourceMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Container) - copy(dAtA[i:], m.Container) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Container))) - i-- - dAtA[i] = 0x22 - { - size, err := m.CurrentAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if m.CurrentAverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.CurrentAverageUtilization)) - i-- - dAtA[i] = 0x10 - } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *CrossVersionObjectReference) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CrossVersionObjectReference) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *CrossVersionObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.APIVersion) - copy(dAtA[i:], m.APIVersion) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) - i-- - dAtA[i] = 0x1a - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - i -= len(m.Kind) - copy(dAtA[i:], m.Kind) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ExternalMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExternalMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExternalMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.TargetAverageValue != nil { - { - size, err := m.TargetAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.TargetValue != nil { - { - size, err := m.TargetValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.MetricSelector != nil { - { - size, err := m.MetricSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ExternalMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExternalMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExternalMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.CurrentAverageValue != nil { - { - size, err := m.CurrentAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - { - size, err := m.CurrentValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if m.MetricSelector != nil { - { - size, err := m.MetricSelector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscaler) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscaler) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscaler) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerCondition) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerCondition) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Message) - copy(dAtA[i:], m.Message) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i-- - dAtA[i] = 0x2a - i -= len(m.Reason) - copy(dAtA[i:], m.Reason) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) - i-- - dAtA[i] = 0x22 - { - size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - i -= len(m.Status) - copy(dAtA[i:], m.Status) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i-- - dAtA[i] = 0x12 - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Metrics) > 0 { - for iNdEx := len(m.Metrics) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Metrics[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - } - i = encodeVarintGenerated(dAtA, i, uint64(m.MaxReplicas)) - i-- - dAtA[i] = 0x18 - if m.MinReplicas != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.MinReplicas)) - i-- - dAtA[i] = 0x10 - } - { - size, err := m.ScaleTargetRef.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Conditions) > 0 { - for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - } - } - if len(m.CurrentMetrics) > 0 { - for iNdEx := len(m.CurrentMetrics) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.CurrentMetrics[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - } - i = encodeVarintGenerated(dAtA, i, uint64(m.DesiredReplicas)) - i-- - dAtA[i] = 0x20 - i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentReplicas)) - i-- - dAtA[i] = 0x18 - if m.LastScaleTime != nil { - { - size, err := m.LastScaleTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.ObservedGeneration != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.ObservedGeneration)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *MetricSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ContainerResource != nil { - { - size, err := m.ContainerResource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - if m.External != nil { - { - size, err := m.External.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Resource != nil { - { - size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.Pods != nil { - { - size, err := m.Pods.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Object != nil { - { - size, err := m.Object.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *MetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ContainerResource != nil { - { - size, err := m.ContainerResource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - if m.External != nil { - { - size, err := m.External.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Resource != nil { - { - size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.Pods != nil { - { - size, err := m.Pods.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Object != nil { - { - size, err := m.Object.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ObjectMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ObjectMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ObjectMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AverageValue != nil { - { - size, err := m.AverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Selector != nil { - { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - { - size, err := m.TargetValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0x12 - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ObjectMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ObjectMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ObjectMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AverageValue != nil { - { - size, err := m.AverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Selector != nil { - { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - { - size, err := m.CurrentValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0x12 - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PodsMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodsMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodsMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Selector != nil { - { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - { - size, err := m.TargetAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PodsMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodsMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodsMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Selector != nil { - { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - { - size, err := m.CurrentAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.MetricName) - copy(dAtA[i:], m.MetricName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.MetricName))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ResourceMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResourceMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.TargetAverageValue != nil { - { - size, err := m.TargetAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.TargetAverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.TargetAverageUtilization)) - i-- - dAtA[i] = 0x10 - } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ResourceMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResourceMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.CurrentAverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if m.CurrentAverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.CurrentAverageUtilization)) - i-- - dAtA[i] = 0x10 - } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ContainerResourceMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.TargetAverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.TargetAverageUtilization)) - } - if m.TargetAverageValue != nil { - l = m.TargetAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.Container) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ContainerResourceMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.CurrentAverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.CurrentAverageUtilization)) - } - l = m.CurrentAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Container) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *CrossVersionObjectReference) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.APIVersion) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ExternalMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - if m.MetricSelector != nil { - l = m.MetricSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.TargetValue != nil { - l = m.TargetValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.TargetAverageValue != nil { - l = m.TargetAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ExternalMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - if m.MetricSelector != nil { - l = m.MetricSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = m.CurrentValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.CurrentAverageValue != nil { - l = m.CurrentAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *HorizontalPodAutoscaler) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HorizontalPodAutoscalerCondition) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = m.LastTransitionTime.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Reason) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HorizontalPodAutoscalerList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *HorizontalPodAutoscalerSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ScaleTargetRef.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.MinReplicas != nil { - n += 1 + sovGenerated(uint64(*m.MinReplicas)) - } - n += 1 + sovGenerated(uint64(m.MaxReplicas)) - if len(m.Metrics) > 0 { - for _, e := range m.Metrics { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *HorizontalPodAutoscalerStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ObservedGeneration != nil { - n += 1 + sovGenerated(uint64(*m.ObservedGeneration)) - } - if m.LastScaleTime != nil { - l = m.LastScaleTime.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - n += 1 + sovGenerated(uint64(m.CurrentReplicas)) - n += 1 + sovGenerated(uint64(m.DesiredReplicas)) - if len(m.CurrentMetrics) > 0 { - for _, e := range m.CurrentMetrics { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Conditions) > 0 { - for _, e := range m.Conditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *MetricSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - if m.Object != nil { - l = m.Object.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Pods != nil { - l = m.Pods.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Resource != nil { - l = m.Resource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.External != nil { - l = m.External.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ContainerResource != nil { - l = m.ContainerResource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *MetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - if m.Object != nil { - l = m.Object.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Pods != nil { - l = m.Pods.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Resource != nil { - l = m.Resource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.External != nil { - l = m.External.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ContainerResource != nil { - l = m.ContainerResource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ObjectMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - l = m.TargetValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageValue != nil { - l = m.AverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ObjectMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - l = m.CurrentValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageValue != nil { - l = m.AverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *PodsMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - l = m.TargetAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *PodsMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.MetricName) - n += 1 + l + sovGenerated(uint64(l)) - l = m.CurrentAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ResourceMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.TargetAverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.TargetAverageUtilization)) - } - if m.TargetAverageValue != nil { - l = m.TargetAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *ResourceMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.CurrentAverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.CurrentAverageUtilization)) - } - l = m.CurrentAverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *ContainerResourceMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ContainerResourceMetricSource{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `TargetAverageUtilization:` + valueToStringGenerated(this.TargetAverageUtilization) + `,`, - `TargetAverageValue:` + strings.Replace(fmt.Sprintf("%v", this.TargetAverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `Container:` + fmt.Sprintf("%v", this.Container) + `,`, - `}`, - }, "") - return s -} -func (this *ContainerResourceMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ContainerResourceMetricStatus{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `CurrentAverageUtilization:` + valueToStringGenerated(this.CurrentAverageUtilization) + `,`, - `CurrentAverageValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.CurrentAverageValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `Container:` + fmt.Sprintf("%v", this.Container) + `,`, - `}`, - }, "") - return s -} -func (this *CrossVersionObjectReference) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CrossVersionObjectReference{`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, - `}`, - }, "") - return s -} -func (this *ExternalMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ExternalMetricSource{`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `MetricSelector:` + strings.Replace(fmt.Sprintf("%v", this.MetricSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `TargetValue:` + strings.Replace(fmt.Sprintf("%v", this.TargetValue), "Quantity", "resource.Quantity", 1) + `,`, - `TargetAverageValue:` + strings.Replace(fmt.Sprintf("%v", this.TargetAverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ExternalMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ExternalMetricStatus{`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `MetricSelector:` + strings.Replace(fmt.Sprintf("%v", this.MetricSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `CurrentValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.CurrentValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `CurrentAverageValue:` + strings.Replace(fmt.Sprintf("%v", this.CurrentAverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscaler) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HorizontalPodAutoscaler{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "HorizontalPodAutoscalerSpec", "HorizontalPodAutoscalerSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "HorizontalPodAutoscalerStatus", "HorizontalPodAutoscalerStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerCondition) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HorizontalPodAutoscalerCondition{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `LastTransitionTime:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, - `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]HorizontalPodAutoscaler{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "HorizontalPodAutoscaler", "HorizontalPodAutoscaler", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerSpec) String() string { - if this == nil { - return "nil" - } - repeatedStringForMetrics := "[]MetricSpec{" - for _, f := range this.Metrics { - repeatedStringForMetrics += strings.Replace(strings.Replace(f.String(), "MetricSpec", "MetricSpec", 1), `&`, ``, 1) + "," - } - repeatedStringForMetrics += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerSpec{`, - `ScaleTargetRef:` + strings.Replace(strings.Replace(this.ScaleTargetRef.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `MinReplicas:` + valueToStringGenerated(this.MinReplicas) + `,`, - `MaxReplicas:` + fmt.Sprintf("%v", this.MaxReplicas) + `,`, - `Metrics:` + repeatedStringForMetrics + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerStatus) String() string { - if this == nil { - return "nil" - } - repeatedStringForCurrentMetrics := "[]MetricStatus{" - for _, f := range this.CurrentMetrics { - repeatedStringForCurrentMetrics += strings.Replace(strings.Replace(f.String(), "MetricStatus", "MetricStatus", 1), `&`, ``, 1) + "," - } - repeatedStringForCurrentMetrics += "}" - repeatedStringForConditions := "[]HorizontalPodAutoscalerCondition{" - for _, f := range this.Conditions { - repeatedStringForConditions += strings.Replace(strings.Replace(f.String(), "HorizontalPodAutoscalerCondition", "HorizontalPodAutoscalerCondition", 1), `&`, ``, 1) + "," - } - repeatedStringForConditions += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerStatus{`, - `ObservedGeneration:` + valueToStringGenerated(this.ObservedGeneration) + `,`, - `LastScaleTime:` + strings.Replace(fmt.Sprintf("%v", this.LastScaleTime), "Time", "v1.Time", 1) + `,`, - `CurrentReplicas:` + fmt.Sprintf("%v", this.CurrentReplicas) + `,`, - `DesiredReplicas:` + fmt.Sprintf("%v", this.DesiredReplicas) + `,`, - `CurrentMetrics:` + repeatedStringForCurrentMetrics + `,`, - `Conditions:` + repeatedStringForConditions + `,`, - `}`, - }, "") - return s -} -func (this *MetricSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricSpec{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Object:` + strings.Replace(this.Object.String(), "ObjectMetricSource", "ObjectMetricSource", 1) + `,`, - `Pods:` + strings.Replace(this.Pods.String(), "PodsMetricSource", "PodsMetricSource", 1) + `,`, - `Resource:` + strings.Replace(this.Resource.String(), "ResourceMetricSource", "ResourceMetricSource", 1) + `,`, - `External:` + strings.Replace(this.External.String(), "ExternalMetricSource", "ExternalMetricSource", 1) + `,`, - `ContainerResource:` + strings.Replace(this.ContainerResource.String(), "ContainerResourceMetricSource", "ContainerResourceMetricSource", 1) + `,`, - `}`, - }, "") - return s -} -func (this *MetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricStatus{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Object:` + strings.Replace(this.Object.String(), "ObjectMetricStatus", "ObjectMetricStatus", 1) + `,`, - `Pods:` + strings.Replace(this.Pods.String(), "PodsMetricStatus", "PodsMetricStatus", 1) + `,`, - `Resource:` + strings.Replace(this.Resource.String(), "ResourceMetricStatus", "ResourceMetricStatus", 1) + `,`, - `External:` + strings.Replace(this.External.String(), "ExternalMetricStatus", "ExternalMetricStatus", 1) + `,`, - `ContainerResource:` + strings.Replace(this.ContainerResource.String(), "ContainerResourceMetricStatus", "ContainerResourceMetricStatus", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ObjectMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ObjectMetricSource{`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `TargetValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.TargetValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `AverageValue:` + strings.Replace(fmt.Sprintf("%v", this.AverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ObjectMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ObjectMetricStatus{`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `CurrentValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.CurrentValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `AverageValue:` + strings.Replace(fmt.Sprintf("%v", this.AverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodsMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodsMetricSource{`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `TargetAverageValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.TargetAverageValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodsMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodsMetricStatus{`, - `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, - `CurrentAverageValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.CurrentAverageValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceMetricSource{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `TargetAverageUtilization:` + valueToStringGenerated(this.TargetAverageUtilization) + `,`, - `TargetAverageValue:` + strings.Replace(fmt.Sprintf("%v", this.TargetAverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceMetricStatus{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `CurrentAverageUtilization:` + valueToStringGenerated(this.CurrentAverageUtilization) + `,`, - `CurrentAverageValue:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.CurrentAverageValue), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *ContainerResourceMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContainerResourceMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerResourceMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.TargetAverageUtilization = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TargetAverageValue == nil { - m.TargetAverageValue = &resource.Quantity{} - } - if err := m.TargetAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Container = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ContainerResourceMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContainerResourceMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerResourceMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.CurrentAverageUtilization = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Container = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CrossVersionObjectReference) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CrossVersionObjectReference: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CrossVersionObjectReference: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.APIVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ExternalMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExternalMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricSelector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MetricSelector == nil { - m.MetricSelector = &v1.LabelSelector{} - } - if err := m.MetricSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TargetValue == nil { - m.TargetValue = &resource.Quantity{} - } - if err := m.TargetValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TargetAverageValue == nil { - m.TargetAverageValue = &resource.Quantity{} - } - if err := m.TargetAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ExternalMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExternalMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricSelector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MetricSelector == nil { - m.MetricSelector = &v1.LabelSelector{} - } - if err := m.MetricSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.CurrentAverageValue == nil { - m.CurrentAverageValue = &resource.Quantity{} - } - if err := m.CurrentAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscaler) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscaler: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscaler: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerCondition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerCondition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerCondition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = HorizontalPodAutoscalerConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, HorizontalPodAutoscaler{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ScaleTargetRef", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ScaleTargetRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinReplicas", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.MinReplicas = &v - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxReplicas", wireType) - } - m.MaxReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MaxReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metrics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Metrics = append(m.Metrics, MetricSpec{}) - if err := m.Metrics[len(m.Metrics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ObservedGeneration = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastScaleTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.LastScaleTime == nil { - m.LastScaleTime = &v1.Time{} - } - if err := m.LastScaleTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentReplicas", wireType) - } - m.CurrentReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CurrentReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredReplicas", wireType) - } - m.DesiredReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DesiredReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentMetrics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CurrentMetrics = append(m.CurrentMetrics, MetricStatus{}) - if err := m.CurrentMetrics[len(m.CurrentMetrics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Conditions = append(m.Conditions, HorizontalPodAutoscalerCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = MetricSourceType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Object == nil { - m.Object = &ObjectMetricSource{} - } - if err := m.Object.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pods", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pods == nil { - m.Pods = &PodsMetricSource{} - } - if err := m.Pods.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Resource == nil { - m.Resource = &ResourceMetricSource{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field External", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.External == nil { - m.External = &ExternalMetricSource{} - } - if err := m.External.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerResource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ContainerResource == nil { - m.ContainerResource = &ContainerResourceMetricSource{} - } - if err := m.ContainerResource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = MetricSourceType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Object == nil { - m.Object = &ObjectMetricStatus{} - } - if err := m.Object.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pods", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pods == nil { - m.Pods = &PodsMetricStatus{} - } - if err := m.Pods.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Resource == nil { - m.Resource = &ResourceMetricStatus{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field External", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.External == nil { - m.External = &ExternalMetricStatus{} - } - if err := m.External.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerResource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ContainerResource == nil { - m.ContainerResource = &ContainerResourceMetricStatus{} - } - if err := m.ContainerResource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ObjectMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ObjectMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ObjectMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TargetValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AverageValue == nil { - m.AverageValue = &resource.Quantity{} - } - if err := m.AverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ObjectMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ObjectMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ObjectMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AverageValue == nil { - m.AverageValue = &resource.Quantity{} - } - if err := m.AverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodsMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodsMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodsMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TargetAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodsMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodsMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodsMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetricName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MetricName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.TargetAverageUtilization = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TargetAverageValue == nil { - m.TargetAverageValue = &resource.Quantity{} - } - if err := m.TargetAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.CurrentAverageUtilization = &v - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentAverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentAverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenerated - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenerated - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto deleted file mode 100644 index 4b71732ab9..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto +++ /dev/null @@ -1,474 +0,0 @@ -/* -Copyright 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. -*/ - - -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -syntax = "proto2"; - -package k8s.io.api.autoscaling.v2beta1; - -import "k8s.io/api/core/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/api/resource/generated.proto"; -import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; - -// Package-wide variables from generator "generated". -option go_package = "k8s.io/api/autoscaling/v2beta1"; - -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -message ContainerResourceMetricSource { - // name is the name of the resource in question. - optional string name = 1; - - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - optional int32 targetAverageUtilization = 2; - - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 3; - - // container is the name of the container in the pods of the scaling target - optional string container = 4; -} - -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -message ContainerResourceMetricStatus { - // name is the name of the resource in question. - optional string name = 1; - - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - // +optional - optional int32 currentAverageUtilization = 2; - - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 3; - - // container is the name of the container in the pods of the scaling target - optional string container = 4; -} - -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - optional string kind = 1; - - // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - optional string name = 2; - - // API version of the referent - // +optional - optional string apiVersion = 3; -} - -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -// Exactly one "target" type should be set. -message ExternalMetricSource { - // metricName is the name of the metric in question. - optional string metricName = 1; - - // metricSelector is used to identify a specific time series - // within a given metric. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector metricSelector = 2; - - // targetValue is the target value of the metric (as a quantity). - // Mutually exclusive with TargetAverageValue. - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetValue = 3; - - // targetAverageValue is the target per-pod value of global metric (as a quantity). - // Mutually exclusive with TargetValue. - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 4; -} - -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -message ExternalMetricStatus { - // metricName is the name of a metric used for autoscaling in - // metric system. - optional string metricName = 1; - - // metricSelector is used to identify a specific time series - // within a given metric. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector metricSelector = 2; - - // currentValue is the current value of the metric (as a quantity) - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentValue = 3; - - // currentAverageValue is the current value of metric averaged over autoscaled pods. - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 4; -} - -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -message HorizontalPodAutoscaler { - // metadata is the standard object metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional - optional HorizontalPodAutoscalerSpec spec = 2; - - // status is the current information about the autoscaler. - // +optional - optional HorizontalPodAutoscalerStatus status = 3; -} - -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -message HorizontalPodAutoscalerCondition { - // type describes the current condition - optional string type = 1; - - // status is the status of the condition (True, False, Unknown) - optional string status = 2; - - // lastTransitionTime is the last time the condition transitioned from - // one status to another - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; - - // reason is the reason for the condition's last transition. - // +optional - optional string reason = 4; - - // message is a human-readable explanation containing details about - // the transition - // +optional - optional string message = 5; -} - -// HorizontalPodAutoscaler is a list of horizontal pod autoscaler objects. -message HorizontalPodAutoscalerList { - // metadata is the standard list metadata. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // items is the list of horizontal pod autoscaler objects. - repeated HorizontalPodAutoscaler items = 2; -} - -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -message HorizontalPodAutoscalerSpec { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - optional CrossVersionObjectReference scaleTargetRef = 1; - - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - // +optional - optional int32 minReplicas = 2; - - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - optional int32 maxReplicas = 3; - - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - // +optional - // +listType=atomic - repeated MetricSpec metrics = 4; -} - -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -message HorizontalPodAutoscalerStatus { - // observedGeneration is the most recent generation observed by this autoscaler. - // +optional - optional int64 observedGeneration = 1; - - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastScaleTime = 2; - - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - optional int32 currentReplicas = 3; - - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - optional int32 desiredReplicas = 4; - - // currentMetrics is the last read state of the metrics used by this autoscaler. - // +optional - // +listType=atomic - repeated MetricStatus currentMetrics = 5; - - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - // +optional - // +listType=atomic - repeated HorizontalPodAutoscalerCondition conditions = 6; -} - -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -message MetricSpec { - // type is the type of metric source. It should be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object. - optional string type = 1; - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - optional ObjectMetricSource object = 2; - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - optional PodsMetricSource pods = 3; - - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ResourceMetricSource resource = 4; - - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - // +optional - optional ContainerResourceMetricSource containerResource = 7; - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - optional ExternalMetricSource external = 5; -} - -// MetricStatus describes the last-read state of a single metric. -message MetricStatus { - // type is the type of metric source. It will be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - optional string type = 1; - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - optional ObjectMetricStatus object = 2; - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - optional PodsMetricStatus pods = 3; - - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ResourceMetricStatus resource = 4; - - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ContainerResourceMetricStatus containerResource = 7; - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - optional ExternalMetricStatus external = 5; -} - -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -message ObjectMetricSource { - // target is the described Kubernetes object. - optional CrossVersionObjectReference target = 1; - - // metricName is the name of the metric in question. - optional string metricName = 2; - - // targetValue is the target value of the metric (as a quantity). - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetValue = 3; - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 4; - - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 5; -} - -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -message ObjectMetricStatus { - // target is the described Kubernetes object. - optional CrossVersionObjectReference target = 1; - - // metricName is the name of the metric in question. - optional string metricName = 2; - - // currentValue is the current value of the metric (as a quantity). - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentValue = 3; - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the ObjectMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 4; - - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 5; -} - -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -message PodsMetricSource { - // metricName is the name of the metric in question - optional string metricName = 1; - - // targetAverageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 2; - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3; -} - -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -message PodsMetricStatus { - // metricName is the name of the metric in question - optional string metricName = 1; - - // currentAverageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 2; - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the PodsMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3; -} - -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -message ResourceMetricSource { - // name is the name of the resource in question. - optional string name = 1; - - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - optional int32 targetAverageUtilization = 2; - - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity targetAverageValue = 3; -} - -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -message ResourceMetricStatus { - // name is the name of the resource in question. - optional string name = 1; - - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - // +optional - optional int32 currentAverageUtilization = 2; - - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - optional .k8s.io.apimachinery.pkg.api.resource.Quantity currentAverageValue = 3; -} - diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/autoscaling/v2beta1/generated.protomessage.pb.go deleted file mode 100644 index ab1fe8c8b2..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v2beta1 - -func (*ContainerResourceMetricSource) ProtoMessage() {} - -func (*ContainerResourceMetricStatus) ProtoMessage() {} - -func (*CrossVersionObjectReference) ProtoMessage() {} - -func (*ExternalMetricSource) ProtoMessage() {} - -func (*ExternalMetricStatus) ProtoMessage() {} - -func (*HorizontalPodAutoscaler) ProtoMessage() {} - -func (*HorizontalPodAutoscalerCondition) ProtoMessage() {} - -func (*HorizontalPodAutoscalerList) ProtoMessage() {} - -func (*HorizontalPodAutoscalerSpec) ProtoMessage() {} - -func (*HorizontalPodAutoscalerStatus) ProtoMessage() {} - -func (*MetricSpec) ProtoMessage() {} - -func (*MetricStatus) ProtoMessage() {} - -func (*ObjectMetricSource) ProtoMessage() {} - -func (*ObjectMetricStatus) ProtoMessage() {} - -func (*PodsMetricSource) ProtoMessage() {} - -func (*PodsMetricStatus) ProtoMessage() {} - -func (*ResourceMetricSource) ProtoMessage() {} - -func (*ResourceMetricStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types.go b/vendor/k8s.io/api/autoscaling/v2beta1/types.go deleted file mode 100644 index c3abdd9bd9..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types.go +++ /dev/null @@ -1,486 +0,0 @@ -/* -Copyright 2016 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 v2beta1 - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent - // +optional - APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` -} - -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -type HorizontalPodAutoscalerSpec struct { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - ScaleTargetRef CrossVersionObjectReference `json:"scaleTargetRef" protobuf:"bytes,1,opt,name=scaleTargetRef"` - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - // +optional - MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - // +optional - // +listType=atomic - Metrics []MetricSpec `json:"metrics,omitempty" protobuf:"bytes,4,rep,name=metrics"` -} - -// MetricSourceType indicates the type of metric. -type MetricSourceType string - -const ( - // ObjectMetricSourceType is a metric describing a kubernetes object - // (for example, hits-per-second on an Ingress object). - ObjectMetricSourceType MetricSourceType = "Object" - // PodsMetricSourceType is a metric describing each pod in the current scale - // target (for example, transactions-processed-per-second). The values - // will be averaged together before being compared to the target value. - PodsMetricSourceType MetricSourceType = "Pods" - // ResourceMetricSourceType is a resource metric known to Kubernetes, as - // specified in requests and limits, describing each pod in the current - // scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics (the "pods" source). - ResourceMetricSourceType MetricSourceType = "Resource" - // ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as - // specified in requests and limits, describing a single container in each pod in the current - // scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics (the "pods" source). - ContainerResourceMetricSourceType MetricSourceType = "ContainerResource" - // ExternalMetricSourceType is a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - ExternalMetricSourceType MetricSourceType = "External" -) - -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -type MetricSpec struct { - // type is the type of metric source. It should be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object. - Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"` - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - // +optional - ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - External *ExternalMetricSource `json:"external,omitempty" protobuf:"bytes,5,opt,name=external"` -} - -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricSource struct { - // target is the described Kubernetes object. - Target CrossVersionObjectReference `json:"target" protobuf:"bytes,1,name=target"` - - // metricName is the name of the metric in question. - MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` - // targetValue is the target value of the metric (as a quantity). - TargetValue resource.Quantity `json:"targetValue" protobuf:"bytes,3,name=targetValue"` - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - // +optional - Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,5,name=averageValue"` -} - -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -type PodsMetricSource struct { - // metricName is the name of the metric in question - MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` - // targetAverageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - TargetAverageValue resource.Quantity `json:"targetAverageValue" protobuf:"bytes,2,name=targetAverageValue"` - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - // +optional - Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,name=selector"` -} - -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ResourceMetricSource struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // +optional - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"` -} - -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ContainerResourceMetricSource struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // +optional - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"` - // container is the name of the container in the pods of the scaling target - Container string `json:"container" protobuf:"bytes,4,opt,name=container"` -} - -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -// Exactly one "target" type should be set. -type ExternalMetricSource struct { - // metricName is the name of the metric in question. - MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` - // metricSelector is used to identify a specific time series - // within a given metric. - // +optional - MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` - // targetValue is the target value of the metric (as a quantity). - // Mutually exclusive with TargetAverageValue. - // +optional - TargetValue *resource.Quantity `json:"targetValue,omitempty" protobuf:"bytes,3,opt,name=targetValue"` - // targetAverageValue is the target per-pod value of global metric (as a quantity). - // Mutually exclusive with TargetValue. - // +optional - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,4,opt,name=targetAverageValue"` -} - -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -type HorizontalPodAutoscalerStatus struct { - // observedGeneration is the most recent generation observed by this autoscaler. - // +optional - ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - // +optional - LastScaleTime *metav1.Time `json:"lastScaleTime,omitempty" protobuf:"bytes,2,opt,name=lastScaleTime"` - - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - CurrentReplicas int32 `json:"currentReplicas" protobuf:"varint,3,opt,name=currentReplicas"` - - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - DesiredReplicas int32 `json:"desiredReplicas" protobuf:"varint,4,opt,name=desiredReplicas"` - - // currentMetrics is the last read state of the metrics used by this autoscaler. - // +optional - // +listType=atomic - CurrentMetrics []MetricStatus `json:"currentMetrics" protobuf:"bytes,5,rep,name=currentMetrics"` - - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - // +optional - // +listType=atomic - Conditions []HorizontalPodAutoscalerCondition `json:"conditions" protobuf:"bytes,6,rep,name=conditions"` -} - -// HorizontalPodAutoscalerConditionType are the valid conditions of -// a HorizontalPodAutoscaler. -type HorizontalPodAutoscalerConditionType string - -const ( - // ScalingActive indicates that the HPA controller is able to scale if necessary: - // it's correctly configured, can fetch the desired metrics, and isn't disabled. - ScalingActive HorizontalPodAutoscalerConditionType = "ScalingActive" - // AbleToScale indicates a lack of transient issues which prevent scaling from occurring, - // such as being in a backoff window, or being unable to access/update the target scale. - AbleToScale HorizontalPodAutoscalerConditionType = "AbleToScale" - // ScalingLimited indicates that the calculated scale based on metrics would be above or - // below the range for the HPA, and has thus been capped. - ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited" -) - -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -type HorizontalPodAutoscalerCondition struct { - // type describes the current condition - Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` - // status is the status of the condition (True, False, Unknown) - Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` - // lastTransitionTime is the last time the condition transitioned from - // one status to another - // +optional - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` - // reason is the reason for the condition's last transition. - // +optional - Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` - // message is a human-readable explanation containing details about - // the transition - // +optional - Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` -} - -// MetricStatus describes the last-read state of a single metric. -type MetricStatus struct { - // type is the type of metric source. It will be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"` - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - External *ExternalMetricStatus `json:"external,omitempty" protobuf:"bytes,5,opt,name=external"` -} - -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricStatus struct { - // target is the described Kubernetes object. - Target CrossVersionObjectReference `json:"target" protobuf:"bytes,1,name=target"` - - // metricName is the name of the metric in question. - MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` - // currentValue is the current value of the metric (as a quantity). - CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the ObjectMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,5,name=averageValue"` -} - -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -type PodsMetricStatus struct { - // metricName is the name of the metric in question - MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` - // currentAverageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,2,name=currentAverageValue"` - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the PodsMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,name=selector"` -} - -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ResourceMetricStatus struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - // +optional - CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"` -} - -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ContainerResourceMetricStatus struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - // +optional - CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"` - // container is the name of the container in the pods of the scaling target - Container string `json:"container" protobuf:"bytes,4,opt,name=container"` -} - -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -type ExternalMetricStatus struct { - // metricName is the name of a metric used for autoscaling in - // metric system. - MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` - // metricSelector is used to identify a specific time series - // within a given metric. - // +optional - MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` - // currentValue is the current value of the metric (as a quantity) - CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` - // currentAverageValue is the current value of metric averaged over autoscaled pods. - // +optional - CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty" protobuf:"bytes,4,opt,name=currentAverageValue"` -} - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.8 -// +k8s:prerelease-lifecycle-gen:deprecated=1.22 -// +k8s:prerelease-lifecycle-gen:replacement=autoscaling,v2,HorizontalPodAutoscaler - -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -type HorizontalPodAutoscaler struct { - metav1.TypeMeta `json:",inline"` - // metadata is the standard object metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional - Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - - // status is the current information about the autoscaler. - // +optional - Status HorizontalPodAutoscalerStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.8 -// +k8s:prerelease-lifecycle-gen:deprecated=1.22 -// +k8s:prerelease-lifecycle-gen:replacement=autoscaling,v2beta2,HorizontalPodAutoscalerList - -// HorizontalPodAutoscaler is a list of horizontal pod autoscaler objects. -type HorizontalPodAutoscalerList struct { - metav1.TypeMeta `json:",inline"` - // metadata is the standard list metadata. - // +optional - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // items is the list of horizontal pod autoscaler objects. - Items []HorizontalPodAutoscaler `json:"items" protobuf:"bytes,2,rep,name=items"` -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go deleted file mode 100644 index c7c72bf356..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go +++ /dev/null @@ -1,247 +0,0 @@ -/* -Copyright 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 v2beta1 - -// This file contains a collection of methods that can be used from go-restful to -// generate Swagger API documentation for its models. Please read this PR for more -// information on the implementation: https://github.com/emicklei/go-restful/pull/215 -// -// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if -// they are on one line! For multiple line or blocks that you want to ignore use ---. -// Any context after a --- is ignored. -// -// Those methods can be generated by using hack/update-codegen.sh - -// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. -var map_ContainerResourceMetricSource = map[string]string{ - "": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.", - "name": "name is the name of the resource in question.", - "targetAverageUtilization": "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", - "targetAverageValue": "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type.", - "container": "container is the name of the container in the pods of the scaling target", -} - -func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { - return map_ContainerResourceMetricSource -} - -var map_ContainerResourceMetricStatus = map[string]string{ - "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "name is the name of the resource in question.", - "currentAverageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.", - "currentAverageValue": "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification.", - "container": "container is the name of the container in the pods of the scaling target", -} - -func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { - return map_ContainerResourceMetricStatus -} - -var map_CrossVersionObjectReference = map[string]string{ - "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", - "apiVersion": "API version of the referent", -} - -func (CrossVersionObjectReference) SwaggerDoc() map[string]string { - return map_CrossVersionObjectReference -} - -var map_ExternalMetricSource = map[string]string{ - "": "ExternalMetricSource indicates how to scale on a metric not associated with any Kubernetes object (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster). Exactly one \"target\" type should be set.", - "metricName": "metricName is the name of the metric in question.", - "metricSelector": "metricSelector is used to identify a specific time series within a given metric.", - "targetValue": "targetValue is the target value of the metric (as a quantity). Mutually exclusive with TargetAverageValue.", - "targetAverageValue": "targetAverageValue is the target per-pod value of global metric (as a quantity). Mutually exclusive with TargetValue.", -} - -func (ExternalMetricSource) SwaggerDoc() map[string]string { - return map_ExternalMetricSource -} - -var map_ExternalMetricStatus = map[string]string{ - "": "ExternalMetricStatus indicates the current value of a global metric not associated with any Kubernetes object.", - "metricName": "metricName is the name of a metric used for autoscaling in metric system.", - "metricSelector": "metricSelector is used to identify a specific time series within a given metric.", - "currentValue": "currentValue is the current value of the metric (as a quantity)", - "currentAverageValue": "currentAverageValue is the current value of metric averaged over autoscaled pods.", -} - -func (ExternalMetricStatus) SwaggerDoc() map[string]string { - return map_ExternalMetricStatus -} - -var map_HorizontalPodAutoscaler = map[string]string{ - "": "HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.", - "metadata": "metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "spec is the specification for the behaviour of the autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "status is the current information about the autoscaler.", -} - -func (HorizontalPodAutoscaler) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscaler -} - -var map_HorizontalPodAutoscalerCondition = map[string]string{ - "": "HorizontalPodAutoscalerCondition describes the state of a HorizontalPodAutoscaler at a certain point.", - "type": "type describes the current condition", - "status": "status is the status of the condition (True, False, Unknown)", - "lastTransitionTime": "lastTransitionTime is the last time the condition transitioned from one status to another", - "reason": "reason is the reason for the condition's last transition.", - "message": "message is a human-readable explanation containing details about the transition", -} - -func (HorizontalPodAutoscalerCondition) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerCondition -} - -var map_HorizontalPodAutoscalerList = map[string]string{ - "": "HorizontalPodAutoscaler is a list of horizontal pod autoscaler objects.", - "metadata": "metadata is the standard list metadata.", - "items": "items is the list of horizontal pod autoscaler objects.", -} - -func (HorizontalPodAutoscalerList) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerList -} - -var map_HorizontalPodAutoscalerSpec = map[string]string{ - "": "HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler.", - "scaleTargetRef": "scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics should be collected, as well as to actually change the replica count.", - "minReplicas": "minReplicas is the lower limit for the number of replicas to which the autoscaler can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the alpha feature gate HPAScaleToZero is enabled and at least one Object or External metric is configured. Scaling is active as long as at least one metric value is available.", - "maxReplicas": "maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas.", - "metrics": "metrics contains the specifications for which to use to calculate the desired replica count (the maximum replica count across all metrics will be used). The desired replica count is calculated multiplying the ratio between the target value and the current value by the current number of pods. Ergo, metrics used must decrease as the pod count is increased, and vice-versa. See the individual metric source types for more information about how each type of metric must respond.", -} - -func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerSpec -} - -var map_HorizontalPodAutoscalerStatus = map[string]string{ - "": "HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler.", - "observedGeneration": "observedGeneration is the most recent generation observed by this autoscaler.", - "lastScaleTime": "lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, used by the autoscaler to control how often the number of pods is changed.", - "currentReplicas": "currentReplicas is current number of replicas of pods managed by this autoscaler, as last seen by the autoscaler.", - "desiredReplicas": "desiredReplicas is the desired number of replicas of pods managed by this autoscaler, as last calculated by the autoscaler.", - "currentMetrics": "currentMetrics is the last read state of the metrics used by this autoscaler.", - "conditions": "conditions is the set of conditions required for this autoscaler to scale its target, and indicates whether or not those conditions are met.", -} - -func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerStatus -} - -var map_MetricSpec = map[string]string{ - "": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).", - "type": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.", - "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", - "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", -} - -func (MetricSpec) SwaggerDoc() map[string]string { - return map_MetricSpec -} - -var map_MetricStatus = map[string]string{ - "": "MetricStatus describes the last-read state of a single metric.", - "type": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.", - "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", - "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", -} - -func (MetricStatus) SwaggerDoc() map[string]string { - return map_MetricStatus -} - -var map_ObjectMetricSource = map[string]string{ - "": "ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).", - "target": "target is the described Kubernetes object.", - "metricName": "metricName is the name of the metric in question.", - "targetValue": "targetValue is the target value of the metric (as a quantity).", - "selector": "selector is the string-encoded form of a standard kubernetes label selector for the given metric When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping When unset, just the metricName will be used to gather metrics.", - "averageValue": "averageValue is the target value of the average of the metric across all relevant pods (as a quantity)", -} - -func (ObjectMetricSource) SwaggerDoc() map[string]string { - return map_ObjectMetricSource -} - -var map_ObjectMetricStatus = map[string]string{ - "": "ObjectMetricStatus indicates the current value of a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).", - "target": "target is the described Kubernetes object.", - "metricName": "metricName is the name of the metric in question.", - "currentValue": "currentValue is the current value of the metric (as a quantity).", - "selector": "selector is the string-encoded form of a standard kubernetes label selector for the given metric When set in the ObjectMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. When unset, just the metricName will be used to gather metrics.", - "averageValue": "averageValue is the current value of the average of the metric across all relevant pods (as a quantity)", -} - -func (ObjectMetricStatus) SwaggerDoc() map[string]string { - return map_ObjectMetricStatus -} - -var map_PodsMetricSource = map[string]string{ - "": "PodsMetricSource indicates how to scale on a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "metricName": "metricName is the name of the metric in question", - "targetAverageValue": "targetAverageValue is the target value of the average of the metric across all relevant pods (as a quantity)", - "selector": "selector is the string-encoded form of a standard kubernetes label selector for the given metric When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping When unset, just the metricName will be used to gather metrics.", -} - -func (PodsMetricSource) SwaggerDoc() map[string]string { - return map_PodsMetricSource -} - -var map_PodsMetricStatus = map[string]string{ - "": "PodsMetricStatus indicates the current value of a metric describing each pod in the current scale target (for example, transactions-processed-per-second).", - "metricName": "metricName is the name of the metric in question", - "currentAverageValue": "currentAverageValue is the current value of the average of the metric across all relevant pods (as a quantity)", - "selector": "selector is the string-encoded form of a standard kubernetes label selector for the given metric When set in the PodsMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. When unset, just the metricName will be used to gather metrics.", -} - -func (PodsMetricStatus) SwaggerDoc() map[string]string { - return map_PodsMetricStatus -} - -var map_ResourceMetricSource = map[string]string{ - "": "ResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.", - "name": "name is the name of the resource in question.", - "targetAverageUtilization": "targetAverageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", - "targetAverageValue": "targetAverageValue is the target value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type.", -} - -func (ResourceMetricSource) SwaggerDoc() map[string]string { - return map_ResourceMetricSource -} - -var map_ResourceMetricStatus = map[string]string{ - "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "name is the name of the resource in question.", - "currentAverageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. It will only be present if `targetAverageValue` was set in the corresponding metric specification.", - "currentAverageValue": "currentAverageValue is the current value of the average of the resource metric across all relevant pods, as a raw value (instead of as a percentage of the request), similar to the \"pods\" metric source type. It will always be set, regardless of the corresponding metric specification.", -} - -func (ResourceMetricStatus) SwaggerDoc() map[string]string { - return map_ResourceMetricStatus -} - -// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.deepcopy.go deleted file mode 100644 index 610e81f81a..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.deepcopy.go +++ /dev/null @@ -1,525 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) { - *out = *in - if in.TargetAverageUtilization != nil { - in, out := &in.TargetAverageUtilization, &out.TargetAverageUtilization - *out = new(int32) - **out = **in - } - if in.TargetAverageValue != nil { - in, out := &in.TargetAverageValue, &out.TargetAverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource. -func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource { - if in == nil { - return nil - } - out := new(ContainerResourceMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) { - *out = *in - if in.CurrentAverageUtilization != nil { - in, out := &in.CurrentAverageUtilization, &out.CurrentAverageUtilization - *out = new(int32) - **out = **in - } - out.CurrentAverageValue = in.CurrentAverageValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus. -func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus { - if in == nil { - return nil - } - out := new(ContainerResourceMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossVersionObjectReference. -func (in *CrossVersionObjectReference) DeepCopy() *CrossVersionObjectReference { - if in == nil { - return nil - } - out := new(CrossVersionObjectReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalMetricSource) DeepCopyInto(out *ExternalMetricSource) { - *out = *in - if in.MetricSelector != nil { - in, out := &in.MetricSelector, &out.MetricSelector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - if in.TargetValue != nil { - in, out := &in.TargetValue, &out.TargetValue - x := (*in).DeepCopy() - *out = &x - } - if in.TargetAverageValue != nil { - in, out := &in.TargetAverageValue, &out.TargetAverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricSource. -func (in *ExternalMetricSource) DeepCopy() *ExternalMetricSource { - if in == nil { - return nil - } - out := new(ExternalMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalMetricStatus) DeepCopyInto(out *ExternalMetricStatus) { - *out = *in - if in.MetricSelector != nil { - in, out := &in.MetricSelector, &out.MetricSelector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - out.CurrentValue = in.CurrentValue.DeepCopy() - if in.CurrentAverageValue != nil { - in, out := &in.CurrentAverageValue, &out.CurrentAverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricStatus. -func (in *ExternalMetricStatus) DeepCopy() *ExternalMetricStatus { - if in == nil { - return nil - } - out := new(ExternalMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscaler) DeepCopyInto(out *HorizontalPodAutoscaler) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscaler. -func (in *HorizontalPodAutoscaler) DeepCopy() *HorizontalPodAutoscaler { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscaler) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HorizontalPodAutoscaler) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerCondition) DeepCopyInto(out *HorizontalPodAutoscalerCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerCondition. -func (in *HorizontalPodAutoscalerCondition) DeepCopy() *HorizontalPodAutoscalerCondition { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerList) DeepCopyInto(out *HorizontalPodAutoscalerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]HorizontalPodAutoscaler, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerList. -func (in *HorizontalPodAutoscalerList) DeepCopy() *HorizontalPodAutoscalerList { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HorizontalPodAutoscalerList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerSpec) DeepCopyInto(out *HorizontalPodAutoscalerSpec) { - *out = *in - out.ScaleTargetRef = in.ScaleTargetRef - if in.MinReplicas != nil { - in, out := &in.MinReplicas, &out.MinReplicas - *out = new(int32) - **out = **in - } - if in.Metrics != nil { - in, out := &in.Metrics, &out.Metrics - *out = make([]MetricSpec, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerSpec. -func (in *HorizontalPodAutoscalerSpec) DeepCopy() *HorizontalPodAutoscalerSpec { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerStatus) DeepCopyInto(out *HorizontalPodAutoscalerStatus) { - *out = *in - if in.ObservedGeneration != nil { - in, out := &in.ObservedGeneration, &out.ObservedGeneration - *out = new(int64) - **out = **in - } - if in.LastScaleTime != nil { - in, out := &in.LastScaleTime, &out.LastScaleTime - *out = (*in).DeepCopy() - } - if in.CurrentMetrics != nil { - in, out := &in.CurrentMetrics, &out.CurrentMetrics - *out = make([]MetricStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]HorizontalPodAutoscalerCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerStatus. -func (in *HorizontalPodAutoscalerStatus) DeepCopy() *HorizontalPodAutoscalerStatus { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricSpec) DeepCopyInto(out *MetricSpec) { - *out = *in - if in.Object != nil { - in, out := &in.Object, &out.Object - *out = new(ObjectMetricSource) - (*in).DeepCopyInto(*out) - } - if in.Pods != nil { - in, out := &in.Pods, &out.Pods - *out = new(PodsMetricSource) - (*in).DeepCopyInto(*out) - } - if in.Resource != nil { - in, out := &in.Resource, &out.Resource - *out = new(ResourceMetricSource) - (*in).DeepCopyInto(*out) - } - if in.ContainerResource != nil { - in, out := &in.ContainerResource, &out.ContainerResource - *out = new(ContainerResourceMetricSource) - (*in).DeepCopyInto(*out) - } - if in.External != nil { - in, out := &in.External, &out.External - *out = new(ExternalMetricSource) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricSpec. -func (in *MetricSpec) DeepCopy() *MetricSpec { - if in == nil { - return nil - } - out := new(MetricSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricStatus) DeepCopyInto(out *MetricStatus) { - *out = *in - if in.Object != nil { - in, out := &in.Object, &out.Object - *out = new(ObjectMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.Pods != nil { - in, out := &in.Pods, &out.Pods - *out = new(PodsMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.Resource != nil { - in, out := &in.Resource, &out.Resource - *out = new(ResourceMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.ContainerResource != nil { - in, out := &in.ContainerResource, &out.ContainerResource - *out = new(ContainerResourceMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.External != nil { - in, out := &in.External, &out.External - *out = new(ExternalMetricStatus) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricStatus. -func (in *MetricStatus) DeepCopy() *MetricStatus { - if in == nil { - return nil - } - out := new(MetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ObjectMetricSource) DeepCopyInto(out *ObjectMetricSource) { - *out = *in - out.Target = in.Target - out.TargetValue = in.TargetValue.DeepCopy() - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - if in.AverageValue != nil { - in, out := &in.AverageValue, &out.AverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMetricSource. -func (in *ObjectMetricSource) DeepCopy() *ObjectMetricSource { - if in == nil { - return nil - } - out := new(ObjectMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ObjectMetricStatus) DeepCopyInto(out *ObjectMetricStatus) { - *out = *in - out.Target = in.Target - out.CurrentValue = in.CurrentValue.DeepCopy() - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - if in.AverageValue != nil { - in, out := &in.AverageValue, &out.AverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMetricStatus. -func (in *ObjectMetricStatus) DeepCopy() *ObjectMetricStatus { - if in == nil { - return nil - } - out := new(ObjectMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodsMetricSource) DeepCopyInto(out *PodsMetricSource) { - *out = *in - out.TargetAverageValue = in.TargetAverageValue.DeepCopy() - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodsMetricSource. -func (in *PodsMetricSource) DeepCopy() *PodsMetricSource { - if in == nil { - return nil - } - out := new(PodsMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodsMetricStatus) DeepCopyInto(out *PodsMetricStatus) { - *out = *in - out.CurrentAverageValue = in.CurrentAverageValue.DeepCopy() - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodsMetricStatus. -func (in *PodsMetricStatus) DeepCopy() *PodsMetricStatus { - if in == nil { - return nil - } - out := new(PodsMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceMetricSource) DeepCopyInto(out *ResourceMetricSource) { - *out = *in - if in.TargetAverageUtilization != nil { - in, out := &in.TargetAverageUtilization, &out.TargetAverageUtilization - *out = new(int32) - **out = **in - } - if in.TargetAverageValue != nil { - in, out := &in.TargetAverageValue, &out.TargetAverageValue - x := (*in).DeepCopy() - *out = &x - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMetricSource. -func (in *ResourceMetricSource) DeepCopy() *ResourceMetricSource { - if in == nil { - return nil - } - out := new(ResourceMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceMetricStatus) DeepCopyInto(out *ResourceMetricStatus) { - *out = *in - if in.CurrentAverageUtilization != nil { - in, out := &in.CurrentAverageUtilization, &out.CurrentAverageUtilization - *out = new(int32) - **out = **in - } - out.CurrentAverageValue = in.CurrentAverageValue.DeepCopy() - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMetricStatus. -func (in *ResourceMetricStatus) DeepCopy() *ResourceMetricStatus { - if in == nil { - return nil - } - out := new(ResourceMetricStatus) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.model_name.go b/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.model_name.go deleted file mode 100644 index 2b8674e651..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.model_name.go +++ /dev/null @@ -1,112 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by openapi-gen. DO NOT EDIT. - -package v2beta1 - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ContainerResourceMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ContainerResourceMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in CrossVersionObjectReference) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ExternalMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ExternalMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ExternalMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscaler) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerCondition) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerCondition" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerList) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerList" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerSpec) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricSpec) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.MetricSpec" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.MetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ObjectMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ObjectMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ObjectMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ObjectMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodsMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.PodsMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodsMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.PodsMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ResourceMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ResourceMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ResourceMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta1.ResourceMetricStatus" -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.prerelease-lifecycle.go deleted file mode 100644 index 3437454ee3..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.prerelease-lifecycle.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. - -package v2beta1 - -import ( - schema "k8s.io/apimachinery/pkg/runtime/schema" -) - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *HorizontalPodAutoscaler) APILifecycleIntroduced() (major, minor int) { - return 1, 8 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *HorizontalPodAutoscaler) APILifecycleDeprecated() (major, minor int) { - return 1, 22 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *HorizontalPodAutoscaler) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "autoscaling", Version: "v2", Kind: "HorizontalPodAutoscaler"} -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *HorizontalPodAutoscaler) APILifecycleRemoved() (major, minor int) { - return 1, 25 -} - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *HorizontalPodAutoscalerList) APILifecycleIntroduced() (major, minor int) { - return 1, 8 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *HorizontalPodAutoscalerList) APILifecycleDeprecated() (major, minor int) { - return 1, 22 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *HorizontalPodAutoscalerList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "autoscaling", Version: "v2beta2", Kind: "HorizontalPodAutoscalerList"} -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *HorizontalPodAutoscalerList) APILifecycleRemoved() (major, minor int) { - return 1, 25 -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/generated.pb.go b/vendor/k8s.io/api/autoscaling/v2beta2/generated.pb.go deleted file mode 100644 index 87c8738678..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/generated.pb.go +++ /dev/null @@ -1,5817 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: k8s.io/api/autoscaling/v2beta2/generated.proto - -package v2beta2 - -import ( - fmt "fmt" - - io "io" - - k8s_io_api_core_v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - math_bits "math/bits" - reflect "reflect" - strings "strings" -) - -func (m *ContainerResourceMetricSource) Reset() { *m = ContainerResourceMetricSource{} } - -func (m *ContainerResourceMetricStatus) Reset() { *m = ContainerResourceMetricStatus{} } - -func (m *CrossVersionObjectReference) Reset() { *m = CrossVersionObjectReference{} } - -func (m *ExternalMetricSource) Reset() { *m = ExternalMetricSource{} } - -func (m *ExternalMetricStatus) Reset() { *m = ExternalMetricStatus{} } - -func (m *HPAScalingPolicy) Reset() { *m = HPAScalingPolicy{} } - -func (m *HPAScalingRules) Reset() { *m = HPAScalingRules{} } - -func (m *HorizontalPodAutoscaler) Reset() { *m = HorizontalPodAutoscaler{} } - -func (m *HorizontalPodAutoscalerBehavior) Reset() { *m = HorizontalPodAutoscalerBehavior{} } - -func (m *HorizontalPodAutoscalerCondition) Reset() { *m = HorizontalPodAutoscalerCondition{} } - -func (m *HorizontalPodAutoscalerList) Reset() { *m = HorizontalPodAutoscalerList{} } - -func (m *HorizontalPodAutoscalerSpec) Reset() { *m = HorizontalPodAutoscalerSpec{} } - -func (m *HorizontalPodAutoscalerStatus) Reset() { *m = HorizontalPodAutoscalerStatus{} } - -func (m *MetricIdentifier) Reset() { *m = MetricIdentifier{} } - -func (m *MetricSpec) Reset() { *m = MetricSpec{} } - -func (m *MetricStatus) Reset() { *m = MetricStatus{} } - -func (m *MetricTarget) Reset() { *m = MetricTarget{} } - -func (m *MetricValueStatus) Reset() { *m = MetricValueStatus{} } - -func (m *ObjectMetricSource) Reset() { *m = ObjectMetricSource{} } - -func (m *ObjectMetricStatus) Reset() { *m = ObjectMetricStatus{} } - -func (m *PodsMetricSource) Reset() { *m = PodsMetricSource{} } - -func (m *PodsMetricStatus) Reset() { *m = PodsMetricStatus{} } - -func (m *ResourceMetricSource) Reset() { *m = ResourceMetricSource{} } - -func (m *ResourceMetricStatus) Reset() { *m = ResourceMetricStatus{} } - -func (m *ContainerResourceMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ContainerResourceMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContainerResourceMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Container) - copy(dAtA[i:], m.Container) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Container))) - i-- - dAtA[i] = 0x1a - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ContainerResourceMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ContainerResourceMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ContainerResourceMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Container) - copy(dAtA[i:], m.Container) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Container))) - i-- - dAtA[i] = 0x1a - { - size, err := m.Current.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *CrossVersionObjectReference) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CrossVersionObjectReference) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *CrossVersionObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.APIVersion) - copy(dAtA[i:], m.APIVersion) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) - i-- - dAtA[i] = 0x1a - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - i -= len(m.Kind) - copy(dAtA[i:], m.Kind) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ExternalMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExternalMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExternalMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ExternalMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExternalMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExternalMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Current.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HPAScalingPolicy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HPAScalingPolicy) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HPAScalingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.PeriodSeconds)) - i-- - dAtA[i] = 0x18 - i = encodeVarintGenerated(dAtA, i, uint64(m.Value)) - i-- - dAtA[i] = 0x10 - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HPAScalingRules) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HPAScalingRules) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HPAScalingRules) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.StabilizationWindowSeconds != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.StabilizationWindowSeconds)) - i-- - dAtA[i] = 0x18 - } - if len(m.Policies) > 0 { - for iNdEx := len(m.Policies) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Policies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.SelectPolicy != nil { - i -= len(*m.SelectPolicy) - copy(dAtA[i:], *m.SelectPolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SelectPolicy))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscaler) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscaler) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscaler) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerBehavior) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerBehavior) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerBehavior) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ScaleDown != nil { - { - size, err := m.ScaleDown.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.ScaleUp != nil { - { - size, err := m.ScaleUp.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerCondition) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerCondition) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Message) - copy(dAtA[i:], m.Message) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) - i-- - dAtA[i] = 0x2a - i -= len(m.Reason) - copy(dAtA[i:], m.Reason) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Reason))) - i-- - dAtA[i] = 0x22 - { - size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - i -= len(m.Status) - copy(dAtA[i:], m.Status) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status))) - i-- - dAtA[i] = 0x12 - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Behavior != nil { - { - size, err := m.Behavior.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if len(m.Metrics) > 0 { - for iNdEx := len(m.Metrics) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Metrics[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - } - i = encodeVarintGenerated(dAtA, i, uint64(m.MaxReplicas)) - i-- - dAtA[i] = 0x18 - if m.MinReplicas != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.MinReplicas)) - i-- - dAtA[i] = 0x10 - } - { - size, err := m.ScaleTargetRef.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HorizontalPodAutoscalerStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HorizontalPodAutoscalerStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HorizontalPodAutoscalerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Conditions) > 0 { - for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - } - } - if len(m.CurrentMetrics) > 0 { - for iNdEx := len(m.CurrentMetrics) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.CurrentMetrics[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - } - i = encodeVarintGenerated(dAtA, i, uint64(m.DesiredReplicas)) - i-- - dAtA[i] = 0x20 - i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentReplicas)) - i-- - dAtA[i] = 0x18 - if m.LastScaleTime != nil { - { - size, err := m.LastScaleTime.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.ObservedGeneration != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.ObservedGeneration)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *MetricIdentifier) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricIdentifier) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricIdentifier) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Selector != nil { - { - size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *MetricSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ContainerResource != nil { - { - size, err := m.ContainerResource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - if m.External != nil { - { - size, err := m.External.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Resource != nil { - { - size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.Pods != nil { - { - size, err := m.Pods.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Object != nil { - { - size, err := m.Object.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *MetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ContainerResource != nil { - { - size, err := m.ContainerResource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - if m.External != nil { - { - size, err := m.External.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Resource != nil { - { - size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.Pods != nil { - { - size, err := m.Pods.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Object != nil { - { - size, err := m.Object.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *MetricTarget) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricTarget) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricTarget) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.AverageUtilization)) - i-- - dAtA[i] = 0x20 - } - if m.AverageValue != nil { - { - size, err := m.AverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Value != nil { - { - size, err := m.Value.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *MetricValueStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MetricValueStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MetricValueStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AverageUtilization != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.AverageUtilization)) - i-- - dAtA[i] = 0x18 - } - if m.AverageValue != nil { - { - size, err := m.AverageValue.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.Value != nil { - { - size, err := m.Value.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ObjectMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ObjectMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ObjectMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.DescribedObject.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ObjectMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ObjectMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ObjectMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.DescribedObject.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Current.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PodsMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodsMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodsMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PodsMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodsMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodsMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Current.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.Metric.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ResourceMetricSource) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceMetricSource) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResourceMetricSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *ResourceMetricStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResourceMetricStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResourceMetricStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Current.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ContainerResourceMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Container) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ContainerResourceMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Current.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Container) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *CrossVersionObjectReference) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.APIVersion) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ExternalMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ExternalMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Current.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HPAScalingPolicy) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.Value)) - n += 1 + sovGenerated(uint64(m.PeriodSeconds)) - return n -} - -func (m *HPAScalingRules) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.SelectPolicy != nil { - l = len(*m.SelectPolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.Policies) > 0 { - for _, e := range m.Policies { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.StabilizationWindowSeconds != nil { - n += 1 + sovGenerated(uint64(*m.StabilizationWindowSeconds)) - } - return n -} - -func (m *HorizontalPodAutoscaler) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HorizontalPodAutoscalerBehavior) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ScaleUp != nil { - l = m.ScaleUp.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ScaleDown != nil { - l = m.ScaleDown.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *HorizontalPodAutoscalerCondition) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Status) - n += 1 + l + sovGenerated(uint64(l)) - l = m.LastTransitionTime.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Reason) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Message) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *HorizontalPodAutoscalerList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *HorizontalPodAutoscalerSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ScaleTargetRef.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.MinReplicas != nil { - n += 1 + sovGenerated(uint64(*m.MinReplicas)) - } - n += 1 + sovGenerated(uint64(m.MaxReplicas)) - if len(m.Metrics) > 0 { - for _, e := range m.Metrics { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.Behavior != nil { - l = m.Behavior.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *HorizontalPodAutoscalerStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ObservedGeneration != nil { - n += 1 + sovGenerated(uint64(*m.ObservedGeneration)) - } - if m.LastScaleTime != nil { - l = m.LastScaleTime.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - n += 1 + sovGenerated(uint64(m.CurrentReplicas)) - n += 1 + sovGenerated(uint64(m.DesiredReplicas)) - if len(m.CurrentMetrics) > 0 { - for _, e := range m.CurrentMetrics { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Conditions) > 0 { - for _, e := range m.Conditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *MetricIdentifier) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.Selector != nil { - l = m.Selector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *MetricSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - if m.Object != nil { - l = m.Object.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Pods != nil { - l = m.Pods.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Resource != nil { - l = m.Resource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.External != nil { - l = m.External.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ContainerResource != nil { - l = m.ContainerResource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *MetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - if m.Object != nil { - l = m.Object.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Pods != nil { - l = m.Pods.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Resource != nil { - l = m.Resource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.External != nil { - l = m.External.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.ContainerResource != nil { - l = m.ContainerResource.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *MetricTarget) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Type) - n += 1 + l + sovGenerated(uint64(l)) - if m.Value != nil { - l = m.Value.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageValue != nil { - l = m.AverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.AverageUtilization)) - } - return n -} - -func (m *MetricValueStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Value != nil { - l = m.Value.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageValue != nil { - l = m.AverageValue.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.AverageUtilization != nil { - n += 1 + sovGenerated(uint64(*m.AverageUtilization)) - } - return n -} - -func (m *ObjectMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.DescribedObject.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ObjectMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Current.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.DescribedObject.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *PodsMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *PodsMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Metric.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Current.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceMetricSource) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Target.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *ResourceMetricStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Current.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *ContainerResourceMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ContainerResourceMetricSource{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "MetricTarget", "MetricTarget", 1), `&`, ``, 1) + `,`, - `Container:` + fmt.Sprintf("%v", this.Container) + `,`, - `}`, - }, "") - return s -} -func (this *ContainerResourceMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ContainerResourceMetricStatus{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Current:` + strings.Replace(strings.Replace(this.Current.String(), "MetricValueStatus", "MetricValueStatus", 1), `&`, ``, 1) + `,`, - `Container:` + fmt.Sprintf("%v", this.Container) + `,`, - `}`, - }, "") - return s -} -func (this *CrossVersionObjectReference) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CrossVersionObjectReference{`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, - `}`, - }, "") - return s -} -func (this *ExternalMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ExternalMetricSource{`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "MetricTarget", "MetricTarget", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ExternalMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ExternalMetricStatus{`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `Current:` + strings.Replace(strings.Replace(this.Current.String(), "MetricValueStatus", "MetricValueStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *HPAScalingPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HPAScalingPolicy{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `PeriodSeconds:` + fmt.Sprintf("%v", this.PeriodSeconds) + `,`, - `}`, - }, "") - return s -} -func (this *HPAScalingRules) String() string { - if this == nil { - return "nil" - } - repeatedStringForPolicies := "[]HPAScalingPolicy{" - for _, f := range this.Policies { - repeatedStringForPolicies += strings.Replace(strings.Replace(f.String(), "HPAScalingPolicy", "HPAScalingPolicy", 1), `&`, ``, 1) + "," - } - repeatedStringForPolicies += "}" - s := strings.Join([]string{`&HPAScalingRules{`, - `SelectPolicy:` + valueToStringGenerated(this.SelectPolicy) + `,`, - `Policies:` + repeatedStringForPolicies + `,`, - `StabilizationWindowSeconds:` + valueToStringGenerated(this.StabilizationWindowSeconds) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscaler) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HorizontalPodAutoscaler{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "HorizontalPodAutoscalerSpec", "HorizontalPodAutoscalerSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "HorizontalPodAutoscalerStatus", "HorizontalPodAutoscalerStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerBehavior) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HorizontalPodAutoscalerBehavior{`, - `ScaleUp:` + strings.Replace(this.ScaleUp.String(), "HPAScalingRules", "HPAScalingRules", 1) + `,`, - `ScaleDown:` + strings.Replace(this.ScaleDown.String(), "HPAScalingRules", "HPAScalingRules", 1) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerCondition) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HorizontalPodAutoscalerCondition{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Status:` + fmt.Sprintf("%v", this.Status) + `,`, - `LastTransitionTime:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, - `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, - `Message:` + fmt.Sprintf("%v", this.Message) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]HorizontalPodAutoscaler{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "HorizontalPodAutoscaler", "HorizontalPodAutoscaler", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerSpec) String() string { - if this == nil { - return "nil" - } - repeatedStringForMetrics := "[]MetricSpec{" - for _, f := range this.Metrics { - repeatedStringForMetrics += strings.Replace(strings.Replace(f.String(), "MetricSpec", "MetricSpec", 1), `&`, ``, 1) + "," - } - repeatedStringForMetrics += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerSpec{`, - `ScaleTargetRef:` + strings.Replace(strings.Replace(this.ScaleTargetRef.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `MinReplicas:` + valueToStringGenerated(this.MinReplicas) + `,`, - `MaxReplicas:` + fmt.Sprintf("%v", this.MaxReplicas) + `,`, - `Metrics:` + repeatedStringForMetrics + `,`, - `Behavior:` + strings.Replace(this.Behavior.String(), "HorizontalPodAutoscalerBehavior", "HorizontalPodAutoscalerBehavior", 1) + `,`, - `}`, - }, "") - return s -} -func (this *HorizontalPodAutoscalerStatus) String() string { - if this == nil { - return "nil" - } - repeatedStringForCurrentMetrics := "[]MetricStatus{" - for _, f := range this.CurrentMetrics { - repeatedStringForCurrentMetrics += strings.Replace(strings.Replace(f.String(), "MetricStatus", "MetricStatus", 1), `&`, ``, 1) + "," - } - repeatedStringForCurrentMetrics += "}" - repeatedStringForConditions := "[]HorizontalPodAutoscalerCondition{" - for _, f := range this.Conditions { - repeatedStringForConditions += strings.Replace(strings.Replace(f.String(), "HorizontalPodAutoscalerCondition", "HorizontalPodAutoscalerCondition", 1), `&`, ``, 1) + "," - } - repeatedStringForConditions += "}" - s := strings.Join([]string{`&HorizontalPodAutoscalerStatus{`, - `ObservedGeneration:` + valueToStringGenerated(this.ObservedGeneration) + `,`, - `LastScaleTime:` + strings.Replace(fmt.Sprintf("%v", this.LastScaleTime), "Time", "v1.Time", 1) + `,`, - `CurrentReplicas:` + fmt.Sprintf("%v", this.CurrentReplicas) + `,`, - `DesiredReplicas:` + fmt.Sprintf("%v", this.DesiredReplicas) + `,`, - `CurrentMetrics:` + repeatedStringForCurrentMetrics + `,`, - `Conditions:` + repeatedStringForConditions + `,`, - `}`, - }, "") - return s -} -func (this *MetricIdentifier) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricIdentifier{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`, - `}`, - }, "") - return s -} -func (this *MetricSpec) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricSpec{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Object:` + strings.Replace(this.Object.String(), "ObjectMetricSource", "ObjectMetricSource", 1) + `,`, - `Pods:` + strings.Replace(this.Pods.String(), "PodsMetricSource", "PodsMetricSource", 1) + `,`, - `Resource:` + strings.Replace(this.Resource.String(), "ResourceMetricSource", "ResourceMetricSource", 1) + `,`, - `External:` + strings.Replace(this.External.String(), "ExternalMetricSource", "ExternalMetricSource", 1) + `,`, - `ContainerResource:` + strings.Replace(this.ContainerResource.String(), "ContainerResourceMetricSource", "ContainerResourceMetricSource", 1) + `,`, - `}`, - }, "") - return s -} -func (this *MetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricStatus{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Object:` + strings.Replace(this.Object.String(), "ObjectMetricStatus", "ObjectMetricStatus", 1) + `,`, - `Pods:` + strings.Replace(this.Pods.String(), "PodsMetricStatus", "PodsMetricStatus", 1) + `,`, - `Resource:` + strings.Replace(this.Resource.String(), "ResourceMetricStatus", "ResourceMetricStatus", 1) + `,`, - `External:` + strings.Replace(this.External.String(), "ExternalMetricStatus", "ExternalMetricStatus", 1) + `,`, - `ContainerResource:` + strings.Replace(this.ContainerResource.String(), "ContainerResourceMetricStatus", "ContainerResourceMetricStatus", 1) + `,`, - `}`, - }, "") - return s -} -func (this *MetricTarget) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricTarget{`, - `Type:` + fmt.Sprintf("%v", this.Type) + `,`, - `Value:` + strings.Replace(fmt.Sprintf("%v", this.Value), "Quantity", "resource.Quantity", 1) + `,`, - `AverageValue:` + strings.Replace(fmt.Sprintf("%v", this.AverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `AverageUtilization:` + valueToStringGenerated(this.AverageUtilization) + `,`, - `}`, - }, "") - return s -} -func (this *MetricValueStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&MetricValueStatus{`, - `Value:` + strings.Replace(fmt.Sprintf("%v", this.Value), "Quantity", "resource.Quantity", 1) + `,`, - `AverageValue:` + strings.Replace(fmt.Sprintf("%v", this.AverageValue), "Quantity", "resource.Quantity", 1) + `,`, - `AverageUtilization:` + valueToStringGenerated(this.AverageUtilization) + `,`, - `}`, - }, "") - return s -} -func (this *ObjectMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ObjectMetricSource{`, - `DescribedObject:` + strings.Replace(strings.Replace(this.DescribedObject.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "MetricTarget", "MetricTarget", 1), `&`, ``, 1) + `,`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ObjectMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ObjectMetricStatus{`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `Current:` + strings.Replace(strings.Replace(this.Current.String(), "MetricValueStatus", "MetricValueStatus", 1), `&`, ``, 1) + `,`, - `DescribedObject:` + strings.Replace(strings.Replace(this.DescribedObject.String(), "CrossVersionObjectReference", "CrossVersionObjectReference", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodsMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodsMetricSource{`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "MetricTarget", "MetricTarget", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodsMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodsMetricStatus{`, - `Metric:` + strings.Replace(strings.Replace(this.Metric.String(), "MetricIdentifier", "MetricIdentifier", 1), `&`, ``, 1) + `,`, - `Current:` + strings.Replace(strings.Replace(this.Current.String(), "MetricValueStatus", "MetricValueStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceMetricSource) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceMetricSource{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Target:` + strings.Replace(strings.Replace(this.Target.String(), "MetricTarget", "MetricTarget", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *ResourceMetricStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ResourceMetricStatus{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Current:` + strings.Replace(strings.Replace(this.Current.String(), "MetricValueStatus", "MetricValueStatus", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *ContainerResourceMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContainerResourceMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerResourceMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Container = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ContainerResourceMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ContainerResourceMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ContainerResourceMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Current.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Container = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CrossVersionObjectReference) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CrossVersionObjectReference: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CrossVersionObjectReference: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.APIVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ExternalMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExternalMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ExternalMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExternalMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExternalMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Current.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HPAScalingPolicy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HPAScalingPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HPAScalingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = HPAScalingPolicyType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - m.Value = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Value |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PeriodSeconds", wireType) - } - m.PeriodSeconds = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.PeriodSeconds |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HPAScalingRules) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HPAScalingRules: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HPAScalingRules: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SelectPolicy", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := ScalingPolicySelect(dAtA[iNdEx:postIndex]) - m.SelectPolicy = &s - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Policies", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Policies = append(m.Policies, HPAScalingPolicy{}) - if err := m.Policies[len(m.Policies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StabilizationWindowSeconds", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.StabilizationWindowSeconds = &v - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscaler) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscaler: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscaler: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerBehavior) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerBehavior: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerBehavior: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ScaleUp", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ScaleUp == nil { - m.ScaleUp = &HPAScalingRules{} - } - if err := m.ScaleUp.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ScaleDown", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ScaleDown == nil { - m.ScaleDown = &HPAScalingRules{} - } - if err := m.ScaleDown.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerCondition) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerCondition: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerCondition: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = HorizontalPodAutoscalerConditionType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Status = k8s_io_api_core_v1.ConditionStatus(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Message = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, HorizontalPodAutoscaler{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ScaleTargetRef", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ScaleTargetRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinReplicas", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.MinReplicas = &v - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxReplicas", wireType) - } - m.MaxReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MaxReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metrics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Metrics = append(m.Metrics, MetricSpec{}) - if err := m.Metrics[len(m.Metrics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Behavior", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Behavior == nil { - m.Behavior = &HorizontalPodAutoscalerBehavior{} - } - if err := m.Behavior.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HorizontalPodAutoscalerStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HorizontalPodAutoscalerStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HorizontalPodAutoscalerStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ObservedGeneration = &v - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastScaleTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.LastScaleTime == nil { - m.LastScaleTime = &v1.Time{} - } - if err := m.LastScaleTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentReplicas", wireType) - } - m.CurrentReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CurrentReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredReplicas", wireType) - } - m.DesiredReplicas = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DesiredReplicas |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CurrentMetrics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CurrentMetrics = append(m.CurrentMetrics, MetricStatus{}) - if err := m.CurrentMetrics[len(m.CurrentMetrics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Conditions = append(m.Conditions, HorizontalPodAutoscalerCondition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricIdentifier) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricIdentifier: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricIdentifier: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Selector == nil { - m.Selector = &v1.LabelSelector{} - } - if err := m.Selector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = MetricSourceType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Object == nil { - m.Object = &ObjectMetricSource{} - } - if err := m.Object.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pods", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pods == nil { - m.Pods = &PodsMetricSource{} - } - if err := m.Pods.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Resource == nil { - m.Resource = &ResourceMetricSource{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field External", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.External == nil { - m.External = &ExternalMetricSource{} - } - if err := m.External.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerResource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ContainerResource == nil { - m.ContainerResource = &ContainerResourceMetricSource{} - } - if err := m.ContainerResource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = MetricSourceType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Object == nil { - m.Object = &ObjectMetricStatus{} - } - if err := m.Object.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pods", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pods == nil { - m.Pods = &PodsMetricStatus{} - } - if err := m.Pods.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Resource == nil { - m.Resource = &ResourceMetricStatus{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field External", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.External == nil { - m.External = &ExternalMetricStatus{} - } - if err := m.External.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerResource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ContainerResource == nil { - m.ContainerResource = &ContainerResourceMetricStatus{} - } - if err := m.ContainerResource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricTarget) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricTarget: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricTarget: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = MetricTargetType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Value == nil { - m.Value = &resource.Quantity{} - } - if err := m.Value.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AverageValue == nil { - m.AverageValue = &resource.Quantity{} - } - if err := m.AverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.AverageUtilization = &v - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MetricValueStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MetricValueStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MetricValueStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Value == nil { - m.Value = &resource.Quantity{} - } - if err := m.Value.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageValue", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AverageValue == nil { - m.AverageValue = &resource.Quantity{} - } - if err := m.AverageValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AverageUtilization", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.AverageUtilization = &v - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ObjectMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ObjectMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ObjectMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DescribedObject", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.DescribedObject.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ObjectMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ObjectMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ObjectMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Current.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DescribedObject", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.DescribedObject.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodsMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodsMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodsMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodsMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodsMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodsMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metric", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metric.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Current.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceMetricSource) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceMetricSource: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceMetricSource: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceMetricStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceMetricStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceMetricStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Current.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenerated - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenerated - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto deleted file mode 100644 index 941d9752ae..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto +++ /dev/null @@ -1,493 +0,0 @@ -/* -Copyright 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. -*/ - - -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -syntax = "proto2"; - -package k8s.io.api.autoscaling.v2beta2; - -import "k8s.io/api/core/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/api/resource/generated.proto"; -import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; - -// Package-wide variables from generator "generated". -option go_package = "k8s.io/api/autoscaling/v2beta2"; - -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -message ContainerResourceMetricSource { - // name is the name of the resource in question. - optional string name = 1; - - // target specifies the target value for the given metric - optional MetricTarget target = 2; - - // container is the name of the container in the pods of the scaling target - optional string container = 3; -} - -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -message ContainerResourceMetricStatus { - // name is the name of the resource in question. - optional string name = 1; - - // current contains the current value for the given metric - optional MetricValueStatus current = 2; - - // container is the name of the container in the pods of the scaling target - optional string container = 3; -} - -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -message CrossVersionObjectReference { - // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - optional string kind = 1; - - // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - optional string name = 2; - - // apiVersion is the API version of the referent - // +optional - optional string apiVersion = 3; -} - -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -message ExternalMetricSource { - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 1; - - // target specifies the target value for the given metric - optional MetricTarget target = 2; -} - -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -message ExternalMetricStatus { - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 1; - - // current contains the current value for the given metric - optional MetricValueStatus current = 2; -} - -// HPAScalingPolicy is a single policy which must hold true for a specified past interval. -message HPAScalingPolicy { - // type is used to specify the scaling policy. - optional string type = 1; - - // value contains the amount of change which is permitted by the policy. - // It must be greater than zero - optional int32 value = 2; - - // periodSeconds specifies the window of time for which the policy should hold true. - // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). - optional int32 periodSeconds = 3; -} - -// HPAScalingRules configures the scaling behavior for one direction. -// These Rules are applied after calculating DesiredReplicas from metrics for the HPA. -// They can limit the scaling velocity by specifying scaling policies. -// They can prevent flapping by specifying the stabilization window, so that the -// number of replicas is not set instantly, instead, the safest value from the stabilization -// window is chosen. -message HPAScalingRules { - // stabilizationWindowSeconds is the number of seconds for which past recommendations should be - // considered while scaling up or scaling down. - // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). - // If not set, use the default values: - // - For scale up: 0 (i.e. no stabilization is done). - // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). - // +optional - optional int32 stabilizationWindowSeconds = 3; - - // selectPolicy is used to specify which policy should be used. - // If not set, the default value MaxPolicySelect is used. - // +optional - optional string selectPolicy = 1; - - // policies is a list of potential scaling polices which can be used during scaling. - // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid - // +optional - // +listType=atomic - repeated HPAScalingPolicy policies = 2; -} - -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -message HorizontalPodAutoscaler { - // metadata is the standard object metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional - optional HorizontalPodAutoscalerSpec spec = 2; - - // status is the current information about the autoscaler. - // +optional - optional HorizontalPodAutoscalerStatus status = 3; -} - -// HorizontalPodAutoscalerBehavior configures the scaling behavior of the target -// in both Up and Down directions (scaleUp and scaleDown fields respectively). -message HorizontalPodAutoscalerBehavior { - // scaleUp is scaling policy for scaling Up. - // If not set, the default value is the higher of: - // * increase no more than 4 pods per 60 seconds - // * double the number of pods per 60 seconds - // No stabilization is used. - // +optional - optional HPAScalingRules scaleUp = 1; - - // scaleDown is scaling policy for scaling Down. - // If not set, the default value is to allow to scale down to minReplicas pods, with a - // 300 second stabilization window (i.e., the highest recommendation for - // the last 300sec is used). - // +optional - optional HPAScalingRules scaleDown = 2; -} - -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -message HorizontalPodAutoscalerCondition { - // type describes the current condition - optional string type = 1; - - // status is the status of the condition (True, False, Unknown) - optional string status = 2; - - // lastTransitionTime is the last time the condition transitioned from - // one status to another - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; - - // reason is the reason for the condition's last transition. - // +optional - optional string reason = 4; - - // message is a human-readable explanation containing details about - // the transition - // +optional - optional string message = 5; -} - -// HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects. -message HorizontalPodAutoscalerList { - // metadata is the standard list metadata. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // items is the list of horizontal pod autoscaler objects. - repeated HorizontalPodAutoscaler items = 2; -} - -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -message HorizontalPodAutoscalerSpec { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - optional CrossVersionObjectReference scaleTargetRef = 1; - - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - // +optional - optional int32 minReplicas = 2; - - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - optional int32 maxReplicas = 3; - - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - // If not set, the default metric will be set to 80% average CPU utilization. - // +optional - // +listType=atomic - repeated MetricSpec metrics = 4; - - // behavior configures the scaling behavior of the target - // in both Up and Down directions (scaleUp and scaleDown fields respectively). - // If not set, the default HPAScalingRules for scale up and scale down are used. - // +optional - optional HorizontalPodAutoscalerBehavior behavior = 5; -} - -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -message HorizontalPodAutoscalerStatus { - // observedGeneration is the most recent generation observed by this autoscaler. - // +optional - optional int64 observedGeneration = 1; - - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastScaleTime = 2; - - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - optional int32 currentReplicas = 3; - - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - optional int32 desiredReplicas = 4; - - // currentMetrics is the last read state of the metrics used by this autoscaler. - // +optional - // +listType=atomic - repeated MetricStatus currentMetrics = 5; - - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - // +optional - // +listType=atomic - repeated HorizontalPodAutoscalerCondition conditions = 6; -} - -// MetricIdentifier defines the name and optionally selector for a metric -message MetricIdentifier { - // name is the name of the given metric - optional string name = 1; - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; -} - -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -message MetricSpec { - // type is the type of metric source. It should be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each mapping to a matching field in the object. - optional string type = 1; - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - optional ObjectMetricSource object = 2; - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - optional PodsMetricSource pods = 3; - - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ResourceMetricSource resource = 4; - - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - // +optional - optional ContainerResourceMetricSource containerResource = 7; - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - optional ExternalMetricSource external = 5; -} - -// MetricStatus describes the last-read state of a single metric. -message MetricStatus { - // type is the type of metric source. It will be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - optional string type = 1; - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - optional ObjectMetricStatus object = 2; - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - optional PodsMetricStatus pods = 3; - - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ResourceMetricStatus resource = 4; - - // containerResource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - optional ContainerResourceMetricStatus containerResource = 7; - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - optional ExternalMetricStatus external = 5; -} - -// MetricTarget defines the target value, average value, or average utilization of a specific metric -message MetricTarget { - // type represents whether the metric type is Utilization, Value, or AverageValue - optional string type = 1; - - // value is the target value of the metric (as a quantity). - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity value = 2; - - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 3; - - // averageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // Currently only valid for Resource metric source type - // +optional - optional int32 averageUtilization = 4; -} - -// MetricValueStatus holds the current value for a metric -message MetricValueStatus { - // value is the current value of the metric (as a quantity). - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity value = 1; - - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - optional .k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 2; - - // averageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - optional int32 averageUtilization = 3; -} - -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -message ObjectMetricSource { - optional CrossVersionObjectReference describedObject = 1; - - // target specifies the target value for the given metric - optional MetricTarget target = 2; - - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 3; -} - -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -message ObjectMetricStatus { - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 1; - - // current contains the current value for the given metric - optional MetricValueStatus current = 2; - - optional CrossVersionObjectReference describedObject = 3; -} - -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -message PodsMetricSource { - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 1; - - // target specifies the target value for the given metric - optional MetricTarget target = 2; -} - -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -message PodsMetricStatus { - // metric identifies the target metric by name and selector - optional MetricIdentifier metric = 1; - - // current contains the current value for the given metric - optional MetricValueStatus current = 2; -} - -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -message ResourceMetricSource { - // name is the name of the resource in question. - optional string name = 1; - - // target specifies the target value for the given metric - optional MetricTarget target = 2; -} - -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -message ResourceMetricStatus { - // name is the name of the resource in question. - optional string name = 1; - - // current contains the current value for the given metric - optional MetricValueStatus current = 2; -} - diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/generated.protomessage.pb.go b/vendor/k8s.io/api/autoscaling/v2beta2/generated.protomessage.pb.go deleted file mode 100644 index 6064b1eb02..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/generated.protomessage.pb.go +++ /dev/null @@ -1,70 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v2beta2 - -func (*ContainerResourceMetricSource) ProtoMessage() {} - -func (*ContainerResourceMetricStatus) ProtoMessage() {} - -func (*CrossVersionObjectReference) ProtoMessage() {} - -func (*ExternalMetricSource) ProtoMessage() {} - -func (*ExternalMetricStatus) ProtoMessage() {} - -func (*HPAScalingPolicy) ProtoMessage() {} - -func (*HPAScalingRules) ProtoMessage() {} - -func (*HorizontalPodAutoscaler) ProtoMessage() {} - -func (*HorizontalPodAutoscalerBehavior) ProtoMessage() {} - -func (*HorizontalPodAutoscalerCondition) ProtoMessage() {} - -func (*HorizontalPodAutoscalerList) ProtoMessage() {} - -func (*HorizontalPodAutoscalerSpec) ProtoMessage() {} - -func (*HorizontalPodAutoscalerStatus) ProtoMessage() {} - -func (*MetricIdentifier) ProtoMessage() {} - -func (*MetricSpec) ProtoMessage() {} - -func (*MetricStatus) ProtoMessage() {} - -func (*MetricTarget) ProtoMessage() {} - -func (*MetricValueStatus) ProtoMessage() {} - -func (*ObjectMetricSource) ProtoMessage() {} - -func (*ObjectMetricStatus) ProtoMessage() {} - -func (*PodsMetricSource) ProtoMessage() {} - -func (*PodsMetricStatus) ProtoMessage() {} - -func (*ResourceMetricSource) ProtoMessage() {} - -func (*ResourceMetricStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types.go b/vendor/k8s.io/api/autoscaling/v2beta2/types.go deleted file mode 100644 index bc9677b147..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types.go +++ /dev/null @@ -1,578 +0,0 @@ -/* -Copyright 2018 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. -*/ - -// +k8s:openapi-gen=true - -package v2beta2 - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.12 -// +k8s:prerelease-lifecycle-gen:deprecated=1.23 -// +k8s:prerelease-lifecycle-gen:replacement=autoscaling,v2,HorizontalPodAutoscaler - -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -type HorizontalPodAutoscaler struct { - metav1.TypeMeta `json:",inline"` - // metadata is the standard object metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - // +optional - Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - - // status is the current information about the autoscaler. - // +optional - Status HorizontalPodAutoscalerStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` -} - -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -type HorizontalPodAutoscalerSpec struct { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - ScaleTargetRef CrossVersionObjectReference `json:"scaleTargetRef" protobuf:"bytes,1,opt,name=scaleTargetRef"` - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - // +optional - MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` - - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` - - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - // If not set, the default metric will be set to 80% average CPU utilization. - // +optional - // +listType=atomic - Metrics []MetricSpec `json:"metrics,omitempty" protobuf:"bytes,4,rep,name=metrics"` - - // behavior configures the scaling behavior of the target - // in both Up and Down directions (scaleUp and scaleDown fields respectively). - // If not set, the default HPAScalingRules for scale up and scale down are used. - // +optional - Behavior *HorizontalPodAutoscalerBehavior `json:"behavior,omitempty" protobuf:"bytes,5,opt,name=behavior"` -} - -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -type CrossVersionObjectReference struct { - // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - - // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - - // apiVersion is the API version of the referent - // +optional - APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` -} - -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -type MetricSpec struct { - // type is the type of metric source. It should be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each mapping to a matching field in the object. - Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"` - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` - - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - // +optional - ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - External *ExternalMetricSource `json:"external,omitempty" protobuf:"bytes,5,opt,name=external"` -} - -// HorizontalPodAutoscalerBehavior configures the scaling behavior of the target -// in both Up and Down directions (scaleUp and scaleDown fields respectively). -type HorizontalPodAutoscalerBehavior struct { - // scaleUp is scaling policy for scaling Up. - // If not set, the default value is the higher of: - // * increase no more than 4 pods per 60 seconds - // * double the number of pods per 60 seconds - // No stabilization is used. - // +optional - ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" protobuf:"bytes,1,opt,name=scaleUp"` - - // scaleDown is scaling policy for scaling Down. - // If not set, the default value is to allow to scale down to minReplicas pods, with a - // 300 second stabilization window (i.e., the highest recommendation for - // the last 300sec is used). - // +optional - ScaleDown *HPAScalingRules `json:"scaleDown,omitempty" protobuf:"bytes,2,opt,name=scaleDown"` -} - -// ScalingPolicySelect is used to specify which policy should be used while scaling in a certain direction -type ScalingPolicySelect string - -const ( - // MaxPolicySelect selects the policy with the highest possible change. - MaxPolicySelect ScalingPolicySelect = "Max" - // MinPolicySelect selects the policy with the lowest possible change. - MinPolicySelect ScalingPolicySelect = "Min" - // DisabledPolicySelect disables the scaling in this direction. - DisabledPolicySelect ScalingPolicySelect = "Disabled" -) - -// HPAScalingRules configures the scaling behavior for one direction. -// These Rules are applied after calculating DesiredReplicas from metrics for the HPA. -// They can limit the scaling velocity by specifying scaling policies. -// They can prevent flapping by specifying the stabilization window, so that the -// number of replicas is not set instantly, instead, the safest value from the stabilization -// window is chosen. -type HPAScalingRules struct { - // stabilizationWindowSeconds is the number of seconds for which past recommendations should be - // considered while scaling up or scaling down. - // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). - // If not set, use the default values: - // - For scale up: 0 (i.e. no stabilization is done). - // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). - // +optional - StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty" protobuf:"varint,3,opt,name=stabilizationWindowSeconds"` - - // selectPolicy is used to specify which policy should be used. - // If not set, the default value MaxPolicySelect is used. - // +optional - SelectPolicy *ScalingPolicySelect `json:"selectPolicy,omitempty" protobuf:"bytes,1,opt,name=selectPolicy"` - - // policies is a list of potential scaling polices which can be used during scaling. - // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid - // +optional - // +listType=atomic - Policies []HPAScalingPolicy `json:"policies,omitempty" protobuf:"bytes,2,rep,name=policies"` -} - -// HPAScalingPolicyType is the type of the policy which could be used while making scaling decisions. -type HPAScalingPolicyType string - -const ( - // PodsScalingPolicy is a policy used to specify a change in absolute number of pods. - PodsScalingPolicy HPAScalingPolicyType = "Pods" - // PercentScalingPolicy is a policy used to specify a relative amount of change with respect to - // the current number of pods. - PercentScalingPolicy HPAScalingPolicyType = "Percent" -) - -// HPAScalingPolicy is a single policy which must hold true for a specified past interval. -type HPAScalingPolicy struct { - // type is used to specify the scaling policy. - Type HPAScalingPolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=HPAScalingPolicyType"` - - // value contains the amount of change which is permitted by the policy. - // It must be greater than zero - Value int32 `json:"value" protobuf:"varint,2,opt,name=value"` - - // periodSeconds specifies the window of time for which the policy should hold true. - // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). - PeriodSeconds int32 `json:"periodSeconds" protobuf:"varint,3,opt,name=periodSeconds"` -} - -// MetricSourceType indicates the type of metric. -type MetricSourceType string - -const ( - // ObjectMetricSourceType is a metric describing a kubernetes object - // (for example, hits-per-second on an Ingress object). - ObjectMetricSourceType MetricSourceType = "Object" - // PodsMetricSourceType is a metric describing each pod in the current scale - // target (for example, transactions-processed-per-second). The values - // will be averaged together before being compared to the target value. - PodsMetricSourceType MetricSourceType = "Pods" - // ResourceMetricSourceType is a resource metric known to Kubernetes, as - // specified in requests and limits, describing each pod in the current - // scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics (the "pods" source). - ResourceMetricSourceType MetricSourceType = "Resource" - // ContainerResourceMetricSourceType is a resource metric known to Kubernetes, as - // specified in requests and limits, describing a single container in each pod in the current - // scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics (the "pods" source). - ContainerResourceMetricSourceType MetricSourceType = "ContainerResource" - // ExternalMetricSourceType is a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - ExternalMetricSourceType MetricSourceType = "External" -) - -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricSource struct { - DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,1,name=describedObject"` - // target specifies the target value for the given metric - Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` - - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,3,name=metric"` -} - -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -type PodsMetricSource struct { - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` - - // target specifies the target value for the given metric - Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` -} - -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ResourceMetricSource struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - - // target specifies the target value for the given metric - Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` -} - -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ContainerResourceMetricSource struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - - // target specifies the target value for the given metric - Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` - - // container is the name of the container in the pods of the scaling target - Container string `json:"container" protobuf:"bytes,3,opt,name=container"` -} - -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -type ExternalMetricSource struct { - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` - - // target specifies the target value for the given metric - Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` -} - -// MetricIdentifier defines the name and optionally selector for a metric -type MetricIdentifier struct { - // name is the name of the given metric - Name string `json:"name" protobuf:"bytes,1,name=name"` - - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - // +optional - Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,name=selector"` -} - -// MetricTarget defines the target value, average value, or average utilization of a specific metric -type MetricTarget struct { - // type represents whether the metric type is Utilization, Value, or AverageValue - Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` - - // value is the target value of the metric (as a quantity). - // +optional - Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` - - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` - - // averageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // Currently only valid for Resource metric source type - // +optional - AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,4,opt,name=averageUtilization"` -} - -// MetricTargetType specifies the type of metric being targeted, and should be either -// "Value", "AverageValue", or "Utilization" -type MetricTargetType string - -const ( - // UtilizationMetricType declares a MetricTarget is an AverageUtilization value - UtilizationMetricType MetricTargetType = "Utilization" - // ValueMetricType declares a MetricTarget is a raw value - ValueMetricType MetricTargetType = "Value" - // AverageValueMetricType declares a MetricTarget is an - AverageValueMetricType MetricTargetType = "AverageValue" -) - -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -type HorizontalPodAutoscalerStatus struct { - // observedGeneration is the most recent generation observed by this autoscaler. - // +optional - ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - // +optional - LastScaleTime *metav1.Time `json:"lastScaleTime,omitempty" protobuf:"bytes,2,opt,name=lastScaleTime"` - - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - CurrentReplicas int32 `json:"currentReplicas" protobuf:"varint,3,opt,name=currentReplicas"` - - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - DesiredReplicas int32 `json:"desiredReplicas" protobuf:"varint,4,opt,name=desiredReplicas"` - - // currentMetrics is the last read state of the metrics used by this autoscaler. - // +optional - // +listType=atomic - CurrentMetrics []MetricStatus `json:"currentMetrics" protobuf:"bytes,5,rep,name=currentMetrics"` - - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - // +optional - // +listType=atomic - Conditions []HorizontalPodAutoscalerCondition `json:"conditions" protobuf:"bytes,6,rep,name=conditions"` -} - -// HorizontalPodAutoscalerConditionType are the valid conditions of -// a HorizontalPodAutoscaler. -type HorizontalPodAutoscalerConditionType string - -const ( - // ScalingActive indicates that the HPA controller is able to scale if necessary: - // it's correctly configured, can fetch the desired metrics, and isn't disabled. - ScalingActive HorizontalPodAutoscalerConditionType = "ScalingActive" - // AbleToScale indicates a lack of transient issues which prevent scaling from occurring, - // such as being in a backoff window, or being unable to access/update the target scale. - AbleToScale HorizontalPodAutoscalerConditionType = "AbleToScale" - // ScalingLimited indicates that the calculated scale based on metrics would be above or - // below the range for the HPA, and has thus been capped. - ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited" -) - -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -type HorizontalPodAutoscalerCondition struct { - // type describes the current condition - Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` - - // status is the status of the condition (True, False, Unknown) - Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` - - // lastTransitionTime is the last time the condition transitioned from - // one status to another - // +optional - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` - - // reason is the reason for the condition's last transition. - // +optional - Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` - - // message is a human-readable explanation containing details about - // the transition - // +optional - Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` -} - -// MetricStatus describes the last-read state of a single metric. -type MetricStatus struct { - // type is the type of metric source. It will be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - Type MetricSourceType `json:"type" protobuf:"bytes,1,name=type"` - - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - // +optional - Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` - - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - // +optional - Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - - // containerResource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - // +optional - ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` - - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - // +optional - External *ExternalMetricStatus `json:"external,omitempty" protobuf:"bytes,5,opt,name=external"` -} - -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricStatus struct { - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` - - // current contains the current value for the given metric - Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - - DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,3,name=describedObject"` -} - -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -type PodsMetricStatus struct { - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` - - // current contains the current value for the given metric - Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` -} - -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ResourceMetricStatus struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - - // current contains the current value for the given metric - Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` -} - -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ContainerResourceMetricStatus struct { - // name is the name of the resource in question. - Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` - - // current contains the current value for the given metric - Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - - // container is the name of the container in the pods of the scaling target - Container string `json:"container" protobuf:"bytes,3,opt,name=container"` -} - -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -type ExternalMetricStatus struct { - // metric identifies the target metric by name and selector - Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` - - // current contains the current value for the given metric - Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` -} - -// MetricValueStatus holds the current value for a metric -type MetricValueStatus struct { - // value is the current value of the metric (as a quantity). - // +optional - Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"` - - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - // +optional - AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"` - - // averageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // +optional - AverageUtilization *int32 `json:"averageUtilization,omitempty" protobuf:"bytes,3,opt,name=averageUtilization"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.12 -// +k8s:prerelease-lifecycle-gen:deprecated=1.22 - -// HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects. -type HorizontalPodAutoscalerList struct { - metav1.TypeMeta `json:",inline"` - // metadata is the standard list metadata. - // +optional - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // items is the list of horizontal pod autoscaler objects. - Items []HorizontalPodAutoscaler `json:"items" protobuf:"bytes,2,rep,name=items"` -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go deleted file mode 100644 index 5d4bb86b83..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go +++ /dev/null @@ -1,297 +0,0 @@ -/* -Copyright 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 v2beta2 - -// This file contains a collection of methods that can be used from go-restful to -// generate Swagger API documentation for its models. Please read this PR for more -// information on the implementation: https://github.com/emicklei/go-restful/pull/215 -// -// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if -// they are on one line! For multiple line or blocks that you want to ignore use ---. -// Any context after a --- is ignored. -// -// Those methods can be generated by using hack/update-codegen.sh - -// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. -var map_ContainerResourceMetricSource = map[string]string{ - "": "ContainerResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.", - "name": "name is the name of the resource in question.", - "target": "target specifies the target value for the given metric", - "container": "container is the name of the container in the pods of the scaling target", -} - -func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { - return map_ContainerResourceMetricSource -} - -var map_ContainerResourceMetricStatus = map[string]string{ - "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "name is the name of the resource in question.", - "current": "current contains the current value for the given metric", - "container": "container is the name of the container in the pods of the scaling target", -} - -func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { - return map_ContainerResourceMetricStatus -} - -var map_CrossVersionObjectReference = map[string]string{ - "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", - "apiVersion": "apiVersion is the API version of the referent", -} - -func (CrossVersionObjectReference) SwaggerDoc() map[string]string { - return map_CrossVersionObjectReference -} - -var map_ExternalMetricSource = map[string]string{ - "": "ExternalMetricSource indicates how to scale on a metric not associated with any Kubernetes object (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", - "metric": "metric identifies the target metric by name and selector", - "target": "target specifies the target value for the given metric", -} - -func (ExternalMetricSource) SwaggerDoc() map[string]string { - return map_ExternalMetricSource -} - -var map_ExternalMetricStatus = map[string]string{ - "": "ExternalMetricStatus indicates the current value of a global metric not associated with any Kubernetes object.", - "metric": "metric identifies the target metric by name and selector", - "current": "current contains the current value for the given metric", -} - -func (ExternalMetricStatus) SwaggerDoc() map[string]string { - return map_ExternalMetricStatus -} - -var map_HPAScalingPolicy = map[string]string{ - "": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", - "type": "type is used to specify the scaling policy.", - "value": "value contains the amount of change which is permitted by the policy. It must be greater than zero", - "periodSeconds": "periodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", -} - -func (HPAScalingPolicy) SwaggerDoc() map[string]string { - return map_HPAScalingPolicy -} - -var map_HPAScalingRules = map[string]string{ - "": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", - "stabilizationWindowSeconds": "stabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", - "selectPolicy": "selectPolicy is used to specify which policy should be used. If not set, the default value MaxPolicySelect is used.", - "policies": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", -} - -func (HPAScalingRules) SwaggerDoc() map[string]string { - return map_HPAScalingRules -} - -var map_HorizontalPodAutoscaler = map[string]string{ - "": "HorizontalPodAutoscaler is the configuration for a horizontal pod autoscaler, which automatically manages the replica count of any resource implementing the scale subresource based on the metrics specified.", - "metadata": "metadata is the standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "spec is the specification for the behaviour of the autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "status is the current information about the autoscaler.", -} - -func (HorizontalPodAutoscaler) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscaler -} - -var map_HorizontalPodAutoscalerBehavior = map[string]string{ - "": "HorizontalPodAutoscalerBehavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively).", - "scaleUp": "scaleUp is scaling policy for scaling Up. If not set, the default value is the higher of:\n * increase no more than 4 pods per 60 seconds\n * double the number of pods per 60 seconds\nNo stabilization is used.", - "scaleDown": "scaleDown is scaling policy for scaling Down. If not set, the default value is to allow to scale down to minReplicas pods, with a 300 second stabilization window (i.e., the highest recommendation for the last 300sec is used).", -} - -func (HorizontalPodAutoscalerBehavior) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerBehavior -} - -var map_HorizontalPodAutoscalerCondition = map[string]string{ - "": "HorizontalPodAutoscalerCondition describes the state of a HorizontalPodAutoscaler at a certain point.", - "type": "type describes the current condition", - "status": "status is the status of the condition (True, False, Unknown)", - "lastTransitionTime": "lastTransitionTime is the last time the condition transitioned from one status to another", - "reason": "reason is the reason for the condition's last transition.", - "message": "message is a human-readable explanation containing details about the transition", -} - -func (HorizontalPodAutoscalerCondition) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerCondition -} - -var map_HorizontalPodAutoscalerList = map[string]string{ - "": "HorizontalPodAutoscalerList is a list of horizontal pod autoscaler objects.", - "metadata": "metadata is the standard list metadata.", - "items": "items is the list of horizontal pod autoscaler objects.", -} - -func (HorizontalPodAutoscalerList) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerList -} - -var map_HorizontalPodAutoscalerSpec = map[string]string{ - "": "HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler.", - "scaleTargetRef": "scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics should be collected, as well as to actually change the replica count.", - "minReplicas": "minReplicas is the lower limit for the number of replicas to which the autoscaler can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the alpha feature gate HPAScaleToZero is enabled and at least one Object or External metric is configured. Scaling is active as long as at least one metric value is available.", - "maxReplicas": "maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. It cannot be less that minReplicas.", - "metrics": "metrics contains the specifications for which to use to calculate the desired replica count (the maximum replica count across all metrics will be used). The desired replica count is calculated multiplying the ratio between the target value and the current value by the current number of pods. Ergo, metrics used must decrease as the pod count is increased, and vice-versa. See the individual metric source types for more information about how each type of metric must respond. If not set, the default metric will be set to 80% average CPU utilization.", - "behavior": "behavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively). If not set, the default HPAScalingRules for scale up and scale down are used.", -} - -func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerSpec -} - -var map_HorizontalPodAutoscalerStatus = map[string]string{ - "": "HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler.", - "observedGeneration": "observedGeneration is the most recent generation observed by this autoscaler.", - "lastScaleTime": "lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, used by the autoscaler to control how often the number of pods is changed.", - "currentReplicas": "currentReplicas is current number of replicas of pods managed by this autoscaler, as last seen by the autoscaler.", - "desiredReplicas": "desiredReplicas is the desired number of replicas of pods managed by this autoscaler, as last calculated by the autoscaler.", - "currentMetrics": "currentMetrics is the last read state of the metrics used by this autoscaler.", - "conditions": "conditions is the set of conditions required for this autoscaler to scale its target, and indicates whether or not those conditions are met.", -} - -func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { - return map_HorizontalPodAutoscalerStatus -} - -var map_MetricIdentifier = map[string]string{ - "": "MetricIdentifier defines the name and optionally selector for a metric", - "name": "name is the name of the given metric", - "selector": "selector is the string-encoded form of a standard kubernetes label selector for the given metric When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. When unset, just the metricName will be used to gather metrics.", -} - -func (MetricIdentifier) SwaggerDoc() map[string]string { - return map_MetricIdentifier -} - -var map_MetricSpec = map[string]string{ - "": "MetricSpec specifies how to scale based on a single metric (only `type` and one other matching field should be set at once).", - "type": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.", - "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", - "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", -} - -func (MetricSpec) SwaggerDoc() map[string]string { - return map_MetricSpec -} - -var map_MetricStatus = map[string]string{ - "": "MetricStatus describes the last-read state of a single metric.", - "type": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\", \"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.", - "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", - "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", -} - -func (MetricStatus) SwaggerDoc() map[string]string { - return map_MetricStatus -} - -var map_MetricTarget = map[string]string{ - "": "MetricTarget defines the target value, average value, or average utilization of a specific metric", - "type": "type represents whether the metric type is Utilization, Value, or AverageValue", - "value": "value is the target value of the metric (as a quantity).", - "averageValue": "averageValue is the target value of the average of the metric across all relevant pods (as a quantity)", - "averageUtilization": "averageUtilization is the target value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. Currently only valid for Resource metric source type", -} - -func (MetricTarget) SwaggerDoc() map[string]string { - return map_MetricTarget -} - -var map_MetricValueStatus = map[string]string{ - "": "MetricValueStatus holds the current value for a metric", - "value": "value is the current value of the metric (as a quantity).", - "averageValue": "averageValue is the current value of the average of the metric across all relevant pods (as a quantity)", - "averageUtilization": "averageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", -} - -func (MetricValueStatus) SwaggerDoc() map[string]string { - return map_MetricValueStatus -} - -var map_ObjectMetricSource = map[string]string{ - "": "ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).", - "target": "target specifies the target value for the given metric", - "metric": "metric identifies the target metric by name and selector", -} - -func (ObjectMetricSource) SwaggerDoc() map[string]string { - return map_ObjectMetricSource -} - -var map_ObjectMetricStatus = map[string]string{ - "": "ObjectMetricStatus indicates the current value of a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).", - "metric": "metric identifies the target metric by name and selector", - "current": "current contains the current value for the given metric", -} - -func (ObjectMetricStatus) SwaggerDoc() map[string]string { - return map_ObjectMetricStatus -} - -var map_PodsMetricSource = map[string]string{ - "": "PodsMetricSource indicates how to scale on a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", - "metric": "metric identifies the target metric by name and selector", - "target": "target specifies the target value for the given metric", -} - -func (PodsMetricSource) SwaggerDoc() map[string]string { - return map_PodsMetricSource -} - -var map_PodsMetricStatus = map[string]string{ - "": "PodsMetricStatus indicates the current value of a metric describing each pod in the current scale target (for example, transactions-processed-per-second).", - "metric": "metric identifies the target metric by name and selector", - "current": "current contains the current value for the given metric", -} - -func (PodsMetricStatus) SwaggerDoc() map[string]string { - return map_PodsMetricStatus -} - -var map_ResourceMetricSource = map[string]string{ - "": "ResourceMetricSource indicates how to scale on a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). The values will be averaged together before being compared to the target. Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. Only one \"target\" type should be set.", - "name": "name is the name of the resource in question.", - "target": "target specifies the target value for the given metric", -} - -func (ResourceMetricSource) SwaggerDoc() map[string]string { - return map_ResourceMetricSource -} - -var map_ResourceMetricStatus = map[string]string{ - "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "name is the name of the resource in question.", - "current": "current contains the current value for the given metric", -} - -func (ResourceMetricStatus) SwaggerDoc() map[string]string { - return map_ResourceMetricStatus -} - -// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.deepcopy.go b/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.deepcopy.go deleted file mode 100644 index 49838843c0..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.deepcopy.go +++ /dev/null @@ -1,610 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerResourceMetricSource) DeepCopyInto(out *ContainerResourceMetricSource) { - *out = *in - in.Target.DeepCopyInto(&out.Target) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricSource. -func (in *ContainerResourceMetricSource) DeepCopy() *ContainerResourceMetricSource { - if in == nil { - return nil - } - out := new(ContainerResourceMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerResourceMetricStatus) DeepCopyInto(out *ContainerResourceMetricStatus) { - *out = *in - in.Current.DeepCopyInto(&out.Current) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceMetricStatus. -func (in *ContainerResourceMetricStatus) DeepCopy() *ContainerResourceMetricStatus { - if in == nil { - return nil - } - out := new(ContainerResourceMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CrossVersionObjectReference) DeepCopyInto(out *CrossVersionObjectReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossVersionObjectReference. -func (in *CrossVersionObjectReference) DeepCopy() *CrossVersionObjectReference { - if in == nil { - return nil - } - out := new(CrossVersionObjectReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalMetricSource) DeepCopyInto(out *ExternalMetricSource) { - *out = *in - in.Metric.DeepCopyInto(&out.Metric) - in.Target.DeepCopyInto(&out.Target) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricSource. -func (in *ExternalMetricSource) DeepCopy() *ExternalMetricSource { - if in == nil { - return nil - } - out := new(ExternalMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExternalMetricStatus) DeepCopyInto(out *ExternalMetricStatus) { - *out = *in - in.Metric.DeepCopyInto(&out.Metric) - in.Current.DeepCopyInto(&out.Current) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricStatus. -func (in *ExternalMetricStatus) DeepCopy() *ExternalMetricStatus { - if in == nil { - return nil - } - out := new(ExternalMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HPAScalingPolicy) DeepCopyInto(out *HPAScalingPolicy) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HPAScalingPolicy. -func (in *HPAScalingPolicy) DeepCopy() *HPAScalingPolicy { - if in == nil { - return nil - } - out := new(HPAScalingPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HPAScalingRules) DeepCopyInto(out *HPAScalingRules) { - *out = *in - if in.StabilizationWindowSeconds != nil { - in, out := &in.StabilizationWindowSeconds, &out.StabilizationWindowSeconds - *out = new(int32) - **out = **in - } - if in.SelectPolicy != nil { - in, out := &in.SelectPolicy, &out.SelectPolicy - *out = new(ScalingPolicySelect) - **out = **in - } - if in.Policies != nil { - in, out := &in.Policies, &out.Policies - *out = make([]HPAScalingPolicy, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HPAScalingRules. -func (in *HPAScalingRules) DeepCopy() *HPAScalingRules { - if in == nil { - return nil - } - out := new(HPAScalingRules) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscaler) DeepCopyInto(out *HorizontalPodAutoscaler) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscaler. -func (in *HorizontalPodAutoscaler) DeepCopy() *HorizontalPodAutoscaler { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscaler) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HorizontalPodAutoscaler) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerBehavior) DeepCopyInto(out *HorizontalPodAutoscalerBehavior) { - *out = *in - if in.ScaleUp != nil { - in, out := &in.ScaleUp, &out.ScaleUp - *out = new(HPAScalingRules) - (*in).DeepCopyInto(*out) - } - if in.ScaleDown != nil { - in, out := &in.ScaleDown, &out.ScaleDown - *out = new(HPAScalingRules) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerBehavior. -func (in *HorizontalPodAutoscalerBehavior) DeepCopy() *HorizontalPodAutoscalerBehavior { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerBehavior) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerCondition) DeepCopyInto(out *HorizontalPodAutoscalerCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerCondition. -func (in *HorizontalPodAutoscalerCondition) DeepCopy() *HorizontalPodAutoscalerCondition { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerList) DeepCopyInto(out *HorizontalPodAutoscalerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]HorizontalPodAutoscaler, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerList. -func (in *HorizontalPodAutoscalerList) DeepCopy() *HorizontalPodAutoscalerList { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HorizontalPodAutoscalerList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerSpec) DeepCopyInto(out *HorizontalPodAutoscalerSpec) { - *out = *in - out.ScaleTargetRef = in.ScaleTargetRef - if in.MinReplicas != nil { - in, out := &in.MinReplicas, &out.MinReplicas - *out = new(int32) - **out = **in - } - if in.Metrics != nil { - in, out := &in.Metrics, &out.Metrics - *out = make([]MetricSpec, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Behavior != nil { - in, out := &in.Behavior, &out.Behavior - *out = new(HorizontalPodAutoscalerBehavior) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerSpec. -func (in *HorizontalPodAutoscalerSpec) DeepCopy() *HorizontalPodAutoscalerSpec { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HorizontalPodAutoscalerStatus) DeepCopyInto(out *HorizontalPodAutoscalerStatus) { - *out = *in - if in.ObservedGeneration != nil { - in, out := &in.ObservedGeneration, &out.ObservedGeneration - *out = new(int64) - **out = **in - } - if in.LastScaleTime != nil { - in, out := &in.LastScaleTime, &out.LastScaleTime - *out = (*in).DeepCopy() - } - if in.CurrentMetrics != nil { - in, out := &in.CurrentMetrics, &out.CurrentMetrics - *out = make([]MetricStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]HorizontalPodAutoscalerCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalPodAutoscalerStatus. -func (in *HorizontalPodAutoscalerStatus) DeepCopy() *HorizontalPodAutoscalerStatus { - if in == nil { - return nil - } - out := new(HorizontalPodAutoscalerStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricIdentifier) DeepCopyInto(out *MetricIdentifier) { - *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricIdentifier. -func (in *MetricIdentifier) DeepCopy() *MetricIdentifier { - if in == nil { - return nil - } - out := new(MetricIdentifier) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricSpec) DeepCopyInto(out *MetricSpec) { - *out = *in - if in.Object != nil { - in, out := &in.Object, &out.Object - *out = new(ObjectMetricSource) - (*in).DeepCopyInto(*out) - } - if in.Pods != nil { - in, out := &in.Pods, &out.Pods - *out = new(PodsMetricSource) - (*in).DeepCopyInto(*out) - } - if in.Resource != nil { - in, out := &in.Resource, &out.Resource - *out = new(ResourceMetricSource) - (*in).DeepCopyInto(*out) - } - if in.ContainerResource != nil { - in, out := &in.ContainerResource, &out.ContainerResource - *out = new(ContainerResourceMetricSource) - (*in).DeepCopyInto(*out) - } - if in.External != nil { - in, out := &in.External, &out.External - *out = new(ExternalMetricSource) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricSpec. -func (in *MetricSpec) DeepCopy() *MetricSpec { - if in == nil { - return nil - } - out := new(MetricSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricStatus) DeepCopyInto(out *MetricStatus) { - *out = *in - if in.Object != nil { - in, out := &in.Object, &out.Object - *out = new(ObjectMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.Pods != nil { - in, out := &in.Pods, &out.Pods - *out = new(PodsMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.Resource != nil { - in, out := &in.Resource, &out.Resource - *out = new(ResourceMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.ContainerResource != nil { - in, out := &in.ContainerResource, &out.ContainerResource - *out = new(ContainerResourceMetricStatus) - (*in).DeepCopyInto(*out) - } - if in.External != nil { - in, out := &in.External, &out.External - *out = new(ExternalMetricStatus) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricStatus. -func (in *MetricStatus) DeepCopy() *MetricStatus { - if in == nil { - return nil - } - out := new(MetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricTarget) DeepCopyInto(out *MetricTarget) { - *out = *in - if in.Value != nil { - in, out := &in.Value, &out.Value - x := (*in).DeepCopy() - *out = &x - } - if in.AverageValue != nil { - in, out := &in.AverageValue, &out.AverageValue - x := (*in).DeepCopy() - *out = &x - } - if in.AverageUtilization != nil { - in, out := &in.AverageUtilization, &out.AverageUtilization - *out = new(int32) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTarget. -func (in *MetricTarget) DeepCopy() *MetricTarget { - if in == nil { - return nil - } - out := new(MetricTarget) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetricValueStatus) DeepCopyInto(out *MetricValueStatus) { - *out = *in - if in.Value != nil { - in, out := &in.Value, &out.Value - x := (*in).DeepCopy() - *out = &x - } - if in.AverageValue != nil { - in, out := &in.AverageValue, &out.AverageValue - x := (*in).DeepCopy() - *out = &x - } - if in.AverageUtilization != nil { - in, out := &in.AverageUtilization, &out.AverageUtilization - *out = new(int32) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricValueStatus. -func (in *MetricValueStatus) DeepCopy() *MetricValueStatus { - if in == nil { - return nil - } - out := new(MetricValueStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ObjectMetricSource) DeepCopyInto(out *ObjectMetricSource) { - *out = *in - out.DescribedObject = in.DescribedObject - in.Target.DeepCopyInto(&out.Target) - in.Metric.DeepCopyInto(&out.Metric) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMetricSource. -func (in *ObjectMetricSource) DeepCopy() *ObjectMetricSource { - if in == nil { - return nil - } - out := new(ObjectMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ObjectMetricStatus) DeepCopyInto(out *ObjectMetricStatus) { - *out = *in - in.Metric.DeepCopyInto(&out.Metric) - in.Current.DeepCopyInto(&out.Current) - out.DescribedObject = in.DescribedObject - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMetricStatus. -func (in *ObjectMetricStatus) DeepCopy() *ObjectMetricStatus { - if in == nil { - return nil - } - out := new(ObjectMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodsMetricSource) DeepCopyInto(out *PodsMetricSource) { - *out = *in - in.Metric.DeepCopyInto(&out.Metric) - in.Target.DeepCopyInto(&out.Target) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodsMetricSource. -func (in *PodsMetricSource) DeepCopy() *PodsMetricSource { - if in == nil { - return nil - } - out := new(PodsMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodsMetricStatus) DeepCopyInto(out *PodsMetricStatus) { - *out = *in - in.Metric.DeepCopyInto(&out.Metric) - in.Current.DeepCopyInto(&out.Current) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodsMetricStatus. -func (in *PodsMetricStatus) DeepCopy() *PodsMetricStatus { - if in == nil { - return nil - } - out := new(PodsMetricStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceMetricSource) DeepCopyInto(out *ResourceMetricSource) { - *out = *in - in.Target.DeepCopyInto(&out.Target) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMetricSource. -func (in *ResourceMetricSource) DeepCopy() *ResourceMetricSource { - if in == nil { - return nil - } - out := new(ResourceMetricSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceMetricStatus) DeepCopyInto(out *ResourceMetricStatus) { - *out = *in - in.Current.DeepCopyInto(&out.Current) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMetricStatus. -func (in *ResourceMetricStatus) DeepCopy() *ResourceMetricStatus { - if in == nil { - return nil - } - out := new(ResourceMetricStatus) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.model_name.go b/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.model_name.go deleted file mode 100644 index 20e8a854c6..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.model_name.go +++ /dev/null @@ -1,142 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by openapi-gen. DO NOT EDIT. - -package v2beta2 - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ContainerResourceMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ContainerResourceMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in CrossVersionObjectReference) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ExternalMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ExternalMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ExternalMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ExternalMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HPAScalingPolicy) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HPAScalingRules) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HPAScalingRules" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscaler) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerBehavior) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerCondition) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerCondition" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerList) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerList" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerSpec) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in HorizontalPodAutoscalerStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricIdentifier) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.MetricIdentifier" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricSpec) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.MetricSpec" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.MetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricTarget) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.MetricTarget" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in MetricValueStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.MetricValueStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ObjectMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ObjectMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ObjectMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ObjectMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodsMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.PodsMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodsMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.PodsMetricStatus" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ResourceMetricSource) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ResourceMetricSource" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ResourceMetricStatus) OpenAPIModelName() string { - return "io.k8s.api.autoscaling.v2beta2.ResourceMetricStatus" -} diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.prerelease-lifecycle.go deleted file mode 100644 index 6d1c2504ab..0000000000 --- a/vendor/k8s.io/api/autoscaling/v2beta2/zz_generated.prerelease-lifecycle.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. - -package v2beta2 - -import ( - schema "k8s.io/apimachinery/pkg/runtime/schema" -) - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *HorizontalPodAutoscaler) APILifecycleIntroduced() (major, minor int) { - return 1, 12 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *HorizontalPodAutoscaler) APILifecycleDeprecated() (major, minor int) { - return 1, 23 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *HorizontalPodAutoscaler) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "autoscaling", Version: "v2", Kind: "HorizontalPodAutoscaler"} -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *HorizontalPodAutoscaler) APILifecycleRemoved() (major, minor int) { - return 1, 26 -} - -// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. -func (in *HorizontalPodAutoscalerList) APILifecycleIntroduced() (major, minor int) { - return 1, 12 -} - -// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. -func (in *HorizontalPodAutoscalerList) APILifecycleDeprecated() (major, minor int) { - return 1, 22 -} - -// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. -// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. -func (in *HorizontalPodAutoscalerList) APILifecycleRemoved() (major, minor int) { - return 1, 25 -} diff --git a/vendor/k8s.io/api/batch/v1/generated.proto b/vendor/k8s.io/api/batch/v1/generated.proto index ca8248ff5b..5c35012852 100644 --- a/vendor/k8s.io/api/batch/v1/generated.proto +++ b/vendor/k8s.io/api/batch/v1/generated.proto @@ -38,7 +38,7 @@ message CronJob { // Specification of the desired behavior of a cron job, including the schedule. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional CronJobSpec spec = 2; // Current status of a cron job. @@ -61,6 +61,8 @@ message CronJobList { // CronJobSpec describes how the job execution will look like and when it will actually run. message CronJobSpec { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string schedule = 1; // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. diff --git a/vendor/k8s.io/api/batch/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/batch/v1/generated.protomessage.pb.go deleted file mode 100644 index 82928e07d1..0000000000 --- a/vendor/k8s.io/api/batch/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*CronJob) ProtoMessage() {} - -func (*CronJobList) ProtoMessage() {} - -func (*CronJobSpec) ProtoMessage() {} - -func (*CronJobStatus) ProtoMessage() {} - -func (*Job) ProtoMessage() {} - -func (*JobCondition) ProtoMessage() {} - -func (*JobList) ProtoMessage() {} - -func (*JobSpec) ProtoMessage() {} - -func (*JobStatus) ProtoMessage() {} - -func (*JobTemplateSpec) ProtoMessage() {} - -func (*PodFailurePolicy) ProtoMessage() {} - -func (*PodFailurePolicyOnExitCodesRequirement) ProtoMessage() {} - -func (*PodFailurePolicyOnPodConditionsPattern) ProtoMessage() {} - -func (*PodFailurePolicyRule) ProtoMessage() {} - -func (*SuccessPolicy) ProtoMessage() {} - -func (*SuccessPolicyRule) ProtoMessage() {} - -func (*UncountedTerminatedPods) ProtoMessage() {} diff --git a/vendor/k8s.io/api/batch/v1/types.go b/vendor/k8s.io/api/batch/v1/types.go index 26d0ee6dc4..d4894e2ef6 100644 --- a/vendor/k8s.io/api/batch/v1/types.go +++ b/vendor/k8s.io/api/batch/v1/types.go @@ -686,7 +686,7 @@ type CronJob struct { // Specification of the desired behavior of a cron job, including the schedule. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec CronJobSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Current status of a cron job. @@ -715,6 +715,8 @@ type CronJobList struct { type CronJobSpec struct { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.proto b/vendor/k8s.io/api/batch/v1beta1/generated.proto index 6dd322128d..47000470c6 100644 --- a/vendor/k8s.io/api/batch/v1beta1/generated.proto +++ b/vendor/k8s.io/api/batch/v1beta1/generated.proto @@ -39,7 +39,7 @@ message CronJob { // Specification of the desired behavior of a cron job, including the schedule. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional CronJobSpec spec = 2; // Current status of a cron job. @@ -62,6 +62,8 @@ message CronJobList { // CronJobSpec describes how the job execution will look like and when it will actually run. message CronJobSpec { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string schedule = 1; // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/batch/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 57520d7aff..0000000000 --- a/vendor/k8s.io/api/batch/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*CronJob) ProtoMessage() {} - -func (*CronJobList) ProtoMessage() {} - -func (*CronJobSpec) ProtoMessage() {} - -func (*CronJobStatus) ProtoMessage() {} - -func (*JobTemplateSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/batch/v1beta1/types.go b/vendor/k8s.io/api/batch/v1beta1/types.go index 976752a926..9e1a1b4704 100644 --- a/vendor/k8s.io/api/batch/v1beta1/types.go +++ b/vendor/k8s.io/api/batch/v1beta1/types.go @@ -52,7 +52,7 @@ type CronJob struct { // Specification of the desired behavior of a cron job, including the schedule. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec CronJobSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` // Current status of a cron job. @@ -84,6 +84,8 @@ type CronJobList struct { type CronJobSpec struct { // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` // The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. diff --git a/vendor/k8s.io/api/certificates/v1/generated.proto b/vendor/k8s.io/api/certificates/v1/generated.proto index a689f3e892..a334db4e18 100644 --- a/vendor/k8s.io/api/certificates/v1/generated.proto +++ b/vendor/k8s.io/api/certificates/v1/generated.proto @@ -39,8 +39,8 @@ option go_package = "k8s.io/api/certificates/v1"; // This API can be used to request client certificates to authenticate to kube-apiserver // (with the "kubernetes.io/kube-apiserver-client" signerName), // or to obtain certificates from custom non-Kubernetes signers. -// +k8s:supportsSubresource=/status -// +k8s:supportsSubresource=/approval +// +k8s:supportsSubresource="/status" +// +k8s:supportsSubresource="/approval" message CertificateSigningRequest { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; @@ -204,12 +204,12 @@ message CertificateSigningRequestStatus { // +listType=map // +listMapKey=type // +optional - // +k8s:listType=map - // +k8s:listMapKey=type - // +k8s:customUnique - // +k8s:optional - // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember - // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=type + // +k8s:alpha(since: "1.36")=+k8s:customUnique + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember repeated CertificateSigningRequestCondition conditions = 1; // certificate is populated with an issued certificate by the signer after an Approved condition is present. diff --git a/vendor/k8s.io/api/certificates/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/certificates/v1/generated.protomessage.pb.go deleted file mode 100644 index 527630582c..0000000000 --- a/vendor/k8s.io/api/certificates/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*CertificateSigningRequest) ProtoMessage() {} - -func (*CertificateSigningRequestCondition) ProtoMessage() {} - -func (*CertificateSigningRequestList) ProtoMessage() {} - -func (*CertificateSigningRequestSpec) ProtoMessage() {} - -func (*CertificateSigningRequestStatus) ProtoMessage() {} - -func (*ExtraValue) ProtoMessage() {} diff --git a/vendor/k8s.io/api/certificates/v1/types.go b/vendor/k8s.io/api/certificates/v1/types.go index 8cd56e6db7..9a86af13a8 100644 --- a/vendor/k8s.io/api/certificates/v1/types.go +++ b/vendor/k8s.io/api/certificates/v1/types.go @@ -39,8 +39,8 @@ import ( // This API can be used to request client certificates to authenticate to kube-apiserver // (with the "kubernetes.io/kube-apiserver-client" signerName), // or to obtain certificates from custom non-Kubernetes signers. -// +k8s:supportsSubresource=/status -// +k8s:supportsSubresource=/approval +// +k8s:supportsSubresource="/status" +// +k8s:supportsSubresource="/approval" type CertificateSigningRequest struct { metav1.TypeMeta `json:",inline"` // +optional @@ -179,12 +179,12 @@ type CertificateSigningRequestStatus struct { // +listType=map // +listMapKey=type // +optional - // +k8s:listType=map - // +k8s:listMapKey=type - // +k8s:customUnique - // +k8s:optional - // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember - // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=type + // +k8s:alpha(since: "1.36")=+k8s:customUnique + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember Conditions []CertificateSigningRequestCondition `json:"conditions,omitempty" protobuf:"bytes,1,rep,name=conditions"` // certificate is populated with an issued certificate by the signer after an Approved condition is present. diff --git a/vendor/k8s.io/api/certificates/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/certificates/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index 81dd80e28a..0000000000 --- a/vendor/k8s.io/api/certificates/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*ClusterTrustBundle) ProtoMessage() {} - -func (*ClusterTrustBundleList) ProtoMessage() {} - -func (*ClusterTrustBundleSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go b/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go index 5a8b8f2d13..f375246a4b 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go @@ -642,6 +642,13 @@ func (m *PodCertificateRequestSpec) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if m.StubPKCS10Request != nil { + i -= len(m.StubPKCS10Request) + copy(dAtA[i:], m.StubPKCS10Request) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.StubPKCS10Request))) + i-- + dAtA[i] = 0x62 + } if len(m.UnverifiedUserAnnotations) > 0 { keysForUnverifiedUserAnnotations := make([]string, 0, len(m.UnverifiedUserAnnotations)) for k := range m.UnverifiedUserAnnotations { @@ -1058,6 +1065,10 @@ func (m *PodCertificateRequestSpec) Size() (n int) { n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } + if m.StubPKCS10Request != nil { + l = len(m.StubPKCS10Request) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -1274,6 +1285,7 @@ func (this *PodCertificateRequestSpec) String() string { `PKIXPublicKey:` + valueToStringGenerated(this.PKIXPublicKey) + `,`, `ProofOfPossession:` + valueToStringGenerated(this.ProofOfPossession) + `,`, `UnverifiedUserAnnotations:` + mapStringForUnverifiedUserAnnotations + `,`, + `StubPKCS10Request:` + valueToStringGenerated(this.StubPKCS10Request) + `,`, `}`, }, "") return s @@ -3490,6 +3502,40 @@ func (m *PodCertificateRequestSpec) Unmarshal(dAtA []byte) error { } m.UnverifiedUserAnnotations[mapkey] = mapvalue iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StubPKCS10Request", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StubPKCS10Request = append(m.StubPKCS10Request[:0], dAtA[iNdEx:postIndex]...) + if m.StubPKCS10Request == nil { + m.StubPKCS10Request = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/certificates/v1beta1/generated.proto b/vendor/k8s.io/api/certificates/v1beta1/generated.proto index a8ffad4727..cc46dee16d 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/generated.proto +++ b/vendor/k8s.io/api/certificates/v1beta1/generated.proto @@ -30,8 +30,8 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; option go_package = "k8s.io/api/certificates/v1beta1"; // Describes a certificate signing request -// +k8s:supportsSubresource=/status -// +k8s:supportsSubresource=/approval +// +k8s:supportsSubresource="/status" +// +k8s:supportsSubresource="/approval" message CertificateSigningRequest { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; @@ -183,12 +183,12 @@ message CertificateSigningRequestStatus { // +listType=map // +listMapKey=type // +optional - // +k8s:listType=map - // +k8s:listMapKey=type - // +k8s:customUnique - // +k8s:optional - // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember - // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=type + // +k8s:alpha(since: "1.36")=+k8s:customUnique + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember repeated CertificateSigningRequestCondition conditions = 1; // If request was approved, the controller will place the issued certificate here. @@ -289,6 +289,7 @@ message PodCertificateRequest { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // spec contains the details about the certificate being requested. + // +required optional PodCertificateRequestSpec spec = 2; // status contains the issued certificate, and a standard set of conditions. @@ -369,8 +370,7 @@ message PodCertificateRequestSpec { // +default=86400 optional int32 maxExpirationSeconds = 8; - // pkixPublicKey is the PKIX-serialized public key the signer will issue the - // certificate to. + // The PKIX-serialized public key the signer will issue the certificate to. // // The key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, // or ED25519. Note that this list may be expanded in the future. @@ -382,11 +382,16 @@ message PodCertificateRequestSpec { // "UnsupportedKeyType". It may also suggest a key type that it does support // in the message field. // - // +required + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. Signer + // implementations should extract the public key from the StubPKCS10Request + // field. + // + // +optional optional bytes pkixPublicKey = 9; - // proofOfPossession proves that the requesting kubelet holds the private - // key corresponding to pkixPublicKey. + // A proof that the requesting kubelet holds the private key corresponding + // to pkixPublicKey. // // It is contructed by signing the ASCII bytes of the pod's UID using // `pkixPublicKey`. @@ -403,12 +408,35 @@ message PodCertificateRequestSpec { // golang library function crypto/ecdsa.SignASN1) // // If the key is an ED25519 key, the the signature is as described by the - // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by - // the golang library crypto/ed25519.Sign). + // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the + // golang library crypto/ed25519.Sign). // - // +required + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. + // + // +optional optional bytes proofOfPossession = 10; + // A PKCS#10 certificate signing request (DER-serialized) generated by + // Kubelet using the subject private key. + // + // Most signer implementations will ignore the contents of the CSR except to + // extract the subject public key. The API server automatically verifies the + // CSR signature during admission, so the signer does not need to repeat the + // verification. CSRs generated by kubelet are completely empty. + // + // The subject public key must be one of RSA3072, RSA4096, ECDSAP256, + // ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in + // the future. + // + // Signer implementations do not need to support all key types supported by + // kube-apiserver and kubelet. If a signer does not support the key type + // used for a given PodCertificateRequest, it must deny the request by + // setting a status.conditions entry with a type of "Denied" and a reason of + // "UnsupportedKeyType". It may also suggest a key type that it does support + // in the message field. + optional bytes stubPKCS10Request = 12; + // unverifiedUserAnnotations allow pod authors to pass additional information to // the signer implementation. Kubernetes does not restrict or validate this // metadata in any way. diff --git a/vendor/k8s.io/api/certificates/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/certificates/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 00ba7faaeb..0000000000 --- a/vendor/k8s.io/api/certificates/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*CertificateSigningRequest) ProtoMessage() {} - -func (*CertificateSigningRequestCondition) ProtoMessage() {} - -func (*CertificateSigningRequestList) ProtoMessage() {} - -func (*CertificateSigningRequestSpec) ProtoMessage() {} - -func (*CertificateSigningRequestStatus) ProtoMessage() {} - -func (*ClusterTrustBundle) ProtoMessage() {} - -func (*ClusterTrustBundleList) ProtoMessage() {} - -func (*ClusterTrustBundleSpec) ProtoMessage() {} - -func (*ExtraValue) ProtoMessage() {} - -func (*PodCertificateRequest) ProtoMessage() {} - -func (*PodCertificateRequestList) ProtoMessage() {} - -func (*PodCertificateRequestSpec) ProtoMessage() {} - -func (*PodCertificateRequestStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/certificates/v1beta1/types.go b/vendor/k8s.io/api/certificates/v1beta1/types.go index acfabbfe9f..e8ffa41e6d 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types.go @@ -32,8 +32,8 @@ import ( // +k8s:prerelease-lifecycle-gen:replacement=certificates.k8s.io,v1,CertificateSigningRequest // Describes a certificate signing request -// +k8s:supportsSubresource=/status -// +k8s:supportsSubresource=/approval +// +k8s:supportsSubresource="/status" +// +k8s:supportsSubresource="/approval" type CertificateSigningRequest struct { metav1.TypeMeta `json:",inline"` // +optional @@ -177,12 +177,12 @@ type CertificateSigningRequestStatus struct { // +listType=map // +listMapKey=type // +optional - // +k8s:listType=map - // +k8s:listMapKey=type - // +k8s:customUnique - // +k8s:optional - // +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember - // +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=type + // +k8s:alpha(since: "1.36")=+k8s:customUnique + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember + // +k8s:alpha(since: "1.36")=+k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember Conditions []CertificateSigningRequestCondition `json:"conditions,omitempty" protobuf:"bytes,1,rep,name=conditions"` // If request was approved, the controller will place the issued certificate here. @@ -273,6 +273,7 @@ const ( // +genclient // +genclient:nonNamespaced // +k8s:prerelease-lifecycle-gen:introduced=1.33 +// +k8s:prerelease-lifecycle-gen:deprecated=1.37 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors @@ -340,6 +341,7 @@ type ClusterTrustBundleSpec struct { } // +k8s:prerelease-lifecycle-gen:introduced=1.33 +// +k8s:prerelease-lifecycle-gen:deprecated=1.37 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ClusterTrustBundleList is a collection of ClusterTrustBundle objects @@ -372,6 +374,7 @@ type PodCertificateRequest struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // spec contains the details about the certificate being requested. + // +required Spec PodCertificateRequestSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` // status contains the issued certificate, and a standard set of conditions. @@ -438,8 +441,7 @@ type PodCertificateRequestSpec struct { // +default=86400 MaxExpirationSeconds *int32 `json:"maxExpirationSeconds,omitempty" protobuf:"varint,8,opt,name=maxExpirationSeconds"` - // pkixPublicKey is the PKIX-serialized public key the signer will issue the - // certificate to. + // The PKIX-serialized public key the signer will issue the certificate to. // // The key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, // or ED25519. Note that this list may be expanded in the future. @@ -451,11 +453,16 @@ type PodCertificateRequestSpec struct { // "UnsupportedKeyType". It may also suggest a key type that it does support // in the message field. // - // +required + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. Signer + // implementations should extract the public key from the StubPKCS10Request + // field. + // + // +optional PKIXPublicKey []byte `json:"pkixPublicKey" protobuf:"bytes,9,opt,name=pkixPublicKey"` - // proofOfPossession proves that the requesting kubelet holds the private - // key corresponding to pkixPublicKey. + // A proof that the requesting kubelet holds the private key corresponding + // to pkixPublicKey. // // It is contructed by signing the ASCII bytes of the pod's UID using // `pkixPublicKey`. @@ -472,12 +479,35 @@ type PodCertificateRequestSpec struct { // golang library function crypto/ecdsa.SignASN1) // // If the key is an ED25519 key, the the signature is as described by the - // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by - // the golang library crypto/ed25519.Sign). + // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the + // golang library crypto/ed25519.Sign). // - // +required + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. + // + // +optional ProofOfPossession []byte `json:"proofOfPossession" protobuf:"bytes,10,opt,name=proofOfPossession"` + // A PKCS#10 certificate signing request (DER-serialized) generated by + // Kubelet using the subject private key. + // + // Most signer implementations will ignore the contents of the CSR except to + // extract the subject public key. The API server automatically verifies the + // CSR signature during admission, so the signer does not need to repeat the + // verification. CSRs generated by kubelet are completely empty. + // + // The subject public key must be one of RSA3072, RSA4096, ECDSAP256, + // ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in + // the future. + // + // Signer implementations do not need to support all key types supported by + // kube-apiserver and kubelet. If a signer does not support the key type + // used for a given PodCertificateRequest, it must deny the request by + // setting a status.conditions entry with a type of "Denied" and a reason of + // "UnsupportedKeyType". It may also suggest a key type that it does support + // in the message field. + StubPKCS10Request []byte `json:"stubPKCS10Request" protobuf:"bytes,12,opt,name=stubPKCS10Request"` + // unverifiedUserAnnotations allow pod authors to pass additional information to // the signer implementation. Kubernetes does not restrict or validate this // metadata in any way. diff --git a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go index bd829fb216..cad8768a59 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go @@ -136,8 +136,9 @@ var map_PodCertificateRequestSpec = map[string]string{ "nodeName": "nodeName is the name of the node the pod is assigned to.", "nodeUID": "nodeUID is the UID of the node the pod is assigned to.", "maxExpirationSeconds": "maxExpirationSeconds is the maximum lifetime permitted for the certificate.\n\nIf omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver will reject values shorter than 3600 (1 hour). The maximum allowable value is 7862400 (91 days).\n\nThe signer implementation is then free to issue a certificate with any lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600 seconds (1 hour). This constraint is enforced by kube-apiserver. `kubernetes.io` signers will never issue certificates with a lifetime longer than 24 hours.", - "pkixPublicKey": "pkixPublicKey is the PKIX-serialized public key the signer will issue the certificate to.\n\nThe key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in the future.\n\nSigner implementations do not need to support all key types supported by kube-apiserver and kubelet. If a signer does not support the key type used for a given PodCertificateRequest, it must deny the request by setting a status.conditions entry with a type of \"Denied\" and a reason of \"UnsupportedKeyType\". It may also suggest a key type that it does support in the message field.", - "proofOfPossession": "proofOfPossession proves that the requesting kubelet holds the private key corresponding to pkixPublicKey.\n\nIt is contructed by signing the ASCII bytes of the pod's UID using `pkixPublicKey`.\n\nkube-apiserver validates the proof of possession during creation of the PodCertificateRequest.\n\nIf the key is an RSA key, then the signature is over the ASCII bytes of the pod UID, using RSASSA-PSS from RFC 8017 (as implemented by the golang function crypto/rsa.SignPSS with nil options).\n\nIf the key is an ECDSA key, then the signature is as described by [SEC 1, Version 2.0](https://www.secg.org/sec1-v2.pdf) (as implemented by the golang library function crypto/ecdsa.SignASN1)\n\nIf the key is an ED25519 key, the the signature is as described by the [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the golang library crypto/ed25519.Sign).", + "pkixPublicKey": "The PKIX-serialized public key the signer will issue the certificate to.\n\nThe key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in the future.\n\nSigner implementations do not need to support all key types supported by kube-apiserver and kubelet. If a signer does not support the key type used for a given PodCertificateRequest, it must deny the request by setting a status.conditions entry with a type of \"Denied\" and a reason of \"UnsupportedKeyType\". It may also suggest a key type that it does support in the message field.\n\nDeprecated: This field is replaced by StubPKCS10Request. If StubPKCS10Request is set, this field must be empty. Signer implementations should extract the public key from the StubPKCS10Request field.", + "proofOfPossession": "A proof that the requesting kubelet holds the private key corresponding to pkixPublicKey.\n\nIt is contructed by signing the ASCII bytes of the pod's UID using `pkixPublicKey`.\n\nkube-apiserver validates the proof of possession during creation of the PodCertificateRequest.\n\nIf the key is an RSA key, then the signature is over the ASCII bytes of the pod UID, using RSASSA-PSS from RFC 8017 (as implemented by the golang function crypto/rsa.SignPSS with nil options).\n\nIf the key is an ECDSA key, then the signature is as described by [SEC 1, Version 2.0](https://www.secg.org/sec1-v2.pdf) (as implemented by the golang library function crypto/ecdsa.SignASN1)\n\nIf the key is an ED25519 key, the the signature is as described by the [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the golang library crypto/ed25519.Sign).\n\nDeprecated: This field is replaced by StubPKCS10Request. If StubPKCS10Request is set, this field must be empty.", + "stubPKCS10Request": "A PKCS#10 certificate signing request (DER-serialized) generated by Kubelet using the subject private key.\n\nMost signer implementations will ignore the contents of the CSR except to extract the subject public key. The API server automatically verifies the CSR signature during admission, so the signer does not need to repeat the verification. CSRs generated by kubelet are completely empty.\n\nThe subject public key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in the future.\n\nSigner implementations do not need to support all key types supported by kube-apiserver and kubelet. If a signer does not support the key type used for a given PodCertificateRequest, it must deny the request by setting a status.conditions entry with a type of \"Denied\" and a reason of \"UnsupportedKeyType\". It may also suggest a key type that it does support in the message field.", "unverifiedUserAnnotations": "unverifiedUserAnnotations allow pod authors to pass additional information to the signer implementation. Kubernetes does not restrict or validate this metadata in any way.\n\nEntries are subject to the same validation as object metadata annotations, with the addition that all keys must be domain-prefixed. No restrictions are placed on values, except an overall size limitation on the entire field.\n\nSigners should document the keys and values they support. Signers should deny requests that contain keys they do not recognize.", } diff --git a/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go index 20b5c2a242..417b8a3e65 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go @@ -364,6 +364,11 @@ func (in *PodCertificateRequestSpec) DeepCopyInto(out *PodCertificateRequestSpec *out = make([]byte, len(*in)) copy(*out, *in) } + if in.StubPKCS10Request != nil { + in, out := &in.StubPKCS10Request, &out.StubPKCS10Request + *out = make([]byte, len(*in)) + copy(*out, *in) + } if in.UnverifiedUserAnnotations != nil { in, out := &in.UnverifiedUserAnnotations, &out.UnverifiedUserAnnotations *out = make(map[string]string, len(*in)) diff --git a/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go index f95e329e2d..d541ffb005 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go @@ -82,13 +82,13 @@ func (in *ClusterTrustBundle) APILifecycleIntroduced() (major, minor int) { // APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. func (in *ClusterTrustBundle) APILifecycleDeprecated() (major, minor int) { - return 1, 36 + return 1, 37 } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *ClusterTrustBundle) APILifecycleRemoved() (major, minor int) { - return 1, 39 + return 1, 40 } // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. @@ -100,13 +100,13 @@ func (in *ClusterTrustBundleList) APILifecycleIntroduced() (major, minor int) { // APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. func (in *ClusterTrustBundleList) APILifecycleDeprecated() (major, minor int) { - return 1, 36 + return 1, 37 } // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. func (in *ClusterTrustBundleList) APILifecycleRemoved() (major, minor int) { - return 1, 39 + return 1, 40 } // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. diff --git a/vendor/k8s.io/api/coordination/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/coordination/v1/generated.protomessage.pb.go deleted file mode 100644 index f9210fce6a..0000000000 --- a/vendor/k8s.io/api/coordination/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*Lease) ProtoMessage() {} - -func (*LeaseList) ProtoMessage() {} - -func (*LeaseSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/coordination/v1alpha2/generated.proto b/vendor/k8s.io/api/coordination/v1alpha2/generated.proto index 250c6113ec..379fcf0d5d 100644 --- a/vendor/k8s.io/api/coordination/v1alpha2/generated.proto +++ b/vendor/k8s.io/api/coordination/v1alpha2/generated.proto @@ -38,7 +38,7 @@ message LeaseCandidate { // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional LeaseCandidateSpec spec = 2; } diff --git a/vendor/k8s.io/api/coordination/v1alpha2/generated.protomessage.pb.go b/vendor/k8s.io/api/coordination/v1alpha2/generated.protomessage.pb.go deleted file mode 100644 index 9374326229..0000000000 --- a/vendor/k8s.io/api/coordination/v1alpha2/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha2 - -func (*LeaseCandidate) ProtoMessage() {} - -func (*LeaseCandidateList) ProtoMessage() {} - -func (*LeaseCandidateSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/coordination/v1alpha2/types.go b/vendor/k8s.io/api/coordination/v1alpha2/types.go index 13e1deb067..f8a6d33af1 100644 --- a/vendor/k8s.io/api/coordination/v1alpha2/types.go +++ b/vendor/k8s.io/api/coordination/v1alpha2/types.go @@ -35,7 +35,7 @@ type LeaseCandidate struct { // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec LeaseCandidateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } diff --git a/vendor/k8s.io/api/coordination/v1beta1/generated.proto b/vendor/k8s.io/api/coordination/v1beta1/generated.proto index 7ca043f528..74df40c64f 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/generated.proto +++ b/vendor/k8s.io/api/coordination/v1beta1/generated.proto @@ -50,7 +50,7 @@ message LeaseCandidate { // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional LeaseCandidateSpec spec = 2; } diff --git a/vendor/k8s.io/api/coordination/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/coordination/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index a1a88e55ff..0000000000 --- a/vendor/k8s.io/api/coordination/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*Lease) ProtoMessage() {} - -func (*LeaseCandidate) ProtoMessage() {} - -func (*LeaseCandidateList) ProtoMessage() {} - -func (*LeaseCandidateSpec) ProtoMessage() {} - -func (*LeaseList) ProtoMessage() {} - -func (*LeaseSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/coordination/v1beta1/types.go b/vendor/k8s.io/api/coordination/v1beta1/types.go index 781d29efce..ba6d6aa095 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/types.go +++ b/vendor/k8s.io/api/coordination/v1beta1/types.go @@ -106,7 +106,7 @@ type LeaseCandidate struct { // spec contains the specification of the Lease. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec LeaseCandidateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } diff --git a/vendor/k8s.io/api/core/v1/generated.pb.go b/vendor/k8s.io/api/core/v1/generated.pb.go index b7de1bea54..0fcbd5edf7 100644 --- a/vendor/k8s.io/api/core/v1/generated.pb.go +++ b/vendor/k8s.io/api/core/v1/generated.pb.go @@ -196,6 +196,8 @@ func (m *ISCSIVolumeSource) Reset() { *m = ISCSIVolumeSource{} } func (m *ImageVolumeSource) Reset() { *m = ImageVolumeSource{} } +func (m *ImageVolumeStatus) Reset() { *m = ImageVolumeStatus{} } + func (m *KeyToPath) Reset() { *m = KeyToPath{} } func (m *Lifecycle) Reset() { *m = Lifecycle{} } @@ -242,6 +244,8 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} } func (m *NodeAffinity) Reset() { *m = NodeAffinity{} } +func (m *NodeAllocatableResourceClaimStatus) Reset() { *m = NodeAllocatableResourceClaimStatus{} } + func (m *NodeCondition) Reset() { *m = NodeCondition{} } func (m *NodeConfigSource) Reset() { *m = NodeConfigSource{} } @@ -346,6 +350,8 @@ func (m *PodResourceClaimStatus) Reset() { *m = PodResourceClaimStatus{} } func (m *PodSchedulingGate) Reset() { *m = PodSchedulingGate{} } +func (m *PodSchedulingGroup) Reset() { *m = PodSchedulingGroup{} } + func (m *PodSecurityContext) Reset() { *m = PodSecurityContext{} } func (m *PodSignature) Reset() { *m = PodSignature{} } @@ -504,14 +510,14 @@ func (m *VolumeResourceRequirements) Reset() { *m = VolumeResourceRequirements{} func (m *VolumeSource) Reset() { *m = VolumeSource{} } +func (m *VolumeStatus) Reset() { *m = VolumeStatus{} } + func (m *VsphereVirtualDiskVolumeSource) Reset() { *m = VsphereVirtualDiskVolumeSource{} } func (m *WeightedPodAffinityTerm) Reset() { *m = WeightedPodAffinityTerm{} } func (m *WindowsSecurityContextOptions) Reset() { *m = WindowsSecurityContextOptions{} } -func (m *WorkloadReference) Reset() { *m = WorkloadReference{} } - func (m *AWSElasticBlockStoreVolumeSource) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5155,6 +5161,34 @@ func (m *ImageVolumeSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ImageVolumeStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ImageVolumeStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ImageVolumeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.ImageRef) + copy(dAtA[i:], m.ImageRef) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ImageRef))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *KeyToPath) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6291,6 +6325,72 @@ func (m *NodeAffinity) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NodeAllocatableResourceClaimStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeAllocatableResourceClaimStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeAllocatableResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Resources) > 0 { + keysForResources := make([]string, 0, len(m.Resources)) + for k := range m.Resources { + keysForResources = append(keysForResources, string(k)) + } + sort.Strings(keysForResources) + for iNdEx := len(keysForResources) - 1; iNdEx >= 0; iNdEx-- { + v := m.Resources[ResourceName(keysForResources[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForResources[iNdEx]) + copy(dAtA[i:], keysForResources[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForResources[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Containers) > 0 { + for iNdEx := len(m.Containers) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Containers[iNdEx]) + copy(dAtA[i:], m.Containers[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Containers[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.ResourceClaimName) + copy(dAtA[i:], m.ResourceClaimName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceClaimName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *NodeCondition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9446,6 +9546,36 @@ func (m *PodSchedulingGate) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PodSchedulingGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodSchedulingGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodSchedulingGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PodGroupName != nil { + i -= len(*m.PodGroupName) + copy(dAtA[i:], *m.PodGroupName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PodGroupName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *PodSecurityContext) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9639,9 +9769,9 @@ func (m *PodSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.WorkloadRef != nil { + if m.SchedulingGroup != nil { { - size, err := m.WorkloadRef.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.SchedulingGroup.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -9651,7 +9781,7 @@ func (m *PodSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2 i-- - dAtA[i] = 0xd2 + dAtA[i] = 0xda } if m.HostnameOverride != nil { i -= len(*m.HostnameOverride) @@ -10150,6 +10280,22 @@ func (m *PodStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.NodeAllocatableResourceClaimStatuses) > 0 { + for iNdEx := len(m.NodeAllocatableResourceClaimStatuses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.NodeAllocatableResourceClaimStatuses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } + } if m.Resources != nil { { size, err := m.Resources.MarshalToSizedBuffer(dAtA[:i]) @@ -11532,6 +11678,13 @@ func (m *ResourceHealth) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Message != nil { + i -= len(*m.Message) + copy(dAtA[i:], *m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Message))) + i-- + dAtA[i] = 0x32 + } i -= len(m.Health) copy(dAtA[i:], m.Health) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Health))) @@ -14149,6 +14302,18 @@ func (m *VolumeMountStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.VolumeStatus != nil { + { + size, err := m.VolumeStatus.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } if m.RecursiveReadOnly != nil { i -= len(*m.RecursiveReadOnly) copy(dAtA[i:], *m.RecursiveReadOnly) @@ -14801,6 +14966,41 @@ func (m *VolumeSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *VolumeStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VolumeStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VolumeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Image != nil { + { + size, err := m.Image.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *VsphereVirtualDiskVolumeSource) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -14934,44 +15134,6 @@ func (m *WindowsSecurityContextOptions) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *WorkloadReference) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *WorkloadReference) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *WorkloadReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.PodGroupReplicaKey) - copy(dAtA[i:], m.PodGroupReplicaKey) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.PodGroupReplicaKey))) - i-- - dAtA[i] = 0x1a - i -= len(m.PodGroup) - copy(dAtA[i:], m.PodGroup) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.PodGroup))) - i-- - dAtA[i] = 0x12 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -16706,6 +16868,17 @@ func (m *ImageVolumeSource) Size() (n int) { return n } +func (m *ImageVolumeStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ImageRef) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *KeyToPath) Size() (n int) { if m == nil { return 0 @@ -17123,6 +17296,32 @@ func (m *NodeAffinity) Size() (n int) { return n } +func (m *NodeAllocatableResourceClaimStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ResourceClaimName) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Containers) > 0 { + for _, s := range m.Containers { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Resources) > 0 { + for k, v := range m.Resources { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + return n +} + func (m *NodeCondition) Size() (n int) { if m == nil { return 0 @@ -18296,6 +18495,19 @@ func (m *PodSchedulingGate) Size() (n int) { return n } +func (m *PodSchedulingGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PodGroupName != nil { + l = len(*m.PodGroupName) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *PodSecurityContext) Size() (n int) { if m == nil { return 0 @@ -18535,8 +18747,8 @@ func (m *PodSpec) Size() (n int) { l = len(*m.HostnameOverride) n += 2 + l + sovGenerated(uint64(l)) } - if m.WorkloadRef != nil { - l = m.WorkloadRef.Size() + if m.SchedulingGroup != nil { + l = m.SchedulingGroup.Size() n += 2 + l + sovGenerated(uint64(l)) } return n @@ -18628,6 +18840,12 @@ func (m *PodStatus) Size() (n int) { l = m.Resources.Size() n += 2 + l + sovGenerated(uint64(l)) } + if len(m.NodeAllocatableResourceClaimStatuses) > 0 { + for _, e := range m.NodeAllocatableResourceClaimStatuses { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -19052,6 +19270,10 @@ func (m *ResourceHealth) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Health) n += 1 + l + sovGenerated(uint64(l)) + if m.Message != nil { + l = len(*m.Message) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -20041,6 +20263,10 @@ func (m *VolumeMountStatus) Size() (n int) { l = len(*m.RecursiveReadOnly) n += 1 + l + sovGenerated(uint64(l)) } + if m.VolumeStatus != nil { + l = m.VolumeStatus.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -20246,6 +20472,19 @@ func (m *VolumeSource) Size() (n int) { return n } +func (m *VolumeStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Image != nil { + l = m.Image.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *VsphereVirtualDiskVolumeSource) Size() (n int) { if m == nil { return 0 @@ -20299,21 +20538,6 @@ func (m *WindowsSecurityContextOptions) Size() (n int) { return n } -func (m *WorkloadReference) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.PodGroup) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.PodGroupReplicaKey) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - func sovGenerated(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -21595,6 +21819,16 @@ func (this *ImageVolumeSource) String() string { }, "") return s } +func (this *ImageVolumeStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ImageVolumeStatus{`, + `ImageRef:` + fmt.Sprintf("%v", this.ImageRef) + `,`, + `}`, + }, "") + return s +} func (this *KeyToPath) String() string { if this == nil { return "nil" @@ -21951,6 +22185,28 @@ func (this *NodeAffinity) String() string { }, "") return s } +func (this *NodeAllocatableResourceClaimStatus) String() string { + if this == nil { + return "nil" + } + keysForResources := make([]string, 0, len(this.Resources)) + for k := range this.Resources { + keysForResources = append(keysForResources, string(k)) + } + sort.Strings(keysForResources) + mapStringForResources := "map[ResourceName]resource.Quantity{" + for _, k := range keysForResources { + mapStringForResources += fmt.Sprintf("%v: %v,", k, this.Resources[ResourceName(k)]) + } + mapStringForResources += "}" + s := strings.Join([]string{`&NodeAllocatableResourceClaimStatus{`, + `ResourceClaimName:` + fmt.Sprintf("%v", this.ResourceClaimName) + `,`, + `Containers:` + fmt.Sprintf("%v", this.Containers) + `,`, + `Resources:` + mapStringForResources + `,`, + `}`, + }, "") + return s +} func (this *NodeCondition) String() string { if this == nil { return "nil" @@ -22800,6 +23056,16 @@ func (this *PodSchedulingGate) String() string { }, "") return s } +func (this *PodSchedulingGroup) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodSchedulingGroup{`, + `PodGroupName:` + valueToStringGenerated(this.PodGroupName) + `,`, + `}`, + }, "") + return s +} func (this *PodSecurityContext) String() string { if this == nil { return "nil" @@ -22958,7 +23224,7 @@ func (this *PodSpec) String() string { `ResourceClaims:` + repeatedStringForResourceClaims + `,`, `Resources:` + strings.Replace(this.Resources.String(), "ResourceRequirements", "ResourceRequirements", 1) + `,`, `HostnameOverride:` + valueToStringGenerated(this.HostnameOverride) + `,`, - `WorkloadRef:` + strings.Replace(this.WorkloadRef.String(), "WorkloadReference", "WorkloadReference", 1) + `,`, + `SchedulingGroup:` + strings.Replace(this.SchedulingGroup.String(), "PodSchedulingGroup", "PodSchedulingGroup", 1) + `,`, `}`, }, "") return s @@ -23002,6 +23268,11 @@ func (this *PodStatus) String() string { repeatedStringForHostIPs += strings.Replace(strings.Replace(f.String(), "HostIP", "HostIP", 1), `&`, ``, 1) + "," } repeatedStringForHostIPs += "}" + repeatedStringForNodeAllocatableResourceClaimStatuses := "[]NodeAllocatableResourceClaimStatus{" + for _, f := range this.NodeAllocatableResourceClaimStatuses { + repeatedStringForNodeAllocatableResourceClaimStatuses += strings.Replace(strings.Replace(f.String(), "NodeAllocatableResourceClaimStatus", "NodeAllocatableResourceClaimStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForNodeAllocatableResourceClaimStatuses += "}" keysForAllocatedResources := make([]string, 0, len(this.AllocatedResources)) for k := range this.AllocatedResources { keysForAllocatedResources = append(keysForAllocatedResources, string(k)) @@ -23033,6 +23304,7 @@ func (this *PodStatus) String() string { `ExtendedResourceClaimStatus:` + strings.Replace(this.ExtendedResourceClaimStatus.String(), "PodExtendedResourceClaimStatus", "PodExtendedResourceClaimStatus", 1) + `,`, `AllocatedResources:` + mapStringForAllocatedResources + `,`, `Resources:` + strings.Replace(this.Resources.String(), "ResourceRequirements", "ResourceRequirements", 1) + `,`, + `NodeAllocatableResourceClaimStatuses:` + repeatedStringForNodeAllocatableResourceClaimStatuses + `,`, `}`, }, "") return s @@ -23365,6 +23637,7 @@ func (this *ResourceHealth) String() string { s := strings.Join([]string{`&ResourceHealth{`, `ResourceID:` + fmt.Sprintf("%v", this.ResourceID) + `,`, `Health:` + fmt.Sprintf("%v", this.Health) + `,`, + `Message:` + valueToStringGenerated(this.Message) + `,`, `}`, }, "") return s @@ -24118,6 +24391,7 @@ func (this *VolumeMountStatus) String() string { `MountPath:` + fmt.Sprintf("%v", this.MountPath) + `,`, `ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`, `RecursiveReadOnly:` + valueToStringGenerated(this.RecursiveReadOnly) + `,`, + `VolumeStatus:` + strings.Replace(this.VolumeStatus.String(), "VolumeStatus", "VolumeStatus", 1) + `,`, `}`, }, "") return s @@ -24217,6 +24491,16 @@ func (this *VolumeSource) String() string { }, "") return s } +func (this *VolumeStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&VolumeStatus{`, + `Image:` + strings.Replace(this.Image.String(), "ImageVolumeStatus", "ImageVolumeStatus", 1) + `,`, + `}`, + }, "") + return s +} func (this *VsphereVirtualDiskVolumeSource) String() string { if this == nil { return "nil" @@ -24254,18 +24538,6 @@ func (this *WindowsSecurityContextOptions) String() string { }, "") return s } -func (this *WorkloadReference) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&WorkloadReference{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `PodGroup:` + fmt.Sprintf("%v", this.PodGroup) + `,`, - `PodGroupReplicaKey:` + fmt.Sprintf("%v", this.PodGroupReplicaKey) + `,`, - `}`, - }, "") - return s -} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -39166,6 +39438,88 @@ func (m *ImageVolumeSource) Unmarshal(dAtA []byte) error { } return nil } +func (m *ImageVolumeStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ImageVolumeStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ImageVolumeStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ImageRef", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ImageRef = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *KeyToPath) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -42742,6 +43096,249 @@ func (m *NodeAffinity) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeAllocatableResourceClaimStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeAllocatableResourceClaimStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeAllocatableResourceClaimStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaimName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Containers", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Containers = append(m.Containers, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Resources == nil { + m.Resources = make(map[ResourceName]resource.Quantity) + } + var mapkey ResourceName + mapvalue := &resource.Quantity{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = ResourceName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &resource.Quantity{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Resources[ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NodeCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -52496,7 +53093,155 @@ func (m *PodResourceClaim) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimName = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimTemplateName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimTemplateName = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodResourceClaimStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodResourceClaimStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodResourceClaimStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) } @@ -52529,39 +53274,6 @@ func (m *PodResourceClaim) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.ResourceClaimName = &s iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimTemplateName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.ResourceClaimTemplateName = &s - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -52583,7 +53295,7 @@ func (m *PodResourceClaim) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodResourceClaimStatus) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingGate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52606,10 +53318,10 @@ func (m *PodResourceClaimStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodResourceClaimStatus: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingGate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodResourceClaimStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingGate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -52644,39 +53356,6 @@ func (m *PodResourceClaimStatus) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.ResourceClaimName = &s - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -52698,7 +53377,7 @@ func (m *PodResourceClaimStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSchedulingGate) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -52721,15 +53400,15 @@ func (m *PodSchedulingGate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSchedulingGate: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSchedulingGate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodGroupName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -52757,7 +53436,8 @@ func (m *PodSchedulingGate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.PodGroupName = &s iNdEx = postIndex default: iNdEx = preIndex @@ -54801,9 +55481,9 @@ func (m *PodSpec) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.HostnameOverride = &s iNdEx = postIndex - case 42: + case 43: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WorkloadRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingGroup", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -54830,10 +55510,10 @@ func (m *PodSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.WorkloadRef == nil { - m.WorkloadRef = &WorkloadReference{} + if m.SchedulingGroup == nil { + m.SchedulingGroup = &PodSchedulingGroup{} } - if err := m.WorkloadRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SchedulingGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -55637,6 +56317,40 @@ func (m *PodStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeAllocatableResourceClaimStatuses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeAllocatableResourceClaimStatuses = append(m.NodeAllocatableResourceClaimStatuses, NodeAllocatableResourceClaimStatus{}) + if err := m.NodeAllocatableResourceClaimStatuses[len(m.NodeAllocatableResourceClaimStatuses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -59194,13 +59908,159 @@ func (m *ResourceClaim) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Request = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceFieldSelector) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceFieldSelector: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceFieldSelector: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resource = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Divisor", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -59210,23 +60070,24 @@ func (m *ResourceClaim) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Request = string(dAtA[iNdEx:postIndex]) + if err := m.Divisor.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -59249,7 +60110,7 @@ func (m *ResourceClaim) Unmarshal(dAtA []byte) error { } return nil } -func (m *ResourceFieldSelector) Unmarshal(dAtA []byte) error { +func (m *ResourceHealth) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -59272,15 +60133,15 @@ func (m *ResourceFieldSelector) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ResourceFieldSelector: wiretype end group for non-group") + return fmt.Errorf("proto: ResourceHealth: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceFieldSelector: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResourceHealth: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -59308,126 +60169,11 @@ func (m *ResourceFieldSelector) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ContainerName = string(dAtA[iNdEx:postIndex]) + m.ResourceID = ResourceID(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resource = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Divisor", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Divisor.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResourceHealth) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResourceHealth: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResourceHealth: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Health", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -59455,11 +60201,11 @@ func (m *ResourceHealth) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ResourceID = ResourceID(dAtA[iNdEx:postIndex]) + m.Health = ResourceHealthStatus(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Health", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -59487,7 +60233,8 @@ func (m *ResourceHealth) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Health = ResourceHealthStatus(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.Message = &s iNdEx = postIndex default: iNdEx = preIndex @@ -68123,6 +68870,42 @@ func (m *VolumeMountStatus) Unmarshal(dAtA []byte) error { s := RecursiveReadOnlyMode(dAtA[iNdEx:postIndex]) m.RecursiveReadOnly = &s iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VolumeStatus", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.VolumeStatus == nil { + m.VolumeStatus = &VolumeStatus{} + } + if err := m.VolumeStatus.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -69690,16 +70473,88 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PortworxVolume == nil { - m.PortworxVolume = &PortworxVolumeSource{} + if m.PortworxVolume == nil { + m.PortworxVolume = &PortworxVolumeSource{} + } + if err := m.PortworxVolume.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 25: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ScaleIO", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ScaleIO == nil { + m.ScaleIO = &ScaleIOVolumeSource{} + } + if err := m.ScaleIO.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Projected", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Projected == nil { + m.Projected = &ProjectedVolumeSource{} } - if err := m.PortworxVolume.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Projected.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 25: + case 27: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ScaleIO", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StorageOS", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -69726,16 +70581,16 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ScaleIO == nil { - m.ScaleIO = &ScaleIOVolumeSource{} + if m.StorageOS == nil { + m.StorageOS = &StorageOSVolumeSource{} } - if err := m.ScaleIO.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.StorageOS.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 26: + case 28: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Projected", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CSI", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -69762,16 +70617,16 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Projected == nil { - m.Projected = &ProjectedVolumeSource{} + if m.CSI == nil { + m.CSI = &CSIVolumeSource{} } - if err := m.Projected.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.CSI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 27: + case 29: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StorageOS", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ephemeral", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -69798,16 +70653,16 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.StorageOS == nil { - m.StorageOS = &StorageOSVolumeSource{} + if m.Ephemeral == nil { + m.Ephemeral = &EphemeralVolumeSource{} } - if err := m.StorageOS.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Ephemeral.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 28: + case 30: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CSI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -69834,50 +70689,64 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CSI == nil { - m.CSI = &CSIVolumeSource{} + if m.Image == nil { + m.Image = &ImageVolumeSource{} } - if err := m.CSI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Image.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 29: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ephemeral", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + msglen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthGenerated } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if m.Ephemeral == nil { - m.Ephemeral = &EphemeralVolumeSource{} + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VolumeStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated } - if err := m.Ephemeral.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF } - iNdEx = postIndex - case 30: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VolumeStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VolumeStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) } @@ -69907,7 +70776,7 @@ func (m *VolumeSource) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Image == nil { - m.Image = &ImageVolumeSource{} + m.Image = &ImageVolumeStatus{} } if err := m.Image.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -70384,152 +71253,6 @@ func (m *WindowsSecurityContextOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *WorkloadReference) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: WorkloadReference: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: WorkloadReference: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodGroup", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PodGroup = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodGroupReplicaKey", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PodGroupReplicaKey = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/core/v1/generated.proto b/vendor/k8s.io/api/core/v1/generated.proto index 570b4d3438..ba4f80e5ec 100644 --- a/vendor/k8s.io/api/core/v1/generated.proto +++ b/vendor/k8s.io/api/core/v1/generated.proto @@ -1132,7 +1132,6 @@ message ContainerStatus { // AllocatedResources represents the compute resources allocated for this container by the // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission // and after successfully admitting desired pod resize. - // +featureGate=InPlacePodVerticalScalingAllocatedStatus // +optional map allocatedResources = 10; @@ -2275,6 +2274,16 @@ message ImageVolumeSource { optional string pullPolicy = 2; } +// ImageVolumeStatus represents the image-based volume status. +message ImageVolumeStatus { + // ImageRef is the digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + // The ImageRef length should not exceed 256 characters. + // +kubebuilder:validation:MaxLength=256 + // +required + optional string imageRef = 1; +} + // Maps a string key to a path within a volume. message KeyToPath { // key is the key to project. @@ -2677,6 +2686,22 @@ message NodeAffinity { repeated PreferredSchedulingTerm preferredDuringSchedulingIgnoredDuringExecution = 2; } +// NodeAllocatableResourceClaimStatus describes the status of node allocatable resources allocated via DRA. +message NodeAllocatableResourceClaimStatus { + // ResourceClaimName is the resource claim referenced by the pod that resulted in this node allocatable resource allocation. + // +required + optional string resourceClaimName = 1; + + // Containers lists the names of all containers in this pod that reference the claim. + // +optional + // +listType=set + repeated string containers = 2; + + // Resources is a map of the node-allocatable resource name to the aggregate quantity allocated to the claim. + // +required + map resources = 3; +} + // NodeCondition contains condition information for a node. message NodeCondition { // Type of node condition. @@ -2812,7 +2837,6 @@ message NodeRuntimeHandlerFeatures { optional bool recursiveReadOnlyMounts = 1; // UserNamespaces is set to true if the runtime handler supports UserNamespaces, including for volumes. - // +featureGate=UserNamespacesSupport // +optional optional bool userNamespaces = 2; } @@ -2974,7 +2998,6 @@ message NodeStatus { optional NodeConfigStatus config = 11; // The available runtime handlers. - // +featureGate=UserNamespacesSupport // +optional // +listType=atomic repeated NodeRuntimeHandler runtimeHandlers = 12; @@ -3528,8 +3551,7 @@ message PersistentVolumeSource { // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional optional PortworxVolumeSource portworxVolume = 18; @@ -3918,8 +3940,6 @@ message PodCondition { optional string type = 1; // If set, this represents the .metadata.generation that the pod condition was set based upon. - // The PodObservedGenerationTracking feature gate must be enabled to use this field. - // +featureGate=PodObservedGenerationTracking // +optional optional int64 observedGeneration = 7; @@ -4153,6 +4173,14 @@ message PodReadinessGate { // // It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. // Containers that need access to the ResourceClaim reference it with this name. +// +// When the DRAWorkloadResourceClaims feature gate is enabled and this Pod +// belongs to a PodGroup, a PodResourceClaim is matched to a +// PodGroupResourceClaim if all of their fields are equal (Name, +// ResourceClaimName, and ResourceClaimTemplateName). A matched claim references +// a single ResourceClaim shared across all Pods in the PodGroup, reserved for +// the PodGroup in ResourceClaimStatus.ReservedFor rather than for individual +// Pods. message PodResourceClaim { // Name uniquely identifies this resource claim inside the pod. // This must be a DNS_LABEL. @@ -4174,6 +4202,16 @@ message PodResourceClaim { // generated component, will be used to form a unique name for the // ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. // + // When the DRAWorkloadResourceClaims feature gate is enabled and the pod + // belongs to a PodGroup that defines a PodGroupResourceClaim with the same + // Name and ResourceClaimTemplateName, this PodResourceClaim resolves to the + // ResourceClaim generated for the PodGroup. All pods in the group that + // define an equivalent PodResourceClaim matching the + // PodGroupResourceClaim's Name and ResourceClaimTemplateName share the same + // generated ResourceClaim. ResourceClaims generated for a PodGroup are + // owned by the PodGroup and their lifecycles are tied to the PodGroup + // instead of any individual pod. + // // This field is immutable and no changes will be made to the // corresponding ResourceClaim by the control plane after creating the // ResourceClaim. @@ -4193,9 +4231,16 @@ message PodResourceClaimStatus { optional string name = 1; // ResourceClaimName is the name of the ResourceClaim that was - // generated for the Pod in the namespace of the Pod. If this is - // unset, then generating a ResourceClaim was not necessary. The - // pod.spec.resourceClaims entry can be ignored in this case. + // generated for the Pod in the namespace of the Pod. + // + // When the DRAWorkloadResourceClaims feature is enabled and the + // corresponding PodResourceClaim matches a PodGroupResourceClaim + // made by the Pod's PodGroup, then this is the name of the + // ResourceClaim generated and reserved for the PodGroup. + // + // If this is unset, then generating a ResourceClaim was not + // necessary. The pod.spec.resourceClaims entry can be ignored in + // this case. // // +optional optional string resourceClaimName = 2; @@ -4208,6 +4253,20 @@ message PodSchedulingGate { optional string name = 1; } +// PodSchedulingGroup identifies the runtime scheduling group instance that a Pod belongs to. +// The scheduler uses this information to apply workload-aware scheduling semantics. +// Exactly one field must be specified. +// +union +message PodSchedulingGroup { + // PodGroupName specifies the name of the standalone PodGroup object + // that represents the runtime instance of this group. + // Must be a DNS subdomain. + // + // +optional + // +oneOf=GroupSelection + optional string podGroupName = 1; +} + // PodSecurityContext holds pod-level security attributes and common container settings. // Some fields are also present in container.securityContext. Field values of // container.securityContext take precedence over field values of PodSecurityContext. @@ -4669,7 +4728,6 @@ message PodSpec { // When set to false, a new userns is created for the pod. Setting false is useful for // mitigating container breakout vulnerabilities even allowing users to run their // containers as root without actually having root privileges on the host. - // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. // +k8s:conversion-gen=false // +optional optional bool hostUsers = 37; @@ -4735,17 +4793,22 @@ message PodSpec { // +optional optional string hostnameOverride = 41; - // WorkloadRef provides a reference to the Workload object that this Pod belongs to. - // This field is used by the scheduler to identify the PodGroup and apply the - // correct group scheduling policies. The Workload object referenced - // by this field may not exist at the time the Pod is created. - // This field is immutable, but a Workload object with the same name - // may be recreated with different policies. Doing this during pod scheduling + // SchedulingGroup provides a reference to the immediate scheduling runtime + // grouping object that this Pod belongs to. + // This field is used by the scheduler to identify the group and apply the + // correct group scheduling policies. The association with a group also + // impacts other lifecycle aspects of a Pod that are relevant in a wider context + // of scheduling like preemption, resource attachment, etc. If not specified, + // the Pod is treated as a single unit in all of these aspects. + // The group object referenced by this field may not exist at the time the + // Pod is created. + // This field is immutable, but a group object with the same name may be + // recreated with different policies. Doing this during pod scheduling // may result in the placement not conforming to the expected policies. // // +featureGate=GenericWorkload // +optional - optional WorkloadReference workloadRef = 42; + optional PodSchedulingGroup schedulingGroup = 43; } // PodStatus represents information about the status of a pod. Status may trail the actual @@ -4754,7 +4817,6 @@ message PodSpec { message PodStatus { // If set, this represents the .metadata.generation that the pod status was set based upon. // The PodObservedGenerationTracking feature gate must be enabled to use this field. - // +featureGate=PodObservedGenerationTracking // +optional optional int64 observedGeneration = 17; @@ -4923,6 +4985,16 @@ message PodStatus { // +featureGate=InPlacePodLevelResourcesVerticalScaling // +optional optional ResourceRequirements resources = 20; + + // NodeAllocatableResourceClaimStatuses contains the status of node-allocatable resources + // that were allocated for this pod through DRA claims. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // +featureGate=DRANodeAllocatableResources + // +optional + // +listType=atomic + repeated NodeAllocatableResourceClaimStatus nodeAllocatableResourceClaimStatuses = 21; } // PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded @@ -5300,8 +5372,8 @@ message ReplicationController { // be the same as the Pod(s) that the replication controller manages. // Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec defines the specification of the desired behavior of the replication controller. @@ -5358,18 +5430,18 @@ message ReplicationControllerSpec { // Defaults to 1. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=1 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 replicas = 1; // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 minReadySeconds = 4; // Selector is a label query over pods that should match the Replicas count. @@ -5468,6 +5540,12 @@ message ResourceHealth { // // In future we may want to introduce the PermanentlyUnhealthy Status. optional string health = 2; + + // Message provides human-readable context for Health (e.g. "ECC error count exceeded threshold"). + // This field is populated by the kubelet when ResourceHealthStatusMessage is enabled if the DRA plugin returns a message, and is null otherwise. + // +featureGate=ResourceHealthStatusMessage + // +optional + optional string message = 6; } // ResourceQuota sets aggregate quota restrictions enforced per namespace @@ -5970,7 +6048,6 @@ message SecurityContext { // procMount denotes the type of proc mount to use for the containers. // The default value is Default which uses the container runtime defaults for // readonly paths and masked paths. - // This requires the ProcMountType feature flag to be enabled. // Note that this field cannot be set when spec.os.name is windows. // +optional optional string procMount = 9; @@ -6885,6 +6962,11 @@ message VolumeMountStatus { // depending on the mount result. // +optional optional string recursiveReadOnly = 4; + + // volumeStatus represents volume-type-specific status about the mounted + // volume. + // +optional + optional VolumeStatus volumeStatus = 5; } // VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from. @@ -7126,8 +7208,7 @@ message VolumeSource { // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional optional PortworxVolumeSource portworxVolume = 24; @@ -7184,14 +7265,22 @@ message VolumeSource { // A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - // The volume will be mounted read-only (ro) and non-executable files (noexec). + // The volume will be mounted read-only (ro). // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. - // +featureGate=ImageVolume // +optional optional ImageVolumeSource image = 30; } +// VolumeStatus represents the status of a mounted volume. +// At most one of its members must be specified. +message VolumeStatus { + // image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + // +featureGate=ImageVolumeWithDigest + // +optional + optional ImageVolumeStatus image = 1; +} + // Represents a vSphere volume resource. message VsphereVirtualDiskVolumeSource { // volumePath is the path that identifies vSphere volume vmdk @@ -7249,33 +7338,3 @@ message WindowsSecurityContextOptions { optional bool hostProcess = 4; } -// WorkloadReference identifies the Workload object and PodGroup membership -// that a Pod belongs to. The scheduler uses this information to apply -// workload-aware scheduling semantics. -message WorkloadReference { - // Name defines the name of the Workload object this Pod belongs to. - // Workload must be in the same namespace as the Pod. - // If it doesn't match any existing Workload, the Pod will remain unschedulable - // until a Workload object is created and observed by the kube-scheduler. - // It must be a DNS subdomain. - // - // +required - optional string name = 1; - - // PodGroup is the name of the PodGroup within the Workload that this Pod - // belongs to. If it doesn't match any existing PodGroup within the Workload, - // the Pod will remain unschedulable until the Workload object is recreated - // and observed by the kube-scheduler. It must be a DNS label. - // - // +required - optional string podGroup = 2; - - // PodGroupReplicaKey specifies the replica key of the PodGroup to which this - // Pod belongs. It is used to distinguish pods belonging to different replicas - // of the same pod group. The pod group policy is applied separately to each replica. - // When set, it must be a DNS label. - // - // +optional - optional string podGroupReplicaKey = 3; -} - diff --git a/vendor/k8s.io/api/core/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/core/v1/generated.protomessage.pb.go deleted file mode 100644 index cf74ffa088..0000000000 --- a/vendor/k8s.io/api/core/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,498 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AWSElasticBlockStoreVolumeSource) ProtoMessage() {} - -func (*Affinity) ProtoMessage() {} - -func (*AppArmorProfile) ProtoMessage() {} - -func (*AttachedVolume) ProtoMessage() {} - -func (*AvoidPods) ProtoMessage() {} - -func (*AzureDiskVolumeSource) ProtoMessage() {} - -func (*AzureFilePersistentVolumeSource) ProtoMessage() {} - -func (*AzureFileVolumeSource) ProtoMessage() {} - -func (*Binding) ProtoMessage() {} - -func (*CSIPersistentVolumeSource) ProtoMessage() {} - -func (*CSIVolumeSource) ProtoMessage() {} - -func (*Capabilities) ProtoMessage() {} - -func (*CephFSPersistentVolumeSource) ProtoMessage() {} - -func (*CephFSVolumeSource) ProtoMessage() {} - -func (*CinderPersistentVolumeSource) ProtoMessage() {} - -func (*CinderVolumeSource) ProtoMessage() {} - -func (*ClientIPConfig) ProtoMessage() {} - -func (*ClusterTrustBundleProjection) ProtoMessage() {} - -func (*ComponentCondition) ProtoMessage() {} - -func (*ComponentStatus) ProtoMessage() {} - -func (*ComponentStatusList) ProtoMessage() {} - -func (*ConfigMap) ProtoMessage() {} - -func (*ConfigMapEnvSource) ProtoMessage() {} - -func (*ConfigMapKeySelector) ProtoMessage() {} - -func (*ConfigMapList) ProtoMessage() {} - -func (*ConfigMapNodeConfigSource) ProtoMessage() {} - -func (*ConfigMapProjection) ProtoMessage() {} - -func (*ConfigMapVolumeSource) ProtoMessage() {} - -func (*Container) ProtoMessage() {} - -func (*ContainerExtendedResourceRequest) ProtoMessage() {} - -func (*ContainerImage) ProtoMessage() {} - -func (*ContainerPort) ProtoMessage() {} - -func (*ContainerResizePolicy) ProtoMessage() {} - -func (*ContainerRestartRule) ProtoMessage() {} - -func (*ContainerRestartRuleOnExitCodes) ProtoMessage() {} - -func (*ContainerState) ProtoMessage() {} - -func (*ContainerStateRunning) ProtoMessage() {} - -func (*ContainerStateTerminated) ProtoMessage() {} - -func (*ContainerStateWaiting) ProtoMessage() {} - -func (*ContainerStatus) ProtoMessage() {} - -func (*ContainerUser) ProtoMessage() {} - -func (*DaemonEndpoint) ProtoMessage() {} - -func (*DownwardAPIProjection) ProtoMessage() {} - -func (*DownwardAPIVolumeFile) ProtoMessage() {} - -func (*DownwardAPIVolumeSource) ProtoMessage() {} - -func (*EmptyDirVolumeSource) ProtoMessage() {} - -func (*EndpointAddress) ProtoMessage() {} - -func (*EndpointPort) ProtoMessage() {} - -func (*EndpointSubset) ProtoMessage() {} - -func (*Endpoints) ProtoMessage() {} - -func (*EndpointsList) ProtoMessage() {} - -func (*EnvFromSource) ProtoMessage() {} - -func (*EnvVar) ProtoMessage() {} - -func (*EnvVarSource) ProtoMessage() {} - -func (*EphemeralContainer) ProtoMessage() {} - -func (*EphemeralContainerCommon) ProtoMessage() {} - -func (*EphemeralVolumeSource) ProtoMessage() {} - -func (*Event) ProtoMessage() {} - -func (*EventList) ProtoMessage() {} - -func (*EventSeries) ProtoMessage() {} - -func (*EventSource) ProtoMessage() {} - -func (*ExecAction) ProtoMessage() {} - -func (*FCVolumeSource) ProtoMessage() {} - -func (*FileKeySelector) ProtoMessage() {} - -func (*FlexPersistentVolumeSource) ProtoMessage() {} - -func (*FlexVolumeSource) ProtoMessage() {} - -func (*FlockerVolumeSource) ProtoMessage() {} - -func (*GCEPersistentDiskVolumeSource) ProtoMessage() {} - -func (*GRPCAction) ProtoMessage() {} - -func (*GitRepoVolumeSource) ProtoMessage() {} - -func (*GlusterfsPersistentVolumeSource) ProtoMessage() {} - -func (*GlusterfsVolumeSource) ProtoMessage() {} - -func (*HTTPGetAction) ProtoMessage() {} - -func (*HTTPHeader) ProtoMessage() {} - -func (*HostAlias) ProtoMessage() {} - -func (*HostIP) ProtoMessage() {} - -func (*HostPathVolumeSource) ProtoMessage() {} - -func (*ISCSIPersistentVolumeSource) ProtoMessage() {} - -func (*ISCSIVolumeSource) ProtoMessage() {} - -func (*ImageVolumeSource) ProtoMessage() {} - -func (*KeyToPath) ProtoMessage() {} - -func (*Lifecycle) ProtoMessage() {} - -func (*LifecycleHandler) ProtoMessage() {} - -func (*LimitRange) ProtoMessage() {} - -func (*LimitRangeItem) ProtoMessage() {} - -func (*LimitRangeList) ProtoMessage() {} - -func (*LimitRangeSpec) ProtoMessage() {} - -func (*LinuxContainerUser) ProtoMessage() {} - -func (*List) ProtoMessage() {} - -func (*LoadBalancerIngress) ProtoMessage() {} - -func (*LoadBalancerStatus) ProtoMessage() {} - -func (*LocalObjectReference) ProtoMessage() {} - -func (*LocalVolumeSource) ProtoMessage() {} - -func (*ModifyVolumeStatus) ProtoMessage() {} - -func (*NFSVolumeSource) ProtoMessage() {} - -func (*Namespace) ProtoMessage() {} - -func (*NamespaceCondition) ProtoMessage() {} - -func (*NamespaceList) ProtoMessage() {} - -func (*NamespaceSpec) ProtoMessage() {} - -func (*NamespaceStatus) ProtoMessage() {} - -func (*Node) ProtoMessage() {} - -func (*NodeAddress) ProtoMessage() {} - -func (*NodeAffinity) ProtoMessage() {} - -func (*NodeCondition) ProtoMessage() {} - -func (*NodeConfigSource) ProtoMessage() {} - -func (*NodeConfigStatus) ProtoMessage() {} - -func (*NodeDaemonEndpoints) ProtoMessage() {} - -func (*NodeFeatures) ProtoMessage() {} - -func (*NodeList) ProtoMessage() {} - -func (*NodeProxyOptions) ProtoMessage() {} - -func (*NodeRuntimeHandler) ProtoMessage() {} - -func (*NodeRuntimeHandlerFeatures) ProtoMessage() {} - -func (*NodeSelector) ProtoMessage() {} - -func (*NodeSelectorRequirement) ProtoMessage() {} - -func (*NodeSelectorTerm) ProtoMessage() {} - -func (*NodeSpec) ProtoMessage() {} - -func (*NodeStatus) ProtoMessage() {} - -func (*NodeSwapStatus) ProtoMessage() {} - -func (*NodeSystemInfo) ProtoMessage() {} - -func (*ObjectFieldSelector) ProtoMessage() {} - -func (*ObjectReference) ProtoMessage() {} - -func (*PersistentVolume) ProtoMessage() {} - -func (*PersistentVolumeClaim) ProtoMessage() {} - -func (*PersistentVolumeClaimCondition) ProtoMessage() {} - -func (*PersistentVolumeClaimList) ProtoMessage() {} - -func (*PersistentVolumeClaimSpec) ProtoMessage() {} - -func (*PersistentVolumeClaimStatus) ProtoMessage() {} - -func (*PersistentVolumeClaimTemplate) ProtoMessage() {} - -func (*PersistentVolumeClaimVolumeSource) ProtoMessage() {} - -func (*PersistentVolumeList) ProtoMessage() {} - -func (*PersistentVolumeSource) ProtoMessage() {} - -func (*PersistentVolumeSpec) ProtoMessage() {} - -func (*PersistentVolumeStatus) ProtoMessage() {} - -func (*PhotonPersistentDiskVolumeSource) ProtoMessage() {} - -func (*Pod) ProtoMessage() {} - -func (*PodAffinity) ProtoMessage() {} - -func (*PodAffinityTerm) ProtoMessage() {} - -func (*PodAntiAffinity) ProtoMessage() {} - -func (*PodAttachOptions) ProtoMessage() {} - -func (*PodCertificateProjection) ProtoMessage() {} - -func (*PodCondition) ProtoMessage() {} - -func (*PodDNSConfig) ProtoMessage() {} - -func (*PodDNSConfigOption) ProtoMessage() {} - -func (*PodExecOptions) ProtoMessage() {} - -func (*PodExtendedResourceClaimStatus) ProtoMessage() {} - -func (*PodIP) ProtoMessage() {} - -func (*PodList) ProtoMessage() {} - -func (*PodLogOptions) ProtoMessage() {} - -func (*PodOS) ProtoMessage() {} - -func (*PodPortForwardOptions) ProtoMessage() {} - -func (*PodProxyOptions) ProtoMessage() {} - -func (*PodReadinessGate) ProtoMessage() {} - -func (*PodResourceClaim) ProtoMessage() {} - -func (*PodResourceClaimStatus) ProtoMessage() {} - -func (*PodSchedulingGate) ProtoMessage() {} - -func (*PodSecurityContext) ProtoMessage() {} - -func (*PodSignature) ProtoMessage() {} - -func (*PodSpec) ProtoMessage() {} - -func (*PodStatus) ProtoMessage() {} - -func (*PodStatusResult) ProtoMessage() {} - -func (*PodTemplate) ProtoMessage() {} - -func (*PodTemplateList) ProtoMessage() {} - -func (*PodTemplateSpec) ProtoMessage() {} - -func (*PortStatus) ProtoMessage() {} - -func (*PortworxVolumeSource) ProtoMessage() {} - -func (*Preconditions) ProtoMessage() {} - -func (*PreferAvoidPodsEntry) ProtoMessage() {} - -func (*PreferredSchedulingTerm) ProtoMessage() {} - -func (*Probe) ProtoMessage() {} - -func (*ProbeHandler) ProtoMessage() {} - -func (*ProjectedVolumeSource) ProtoMessage() {} - -func (*QuobyteVolumeSource) ProtoMessage() {} - -func (*RBDPersistentVolumeSource) ProtoMessage() {} - -func (*RBDVolumeSource) ProtoMessage() {} - -func (*RangeAllocation) ProtoMessage() {} - -func (*ReplicationController) ProtoMessage() {} - -func (*ReplicationControllerCondition) ProtoMessage() {} - -func (*ReplicationControllerList) ProtoMessage() {} - -func (*ReplicationControllerSpec) ProtoMessage() {} - -func (*ReplicationControllerStatus) ProtoMessage() {} - -func (*ResourceClaim) ProtoMessage() {} - -func (*ResourceFieldSelector) ProtoMessage() {} - -func (*ResourceHealth) ProtoMessage() {} - -func (*ResourceQuota) ProtoMessage() {} - -func (*ResourceQuotaList) ProtoMessage() {} - -func (*ResourceQuotaSpec) ProtoMessage() {} - -func (*ResourceQuotaStatus) ProtoMessage() {} - -func (*ResourceRequirements) ProtoMessage() {} - -func (*ResourceStatus) ProtoMessage() {} - -func (*SELinuxOptions) ProtoMessage() {} - -func (*ScaleIOPersistentVolumeSource) ProtoMessage() {} - -func (*ScaleIOVolumeSource) ProtoMessage() {} - -func (*ScopeSelector) ProtoMessage() {} - -func (*ScopedResourceSelectorRequirement) ProtoMessage() {} - -func (*SeccompProfile) ProtoMessage() {} - -func (*Secret) ProtoMessage() {} - -func (*SecretEnvSource) ProtoMessage() {} - -func (*SecretKeySelector) ProtoMessage() {} - -func (*SecretList) ProtoMessage() {} - -func (*SecretProjection) ProtoMessage() {} - -func (*SecretReference) ProtoMessage() {} - -func (*SecretVolumeSource) ProtoMessage() {} - -func (*SecurityContext) ProtoMessage() {} - -func (*SerializedReference) ProtoMessage() {} - -func (*Service) ProtoMessage() {} - -func (*ServiceAccount) ProtoMessage() {} - -func (*ServiceAccountList) ProtoMessage() {} - -func (*ServiceAccountTokenProjection) ProtoMessage() {} - -func (*ServiceList) ProtoMessage() {} - -func (*ServicePort) ProtoMessage() {} - -func (*ServiceProxyOptions) ProtoMessage() {} - -func (*ServiceSpec) ProtoMessage() {} - -func (*ServiceStatus) ProtoMessage() {} - -func (*SessionAffinityConfig) ProtoMessage() {} - -func (*SleepAction) ProtoMessage() {} - -func (*StorageOSPersistentVolumeSource) ProtoMessage() {} - -func (*StorageOSVolumeSource) ProtoMessage() {} - -func (*Sysctl) ProtoMessage() {} - -func (*TCPSocketAction) ProtoMessage() {} - -func (*Taint) ProtoMessage() {} - -func (*Toleration) ProtoMessage() {} - -func (*TopologySelectorLabelRequirement) ProtoMessage() {} - -func (*TopologySelectorTerm) ProtoMessage() {} - -func (*TopologySpreadConstraint) ProtoMessage() {} - -func (*TypedLocalObjectReference) ProtoMessage() {} - -func (*TypedObjectReference) ProtoMessage() {} - -func (*Volume) ProtoMessage() {} - -func (*VolumeDevice) ProtoMessage() {} - -func (*VolumeMount) ProtoMessage() {} - -func (*VolumeMountStatus) ProtoMessage() {} - -func (*VolumeNodeAffinity) ProtoMessage() {} - -func (*VolumeProjection) ProtoMessage() {} - -func (*VolumeResourceRequirements) ProtoMessage() {} - -func (*VolumeSource) ProtoMessage() {} - -func (*VsphereVirtualDiskVolumeSource) ProtoMessage() {} - -func (*WeightedPodAffinityTerm) ProtoMessage() {} - -func (*WindowsSecurityContextOptions) ProtoMessage() {} - -func (*WorkloadReference) ProtoMessage() {} diff --git a/vendor/k8s.io/api/core/v1/types.go b/vendor/k8s.io/api/core/v1/types.go index 705c82083c..ac0494f3c5 100644 --- a/vendor/k8s.io/api/core/v1/types.go +++ b/vendor/k8s.io/api/core/v1/types.go @@ -161,8 +161,7 @@ type VolumeSource struct { Projected *ProjectedVolumeSource `json:"projected,omitempty" protobuf:"bytes,26,opt,name=projected"` // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" protobuf:"bytes,24,opt,name=portworxVolume"` // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. @@ -214,10 +213,9 @@ type VolumeSource struct { // A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - // The volume will be mounted read-only (ro) and non-executable files (noexec). + // The volume will be mounted read-only (ro). // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. - // +featureGate=ImageVolume // +optional Image *ImageVolumeSource `json:"image,omitempty" protobuf:"bytes,30,opt,name=image"` } @@ -325,8 +323,7 @@ type PersistentVolumeSource struct { PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" protobuf:"bytes,17,opt,name=photonPersistentDisk"` // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" protobuf:"bytes,18,opt,name=portworxVolume"` // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. @@ -672,6 +669,17 @@ const ( PersistentVolumeClaimVolumeModifyVolumeError PersistentVolumeClaimConditionType = "ModifyVolumeError" // Volume is being modified PersistentVolumeClaimVolumeModifyingVolume PersistentVolumeClaimConditionType = "ModifyingVolume" + + // PersistentVolumeClaimUnused indicates whether the PVC is currently not in use by any Pod. + // When status is True, the PVC is not referenced by any non-terminal Pod. + // The lastTransitionTime indicates when the PVC last transitioned to being unused. + // + // Both in-use time and unused time duration indicated by this condition may be shorter or + // slightly longer than actual in-use time or unused time because of processing delays or + // when this feature was enabled in the cluster. + // + // Requires PersistentVolumeClaimUnusedSinceTime alpha featuregate + PersistentVolumeClaimUnused PersistentVolumeClaimConditionType = "Unused" ) // +enum @@ -3363,7 +3371,6 @@ type ContainerStatus struct { // AllocatedResources represents the compute resources allocated for this container by the // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission // and after successfully admitting desired pod resize. - // +featureGate=InPlacePodVerticalScalingAllocatedStatus // +optional AllocatedResources ResourceList `json:"allocatedResources,omitempty" protobuf:"bytes,10,rep,name=allocatedResources,casttype=ResourceList,castkey=ResourceName"` // Resources represents the compute resource requests and limits that have been successfully @@ -3421,6 +3428,10 @@ const ( ResourceHealthStatusUnknown ResourceHealthStatus = "Unknown" ) +// ResourceHealthMessageMaxLength is the maximum length for ResourceHealth.Message field. +// Messages longer than this will be truncated with "..." appended. +const ResourceHealthMessageMaxLength = 1024 + // ResourceID is calculated based on the source of this resource health information. // For DevicePlugin: // @@ -3448,6 +3459,11 @@ type ResourceHealth struct { // // In future we may want to introduce the PermanentlyUnhealthy Status. Health ResourceHealthStatus `json:"health,omitempty" protobuf:"bytes,2,name=health"` + // Message provides human-readable context for Health (e.g. "ECC error count exceeded threshold"). + // This field is populated by the kubelet when ResourceHealthStatusMessage is enabled if the DRA plugin returns a message, and is null otherwise. + // +featureGate=ResourceHealthStatusMessage + // +optional + Message *string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"` } // ContainerUser represents user identity information @@ -3575,8 +3591,6 @@ type PodCondition struct { // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions Type PodConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=PodConditionType"` // If set, this represents the .metadata.generation that the pod condition was set based upon. - // The PodObservedGenerationTracking feature gate must be enabled to use this field. - // +featureGate=PodObservedGenerationTracking // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,7,opt,name=observedGeneration"` // Status is the status of the condition. @@ -3623,6 +3637,29 @@ type VolumeMountStatus struct { // depending on the mount result. // +optional RecursiveReadOnly *RecursiveReadOnlyMode `json:"recursiveReadOnly,omitempty" protobuf:"bytes,4,opt,name=recursiveReadOnly,casttype=RecursiveReadOnlyMode"` + // volumeStatus represents volume-type-specific status about the mounted + // volume. + // +optional + VolumeStatus *VolumeStatus `json:"volumeStatus,omitempty" protobuf:"bytes,5,opt,name=volumeStatus"` +} + +// VolumeStatus represents the status of a mounted volume. +// At most one of its members must be specified. +type VolumeStatus struct { + // image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + // +featureGate=ImageVolumeWithDigest + // +optional + Image *ImageVolumeStatus `json:"image,omitempty" protobuf:"bytes,1,opt,name=image"` +} + +// ImageVolumeStatus represents the image-based volume status. +type ImageVolumeStatus struct { + // ImageRef is the digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + // The ImageRef length should not exceed 256 characters. + // +kubebuilder:validation:MaxLength=256 + // +required + ImageRef string `json:"imageRef,omitempty" protobuf:"bytes,1,opt,name=imageRef"` } // RestartPolicy describes how the container should be restarted. @@ -4378,7 +4415,6 @@ type PodSpec struct { // When set to false, a new userns is created for the pod. Setting false is useful for // mitigating container breakout vulnerabilities even allowing users to run their // containers as root without actually having root privileges on the host. - // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. // +k8s:conversion-gen=false // +optional HostUsers *bool `json:"hostUsers,omitempty" protobuf:"bytes,37,opt,name=hostUsers"` @@ -4440,17 +4476,27 @@ type PodSpec struct { // +featureGate=HostnameOverride // +optional HostnameOverride *string `json:"hostnameOverride,omitempty" protobuf:"bytes,41,opt,name=hostnameOverride"` - // WorkloadRef provides a reference to the Workload object that this Pod belongs to. - // This field is used by the scheduler to identify the PodGroup and apply the - // correct group scheduling policies. The Workload object referenced - // by this field may not exist at the time the Pod is created. - // This field is immutable, but a Workload object with the same name - // may be recreated with different policies. Doing this during pod scheduling + + // WorkloadRef is tombstoned to show why 42 is a reserved protobuf tag. + // This field got replaced with the SchedulingGroup field in Kubernetes 1.36. + // WorkloadRef *WorkloadReference `json:"workloadRef,omitempty" protobuf:"bytes,42,opt,name=workloadRef"` + + // SchedulingGroup provides a reference to the immediate scheduling runtime + // grouping object that this Pod belongs to. + // This field is used by the scheduler to identify the group and apply the + // correct group scheduling policies. The association with a group also + // impacts other lifecycle aspects of a Pod that are relevant in a wider context + // of scheduling like preemption, resource attachment, etc. If not specified, + // the Pod is treated as a single unit in all of these aspects. + // The group object referenced by this field may not exist at the time the + // Pod is created. + // This field is immutable, but a group object with the same name may be + // recreated with different policies. Doing this during pod scheduling // may result in the placement not conforming to the expected policies. // // +featureGate=GenericWorkload // +optional - WorkloadRef *WorkloadReference `json:"workloadRef,omitempty" protobuf:"bytes,42,opt,name=workloadRef"` + SchedulingGroup *PodSchedulingGroup `json:"schedulingGroup,omitempty" protobuf:"bytes,43,opt,name=schedulingGroup"` } // PodResourceClaim references exactly one ResourceClaim, either directly @@ -4459,6 +4505,14 @@ type PodSpec struct { // // It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. // Containers that need access to the ResourceClaim reference it with this name. +// +// When the DRAWorkloadResourceClaims feature gate is enabled and this Pod +// belongs to a PodGroup, a PodResourceClaim is matched to a +// PodGroupResourceClaim if all of their fields are equal (Name, +// ResourceClaimName, and ResourceClaimTemplateName). A matched claim references +// a single ResourceClaim shared across all Pods in the PodGroup, reserved for +// the PodGroup in ResourceClaimStatus.ReservedFor rather than for individual +// Pods. type PodResourceClaim struct { // Name uniquely identifies this resource claim inside the pod. // This must be a DNS_LABEL. @@ -4485,6 +4539,16 @@ type PodResourceClaim struct { // generated component, will be used to form a unique name for the // ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. // + // When the DRAWorkloadResourceClaims feature gate is enabled and the pod + // belongs to a PodGroup that defines a PodGroupResourceClaim with the same + // Name and ResourceClaimTemplateName, this PodResourceClaim resolves to the + // ResourceClaim generated for the PodGroup. All pods in the group that + // define an equivalent PodResourceClaim matching the + // PodGroupResourceClaim's Name and ResourceClaimTemplateName share the same + // generated ResourceClaim. ResourceClaims generated for a PodGroup are + // owned by the PodGroup and their lifecycles are tied to the PodGroup + // instead of any individual pod. + // // This field is immutable and no changes will be made to the // corresponding ResourceClaim by the control plane after creating the // ResourceClaim. @@ -4504,9 +4568,16 @@ type PodResourceClaimStatus struct { Name string `json:"name" protobuf:"bytes,1,name=name"` // ResourceClaimName is the name of the ResourceClaim that was - // generated for the Pod in the namespace of the Pod. If this is - // unset, then generating a ResourceClaim was not necessary. The - // pod.spec.resourceClaims entry can be ignored in this case. + // generated for the Pod in the namespace of the Pod. + // + // When the DRAWorkloadResourceClaims feature is enabled and the + // corresponding PodResourceClaim matches a PodGroupResourceClaim + // made by the Pod's PodGroup, then this is the name of the + // ResourceClaim generated and reserved for the PodGroup. + // + // If this is unset, then generating a ResourceClaim was not + // necessary. The pod.spec.resourceClaims entry can be ignored in + // this case. // // +optional ResourceClaimName *string `json:"resourceClaimName,omitempty" protobuf:"bytes,2,opt,name=resourceClaimName"` @@ -4562,34 +4633,18 @@ type PodSchedulingGate struct { Name string `json:"name" protobuf:"bytes,1,opt,name=name"` } -// WorkloadReference identifies the Workload object and PodGroup membership -// that a Pod belongs to. The scheduler uses this information to apply -// workload-aware scheduling semantics. -type WorkloadReference struct { - // Name defines the name of the Workload object this Pod belongs to. - // Workload must be in the same namespace as the Pod. - // If it doesn't match any existing Workload, the Pod will remain unschedulable - // until a Workload object is created and observed by the kube-scheduler. - // It must be a DNS subdomain. - // - // +required - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - - // PodGroup is the name of the PodGroup within the Workload that this Pod - // belongs to. If it doesn't match any existing PodGroup within the Workload, - // the Pod will remain unschedulable until the Workload object is recreated - // and observed by the kube-scheduler. It must be a DNS label. - // - // +required - PodGroup string `json:"podGroup" protobuf:"bytes,2,opt,name=podGroup"` - - // PodGroupReplicaKey specifies the replica key of the PodGroup to which this - // Pod belongs. It is used to distinguish pods belonging to different replicas - // of the same pod group. The pod group policy is applied separately to each replica. - // When set, it must be a DNS label. +// PodSchedulingGroup identifies the runtime scheduling group instance that a Pod belongs to. +// The scheduler uses this information to apply workload-aware scheduling semantics. +// Exactly one field must be specified. +// +union +type PodSchedulingGroup struct { + // PodGroupName specifies the name of the standalone PodGroup object + // that represents the runtime instance of this group. + // Must be a DNS subdomain. // // +optional - PodGroupReplicaKey string `json:"podGroupReplicaKey,omitempty" protobuf:"bytes,3,opt,name=podGroupReplicaKey"` + // +oneOf=GroupSelection + PodGroupName *string `json:"podGroupName,omitempty" protobuf:"bytes,1,opt,name=podGroupName"` } // +enum @@ -5251,7 +5306,6 @@ type EphemeralContainer struct { type PodStatus struct { // If set, this represents the .metadata.generation that the pod status was set based upon. // The PodObservedGenerationTracking feature gate must be enabled to use this field. - // +featureGate=PodObservedGenerationTracking // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,17,opt,name=observedGeneration"` // The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. @@ -5414,6 +5468,16 @@ type PodStatus struct { // +featureGate=InPlacePodLevelResourcesVerticalScaling // +optional Resources *ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,20,opt,name=resources"` + + // NodeAllocatableResourceClaimStatuses contains the status of node-allocatable resources + // that were allocated for this pod through DRA claims. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // +featureGate=DRANodeAllocatableResources + // +optional + // +listType=atomic + NodeAllocatableResourceClaimStatuses []NodeAllocatableResourceClaimStatus `json:"nodeAllocatableResourceClaimStatuses,omitempty" protobuf:"bytes,21,rep,name=nodeAllocatableResourceClaimStatuses"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -5533,18 +5597,18 @@ type ReplicationControllerSpec struct { // Defaults to 1. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=1 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,4,opt,name=minReadySeconds"` // Selector is a label query over pods that should match the Replicas count. @@ -5634,7 +5698,7 @@ type ReplicationControllerCondition struct { // +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.0 -// +k8s:supportsSubresource=/scale +// +k8s:supportsSubresource="/scale" // ReplicationController represents the configuration of a replication controller. type ReplicationController struct { @@ -5644,8 +5708,8 @@ type ReplicationController struct { // be the same as the Pod(s) that the replication controller manages. // Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec defines the specification of the desired behavior of the replication controller. @@ -6585,7 +6649,6 @@ type NodeRuntimeHandlerFeatures struct { // +optional RecursiveReadOnlyMounts *bool `json:"recursiveReadOnlyMounts,omitempty" protobuf:"varint,1,opt,name=recursiveReadOnlyMounts"` // UserNamespaces is set to true if the runtime handler supports UserNamespaces, including for volumes. - // +featureGate=UserNamespacesSupport // +optional UserNamespaces *bool `json:"userNamespaces,omitempty" protobuf:"varint,2,opt,name=userNamespaces"` } @@ -6756,7 +6819,6 @@ type NodeStatus struct { // +optional Config *NodeConfigStatus `json:"config,omitempty" protobuf:"bytes,11,opt,name=config"` // The available runtime handlers. - // +featureGate=UserNamespacesSupport // +optional // +listType=atomic RuntimeHandlers []NodeRuntimeHandler `json:"runtimeHandlers,omitempty" protobuf:"bytes,12,rep,name=runtimeHandlers"` @@ -8247,7 +8309,6 @@ type SecurityContext struct { // procMount denotes the type of proc mount to use for the containers. // The default value is Default which uses the container runtime defaults for // readonly paths and masked paths. - // This requires the ProcMountType feature flag to be enabled. // Note that this field cannot be set when spec.os.name is windows. // +optional ProcMount *ProcMountType `json:"procMount,omitempty" protobuf:"bytes,9,opt,name=procMount"` @@ -8452,3 +8513,17 @@ type ImageVolumeSource struct { // +optional PullPolicy PullPolicy `json:"pullPolicy,omitempty" protobuf:"bytes,2,opt,name=pullPolicy,casttype=PullPolicy"` } + +// NodeAllocatableResourceClaimStatus describes the status of node allocatable resources allocated via DRA. +type NodeAllocatableResourceClaimStatus struct { + // ResourceClaimName is the resource claim referenced by the pod that resulted in this node allocatable resource allocation. + // +required + ResourceClaimName string `json:"resourceClaimName" protobuf:"bytes,1,opt,name=resourceClaimName"` + // Containers lists the names of all containers in this pod that reference the claim. + // +optional + // +listType=set + Containers []string `json:"containers,omitempty" protobuf:"bytes,2,rep,name=containers"` + // Resources is a map of the node-allocatable resource name to the aggregate quantity allocated to the claim. + // +required + Resources map[ResourceName]resource.Quantity `json:"resources" protobuf:"bytes,3,rep,name=resources"` +} diff --git a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go index 0f5e44e917..97eb5ceec3 100644 --- a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -992,6 +992,15 @@ func (ImageVolumeSource) SwaggerDoc() map[string]string { return map_ImageVolumeSource } +var map_ImageVolumeStatus = map[string]string{ + "": "ImageVolumeStatus represents the image-based volume status.", + "imageRef": "ImageRef is the digest of the image used for this volume. It should have a value that's similar to the pod's status.containerStatuses[i].imageID. The ImageRef length should not exceed 256 characters.", +} + +func (ImageVolumeStatus) SwaggerDoc() map[string]string { + return map_ImageVolumeStatus +} + var map_KeyToPath = map[string]string{ "": "Maps a string key to a path within a volume.", "key": "key is the key to project.", @@ -1225,6 +1234,17 @@ func (NodeAffinity) SwaggerDoc() map[string]string { return map_NodeAffinity } +var map_NodeAllocatableResourceClaimStatus = map[string]string{ + "": "NodeAllocatableResourceClaimStatus describes the status of node allocatable resources allocated via DRA.", + "resourceClaimName": "ResourceClaimName is the resource claim referenced by the pod that resulted in this node allocatable resource allocation.", + "containers": "Containers lists the names of all containers in this pod that reference the claim.", + "resources": "Resources is a map of the node-allocatable resource name to the aggregate quantity allocated to the claim.", +} + +func (NodeAllocatableResourceClaimStatus) SwaggerDoc() map[string]string { + return map_NodeAllocatableResourceClaimStatus +} + var map_NodeCondition = map[string]string{ "": "NodeCondition contains condition information for a node.", "type": "Type of node condition.", @@ -1565,7 +1585,7 @@ var map_PersistentVolumeSource = map[string]string{ "quobyte": "quobyte represents a Quobyte mount on the host that shares a pod's lifetime. Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.", "azureDisk": "azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type are redirected to the disk.csi.azure.com CSI driver.", "photonPersistentDisk": "photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.", - "portworxVolume": "portworxVolume represents a portworx volume attached and mounted on kubelets host machine. Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate is on.", + "portworxVolume": "portworxVolume represents a portworx volume attached and mounted on kubelets host machine. Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type are redirected to the pxd.portworx.com CSI driver.", "scaleIO": "scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.", "local": "local represents directly-attached storage with node affinity", "storageos": "storageOS represents a StorageOS volume that is attached to the kubelet's host machine and mounted into the pod. Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported. More info: https://examples.k8s.io/volumes/storageos/README.md", @@ -1691,7 +1711,7 @@ func (PodCertificateProjection) SwaggerDoc() map[string]string { var map_PodCondition = map[string]string{ "": "PodCondition contains details for the current condition of this pod.", "type": "Type is the type of the condition. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", - "observedGeneration": "If set, this represents the .metadata.generation that the pod condition was set based upon. The PodObservedGenerationTracking feature gate must be enabled to use this field.", + "observedGeneration": "If set, this represents the .metadata.generation that the pod condition was set based upon.", "status": "Status is the status of the condition. Can be True, False, Unknown. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", "lastProbeTime": "Last time we probed the condition.", "lastTransitionTime": "Last time the condition transitioned from one status to another.", @@ -1822,10 +1842,10 @@ func (PodReadinessGate) SwaggerDoc() map[string]string { } var map_PodResourceClaim = map[string]string{ - "": "PodResourceClaim references exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod.\n\nIt adds a name to it that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name.", + "": "PodResourceClaim references exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the pod.\n\nIt adds a name to it that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name.\n\nWhen the DRAWorkloadResourceClaims feature gate is enabled and this Pod belongs to a PodGroup, a PodResourceClaim is matched to a PodGroupResourceClaim if all of their fields are equal (Name, ResourceClaimName, and ResourceClaimTemplateName). A matched claim references a single ResourceClaim shared across all Pods in the PodGroup, reserved for the PodGroup in ResourceClaimStatus.ReservedFor rather than for individual Pods.", "name": "Name uniquely identifies this resource claim inside the pod. This must be a DNS_LABEL.", "resourceClaimName": "ResourceClaimName is the name of a ResourceClaim object in the same namespace as this pod.\n\nExactly one of ResourceClaimName and ResourceClaimTemplateName must be set.", - "resourceClaimTemplateName": "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, along with a generated component, will be used to form a unique name for the ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.\n\nExactly one of ResourceClaimName and ResourceClaimTemplateName must be set.", + "resourceClaimTemplateName": "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The pod name and resource name, along with a generated component, will be used to form a unique name for the ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses.\n\nWhen the DRAWorkloadResourceClaims feature gate is enabled and the pod belongs to a PodGroup that defines a PodGroupResourceClaim with the same Name and ResourceClaimTemplateName, this PodResourceClaim resolves to the ResourceClaim generated for the PodGroup. All pods in the group that define an equivalent PodResourceClaim matching the PodGroupResourceClaim's Name and ResourceClaimTemplateName share the same generated ResourceClaim. ResourceClaims generated for a PodGroup are owned by the PodGroup and their lifecycles are tied to the PodGroup instead of any individual pod.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.\n\nExactly one of ResourceClaimName and ResourceClaimTemplateName must be set.", } func (PodResourceClaim) SwaggerDoc() map[string]string { @@ -1835,7 +1855,7 @@ func (PodResourceClaim) SwaggerDoc() map[string]string { var map_PodResourceClaimStatus = map[string]string{ "": "PodResourceClaimStatus is stored in the PodStatus for each PodResourceClaim which references a ResourceClaimTemplate. It stores the generated name for the corresponding ResourceClaim.", "name": "Name uniquely identifies this resource claim inside the pod. This must match the name of an entry in pod.spec.resourceClaims, which implies that the string must be a DNS_LABEL.", - "resourceClaimName": "ResourceClaimName is the name of the ResourceClaim that was generated for the Pod in the namespace of the Pod. If this is unset, then generating a ResourceClaim was not necessary. The pod.spec.resourceClaims entry can be ignored in this case.", + "resourceClaimName": "ResourceClaimName is the name of the ResourceClaim that was generated for the Pod in the namespace of the Pod.\n\nWhen the DRAWorkloadResourceClaims feature is enabled and the corresponding PodResourceClaim matches a PodGroupResourceClaim made by the Pod's PodGroup, then this is the name of the ResourceClaim generated and reserved for the PodGroup.\n\nIf this is unset, then generating a ResourceClaim was not necessary. The pod.spec.resourceClaims entry can be ignored in this case.", } func (PodResourceClaimStatus) SwaggerDoc() map[string]string { @@ -1851,6 +1871,15 @@ func (PodSchedulingGate) SwaggerDoc() map[string]string { return map_PodSchedulingGate } +var map_PodSchedulingGroup = map[string]string{ + "": "PodSchedulingGroup identifies the runtime scheduling group instance that a Pod belongs to. The scheduler uses this information to apply workload-aware scheduling semantics. Exactly one field must be specified.", + "podGroupName": "PodGroupName specifies the name of the standalone PodGroup object that represents the runtime instance of this group. Must be a DNS subdomain.", +} + +func (PodSchedulingGroup) SwaggerDoc() map[string]string { + return map_PodSchedulingGroup +} + var map_PodSecurityContext = map[string]string{ "": "PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext.", "seLinuxOptions": "The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows.", @@ -1919,12 +1948,12 @@ var map_PodSpec = map[string]string{ "topologySpreadConstraints": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "setHostnameAsFQDN": "If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false.", "os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.resources - spec.securityContext.appArmorProfile - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.securityContext.supplementalGroupsPolicy - spec.containers[*].securityContext.appArmorProfile - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup", - "hostUsers": "Use the host's user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.", + "hostUsers": "Use the host's user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host.", "schedulingGates": "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the scheduler will not attempt to schedule the pod.\n\nSchedulingGates can only be set at pod creation time, and be removed only afterwards.", "resourceClaims": "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.\n\nThis is a stable field but requires that the DynamicResourceAllocation feature gate is enabled.\n\nThis field is immutable.", "resources": "Resources is the total amount of CPU and Memory resources required by all containers in the pod. It supports specifying Requests and Limits for \"cpu\", \"memory\" and \"hugepages-\" resource names only. ResourceClaims are not supported.\n\nThis field enables fine-grained control over resource allocation for the entire pod, allowing resource sharing among containers in a pod.\n\nThis is an alpha field and requires enabling the PodLevelResources feature gate.", "hostnameOverride": "HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. This field only specifies the pod's hostname and does not affect its DNS records. When this field is set to a non-empty string: - It takes precedence over the values set in `hostname` and `subdomain`. - The Pod's hostname will be set to this value. - `setHostnameAsFQDN` must be nil or set to false. - `hostNetwork` must be set to false.\n\nThis field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. Requires the HostnameOverride feature gate to be enabled.", - "workloadRef": "WorkloadRef provides a reference to the Workload object that this Pod belongs to. This field is used by the scheduler to identify the PodGroup and apply the correct group scheduling policies. The Workload object referenced by this field may not exist at the time the Pod is created. This field is immutable, but a Workload object with the same name may be recreated with different policies. Doing this during pod scheduling may result in the placement not conforming to the expected policies.", + "schedulingGroup": "SchedulingGroup provides a reference to the immediate scheduling runtime grouping object that this Pod belongs to. This field is used by the scheduler to identify the group and apply the correct group scheduling policies. The association with a group also impacts other lifecycle aspects of a Pod that are relevant in a wider context of scheduling like preemption, resource attachment, etc. If not specified, the Pod is treated as a single unit in all of these aspects. The group object referenced by this field may not exist at the time the Pod is created. This field is immutable, but a group object with the same name may be recreated with different policies. Doing this during pod scheduling may result in the placement not conforming to the expected policies.", } func (PodSpec) SwaggerDoc() map[string]string { @@ -1932,27 +1961,28 @@ func (PodSpec) SwaggerDoc() map[string]string { } var map_PodStatus = map[string]string{ - "": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system, especially if the node that hosts the pod cannot contact the control plane.", - "observedGeneration": "If set, this represents the .metadata.generation that the pod status was set based upon. The PodObservedGenerationTracking feature gate must be enabled to use this field.", - "phase": "The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. The conditions array, the reason and message fields, and the individual container status arrays contain more detail about the pod's status. There are five possible phase values:\n\nPending: The pod has been accepted by the Kubernetes system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. Succeeded: All containers in the pod have terminated in success, and will not be restarted. Failed: All containers in the pod have terminated, and at least one container has terminated in failure. The container either exited with non-zero status or was terminated by the system. Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase", - "conditions": "Current service state of pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", - "message": "A human readable message indicating details about why the pod is in this condition.", - "reason": "A brief CamelCase message indicating details about why the pod is in this state. e.g. 'Evicted'", - "nominatedNodeName": "nominatedNodeName is set only when this pod preempts other pods on the node, but it cannot be scheduled right away as preemption victims receive their graceful termination periods. This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to give the resources on this node to a higher priority pod that is created after preemption. As a result, this field may be different than PodSpec.nodeName when the pod is scheduled.", - "hostIP": "hostIP holds the IP address of the host to which the pod is assigned. Empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns mean that HostIP will not be updated even if there is a node is assigned to pod", - "hostIPs": "hostIPs holds the IP addresses allocated to the host. If this field is specified, the first entry must match the hostIP field. This list is empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns means that HostIPs will not be updated even if there is a node is assigned to this pod.", - "podIP": "podIP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.", - "podIPs": "podIPs holds the IP addresses allocated to the pod. If this field is specified, the 0th entry must match the podIP field. Pods may be allocated at most 1 value for each of IPv4 and IPv6. This list is empty if no IPs have been allocated yet.", - "startTime": "RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.", - "initContainerStatuses": "Statuses of init containers in this pod. The most recent successful non-restartable init container will have ready = true, the most recently started container will have startTime set. Each init container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-and-container-status", - "containerStatuses": "Statuses of containers in this pod. Each container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", - "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes", - "ephemeralContainerStatuses": "Statuses for any ephemeral containers that have run in this pod. Each ephemeral container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", - "resize": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\" Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources.", - "resourceClaimStatuses": "Status of resource claims.", - "extendedResourceClaimStatus": "Status of extended resource claim backed by DRA.", - "allocatedResources": "AllocatedResources is the total requests allocated for this pod by the node. If pod-level requests are not set, this will be the total requests aggregated across containers in the pod.", - "resources": "Resources represents the compute resource requests and limits that have been applied at the pod level if pod-level requests or limits are set in PodSpec.Resources", + "": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system, especially if the node that hosts the pod cannot contact the control plane.", + "observedGeneration": "If set, this represents the .metadata.generation that the pod status was set based upon. The PodObservedGenerationTracking feature gate must be enabled to use this field.", + "phase": "The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. The conditions array, the reason and message fields, and the individual container status arrays contain more detail about the pod's status. There are five possible phase values:\n\nPending: The pod has been accepted by the Kubernetes system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. Succeeded: All containers in the pod have terminated in success, and will not be restarted. Failed: All containers in the pod have terminated, and at least one container has terminated in failure. The container either exited with non-zero status or was terminated by the system. Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase", + "conditions": "Current service state of pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", + "message": "A human readable message indicating details about why the pod is in this condition.", + "reason": "A brief CamelCase message indicating details about why the pod is in this state. e.g. 'Evicted'", + "nominatedNodeName": "nominatedNodeName is set only when this pod preempts other pods on the node, but it cannot be scheduled right away as preemption victims receive their graceful termination periods. This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to give the resources on this node to a higher priority pod that is created after preemption. As a result, this field may be different than PodSpec.nodeName when the pod is scheduled.", + "hostIP": "hostIP holds the IP address of the host to which the pod is assigned. Empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns mean that HostIP will not be updated even if there is a node is assigned to pod", + "hostIPs": "hostIPs holds the IP addresses allocated to the host. If this field is specified, the first entry must match the hostIP field. This list is empty if the pod has not started yet. A pod can be assigned to a node that has a problem in kubelet which in turns means that HostIPs will not be updated even if there is a node is assigned to this pod.", + "podIP": "podIP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.", + "podIPs": "podIPs holds the IP addresses allocated to the pod. If this field is specified, the 0th entry must match the podIP field. Pods may be allocated at most 1 value for each of IPv4 and IPv6. This list is empty if no IPs have been allocated yet.", + "startTime": "RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.", + "initContainerStatuses": "Statuses of init containers in this pod. The most recent successful non-restartable init container will have ready = true, the most recently started container will have startTime set. Each init container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-and-container-status", + "containerStatuses": "Statuses of containers in this pod. Each container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", + "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes", + "ephemeralContainerStatuses": "Statuses for any ephemeral containers that have run in this pod. Each ephemeral container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", + "resize": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\" Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources.", + "resourceClaimStatuses": "Status of resource claims.", + "extendedResourceClaimStatus": "Status of extended resource claim backed by DRA.", + "allocatedResources": "AllocatedResources is the total requests allocated for this pod by the node. If pod-level requests are not set, this will be the total requests aggregated across containers in the pod.", + "resources": "Resources represents the compute resource requests and limits that have been applied at the pod level if pod-level requests or limits are set in PodSpec.Resources", + "nodeAllocatableResourceClaimStatuses": "NodeAllocatableResourceClaimStatuses contains the status of node-allocatable resources that were allocated for this pod through DRA claims. This includes resources currently reported in v1.Node `status.allocatable` that are not extended resources (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). Examples include \"cpu\", \"memory\", \"ephemeral-storage\", and hugepages.", } func (PodStatus) SwaggerDoc() map[string]string { @@ -2230,6 +2260,7 @@ var map_ResourceHealth = map[string]string{ "": "ResourceHealth represents the health of a resource. It has the latest device health information. This is a part of KEP https://kep.k8s.io/4680.", "resourceID": "ResourceID is the unique identifier of the resource. See the ResourceID type for more information.", "health": "Health of the resource. can be one of:\n - Healthy: operates as normal\n - Unhealthy: reported unhealthy. We consider this a temporary health issue\n since we do not have a mechanism today to distinguish\n temporary and permanent issues.\n - Unknown: The status cannot be determined.\n For example, Device Plugin got unregistered and hasn't been re-registered since.\n\nIn future we may want to introduce the PermanentlyUnhealthy Status.", + "message": "Message provides human-readable context for Health (e.g. \"ECC error count exceeded threshold\"). This field is populated by the kubelet when ResourceHealthStatusMessage is enabled if the DRA plugin returns a message, and is null otherwise.", } func (ResourceHealth) SwaggerDoc() map[string]string { @@ -2462,7 +2493,7 @@ var map_SecurityContext = map[string]string{ "runAsNonRoot": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", "readOnlyRootFilesystem": "Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows.", "allowPrivilegeEscalation": "AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.", - "procMount": "procMount denotes the type of proc mount to use for the containers. The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows.", + "procMount": "procMount denotes the type of proc mount to use for the containers. The default value is Default which uses the container runtime defaults for readonly paths and masked paths. Note that this field cannot be set when spec.os.name is windows.", "seccompProfile": "The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows.", "appArmorProfile": "appArmorProfile is the AppArmor options to use by this container. If set, this profile overrides the pod's appArmorProfile. Note that this field cannot be set when spec.os.name is windows.", } @@ -2782,6 +2813,7 @@ var map_VolumeMountStatus = map[string]string{ "mountPath": "MountPath corresponds to the original VolumeMount.", "readOnly": "ReadOnly corresponds to the original VolumeMount.", "recursiveReadOnly": "RecursiveReadOnly must be set to Disabled, Enabled, or unspecified (for non-readonly mounts). An IfPossible value in the original VolumeMount must be translated to Disabled or Enabled, depending on the mount result.", + "volumeStatus": "volumeStatus represents volume-type-specific status about the mounted volume.", } func (VolumeMountStatus) SwaggerDoc() map[string]string { @@ -2847,18 +2879,27 @@ var map_VolumeSource = map[string]string{ "azureDisk": "azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type are redirected to the disk.csi.azure.com CSI driver.", "photonPersistentDisk": "photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine. Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.", "projected": "projected items for all in one resources secrets, configmaps, and downward API", - "portworxVolume": "portworxVolume represents a portworx volume attached and mounted on kubelets host machine. Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate is on.", + "portworxVolume": "portworxVolume represents a portworx volume attached and mounted on kubelets host machine. Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type are redirected to the pxd.portworx.com CSI driver.", "scaleIO": "scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.", "storageos": "storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.", "csi": "csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.", "ephemeral": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.\n\nUse this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity\n tracking are needed,\nc) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through\n a PersistentVolumeClaim (see EphemeralVolumeSource for more\n information on the connection between this volume type\n and PersistentVolumeClaim).\n\nUse PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod.\n\nUse CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information.\n\nA pod can use both types of ephemeral volumes and persistent volumes at the same time.", - "image": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro) and non-executable files (noexec). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.", + "image": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.", } func (VolumeSource) SwaggerDoc() map[string]string { return map_VolumeSource } +var map_VolumeStatus = map[string]string{ + "": "VolumeStatus represents the status of a mounted volume. At most one of its members must be specified.", + "image": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.", +} + +func (VolumeStatus) SwaggerDoc() map[string]string { + return map_VolumeStatus +} + var map_VsphereVirtualDiskVolumeSource = map[string]string{ "": "Represents a vSphere volume resource.", "volumePath": "volumePath is the path that identifies vSphere volume vmdk", @@ -2893,15 +2934,4 @@ func (WindowsSecurityContextOptions) SwaggerDoc() map[string]string { return map_WindowsSecurityContextOptions } -var map_WorkloadReference = map[string]string{ - "": "WorkloadReference identifies the Workload object and PodGroup membership that a Pod belongs to. The scheduler uses this information to apply workload-aware scheduling semantics.", - "name": "Name defines the name of the Workload object this Pod belongs to. Workload must be in the same namespace as the Pod. If it doesn't match any existing Workload, the Pod will remain unschedulable until a Workload object is created and observed by the kube-scheduler. It must be a DNS subdomain.", - "podGroup": "PodGroup is the name of the PodGroup within the Workload that this Pod belongs to. If it doesn't match any existing PodGroup within the Workload, the Pod will remain unschedulable until the Workload object is recreated and observed by the kube-scheduler. It must be a DNS label.", - "podGroupReplicaKey": "PodGroupReplicaKey specifies the replica key of the PodGroup to which this Pod belongs. It is used to distinguish pods belonging to different replicas of the same pod group. The pod group policy is applied separately to each replica. When set, it must be a DNS label.", -} - -func (WorkloadReference) SwaggerDoc() map[string]string { - return map_WorkloadReference -} - // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go index 15bc2ee033..10af6c17d2 100644 --- a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ limitations under the License. package v1 import ( + resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" types "k8s.io/apimachinery/pkg/types" @@ -2170,6 +2171,22 @@ func (in *ImageVolumeSource) DeepCopy() *ImageVolumeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageVolumeStatus) DeepCopyInto(out *ImageVolumeStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageVolumeStatus. +func (in *ImageVolumeStatus) DeepCopy() *ImageVolumeStatus { + if in == nil { + return nil + } + out := new(ImageVolumeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KeyToPath) DeepCopyInto(out *KeyToPath) { *out = *in @@ -2760,6 +2777,34 @@ func (in *NodeAffinity) DeepCopy() *NodeAffinity { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeAllocatableResourceClaimStatus) DeepCopyInto(out *NodeAllocatableResourceClaimStatus) { + *out = *in + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make(map[ResourceName]resource.Quantity, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAllocatableResourceClaimStatus. +func (in *NodeAllocatableResourceClaimStatus) DeepCopy() *NodeAllocatableResourceClaimStatus { + if in == nil { + return nil + } + out := new(NodeAllocatableResourceClaimStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeCondition) DeepCopyInto(out *NodeCondition) { *out = *in @@ -4299,6 +4344,27 @@ func (in *PodSchedulingGate) DeepCopy() *PodSchedulingGate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingGroup) DeepCopyInto(out *PodSchedulingGroup) { + *out = *in + if in.PodGroupName != nil { + in, out := &in.PodGroupName, &out.PodGroupName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingGroup. +func (in *PodSchedulingGroup) DeepCopy() *PodSchedulingGroup { + if in == nil { + return nil + } + out := new(PodSchedulingGroup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) { *out = *in @@ -4569,10 +4635,10 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { *out = new(string) **out = **in } - if in.WorkloadRef != nil { - in, out := &in.WorkloadRef, &out.WorkloadRef - *out = new(WorkloadReference) - **out = **in + if in.SchedulingGroup != nil { + in, out := &in.SchedulingGroup, &out.SchedulingGroup + *out = new(PodSchedulingGroup) + (*in).DeepCopyInto(*out) } return } @@ -4656,6 +4722,13 @@ func (in *PodStatus) DeepCopyInto(out *PodStatus) { *out = new(ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.NodeAllocatableResourceClaimStatuses != nil { + in, out := &in.NodeAllocatableResourceClaimStatuses, &out.NodeAllocatableResourceClaimStatuses + *out = make([]NodeAllocatableResourceClaimStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -5222,6 +5295,11 @@ func (in *ResourceFieldSelector) DeepCopy() *ResourceFieldSelector { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceHealth) DeepCopyInto(out *ResourceHealth) { *out = *in + if in.Message != nil { + in, out := &in.Message, &out.Message + *out = new(string) + **out = **in + } return } @@ -5422,7 +5500,9 @@ func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) { if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = make([]ResourceHealth, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -6529,6 +6609,11 @@ func (in *VolumeMountStatus) DeepCopyInto(out *VolumeMountStatus) { *out = new(RecursiveReadOnlyMode) **out = **in } + if in.VolumeStatus != nil { + in, out := &in.VolumeStatus, &out.VolumeStatus + *out = new(VolumeStatus) + (*in).DeepCopyInto(*out) + } return } @@ -6805,6 +6890,27 @@ func (in *VolumeSource) DeepCopy() *VolumeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeStatus) DeepCopyInto(out *VolumeStatus) { + *out = *in + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageVolumeStatus) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeStatus. +func (in *VolumeStatus) DeepCopy() *VolumeStatus { + if in == nil { + return nil + } + out := new(VolumeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VsphereVirtualDiskVolumeSource) DeepCopyInto(out *VsphereVirtualDiskVolumeSource) { *out = *in @@ -6873,19 +6979,3 @@ func (in *WindowsSecurityContextOptions) DeepCopy() *WindowsSecurityContextOptio in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkloadReference) DeepCopyInto(out *WorkloadReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadReference. -func (in *WorkloadReference) DeepCopy() *WorkloadReference { - if in == nil { - return nil - } - out := new(WorkloadReference) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/core/v1/zz_generated.model_name.go b/vendor/k8s.io/api/core/v1/zz_generated.model_name.go index 523bb3a852..8e79ad909e 100644 --- a/vendor/k8s.io/api/core/v1/zz_generated.model_name.go +++ b/vendor/k8s.io/api/core/v1/zz_generated.model_name.go @@ -421,6 +421,11 @@ func (in ImageVolumeSource) OpenAPIModelName() string { return "io.k8s.api.core.v1.ImageVolumeSource" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ImageVolumeStatus) OpenAPIModelName() string { + return "io.k8s.api.core.v1.ImageVolumeStatus" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in KeyToPath) OpenAPIModelName() string { return "io.k8s.api.core.v1.KeyToPath" @@ -536,6 +541,11 @@ func (in NodeAffinity) OpenAPIModelName() string { return "io.k8s.api.core.v1.NodeAffinity" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in NodeAllocatableResourceClaimStatus) OpenAPIModelName() string { + return "io.k8s.api.core.v1.NodeAllocatableResourceClaimStatus" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in NodeCondition) OpenAPIModelName() string { return "io.k8s.api.core.v1.NodeCondition" @@ -796,6 +806,11 @@ func (in PodSchedulingGate) OpenAPIModelName() string { return "io.k8s.api.core.v1.PodSchedulingGate" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodSchedulingGroup) OpenAPIModelName() string { + return "io.k8s.api.core.v1.PodSchedulingGroup" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in PodSecurityContext) OpenAPIModelName() string { return "io.k8s.api.core.v1.PodSecurityContext" @@ -1191,6 +1206,11 @@ func (in VolumeSource) OpenAPIModelName() string { return "io.k8s.api.core.v1.VolumeSource" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in VolumeStatus) OpenAPIModelName() string { + return "io.k8s.api.core.v1.VolumeStatus" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in VsphereVirtualDiskVolumeSource) OpenAPIModelName() string { return "io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource" @@ -1205,8 +1225,3 @@ func (in WeightedPodAffinityTerm) OpenAPIModelName() string { func (in WindowsSecurityContextOptions) OpenAPIModelName() string { return "io.k8s.api.core.v1.WindowsSecurityContextOptions" } - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in WorkloadReference) OpenAPIModelName() string { - return "io.k8s.api.core.v1.WorkloadReference" -} diff --git a/vendor/k8s.io/api/discovery/v1/generated.proto b/vendor/k8s.io/api/discovery/v1/generated.proto index 97582a1b2a..edbc4304b1 100644 --- a/vendor/k8s.io/api/discovery/v1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1/generated.proto @@ -38,6 +38,9 @@ message Endpoint { // controller will always have exactly 1 address. No semantics are defined for // additional addresses beyond the first, and kube-proxy does not look at them. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxItems=100 repeated string addresses = 1; // conditions contains information about the current status of the endpoint. @@ -181,11 +184,16 @@ message EndpointSlice { // The EndpointSlice controller only generates, and kube-proxy only processes, // slices of addressType "IPv4" and "IPv6". No semantics are defined for // the "FQDN" type. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional string addressType = 4; // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. + // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Endpoint endpoints = 2; // ports specifies the list of network ports exposed by each endpoint in diff --git a/vendor/k8s.io/api/discovery/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/discovery/v1/generated.protomessage.pb.go deleted file mode 100644 index 9e246b87b8..0000000000 --- a/vendor/k8s.io/api/discovery/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*Endpoint) ProtoMessage() {} - -func (*EndpointConditions) ProtoMessage() {} - -func (*EndpointHints) ProtoMessage() {} - -func (*EndpointPort) ProtoMessage() {} - -func (*EndpointSlice) ProtoMessage() {} - -func (*EndpointSliceList) ProtoMessage() {} - -func (*ForNode) ProtoMessage() {} - -func (*ForZone) ProtoMessage() {} diff --git a/vendor/k8s.io/api/discovery/v1/types.go b/vendor/k8s.io/api/discovery/v1/types.go index ca78ce3869..c291ed85dd 100644 --- a/vendor/k8s.io/api/discovery/v1/types.go +++ b/vendor/k8s.io/api/discovery/v1/types.go @@ -48,11 +48,16 @@ type EndpointSlice struct { // The EndpointSlice controller only generates, and kube-proxy only processes, // slices of addressType "IPv4" and "IPv6". No semantics are defined for // the "FQDN" type. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. + // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Endpoints []Endpoint `json:"endpoints" protobuf:"bytes,2,rep,name=endpoints"` // ports specifies the list of network ports exposed by each endpoint in @@ -68,6 +73,7 @@ type EndpointSlice struct { // AddressType represents the type of address referred to by an endpoint. // +enum +// +k8s:alpha(since: "1.36")=+k8s:enum type AddressType string const ( @@ -90,6 +96,9 @@ type Endpoint struct { // controller will always have exactly 1 address. No semantics are defined for // additional addresses beyond the first, and kube-proxy does not look at them. // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxItems=100 Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` // conditions contains information about the current status of the endpoint. diff --git a/vendor/k8s.io/api/discovery/v1beta1/generated.proto b/vendor/k8s.io/api/discovery/v1beta1/generated.proto index 7b9d983b83..9b6edb1479 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1beta1/generated.proto @@ -38,6 +38,9 @@ message Endpoint { // 100. These are all assumed to be fungible and clients may choose to only // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxItems=100 repeated string addresses = 1; // conditions contains information about the current status of the endpoint. @@ -167,11 +170,15 @@ message EndpointSlice { // * IPv4: Represents an IPv4 Address. // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional string addressType = 4; // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Endpoint endpoints = 2; // ports specifies the list of network ports exposed by each endpoint in diff --git a/vendor/k8s.io/api/discovery/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/discovery/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 6e60bb139e..0000000000 --- a/vendor/k8s.io/api/discovery/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*Endpoint) ProtoMessage() {} - -func (*EndpointConditions) ProtoMessage() {} - -func (*EndpointHints) ProtoMessage() {} - -func (*EndpointPort) ProtoMessage() {} - -func (*EndpointSlice) ProtoMessage() {} - -func (*EndpointSliceList) ProtoMessage() {} - -func (*ForNode) ProtoMessage() {} - -func (*ForZone) ProtoMessage() {} diff --git a/vendor/k8s.io/api/discovery/v1beta1/types.go b/vendor/k8s.io/api/discovery/v1beta1/types.go index 11ec1b3968..1334194d2a 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/types.go +++ b/vendor/k8s.io/api/discovery/v1beta1/types.go @@ -45,11 +45,15 @@ type EndpointSlice struct { // * IPv4: Represents an IPv4 Address. // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Endpoints []Endpoint `json:"endpoints" protobuf:"bytes,2,rep,name=endpoints"` // ports specifies the list of network ports exposed by each endpoint in @@ -63,6 +67,8 @@ type EndpointSlice struct { } // AddressType represents the type of address referred to by an endpoint. +// +enum +// +k8s:alpha(since: "1.36")=+k8s:enum type AddressType string const ( @@ -85,6 +91,9 @@ type Endpoint struct { // 100. These are all assumed to be fungible and clients may choose to only // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxItems=100 Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` // conditions contains information about the current status of the endpoint. diff --git a/vendor/k8s.io/api/events/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/events/v1/generated.protomessage.pb.go deleted file mode 100644 index 09ff231dac..0000000000 --- a/vendor/k8s.io/api/events/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*Event) ProtoMessage() {} - -func (*EventList) ProtoMessage() {} - -func (*EventSeries) ProtoMessage() {} diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.proto b/vendor/k8s.io/api/extensions/v1beta1/generated.proto index c664c71bd2..f090306686 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.proto +++ b/vendor/k8s.io/api/extensions/v1beta1/generated.proto @@ -428,6 +428,8 @@ message HTTPIngressRuleValue { message IPBlock { // CIDR is a string representing the IP Block // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string cidr = 1; // Except is a slice of CIDRs that should not be included within an IP Block @@ -686,6 +688,7 @@ message NetworkPolicyEgressRule { // allows traffic only if the traffic matches at least one item in the to list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyPeer to = 2; } @@ -708,6 +711,7 @@ message NetworkPolicyIngressRule { // traffic matches at least one item in the from list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyPeer from = 2; } @@ -746,6 +750,7 @@ message NetworkPolicyPeer { // IPBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional IPBlock ipBlock = 3; } @@ -789,6 +794,7 @@ message NetworkPolicySpec { // (and serves solely to ensure that the pods it selects are isolated by default). // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyIngressRule ingress = 2; // List of egress rules to be applied to the selected pods. Outgoing traffic is @@ -800,6 +806,7 @@ message NetworkPolicySpec { // This field is beta-level in 1.8 // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyEgressRule egress = 3; // List of rule types that the NetworkPolicy relates to. @@ -1039,9 +1046,9 @@ message Scale { message ScaleSpec { // desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 optional int32 replicas = 1; } diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/extensions/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index ef18ae2996..0000000000 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,112 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*DaemonSet) ProtoMessage() {} - -func (*DaemonSetCondition) ProtoMessage() {} - -func (*DaemonSetList) ProtoMessage() {} - -func (*DaemonSetSpec) ProtoMessage() {} - -func (*DaemonSetStatus) ProtoMessage() {} - -func (*DaemonSetUpdateStrategy) ProtoMessage() {} - -func (*Deployment) ProtoMessage() {} - -func (*DeploymentCondition) ProtoMessage() {} - -func (*DeploymentList) ProtoMessage() {} - -func (*DeploymentRollback) ProtoMessage() {} - -func (*DeploymentSpec) ProtoMessage() {} - -func (*DeploymentStatus) ProtoMessage() {} - -func (*DeploymentStrategy) ProtoMessage() {} - -func (*HTTPIngressPath) ProtoMessage() {} - -func (*HTTPIngressRuleValue) ProtoMessage() {} - -func (*IPBlock) ProtoMessage() {} - -func (*Ingress) ProtoMessage() {} - -func (*IngressBackend) ProtoMessage() {} - -func (*IngressList) ProtoMessage() {} - -func (*IngressLoadBalancerIngress) ProtoMessage() {} - -func (*IngressLoadBalancerStatus) ProtoMessage() {} - -func (*IngressPortStatus) ProtoMessage() {} - -func (*IngressRule) ProtoMessage() {} - -func (*IngressRuleValue) ProtoMessage() {} - -func (*IngressSpec) ProtoMessage() {} - -func (*IngressStatus) ProtoMessage() {} - -func (*IngressTLS) ProtoMessage() {} - -func (*NetworkPolicy) ProtoMessage() {} - -func (*NetworkPolicyEgressRule) ProtoMessage() {} - -func (*NetworkPolicyIngressRule) ProtoMessage() {} - -func (*NetworkPolicyList) ProtoMessage() {} - -func (*NetworkPolicyPeer) ProtoMessage() {} - -func (*NetworkPolicyPort) ProtoMessage() {} - -func (*NetworkPolicySpec) ProtoMessage() {} - -func (*ReplicaSet) ProtoMessage() {} - -func (*ReplicaSetCondition) ProtoMessage() {} - -func (*ReplicaSetList) ProtoMessage() {} - -func (*ReplicaSetSpec) ProtoMessage() {} - -func (*ReplicaSetStatus) ProtoMessage() {} - -func (*RollbackConfig) ProtoMessage() {} - -func (*RollingUpdateDaemonSet) ProtoMessage() {} - -func (*RollingUpdateDeployment) ProtoMessage() {} - -func (*Scale) ProtoMessage() {} - -func (*ScaleSpec) ProtoMessage() {} - -func (*ScaleStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/extensions/v1beta1/types.go b/vendor/k8s.io/api/extensions/v1beta1/types.go index c0d8b4f959..09d143ea60 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/types.go +++ b/vendor/k8s.io/api/extensions/v1beta1/types.go @@ -27,9 +27,9 @@ import ( type ScaleSpec struct { // desired number of instances for the scaled object. // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +default=0 - // +k8s:minimum=0 + // +k8s:alpha(since: "1.36")=+k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } @@ -57,7 +57,7 @@ type ScaleStatus struct { // +k8s:prerelease-lifecycle-gen:introduced=1.1 // +k8s:prerelease-lifecycle-gen:deprecated=1.2 // +k8s:prerelease-lifecycle-gen:removed=1.16 -// +k8s:isSubresource=/scale +// +k8s:isSubresource="/scale" // represents a scaling request for a resource. type Scale struct { @@ -1106,6 +1106,7 @@ type NetworkPolicySpec struct { // (and serves solely to ensure that the pods it selects are isolated by default). // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` // List of egress rules to be applied to the selected pods. Outgoing traffic is @@ -1117,6 +1118,7 @@ type NetworkPolicySpec struct { // This field is beta-level in 1.8 // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` // List of rule types that the NetworkPolicy relates to. @@ -1153,6 +1155,7 @@ type NetworkPolicyIngressRule struct { // traffic matches at least one item in the from list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` } @@ -1177,6 +1180,7 @@ type NetworkPolicyEgressRule struct { // allows traffic only if the traffic matches at least one item in the to list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"` } @@ -1209,6 +1213,8 @@ type NetworkPolicyPort struct { type IPBlock struct { // CIDR is a string representing the IP Block // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // +required + // +k8s:alpha(since: "1.36")=+k8s:required CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"` // Except is a slice of CIDRs that should not be included within an IP Block // Valid examples are "192.168.1.0/24" or "2001:db8::/64" @@ -1241,6 +1247,7 @@ type NetworkPolicyPeer struct { // IPBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` } diff --git a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.validations.go b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.validations.go index f4f0e317a7..d504d5452e 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.validations.go +++ b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.validations.go @@ -25,6 +25,7 @@ import ( context "context" fmt "fmt" + equality "k8s.io/apimachinery/pkg/api/equality" operation "k8s.io/apimachinery/pkg/api/operation" safe "k8s.io/apimachinery/pkg/api/safe" validate "k8s.io/apimachinery/pkg/api/validate" @@ -37,6 +38,14 @@ func init() { localSchemeBuilder.Register(RegisterValidations) } // RegisterValidations adds validation functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterValidations(scheme *runtime.Scheme) error { + // type NetworkPolicy + scheme.AddValidationFunc((*NetworkPolicy)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + switch op.Request.SubresourcePath() { + case "/": + return Validate_NetworkPolicy(ctx, op, nil /* fldPath */, obj.(*NetworkPolicy), safe.Cast[*NetworkPolicy](oldObj)) + } + return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} + }) // type Scale scheme.AddValidationFunc((*Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -48,6 +57,187 @@ func RegisterValidations(scheme *runtime.Scheme) error { return nil } +// Validate_IPBlock validates an instance of IPBlock according +// to declarative validation rules in the API schema. +func Validate_IPBlock(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *IPBlock) (errs field.ErrorList) { + // field IPBlock.CIDR + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + }(fldPath.Child("cidr"), &obj.CIDR, safe.Field(oldObj, func(oldObj *IPBlock) *string { return &oldObj.CIDR }), oldObj != nil)...) + + // field IPBlock.Except has no validation + return errs +} + +// Validate_NetworkPolicy validates an instance of NetworkPolicy according +// to declarative validation rules in the API schema. +func Validate_NetworkPolicy(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicy) (errs field.ErrorList) { + // field NetworkPolicy.TypeMeta has no validation + // field NetworkPolicy.ObjectMeta has no validation + + // field NetworkPolicy.Spec + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *NetworkPolicySpec, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call the type's validation function + errs = append(errs, Validate_NetworkPolicySpec(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *NetworkPolicy) *NetworkPolicySpec { return &oldObj.Spec }), oldObj != nil)...) + + return errs +} + +// Validate_NetworkPolicyEgressRule validates an instance of NetworkPolicyEgressRule according +// to declarative validation rules in the API schema. +func Validate_NetworkPolicyEgressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyEgressRule) (errs field.ErrorList) { + // field NetworkPolicyEgressRule.Ports has no validation + + // field NetworkPolicyEgressRule.To + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...) + return + }(fldPath.Child("to"), obj.To, safe.Field(oldObj, func(oldObj *NetworkPolicyEgressRule) []NetworkPolicyPeer { return oldObj.To }), oldObj != nil)...) + + return errs +} + +// Validate_NetworkPolicyIngressRule validates an instance of NetworkPolicyIngressRule according +// to declarative validation rules in the API schema. +func Validate_NetworkPolicyIngressRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyIngressRule) (errs field.ErrorList) { + // field NetworkPolicyIngressRule.Ports has no validation + + // field NetworkPolicyIngressRule.From + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []NetworkPolicyPeer, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer)...) + return + }(fldPath.Child("from"), obj.From, safe.Field(oldObj, func(oldObj *NetworkPolicyIngressRule) []NetworkPolicyPeer { return oldObj.From }), oldObj != nil)...) + + return errs +} + +// Validate_NetworkPolicyPeer validates an instance of NetworkPolicyPeer according +// to declarative validation rules in the API schema. +func Validate_NetworkPolicyPeer(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicyPeer) (errs field.ErrorList) { + // field NetworkPolicyPeer.PodSelector has no validation + // field NetworkPolicyPeer.NamespaceSelector has no validation + + // field NetworkPolicyPeer.IPBlock + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *IPBlock, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_IPBlock(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("ipBlock"), obj.IPBlock, safe.Field(oldObj, func(oldObj *NetworkPolicyPeer) *IPBlock { return oldObj.IPBlock }), oldObj != nil)...) + + return errs +} + +// Validate_NetworkPolicySpec validates an instance of NetworkPolicySpec according +// to declarative validation rules in the API schema. +func Validate_NetworkPolicySpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *NetworkPolicySpec) (errs field.ErrorList) { + // field NetworkPolicySpec.PodSelector has no validation + + // field NetworkPolicySpec.Ingress + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []NetworkPolicyIngressRule, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyIngressRule)...) + return + }(fldPath.Child("ingress"), obj.Ingress, safe.Field(oldObj, func(oldObj *NetworkPolicySpec) []NetworkPolicyIngressRule { return oldObj.Ingress }), oldObj != nil)...) + + // field NetworkPolicySpec.Egress + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []NetworkPolicyEgressRule, oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyEgressRule)...) + return + }(fldPath.Child("egress"), obj.Egress, safe.Field(oldObj, func(oldObj *NetworkPolicySpec) []NetworkPolicyEgressRule { return oldObj.Egress }), oldObj != nil)...) + + // field NetworkPolicySpec.PolicyTypes has no validation + return errs +} + // Validate_Scale validates an instance of Scale according // to declarative validation rules in the API schema. func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Scale) (errs field.ErrorList) { @@ -76,13 +266,12 @@ func Validate_ScaleSpec(ctx context.Context, op operation.Operation, fldPath *fi // field ScaleSpec.Replicas errs = append(errs, func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) { - // optional value-type fields with zero-value defaults are purely documentation // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { return nil } // call field-attached validations - errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha()...) return }(fldPath.Child("replicas"), &obj.Replicas, safe.Field(oldObj, func(oldObj *ScaleSpec) *int32 { return &oldObj.Replicas }), oldObj != nil)...) diff --git a/vendor/k8s.io/api/flowcontrol/v1/generated.proto b/vendor/k8s.io/api/flowcontrol/v1/generated.proto index 33a135889e..eb9186d013 100644 --- a/vendor/k8s.io/api/flowcontrol/v1/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1/generated.proto @@ -179,11 +179,16 @@ message LimitResponse { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden optional QueuingConfiguration queuing = 2; } @@ -367,11 +372,16 @@ message PriorityLevelConfigurationSpec { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden optional LimitedPriorityLevelConfiguration limited = 2; // `exempt` specifies how requests are handled for an exempt priority level. @@ -380,6 +390,9 @@ message PriorityLevelConfigurationSpec { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden optional ExemptPriorityLevelConfiguration exempt = 3; } diff --git a/vendor/k8s.io/api/flowcontrol/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/flowcontrol/v1/generated.protomessage.pb.go deleted file mode 100644 index 51612dee82..0000000000 --- a/vendor/k8s.io/api/flowcontrol/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*ExemptPriorityLevelConfiguration) ProtoMessage() {} - -func (*FlowDistinguisherMethod) ProtoMessage() {} - -func (*FlowSchema) ProtoMessage() {} - -func (*FlowSchemaCondition) ProtoMessage() {} - -func (*FlowSchemaList) ProtoMessage() {} - -func (*FlowSchemaSpec) ProtoMessage() {} - -func (*FlowSchemaStatus) ProtoMessage() {} - -func (*GroupSubject) ProtoMessage() {} - -func (*LimitResponse) ProtoMessage() {} - -func (*LimitedPriorityLevelConfiguration) ProtoMessage() {} - -func (*NonResourcePolicyRule) ProtoMessage() {} - -func (*PolicyRulesWithSubjects) ProtoMessage() {} - -func (*PriorityLevelConfiguration) ProtoMessage() {} - -func (*PriorityLevelConfigurationCondition) ProtoMessage() {} - -func (*PriorityLevelConfigurationList) ProtoMessage() {} - -func (*PriorityLevelConfigurationReference) ProtoMessage() {} - -func (*PriorityLevelConfigurationSpec) ProtoMessage() {} - -func (*PriorityLevelConfigurationStatus) ProtoMessage() {} - -func (*QueuingConfiguration) ProtoMessage() {} - -func (*ResourcePolicyRule) ProtoMessage() {} - -func (*ServiceAccountSubject) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} - -func (*UserSubject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/flowcontrol/v1/types.go b/vendor/k8s.io/api/flowcontrol/v1/types.go index ad72bcee22..4a40bdca42 100644 --- a/vendor/k8s.io/api/flowcontrol/v1/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1/types.go @@ -429,11 +429,16 @@ type PriorityLevelConfigurationSpec struct { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type PriorityLevelEnablement `json:"type" protobuf:"bytes,1,opt,name=type"` // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden Limited *LimitedPriorityLevelConfiguration `json:"limited,omitempty" protobuf:"bytes,2,opt,name=limited"` // `exempt` specifies how requests are handled for an exempt priority level. @@ -442,6 +447,9 @@ type PriorityLevelConfigurationSpec struct { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden Exempt *ExemptPriorityLevelConfiguration `json:"exempt,omitempty" protobuf:"bytes,3,opt,name=exempt"` } @@ -566,11 +574,16 @@ type LimitResponse struct { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type LimitResponseType `json:"type" protobuf:"bytes,1,opt,name=type"` // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden Queuing *QueuingConfiguration `json:"queuing,omitempty" protobuf:"bytes,2,opt,name=queuing"` } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto index 61ed3833ae..8a701a6100 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.proto @@ -177,11 +177,16 @@ message LimitResponse { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden optional QueuingConfiguration queuing = 2; } @@ -360,11 +365,16 @@ message PriorityLevelConfigurationSpec { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden optional LimitedPriorityLevelConfiguration limited = 2; // `exempt` specifies how requests are handled for an exempt priority level. @@ -373,6 +383,9 @@ message PriorityLevelConfigurationSpec { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden optional ExemptPriorityLevelConfiguration exempt = 3; } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 9d2059597a..0000000000 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ExemptPriorityLevelConfiguration) ProtoMessage() {} - -func (*FlowDistinguisherMethod) ProtoMessage() {} - -func (*FlowSchema) ProtoMessage() {} - -func (*FlowSchemaCondition) ProtoMessage() {} - -func (*FlowSchemaList) ProtoMessage() {} - -func (*FlowSchemaSpec) ProtoMessage() {} - -func (*FlowSchemaStatus) ProtoMessage() {} - -func (*GroupSubject) ProtoMessage() {} - -func (*LimitResponse) ProtoMessage() {} - -func (*LimitedPriorityLevelConfiguration) ProtoMessage() {} - -func (*NonResourcePolicyRule) ProtoMessage() {} - -func (*PolicyRulesWithSubjects) ProtoMessage() {} - -func (*PriorityLevelConfiguration) ProtoMessage() {} - -func (*PriorityLevelConfigurationCondition) ProtoMessage() {} - -func (*PriorityLevelConfigurationList) ProtoMessage() {} - -func (*PriorityLevelConfigurationReference) ProtoMessage() {} - -func (*PriorityLevelConfigurationSpec) ProtoMessage() {} - -func (*PriorityLevelConfigurationStatus) ProtoMessage() {} - -func (*QueuingConfiguration) ProtoMessage() {} - -func (*ResourcePolicyRule) ProtoMessage() {} - -func (*ServiceAccountSubject) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} - -func (*UserSubject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/types.go b/vendor/k8s.io/api/flowcontrol/v1beta1/types.go index abc3e42009..0de6ea940e 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/types.go @@ -431,11 +431,16 @@ type PriorityLevelConfigurationSpec struct { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type PriorityLevelEnablement `json:"type" protobuf:"bytes,1,opt,name=type"` // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden Limited *LimitedPriorityLevelConfiguration `json:"limited,omitempty" protobuf:"bytes,2,opt,name=limited"` // `exempt` specifies how requests are handled for an exempt priority level. @@ -444,6 +449,9 @@ type PriorityLevelConfigurationSpec struct { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden Exempt *ExemptPriorityLevelConfiguration `json:"exempt,omitempty" protobuf:"bytes,3,opt,name=exempt"` } @@ -563,11 +571,16 @@ type LimitResponse struct { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type LimitResponseType `json:"type" protobuf:"bytes,1,opt,name=type"` // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden Queuing *QueuingConfiguration `json:"queuing,omitempty" protobuf:"bytes,2,opt,name=queuing"` } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto index d6073fc925..371b90a5cd 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.proto @@ -177,11 +177,16 @@ message LimitResponse { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden optional QueuingConfiguration queuing = 2; } @@ -360,11 +365,16 @@ message PriorityLevelConfigurationSpec { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden optional LimitedPriorityLevelConfiguration limited = 2; // `exempt` specifies how requests are handled for an exempt priority level. @@ -373,6 +383,9 @@ message PriorityLevelConfigurationSpec { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden optional ExemptPriorityLevelConfiguration exempt = 3; } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.protomessage.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta2/generated.protomessage.pb.go deleted file mode 100644 index 672834e9fa..0000000000 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/generated.protomessage.pb.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta2 - -func (*ExemptPriorityLevelConfiguration) ProtoMessage() {} - -func (*FlowDistinguisherMethod) ProtoMessage() {} - -func (*FlowSchema) ProtoMessage() {} - -func (*FlowSchemaCondition) ProtoMessage() {} - -func (*FlowSchemaList) ProtoMessage() {} - -func (*FlowSchemaSpec) ProtoMessage() {} - -func (*FlowSchemaStatus) ProtoMessage() {} - -func (*GroupSubject) ProtoMessage() {} - -func (*LimitResponse) ProtoMessage() {} - -func (*LimitedPriorityLevelConfiguration) ProtoMessage() {} - -func (*NonResourcePolicyRule) ProtoMessage() {} - -func (*PolicyRulesWithSubjects) ProtoMessage() {} - -func (*PriorityLevelConfiguration) ProtoMessage() {} - -func (*PriorityLevelConfigurationCondition) ProtoMessage() {} - -func (*PriorityLevelConfigurationList) ProtoMessage() {} - -func (*PriorityLevelConfigurationReference) ProtoMessage() {} - -func (*PriorityLevelConfigurationSpec) ProtoMessage() {} - -func (*PriorityLevelConfigurationStatus) ProtoMessage() {} - -func (*QueuingConfiguration) ProtoMessage() {} - -func (*ResourcePolicyRule) ProtoMessage() {} - -func (*ServiceAccountSubject) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} - -func (*UserSubject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/types.go b/vendor/k8s.io/api/flowcontrol/v1beta2/types.go index c66cb173f4..2f82a6823b 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/types.go @@ -431,11 +431,16 @@ type PriorityLevelConfigurationSpec struct { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type PriorityLevelEnablement `json:"type" protobuf:"bytes,1,opt,name=type"` // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden Limited *LimitedPriorityLevelConfiguration `json:"limited,omitempty" protobuf:"bytes,2,opt,name=limited"` // `exempt` specifies how requests are handled for an exempt priority level. @@ -444,6 +449,9 @@ type PriorityLevelConfigurationSpec struct { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden Exempt *ExemptPriorityLevelConfiguration `json:"exempt,omitempty" protobuf:"bytes,3,opt,name=exempt"` } @@ -563,11 +571,16 @@ type LimitResponse struct { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type LimitResponseType `json:"type" protobuf:"bytes,1,opt,name=type"` // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden Queuing *QueuingConfiguration `json:"queuing,omitempty" protobuf:"bytes,2,opt,name=queuing"` } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto index c6504d4353..7e11de2a28 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.proto @@ -179,11 +179,16 @@ message LimitResponse { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden optional QueuingConfiguration queuing = 2; } @@ -362,11 +367,16 @@ message PriorityLevelConfigurationSpec { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator optional string type = 1; // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden optional LimitedPriorityLevelConfiguration limited = 2; // `exempt` specifies how requests are handled for an exempt priority level. @@ -375,6 +385,9 @@ message PriorityLevelConfigurationSpec { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden optional ExemptPriorityLevelConfiguration exempt = 3; } diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.protomessage.pb.go b/vendor/k8s.io/api/flowcontrol/v1beta3/generated.protomessage.pb.go deleted file mode 100644 index 20407c045c..0000000000 --- a/vendor/k8s.io/api/flowcontrol/v1beta3/generated.protomessage.pb.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta3 - -func (*ExemptPriorityLevelConfiguration) ProtoMessage() {} - -func (*FlowDistinguisherMethod) ProtoMessage() {} - -func (*FlowSchema) ProtoMessage() {} - -func (*FlowSchemaCondition) ProtoMessage() {} - -func (*FlowSchemaList) ProtoMessage() {} - -func (*FlowSchemaSpec) ProtoMessage() {} - -func (*FlowSchemaStatus) ProtoMessage() {} - -func (*GroupSubject) ProtoMessage() {} - -func (*LimitResponse) ProtoMessage() {} - -func (*LimitedPriorityLevelConfiguration) ProtoMessage() {} - -func (*NonResourcePolicyRule) ProtoMessage() {} - -func (*PolicyRulesWithSubjects) ProtoMessage() {} - -func (*PriorityLevelConfiguration) ProtoMessage() {} - -func (*PriorityLevelConfigurationCondition) ProtoMessage() {} - -func (*PriorityLevelConfigurationList) ProtoMessage() {} - -func (*PriorityLevelConfigurationReference) ProtoMessage() {} - -func (*PriorityLevelConfigurationSpec) ProtoMessage() {} - -func (*PriorityLevelConfigurationStatus) ProtoMessage() {} - -func (*QueuingConfiguration) ProtoMessage() {} - -func (*ResourcePolicyRule) ProtoMessage() {} - -func (*ServiceAccountSubject) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} - -func (*UserSubject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/types.go b/vendor/k8s.io/api/flowcontrol/v1beta3/types.go index 0ffc22a236..26b67629ce 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta3/types.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/types.go @@ -447,11 +447,16 @@ type PriorityLevelConfigurationSpec struct { // capacity is made available exclusively to this priority level. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type PriorityLevelEnablement `json:"type" protobuf:"bytes,1,opt,name=type"` // `limited` specifies how requests are handled for a Limited priority level. // This field must be non-empty if and only if `type` is `"Limited"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:forbidden Limited *LimitedPriorityLevelConfiguration `json:"limited,omitempty" protobuf:"bytes,2,opt,name=limited"` // `exempt` specifies how requests are handled for an exempt priority level. @@ -460,6 +465,9 @@ type PriorityLevelConfigurationSpec struct { // If empty and `type` is `"Exempt"` then the default values // for `ExemptPriorityLevelConfiguration` apply. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Exempt")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Limited")=+k8s:forbidden Exempt *ExemptPriorityLevelConfiguration `json:"exempt,omitempty" protobuf:"bytes,3,opt,name=exempt"` } @@ -579,11 +587,16 @@ type LimitResponse struct { // are rejected. // Required. // +unionDiscriminator + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:discriminator Type LimitResponseType `json:"type" protobuf:"bytes,1,opt,name=type"` // `queuing` holds the configuration parameters for queuing. // This field may be non-empty only if `type` is `"Queue"`. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:member("Queue")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:member("Reject")=+k8s:forbidden Queuing *QueuingConfiguration `json:"queuing,omitempty" protobuf:"bytes,2,opt,name=queuing"` } diff --git a/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.proto b/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.proto index 5ea5c0ec8e..03b1ac45c0 100644 --- a/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.proto @@ -36,6 +36,7 @@ message ImageReview { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec holds information about the pod being evaluated + // +optional optional ImageReviewSpec spec = 2; // Status is filled in by the backend and indicates whether the pod should be allowed. @@ -71,6 +72,7 @@ message ImageReviewSpec { // ImageReviewStatus is the result of the review for the pod creation request. message ImageReviewStatus { // Allowed indicates that all images were allowed to be run. + // +optional optional bool allowed = 1; // Reason should be empty unless Allowed is false in which case it diff --git a/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index 215f52a377..0000000000 --- a/vendor/k8s.io/api/imagepolicy/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*ImageReview) ProtoMessage() {} - -func (*ImageReviewContainerSpec) ProtoMessage() {} - -func (*ImageReviewSpec) ProtoMessage() {} - -func (*ImageReviewStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/imagepolicy/v1alpha1/types.go b/vendor/k8s.io/api/imagepolicy/v1alpha1/types.go index 19ac2b536f..cc8f4cf89f 100644 --- a/vendor/k8s.io/api/imagepolicy/v1alpha1/types.go +++ b/vendor/k8s.io/api/imagepolicy/v1alpha1/types.go @@ -34,6 +34,7 @@ type ImageReview struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec holds information about the pod being evaluated + // +optional Spec ImageReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` // Status is filled in by the backend and indicates whether the pod should be allowed. @@ -68,6 +69,7 @@ type ImageReviewContainerSpec struct { // ImageReviewStatus is the result of the review for the pod creation request. type ImageReviewStatus struct { // Allowed indicates that all images were allowed to be run. + // +optional Allowed bool `json:"allowed" protobuf:"varint,1,opt,name=allowed"` // Reason should be empty unless Allowed is false in which case it // may contain a short description of what is wrong. Kubernetes diff --git a/vendor/k8s.io/api/networking/v1/generated.proto b/vendor/k8s.io/api/networking/v1/generated.proto index 16a2792aa6..26dcfdfcc3 100644 --- a/vendor/k8s.io/api/networking/v1/generated.proto +++ b/vendor/k8s.io/api/networking/v1/generated.proto @@ -87,7 +87,7 @@ message IPAddress { // spec is the desired state of the IPAddress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional IPAddressSpec spec = 2; } @@ -107,6 +107,8 @@ message IPAddressSpec { // ParentRef references the resource that an IPAddress is attached to. // An IPAddress must reference a parent object. // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional ParentReference parentRef = 1; } @@ -116,6 +118,8 @@ message IPAddressSpec { message IPBlock { // cidr is a string representing the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string cidr = 1; // except is a slice of CIDRs that should not be included within an IPBlock @@ -199,9 +203,13 @@ message IngressClassParametersReference { optional string aPIGroup = 1; // kind is the type of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string kind = 2; // name is the name of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; // scope represents if this refers to a cluster or namespace scoped resource. @@ -230,6 +238,7 @@ message IngressClassSpec { // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional IngressClassParametersReference parameters = 2; } @@ -446,6 +455,7 @@ message NetworkPolicyEgressRule { // allows traffic only if the traffic matches at least one item in the to list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyPeer to = 2; } @@ -468,6 +478,7 @@ message NetworkPolicyIngressRule { // allows traffic only if the traffic matches at least one item in the from list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyPeer from = 2; } @@ -506,6 +517,7 @@ message NetworkPolicyPeer { // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional IPBlock ipBlock = 3; } @@ -551,6 +563,7 @@ message NetworkPolicySpec { // solely to ensure that the pods it selects are isolated by default) // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyIngressRule ingress = 2; // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic @@ -562,6 +575,7 @@ message NetworkPolicySpec { // This field is beta-level in 1.8 // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated NetworkPolicyEgressRule egress = 3; // policyTypes is a list of rule types that the NetworkPolicy relates to. @@ -587,6 +601,7 @@ message ParentReference { // Resource is the resource of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string resource = 2; // Namespace is the namespace of the object being referenced. @@ -595,6 +610,7 @@ message ParentReference { // Name is the name of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 4; } diff --git a/vendor/k8s.io/api/networking/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/networking/v1/generated.protomessage.pb.go deleted file mode 100644 index 54918d47e7..0000000000 --- a/vendor/k8s.io/api/networking/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,92 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*HTTPIngressPath) ProtoMessage() {} - -func (*HTTPIngressRuleValue) ProtoMessage() {} - -func (*IPAddress) ProtoMessage() {} - -func (*IPAddressList) ProtoMessage() {} - -func (*IPAddressSpec) ProtoMessage() {} - -func (*IPBlock) ProtoMessage() {} - -func (*Ingress) ProtoMessage() {} - -func (*IngressBackend) ProtoMessage() {} - -func (*IngressClass) ProtoMessage() {} - -func (*IngressClassList) ProtoMessage() {} - -func (*IngressClassParametersReference) ProtoMessage() {} - -func (*IngressClassSpec) ProtoMessage() {} - -func (*IngressList) ProtoMessage() {} - -func (*IngressLoadBalancerIngress) ProtoMessage() {} - -func (*IngressLoadBalancerStatus) ProtoMessage() {} - -func (*IngressPortStatus) ProtoMessage() {} - -func (*IngressRule) ProtoMessage() {} - -func (*IngressRuleValue) ProtoMessage() {} - -func (*IngressServiceBackend) ProtoMessage() {} - -func (*IngressSpec) ProtoMessage() {} - -func (*IngressStatus) ProtoMessage() {} - -func (*IngressTLS) ProtoMessage() {} - -func (*NetworkPolicy) ProtoMessage() {} - -func (*NetworkPolicyEgressRule) ProtoMessage() {} - -func (*NetworkPolicyIngressRule) ProtoMessage() {} - -func (*NetworkPolicyList) ProtoMessage() {} - -func (*NetworkPolicyPeer) ProtoMessage() {} - -func (*NetworkPolicyPort) ProtoMessage() {} - -func (*NetworkPolicySpec) ProtoMessage() {} - -func (*ParentReference) ProtoMessage() {} - -func (*ServiceBackendPort) ProtoMessage() {} - -func (*ServiceCIDR) ProtoMessage() {} - -func (*ServiceCIDRList) ProtoMessage() {} - -func (*ServiceCIDRSpec) ProtoMessage() {} - -func (*ServiceCIDRStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/networking/v1/types.go b/vendor/k8s.io/api/networking/v1/types.go index 7d9a4fc94c..a0e737ee15 100644 --- a/vendor/k8s.io/api/networking/v1/types.go +++ b/vendor/k8s.io/api/networking/v1/types.go @@ -77,6 +77,7 @@ type NetworkPolicySpec struct { // solely to ensure that the pods it selects are isolated by default) // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic @@ -88,6 +89,7 @@ type NetworkPolicySpec struct { // This field is beta-level in 1.8 // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` // policyTypes is a list of rule types that the NetworkPolicy relates to. @@ -124,6 +126,7 @@ type NetworkPolicyIngressRule struct { // allows traffic only if the traffic matches at least one item in the from list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` } @@ -147,6 +150,7 @@ type NetworkPolicyEgressRule struct { // allows traffic only if the traffic matches at least one item in the to list. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"` } @@ -178,6 +182,8 @@ type NetworkPolicyPort struct { type IPBlock struct { // cidr is a string representing the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // +required + // +k8s:alpha(since: "1.36")=+k8s:required CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"` // except is a slice of CIDRs that should not be included within an IPBlock @@ -212,6 +218,7 @@ type NetworkPolicyPeer struct { // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` } @@ -583,6 +590,7 @@ type IngressClassSpec struct { // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Parameters *IngressClassParametersReference `json:"parameters,omitempty" protobuf:"bytes,2,opt,name=parameters"` } @@ -605,9 +613,13 @@ type IngressClassParametersReference struct { APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` // kind is the type of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // name is the name of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // scope represents if this refers to a cluster or namespace scoped resource. @@ -657,7 +669,7 @@ type IPAddress struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // spec is the desired state of the IPAddress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec IPAddressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -666,6 +678,8 @@ type IPAddressSpec struct { // ParentRef references the resource that an IPAddress is attached to. // An IPAddress must reference a parent object. // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable ParentRef *ParentReference `json:"parentRef,omitempty" protobuf:"bytes,1,opt,name=parentRef"` } @@ -676,12 +690,14 @@ type ParentReference struct { Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` // Resource is the resource of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required Resource string `json:"resource,omitempty" protobuf:"bytes,2,opt,name=resource"` // Namespace is the namespace of the object being referenced. // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` // Name is the name of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` } diff --git a/vendor/k8s.io/api/networking/v1beta1/generated.proto b/vendor/k8s.io/api/networking/v1beta1/generated.proto index 3368dcaec3..a6944d6034 100644 --- a/vendor/k8s.io/api/networking/v1beta1/generated.proto +++ b/vendor/k8s.io/api/networking/v1beta1/generated.proto @@ -88,7 +88,7 @@ message IPAddress { // spec is the desired state of the IPAddress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required optional IPAddressSpec spec = 2; } @@ -108,6 +108,8 @@ message IPAddressSpec { // ParentRef references the resource that an IPAddress is attached to. // An IPAddress must reference a parent object. // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional ParentReference parentRef = 1; } @@ -186,9 +188,13 @@ message IngressClassParametersReference { optional string aPIGroup = 1; // kind is the type of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string kind = 2; // name is the name of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; // scope represents if this refers to a cluster or namespace scoped resource. @@ -216,6 +222,7 @@ message IngressClassSpec { // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional IngressClassParametersReference parameters = 2; } @@ -397,6 +404,7 @@ message ParentReference { // Resource is the resource of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string resource = 2; // Namespace is the namespace of the object being referenced. @@ -405,6 +413,7 @@ message ParentReference { // Name is the name of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 4; } diff --git a/vendor/k8s.io/api/networking/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/networking/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index abd29cba98..0000000000 --- a/vendor/k8s.io/api/networking/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,72 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*HTTPIngressPath) ProtoMessage() {} - -func (*HTTPIngressRuleValue) ProtoMessage() {} - -func (*IPAddress) ProtoMessage() {} - -func (*IPAddressList) ProtoMessage() {} - -func (*IPAddressSpec) ProtoMessage() {} - -func (*Ingress) ProtoMessage() {} - -func (*IngressBackend) ProtoMessage() {} - -func (*IngressClass) ProtoMessage() {} - -func (*IngressClassList) ProtoMessage() {} - -func (*IngressClassParametersReference) ProtoMessage() {} - -func (*IngressClassSpec) ProtoMessage() {} - -func (*IngressList) ProtoMessage() {} - -func (*IngressLoadBalancerIngress) ProtoMessage() {} - -func (*IngressLoadBalancerStatus) ProtoMessage() {} - -func (*IngressPortStatus) ProtoMessage() {} - -func (*IngressRule) ProtoMessage() {} - -func (*IngressRuleValue) ProtoMessage() {} - -func (*IngressSpec) ProtoMessage() {} - -func (*IngressStatus) ProtoMessage() {} - -func (*IngressTLS) ProtoMessage() {} - -func (*ParentReference) ProtoMessage() {} - -func (*ServiceCIDR) ProtoMessage() {} - -func (*ServiceCIDRList) ProtoMessage() {} - -func (*ServiceCIDRSpec) ProtoMessage() {} - -func (*ServiceCIDRStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/networking/v1beta1/types.go b/vendor/k8s.io/api/networking/v1beta1/types.go index cd7126a5a8..7cd9b2b58b 100644 --- a/vendor/k8s.io/api/networking/v1beta1/types.go +++ b/vendor/k8s.io/api/networking/v1beta1/types.go @@ -368,6 +368,7 @@ type IngressClassSpec struct { // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Parameters *IngressClassParametersReference `json:"parameters,omitempty" protobuf:"bytes,2,opt,name=parameters"` } @@ -390,9 +391,13 @@ type IngressClassParametersReference struct { APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` // kind is the type of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // name is the name of resource being referenced. + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // scope represents if this refers to a cluster or namespace scoped resource. @@ -442,7 +447,7 @@ type IPAddress struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // spec is the desired state of the IPAddress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional + // +required Spec IPAddressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` } @@ -451,6 +456,8 @@ type IPAddressSpec struct { // ParentRef references the resource that an IPAddress is attached to. // An IPAddress must reference a parent object. // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable ParentRef *ParentReference `json:"parentRef,omitempty" protobuf:"bytes,1,opt,name=parentRef"` } @@ -461,12 +468,14 @@ type ParentReference struct { Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` // Resource is the resource of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required Resource string `json:"resource,omitempty" protobuf:"bytes,2,opt,name=resource"` // Namespace is the namespace of the object being referenced. // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` // Name is the name of the object being referenced. // +required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` } diff --git a/vendor/k8s.io/api/node/v1/generated.proto b/vendor/k8s.io/api/node/v1/generated.proto index e6b8852ec1..4d77c9b781 100644 --- a/vendor/k8s.io/api/node/v1/generated.proto +++ b/vendor/k8s.io/api/node/v1/generated.proto @@ -59,6 +59,10 @@ message RuntimeClass { // in a pod. // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required optional string handler = 2; // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/node/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/node/v1/generated.protomessage.pb.go deleted file mode 100644 index 97072dfa1e..0000000000 --- a/vendor/k8s.io/api/node/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*Overhead) ProtoMessage() {} - -func (*RuntimeClass) ProtoMessage() {} - -func (*RuntimeClassList) ProtoMessage() {} - -func (*Scheduling) ProtoMessage() {} diff --git a/vendor/k8s.io/api/node/v1/types.go b/vendor/k8s.io/api/node/v1/types.go index 169862ea94..c2ea739dc8 100644 --- a/vendor/k8s.io/api/node/v1/types.go +++ b/vendor/k8s.io/api/node/v1/types.go @@ -50,6 +50,10 @@ type RuntimeClass struct { // in a pod. // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/node/v1alpha1/generated.proto b/vendor/k8s.io/api/node/v1alpha1/generated.proto index bc68718d90..c50b639065 100644 --- a/vendor/k8s.io/api/node/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/node/v1alpha1/generated.proto @@ -51,6 +51,7 @@ message RuntimeClass { // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +required optional RuntimeClassSpec spec = 2; } @@ -80,6 +81,10 @@ message RuntimeClassSpec { // in a pod. // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required optional string runtimeHandler = 1; // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/node/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/node/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index acd3b604ee..0000000000 --- a/vendor/k8s.io/api/node/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*Overhead) ProtoMessage() {} - -func (*RuntimeClass) ProtoMessage() {} - -func (*RuntimeClassList) ProtoMessage() {} - -func (*RuntimeClassSpec) ProtoMessage() {} - -func (*Scheduling) ProtoMessage() {} diff --git a/vendor/k8s.io/api/node/v1alpha1/types.go b/vendor/k8s.io/api/node/v1alpha1/types.go index bf9e284bf7..3521335b07 100644 --- a/vendor/k8s.io/api/node/v1alpha1/types.go +++ b/vendor/k8s.io/api/node/v1alpha1/types.go @@ -41,6 +41,7 @@ type RuntimeClass struct { // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +required Spec RuntimeClassSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -59,6 +60,10 @@ type RuntimeClassSpec struct { // in a pod. // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required RuntimeHandler string `json:"runtimeHandler" protobuf:"bytes,1,opt,name=runtimeHandler"` // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/node/v1beta1/generated.proto b/vendor/k8s.io/api/node/v1beta1/generated.proto index 497027e033..073a185e2c 100644 --- a/vendor/k8s.io/api/node/v1beta1/generated.proto +++ b/vendor/k8s.io/api/node/v1beta1/generated.proto @@ -59,6 +59,10 @@ message RuntimeClass { // in a pod. // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required optional string handler = 2; // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/node/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/node/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index dfe8e29d95..0000000000 --- a/vendor/k8s.io/api/node/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*Overhead) ProtoMessage() {} - -func (*RuntimeClass) ProtoMessage() {} - -func (*RuntimeClassList) ProtoMessage() {} - -func (*Scheduling) ProtoMessage() {} diff --git a/vendor/k8s.io/api/node/v1beta1/types.go b/vendor/k8s.io/api/node/v1beta1/types.go index 74ecca26ad..145e138663 100644 --- a/vendor/k8s.io/api/node/v1beta1/types.go +++ b/vendor/k8s.io/api/node/v1beta1/types.go @@ -51,6 +51,10 @@ type RuntimeClass struct { // in a pod. // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. + // +required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-short-name" + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:required Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` // overhead represents the resource overhead associated with running a pod for a diff --git a/vendor/k8s.io/api/policy/v1/generated.proto b/vendor/k8s.io/api/policy/v1/generated.proto index 9534890723..704cc10b7d 100644 --- a/vendor/k8s.io/api/policy/v1/generated.proto +++ b/vendor/k8s.io/api/policy/v1/generated.proto @@ -142,15 +142,19 @@ message PodDisruptionBudgetStatus { map disruptedPods = 2; // Number of pod disruptions that are currently allowed. + // +optional optional int32 disruptionsAllowed = 3; // current number of healthy pods + // +optional optional int32 currentHealthy = 4; // minimum desired number of healthy pods + // +optional optional int32 desiredHealthy = 5; // total number of pods counted by this disruption budget + // +optional optional int32 expectedPods = 6; // Conditions contain conditions for PDB. The disruption controller sets the diff --git a/vendor/k8s.io/api/policy/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/policy/v1/generated.protomessage.pb.go deleted file mode 100644 index 2ede217639..0000000000 --- a/vendor/k8s.io/api/policy/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*Eviction) ProtoMessage() {} - -func (*PodDisruptionBudget) ProtoMessage() {} - -func (*PodDisruptionBudgetList) ProtoMessage() {} - -func (*PodDisruptionBudgetSpec) ProtoMessage() {} - -func (*PodDisruptionBudgetStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/policy/v1/types.go b/vendor/k8s.io/api/policy/v1/types.go index 4e74367894..ebf349e317 100644 --- a/vendor/k8s.io/api/policy/v1/types.go +++ b/vendor/k8s.io/api/policy/v1/types.go @@ -117,15 +117,19 @@ type PodDisruptionBudgetStatus struct { DisruptedPods map[string]metav1.Time `json:"disruptedPods,omitempty" protobuf:"bytes,2,rep,name=disruptedPods"` // Number of pod disruptions that are currently allowed. + // +optional DisruptionsAllowed int32 `json:"disruptionsAllowed" protobuf:"varint,3,opt,name=disruptionsAllowed"` // current number of healthy pods + // +optional CurrentHealthy int32 `json:"currentHealthy" protobuf:"varint,4,opt,name=currentHealthy"` // minimum desired number of healthy pods + // +optional DesiredHealthy int32 `json:"desiredHealthy" protobuf:"varint,5,opt,name=desiredHealthy"` // total number of pods counted by this disruption budget + // +optional ExpectedPods int32 `json:"expectedPods" protobuf:"varint,6,opt,name=expectedPods"` // Conditions contain conditions for PDB. The disruption controller sets the diff --git a/vendor/k8s.io/api/policy/v1beta1/generated.proto b/vendor/k8s.io/api/policy/v1beta1/generated.proto index e0cbe00f1c..a8200a2d78 100644 --- a/vendor/k8s.io/api/policy/v1beta1/generated.proto +++ b/vendor/k8s.io/api/policy/v1beta1/generated.proto @@ -142,15 +142,19 @@ message PodDisruptionBudgetStatus { map disruptedPods = 2; // Number of pod disruptions that are currently allowed. + // +optional optional int32 disruptionsAllowed = 3; // current number of healthy pods + // +optional optional int32 currentHealthy = 4; // minimum desired number of healthy pods + // +optional optional int32 desiredHealthy = 5; // total number of pods counted by this disruption budget + // +optional optional int32 expectedPods = 6; // Conditions contain conditions for PDB. The disruption controller sets the diff --git a/vendor/k8s.io/api/policy/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/policy/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 01e0847fce..0000000000 --- a/vendor/k8s.io/api/policy/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*Eviction) ProtoMessage() {} - -func (*PodDisruptionBudget) ProtoMessage() {} - -func (*PodDisruptionBudgetList) ProtoMessage() {} - -func (*PodDisruptionBudgetSpec) ProtoMessage() {} - -func (*PodDisruptionBudgetStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/api/policy/v1beta1/types.go b/vendor/k8s.io/api/policy/v1beta1/types.go index 9bba454f94..354c22a3d0 100644 --- a/vendor/k8s.io/api/policy/v1beta1/types.go +++ b/vendor/k8s.io/api/policy/v1beta1/types.go @@ -114,15 +114,19 @@ type PodDisruptionBudgetStatus struct { DisruptedPods map[string]metav1.Time `json:"disruptedPods,omitempty" protobuf:"bytes,2,rep,name=disruptedPods"` // Number of pod disruptions that are currently allowed. + // +optional DisruptionsAllowed int32 `json:"disruptionsAllowed" protobuf:"varint,3,opt,name=disruptionsAllowed"` // current number of healthy pods + // +optional CurrentHealthy int32 `json:"currentHealthy" protobuf:"varint,4,opt,name=currentHealthy"` // minimum desired number of healthy pods + // +optional DesiredHealthy int32 `json:"desiredHealthy" protobuf:"varint,5,opt,name=desiredHealthy"` // total number of pods counted by this disruption budget + // +optional ExpectedPods int32 `json:"expectedPods" protobuf:"varint,6,opt,name=expectedPods"` // Conditions contain conditions for PDB. The disruption controller sets the diff --git a/vendor/k8s.io/api/rbac/v1/generated.proto b/vendor/k8s.io/api/rbac/v1/generated.proto index 56869814ec..7b4ec2afc1 100644 --- a/vendor/k8s.io/api/rbac/v1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1/generated.proto @@ -46,6 +46,7 @@ message ClusterRole { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. @@ -65,11 +66,13 @@ message ClusterRoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. // This field is immutable. + // +required optional RoleRef roleRef = 3; } @@ -98,6 +101,8 @@ message ClusterRoleList { message PolicyRule { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -133,6 +138,7 @@ message Role { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; } @@ -147,11 +153,13 @@ message RoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. // This field is immutable. + // +required optional RoleRef roleRef = 3; } @@ -179,14 +187,16 @@ message RoleList { // +structType=atomic message RoleRef { // APIGroup is the group for the resource being referenced + // +optional optional string apiGroup = 1; // Kind is the type of resource being referenced + // +required optional string kind = 2; // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; } @@ -196,6 +206,7 @@ message RoleRef { message Subject { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required optional string kind = 1; // APIGroup holds the API group of the referenced subject. @@ -206,7 +217,7 @@ message Subject { // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty diff --git a/vendor/k8s.io/api/rbac/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/rbac/v1/generated.protomessage.pb.go deleted file mode 100644 index 6e29e012fa..0000000000 --- a/vendor/k8s.io/api/rbac/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AggregationRule) ProtoMessage() {} - -func (*ClusterRole) ProtoMessage() {} - -func (*ClusterRoleBinding) ProtoMessage() {} - -func (*ClusterRoleBindingList) ProtoMessage() {} - -func (*ClusterRoleList) ProtoMessage() {} - -func (*PolicyRule) ProtoMessage() {} - -func (*Role) ProtoMessage() {} - -func (*RoleBinding) ProtoMessage() {} - -func (*RoleBindingList) ProtoMessage() {} - -func (*RoleList) ProtoMessage() {} - -func (*RoleRef) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/rbac/v1/types.go b/vendor/k8s.io/api/rbac/v1/types.go index 2fde11b306..d3bb6d1a9c 100644 --- a/vendor/k8s.io/api/rbac/v1/types.go +++ b/vendor/k8s.io/api/rbac/v1/types.go @@ -49,6 +49,8 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -79,6 +81,7 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIGroup holds the API group of the referenced subject. // Defaults to "" for ServiceAccount subjects. @@ -87,7 +90,7 @@ type Subject struct { APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt,name=apiGroup"` // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty // the Authorizer should report an error. @@ -99,12 +102,14 @@ type Subject struct { // +structType=atomic type RoleRef struct { // APIGroup is the group for the resource being referenced + // +optional APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` } @@ -122,6 +127,7 @@ type Role struct { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` } @@ -141,11 +147,13 @@ type RoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. // This field is immutable. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } @@ -192,6 +200,7 @@ type ClusterRole struct { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. @@ -226,11 +235,13 @@ type ClusterRoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. // This field is immutable. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } diff --git a/vendor/k8s.io/api/rbac/v1alpha1/generated.proto b/vendor/k8s.io/api/rbac/v1alpha1/generated.proto index f787f3976e..9551d11921 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1alpha1/generated.proto @@ -47,6 +47,7 @@ message ClusterRole { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. @@ -67,10 +68,12 @@ message ClusterRoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required optional RoleRef roleRef = 3; } @@ -101,6 +104,8 @@ message ClusterRoleList { message PolicyRule { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -137,6 +142,7 @@ message Role { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; } @@ -152,10 +158,12 @@ message RoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required optional RoleRef roleRef = 3; } @@ -184,14 +192,16 @@ message RoleList { // RoleRef contains information that points to the role being used message RoleRef { // APIGroup is the group for the resource being referenced + // +optional optional string apiGroup = 1; // Kind is the type of resource being referenced + // +required optional string kind = 2; // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; } @@ -200,6 +210,7 @@ message RoleRef { message Subject { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required optional string kind = 1; // APIVersion holds the API group and version of the referenced subject. @@ -211,7 +222,7 @@ message Subject { // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty diff --git a/vendor/k8s.io/api/rbac/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/rbac/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index 20f8d575ea..0000000000 --- a/vendor/k8s.io/api/rbac/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*AggregationRule) ProtoMessage() {} - -func (*ClusterRole) ProtoMessage() {} - -func (*ClusterRoleBinding) ProtoMessage() {} - -func (*ClusterRoleBindingList) ProtoMessage() {} - -func (*ClusterRoleList) ProtoMessage() {} - -func (*PolicyRule) ProtoMessage() {} - -func (*Role) ProtoMessage() {} - -func (*RoleBinding) ProtoMessage() {} - -func (*RoleBindingList) ProtoMessage() {} - -func (*RoleList) ProtoMessage() {} - -func (*RoleRef) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/rbac/v1alpha1/types.go b/vendor/k8s.io/api/rbac/v1alpha1/types.go index a0d52ee4fc..4ff4c06015 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/types.go +++ b/vendor/k8s.io/api/rbac/v1alpha1/types.go @@ -49,6 +49,8 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -78,6 +80,7 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIVersion holds the API group and version of the referenced subject. // Defaults to "v1" for ServiceAccount subjects. @@ -87,7 +90,7 @@ type Subject struct { APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"` // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty // the Authorizer should report an error. @@ -98,12 +101,14 @@ type Subject struct { // RoleRef contains information that points to the role being used type RoleRef struct { // APIGroup is the group for the resource being referenced + // +optional APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` } @@ -121,6 +126,7 @@ type Role struct { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` } @@ -140,10 +146,12 @@ type RoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } @@ -190,6 +198,7 @@ type ClusterRole struct { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. @@ -224,10 +233,12 @@ type ClusterRoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } diff --git a/vendor/k8s.io/api/rbac/v1beta1/generated.proto b/vendor/k8s.io/api/rbac/v1beta1/generated.proto index cac7b413e8..326f312ec4 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/generated.proto +++ b/vendor/k8s.io/api/rbac/v1beta1/generated.proto @@ -47,6 +47,7 @@ message ClusterRole { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. @@ -67,10 +68,12 @@ message ClusterRoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required optional RoleRef roleRef = 3; } @@ -101,6 +104,8 @@ message ClusterRoleList { message PolicyRule { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required repeated string verbs = 1; // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -138,6 +143,7 @@ message Role { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated PolicyRule rules = 2; } @@ -153,10 +159,12 @@ message RoleBinding { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional repeated Subject subjects = 2; // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required optional RoleRef roleRef = 3; } @@ -185,14 +193,16 @@ message RoleList { // RoleRef contains information that points to the role being used message RoleRef { // APIGroup is the group for the resource being referenced + // +optional optional string apiGroup = 1; // Kind is the type of resource being referenced + // +required optional string kind = 2; // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; } @@ -201,6 +211,7 @@ message RoleRef { message Subject { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required optional string kind = 1; // APIGroup holds the API group of the referenced subject. @@ -211,7 +222,7 @@ message Subject { // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string name = 3; // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty diff --git a/vendor/k8s.io/api/rbac/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/rbac/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index b298968367..0000000000 --- a/vendor/k8s.io/api/rbac/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*AggregationRule) ProtoMessage() {} - -func (*ClusterRole) ProtoMessage() {} - -func (*ClusterRoleBinding) ProtoMessage() {} - -func (*ClusterRoleBindingList) ProtoMessage() {} - -func (*ClusterRoleList) ProtoMessage() {} - -func (*PolicyRule) ProtoMessage() {} - -func (*Role) ProtoMessage() {} - -func (*RoleBinding) ProtoMessage() {} - -func (*RoleBindingList) ProtoMessage() {} - -func (*RoleList) ProtoMessage() {} - -func (*RoleRef) ProtoMessage() {} - -func (*Subject) ProtoMessage() {} diff --git a/vendor/k8s.io/api/rbac/v1beta1/types.go b/vendor/k8s.io/api/rbac/v1beta1/types.go index 861e33c975..c653d071fe 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/types.go +++ b/vendor/k8s.io/api/rbac/v1beta1/types.go @@ -49,6 +49,8 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic + // +required + // +k8s:alpha(since: "1.36")=+k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of @@ -79,6 +81,7 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIGroup holds the API group of the referenced subject. // Defaults to "" for ServiceAccount subjects. @@ -87,7 +90,7 @@ type Subject struct { APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt,name=apiGroup"` // Name of the object being referenced. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty // the Authorizer should report an error. @@ -98,12 +101,14 @@ type Subject struct { // RoleRef contains information that points to the role being used type RoleRef struct { // APIGroup is the group for the resource being referenced + // +optional APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` } @@ -125,6 +130,7 @@ type Role struct { // Rules holds all the PolicyRules for this Role // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` } @@ -148,10 +154,12 @@ type RoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } @@ -210,6 +218,7 @@ type ClusterRole struct { // Rules holds all the PolicyRules for this ClusterRole // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` // AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. // If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be @@ -247,10 +256,12 @@ type ClusterRoleBinding struct { // Subjects holds references to the objects the role applies to. // +optional // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"` // RoleRef can only reference a ClusterRole in the global namespace. // If the RoleRef cannot be resolved, the Authorizer must return an error. + // +required RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` } diff --git a/vendor/k8s.io/api/resource/v1/generated.pb.go b/vendor/k8s.io/api/resource/v1/generated.pb.go index e690204905..f59e829057 100644 --- a/vendor/k8s.io/api/resource/v1/generated.pb.go +++ b/vendor/k8s.io/api/resource/v1/generated.pb.go @@ -25,6 +25,7 @@ import ( io "io" "sort" + k8s_io_api_core_v1 "k8s.io/api/core/v1" v11 "k8s.io/api/core/v1" resource "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -97,6 +98,8 @@ func (m *ExactDeviceRequest) Reset() { *m = ExactDeviceRequest{} } func (m *NetworkDeviceData) Reset() { *m = NetworkDeviceData{} } +func (m *NodeAllocatableResourceMapping) Reset() { *m = NodeAllocatableResourceMapping{} } + func (m *OpaqueDeviceConfiguration) Reset() { *m = OpaqueDeviceConfiguration{} } func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } @@ -573,6 +576,35 @@ func (m *Device) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.NodeAllocatableResourceMappings) > 0 { + keysForNodeAllocatableResourceMappings := make([]string, 0, len(m.NodeAllocatableResourceMappings)) + for k := range m.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + for iNdEx := len(keysForNodeAllocatableResourceMappings) - 1; iNdEx >= 0; iNdEx-- { + v := m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(keysForNodeAllocatableResourceMappings[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForNodeAllocatableResourceMappings[iNdEx]) + copy(dAtA[i:], keysForNodeAllocatableResourceMappings[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForNodeAllocatableResourceMappings[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x6a + } + } if m.AllowMultipleAllocations != nil { i-- if *m.AllowMultipleAllocations { @@ -852,6 +884,43 @@ func (m *DeviceAttribute) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.VersionValues) > 0 { + for iNdEx := len(m.VersionValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.VersionValues[iNdEx]) + copy(dAtA[i:], m.VersionValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.VersionValues[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(m.StringValues) > 0 { + for iNdEx := len(m.StringValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.StringValues[iNdEx]) + copy(dAtA[i:], m.StringValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.StringValues[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.BoolValues) > 0 { + for iNdEx := len(m.BoolValues) - 1; iNdEx >= 0; iNdEx-- { + i-- + if m.BoolValues[iNdEx] { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + } + if len(m.IntValues) > 0 { + for iNdEx := len(m.IntValues) - 1; iNdEx >= 0; iNdEx-- { + i = encodeVarintGenerated(dAtA, i, uint64(m.IntValues[iNdEx])) + i-- + dAtA[i] = 0x30 + } + } if m.VersionValue != nil { i -= len(*m.VersionValue) copy(dAtA[i:], *m.VersionValue) @@ -1872,6 +1941,48 @@ func (m *NetworkDeviceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NodeAllocatableResourceMapping) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeAllocatableResourceMapping) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeAllocatableResourceMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AllocationMultiplier != nil { + { + size, err := m.AllocationMultiplier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.CapacityKey != nil { + i -= len(*m.CapacityKey) + copy(dAtA[i:], *m.CapacityKey) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.CapacityKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2745,6 +2856,15 @@ func (m *Device) Size() (n int) { if m.AllowMultipleAllocations != nil { n += 2 } + if len(m.NodeAllocatableResourceMappings) > 0 { + for k, v := range m.NodeAllocatableResourceMappings { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } return n } @@ -2808,6 +2928,26 @@ func (m *DeviceAttribute) Size() (n int) { l = len(*m.VersionValue) n += 1 + l + sovGenerated(uint64(l)) } + if len(m.IntValues) > 0 { + for _, e := range m.IntValues { + n += 1 + sovGenerated(uint64(e)) + } + } + if len(m.BoolValues) > 0 { + n += 2 * len(m.BoolValues) + } + if len(m.StringValues) > 0 { + for _, s := range m.StringValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.VersionValues) > 0 { + for _, s := range m.VersionValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -3200,6 +3340,23 @@ func (m *NetworkDeviceData) Size() (n int) { return n } +func (m *NodeAllocatableResourceMapping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CapacityKey != nil { + l = len(*m.CapacityKey) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.AllocationMultiplier != nil { + l = m.AllocationMultiplier.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *OpaqueDeviceConfiguration) Size() (n int) { if m == nil { return 0 @@ -3586,6 +3743,16 @@ func (this *Device) String() string { mapStringForCapacity += fmt.Sprintf("%v: %v,", k, this.Capacity[QualifiedName(k)]) } mapStringForCapacity += "}" + keysForNodeAllocatableResourceMappings := make([]string, 0, len(this.NodeAllocatableResourceMappings)) + for k := range this.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + mapStringForNodeAllocatableResourceMappings := "map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping{" + for _, k := range keysForNodeAllocatableResourceMappings { + mapStringForNodeAllocatableResourceMappings += fmt.Sprintf("%v: %v,", k, this.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(k)]) + } + mapStringForNodeAllocatableResourceMappings += "}" s := strings.Join([]string{`&Device{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Attributes:` + mapStringForAttributes + `,`, @@ -3599,6 +3766,7 @@ func (this *Device) String() string { `BindingConditions:` + fmt.Sprintf("%v", this.BindingConditions) + `,`, `BindingFailureConditions:` + fmt.Sprintf("%v", this.BindingFailureConditions) + `,`, `AllowMultipleAllocations:` + valueToStringGenerated(this.AllowMultipleAllocations) + `,`, + `NodeAllocatableResourceMappings:` + mapStringForNodeAllocatableResourceMappings + `,`, `}`, }, "") return s @@ -3645,6 +3813,10 @@ func (this *DeviceAttribute) String() string { `BoolValue:` + valueToStringGenerated(this.BoolValue) + `,`, `StringValue:` + valueToStringGenerated(this.StringValue) + `,`, `VersionValue:` + valueToStringGenerated(this.VersionValue) + `,`, + `IntValues:` + fmt.Sprintf("%v", this.IntValues) + `,`, + `BoolValues:` + fmt.Sprintf("%v", this.BoolValues) + `,`, + `StringValues:` + fmt.Sprintf("%v", this.StringValues) + `,`, + `VersionValues:` + fmt.Sprintf("%v", this.VersionValues) + `,`, `}`, }, "") return s @@ -3939,6 +4111,17 @@ func (this *NetworkDeviceData) String() string { }, "") return s } +func (this *NodeAllocatableResourceMapping) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeAllocatableResourceMapping{`, + `CapacityKey:` + valueToStringGenerated(this.CapacityKey) + `,`, + `AllocationMultiplier:` + strings.Replace(fmt.Sprintf("%v", this.AllocationMultiplier), "Quantity", "resource.Quantity", 1) + `,`, + `}`, + }, "") + return s +} func (this *OpaqueDeviceConfiguration) String() string { if this == nil { return "nil" @@ -6027,6 +6210,135 @@ func (m *Device) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.AllowMultipleAllocations = &b + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeAllocatableResourceMappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeAllocatableResourceMappings == nil { + m.NodeAllocatableResourceMappings = make(map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping) + } + var mapkey k8s_io_api_core_v1.ResourceName + mapvalue := &NodeAllocatableResourceMapping{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &NodeAllocatableResourceMapping{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -6449,6 +6761,216 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.VersionValue = &s iNdEx = postIndex + case 6: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValues = append(m.IntValues, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.IntValues) == 0 { + m.IntValues = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValues = append(m.IntValues, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field IntValues", wireType) + } + case 7: + if wireType == 0 { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + elementCount = packedLen + if elementCount != 0 && len(m.BoolValues) == 0 { + m.BoolValues = make([]bool, 0, elementCount) + } + for iNdEx < postIndex { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field BoolValues", wireType) + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StringValues = append(m.StringValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VersionValues = append(m.VersionValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9518,6 +10040,125 @@ func (m *NetworkDeviceData) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeAllocatableResourceMapping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CapacityKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := QualifiedName(dAtA[iNdEx:postIndex]) + m.CapacityKey = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMultiplier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AllocationMultiplier == nil { + m.AllocationMultiplier = &resource.Quantity{} + } + if err := m.AllocationMultiplier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *OpaqueDeviceConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/resource/v1/generated.proto b/vendor/k8s.io/api/resource/v1/generated.proto index c254137c43..8bacfd846f 100644 --- a/vendor/k8s.io/api/resource/v1/generated.proto +++ b/vendor/k8s.io/api/resource/v1/generated.proto @@ -65,8 +65,8 @@ message AllocatedDeviceStatus { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 7; // Conditions contains the latest observation of the device's state. @@ -90,7 +90,7 @@ message AllocatedDeviceStatus { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional NetworkDeviceData networkData = 6; } @@ -110,7 +110,7 @@ message AllocationResult { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -169,6 +169,14 @@ message CELDeviceSelector { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -307,8 +315,8 @@ message CounterSet { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string name = 1; // Counters defines the set of counters for this CounterSet @@ -317,6 +325,8 @@ message CounterSet { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -335,6 +345,7 @@ message Device { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional map attributes = 2; // Capacity defines the set of capacities for this device. @@ -355,13 +366,13 @@ message Device { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 repeated DeviceCounterConsumption consumesCounters = 4; // NodeName identifies the node where the device is available. @@ -402,12 +413,13 @@ message Device { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceTaint taints = 8; // BindsToNode indicates if the usage of an allocation involving this device @@ -415,7 +427,7 @@ message Device { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -431,14 +443,14 @@ message Device { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 10; // BindingFailureConditions defines the conditions for binding failure. @@ -449,14 +461,14 @@ message Device { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 11; // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -467,6 +479,21 @@ message Device { // +optional // +featureGate=DRAConsumableCapacity optional bool allowMultipleAllocations = 12; + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + map nodeAllocatableResourceMappings = 13; } // DeviceAllocationConfiguration gets embedded in an AllocationResult. @@ -476,7 +503,7 @@ message DeviceAllocationConfiguration { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string source = 1; // Requests lists the names of requests where the configuration applies. @@ -488,10 +515,10 @@ message DeviceAllocationConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 2; optional DeviceConfiguration deviceConfiguration = 3; @@ -503,8 +530,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequestAllocationResult results = 1; // This field is a combination of all the claim and class configuration parameters. @@ -517,8 +544,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 repeated DeviceAllocationConfiguration config = 2; } @@ -527,31 +554,79 @@ message DeviceAttribute { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional int64 int = 2; // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional bool bool = 3; // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string string = 4; // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string version = 5; + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated int64 ints = 6; + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated bool bools = 7; + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string strings = 8; + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string versions = 9; } // DeviceCapacity describes a quantity associated with a device. @@ -587,11 +662,11 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequest requests = 1; // These constraints must be satisfied by the set of devices that get @@ -599,8 +674,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceConstraint constraints = 2; // This field holds configuration for multiple potential drivers which @@ -609,8 +684,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClaimConfiguration config = 3; } @@ -625,10 +700,10 @@ message DeviceClaimConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; optional DeviceConfiguration deviceConfiguration = 2; @@ -638,14 +713,11 @@ message DeviceClaimConfiguration { // device configuration and selectors. It can be referenced in // the device requests of a claim to apply these presets. // Cluster scoped. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. message DeviceClass { // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec defines what can be allocated and how to configure it. @@ -681,8 +753,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 1; // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -693,8 +765,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClassConfiguration config = 2; // ExtendedResourceName is the extended resource name for the devices of this class. @@ -706,11 +778,11 @@ message DeviceClassSpec { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name optional string extendedResourceName = 4; } @@ -722,7 +794,7 @@ message DeviceConfiguration { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional OpaqueDeviceConfiguration opaque = 1; } @@ -740,10 +812,10 @@ message DeviceConstraint { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; // MatchAttribute requires that all devices in question have this @@ -757,17 +829,27 @@ message DeviceConstraint { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as single-element lists for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name optional string matchAttribute = 2; // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -789,8 +871,8 @@ message DeviceCounterConsumption { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string counterSet = 1; // Counters defines the counters that will be consumed by the device. @@ -798,6 +880,8 @@ message DeviceCounterConsumption { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -827,7 +911,7 @@ message DeviceRequest { // // +optional // +oneOf=deviceRequestType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional ExactDeviceRequest exactly = 2; // FirstAvailable contains subrequests, of which exactly one will be @@ -848,11 +932,11 @@ message DeviceRequest { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated DeviceSubRequest firstAvailable = 3; } @@ -877,8 +961,9 @@ message DeviceRequestAllocationResult { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string driver = 2; // This name together with the driver name and the device name field @@ -888,8 +973,8 @@ message DeviceRequestAllocationResult { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name optional string pool = 3; // Device references one device instance via its name in the driver's @@ -902,8 +987,7 @@ message DeviceRequestAllocationResult { // administrative access. See the corresponding request field // for a definition of mode. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. // // +optional @@ -915,38 +999,39 @@ message DeviceRequestAllocationResult { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 7; // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 8; // ShareID uniquely identifies an individual allocation share of the device, @@ -956,8 +1041,8 @@ message DeviceRequestAllocationResult { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 9; // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1014,8 +1099,8 @@ message DeviceSubRequest { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name optional string deviceClassName = 2; // Selectors define criteria which must be satisfied by a specific @@ -1025,8 +1110,8 @@ message DeviceSubRequest { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 3; // AllocationMode and its related fields define how devices are allocated @@ -1048,6 +1133,7 @@ message DeviceSubRequest { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 4; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1072,12 +1158,13 @@ message DeviceSubRequest { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // Capacity define resource requirements against each capacity. @@ -1124,12 +1211,21 @@ message DeviceTaint { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string effect = 3; - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; } @@ -1142,8 +1238,8 @@ message DeviceToleration { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key optional string key = 1; // Operator represents a key's relationship to the value. @@ -1153,6 +1249,7 @@ message DeviceToleration { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional optional string operator = 2; // Value is the taint value the toleration matches to. @@ -1166,6 +1263,7 @@ message DeviceToleration { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string effect = 4; // TolerationSeconds represents the period of time the toleration (which must be @@ -1203,8 +1301,8 @@ message ExactDeviceRequest { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 2; // AllocationMode and its related fields define how devices are allocated @@ -1227,7 +1325,7 @@ message ExactDeviceRequest { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 3; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1243,8 +1341,7 @@ message ExactDeviceRequest { // all ordinary claims to the device with respect to access modes and // any resource allocations. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. // // +optional @@ -1266,12 +1363,13 @@ message ExactDeviceRequest { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // Capacity define resource requirements against each capacity. @@ -1300,11 +1398,11 @@ message NetworkDeviceData { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 optional string interfaceName = 1; // IPs lists the network addresses assigned to the device's network interface. @@ -1315,22 +1413,60 @@ message NetworkDeviceData { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 repeated string ips = 2; // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 optional string hardwareAddress = 3; } +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +message NodeAllocatableResourceMapping { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + optional string capacityKey = 1; + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + optional .k8s.io.apimachinery.pkg.api.resource.Quantity allocationMultiplier = 2; +} + // OpaqueDeviceConfiguration contains configuration parameters for a driver // in a format defined by the driver vendor. message OpaqueDeviceConfiguration { @@ -1344,8 +1480,9 @@ message OpaqueDeviceConfiguration { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string driver = 1; // Parameters can contain arbitrary data. It is the responsibility of @@ -1364,9 +1501,6 @@ message OpaqueDeviceConfiguration { // with specific properties, this is how that request is expressed. The status // stanza tracks whether this claim has been satisfied and what specific // resources have been allocated. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. message ResourceClaim { // Standard object metadata // +optional @@ -1374,7 +1508,7 @@ message ResourceClaim { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable optional ResourceClaimSpec spec = 2; // Status describes whether the claim is ready to use and what has been allocated. @@ -1429,8 +1563,8 @@ message ResourceClaimStatus { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify optional AllocationResult allocation = 1; // ReservedFor indicates which entities are currently allowed to use @@ -1458,10 +1592,10 @@ message ResourceClaimStatus { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 repeated ResourceClaimConsumerReference reservedFor = 2; // Devices contains the status of each device allocated for this @@ -1469,25 +1603,22 @@ message ResourceClaimStatus { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID repeated AllocatedDeviceStatus devices = 4; } // ResourceClaimTemplate is used to produce ResourceClaim objects. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. message ResourceClaimTemplate { // Standard object metadata // +optional @@ -1583,9 +1714,6 @@ message ResourcePool { // // For resources that are not local to a node, the node name is not set. Instead, // the driver may use a node selector to specify where the devices are available. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. message ResourceSlice { // Standard object metadata // +optional @@ -1594,6 +1722,7 @@ message ResourceSlice { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required optional ResourceSliceSpec spec = 2; } @@ -1668,7 +1797,7 @@ message ResourceSliceSpec { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType repeated Device devices = 6; @@ -1694,14 +1823,14 @@ message ResourceSliceSpec { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated CounterSet sharedCounters = 8; } diff --git a/vendor/k8s.io/api/resource/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/resource/v1/generated.protomessage.pb.go deleted file mode 100644 index 97035a9360..0000000000 --- a/vendor/k8s.io/api/resource/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AllocatedDeviceStatus) ProtoMessage() {} - -func (*AllocationResult) ProtoMessage() {} - -func (*CELDeviceSelector) ProtoMessage() {} - -func (*CapacityRequestPolicy) ProtoMessage() {} - -func (*CapacityRequestPolicyRange) ProtoMessage() {} - -func (*CapacityRequirements) ProtoMessage() {} - -func (*Counter) ProtoMessage() {} - -func (*CounterSet) ProtoMessage() {} - -func (*Device) ProtoMessage() {} - -func (*DeviceAllocationConfiguration) ProtoMessage() {} - -func (*DeviceAllocationResult) ProtoMessage() {} - -func (*DeviceAttribute) ProtoMessage() {} - -func (*DeviceCapacity) ProtoMessage() {} - -func (*DeviceClaim) ProtoMessage() {} - -func (*DeviceClaimConfiguration) ProtoMessage() {} - -func (*DeviceClass) ProtoMessage() {} - -func (*DeviceClassConfiguration) ProtoMessage() {} - -func (*DeviceClassList) ProtoMessage() {} - -func (*DeviceClassSpec) ProtoMessage() {} - -func (*DeviceConfiguration) ProtoMessage() {} - -func (*DeviceConstraint) ProtoMessage() {} - -func (*DeviceCounterConsumption) ProtoMessage() {} - -func (*DeviceRequest) ProtoMessage() {} - -func (*DeviceRequestAllocationResult) ProtoMessage() {} - -func (*DeviceSelector) ProtoMessage() {} - -func (*DeviceSubRequest) ProtoMessage() {} - -func (*DeviceTaint) ProtoMessage() {} - -func (*DeviceToleration) ProtoMessage() {} - -func (*ExactDeviceRequest) ProtoMessage() {} - -func (*NetworkDeviceData) ProtoMessage() {} - -func (*OpaqueDeviceConfiguration) ProtoMessage() {} - -func (*ResourceClaim) ProtoMessage() {} - -func (*ResourceClaimConsumerReference) ProtoMessage() {} - -func (*ResourceClaimList) ProtoMessage() {} - -func (*ResourceClaimSpec) ProtoMessage() {} - -func (*ResourceClaimStatus) ProtoMessage() {} - -func (*ResourceClaimTemplate) ProtoMessage() {} - -func (*ResourceClaimTemplateList) ProtoMessage() {} - -func (*ResourceClaimTemplateSpec) ProtoMessage() {} - -func (*ResourcePool) ProtoMessage() {} - -func (*ResourceSlice) ProtoMessage() {} - -func (*ResourceSliceList) ProtoMessage() {} - -func (*ResourceSliceSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/resource/v1/types.go b/vendor/k8s.io/api/resource/v1/types.go index 29b4a5fbac..27d5eff29c 100644 --- a/vendor/k8s.io/api/resource/v1/types.go +++ b/vendor/k8s.io/api/resource/v1/types.go @@ -35,6 +35,11 @@ const ( // special ResourceClaim. Its single valid value is "true". // This is used only inside the scheduler. ExtendedResourceClaimAnnotation = "resource.kubernetes.io/extended-resource-claim" + // PodResourceClaimAnnotation is the annotation set on template-generated + // ResourceClaims by the ResourceClaim controller. Its value is the + // spec.resourceClaims[].name of the Pod or PodGroup for which the claim was + // generated. The Pod and its PodGroup are guaranteed to use the same name. + PodResourceClaimAnnotation = "resource.kubernetes.io/pod-claim-name" // Resource device class prefix is for generating implicit extended resource // name for a device class when its ExtendedResourceName field is not // specified. The generated name is this prefix + the device class name. @@ -42,6 +47,23 @@ const ( // in pod.Spec.Resources.Requests, in that case, a valid name has to be specified // explicitly in device class. ResourceDeviceClassPrefix string = "deviceclass.resource.kubernetes.io/" + + // The constants below are all related to synthetic authorization checks for resourceclaims.status writes. + + // SubresourceBinding is the synthetic subresource used for authorization + // of updates to status.allocation and status.reservedFor. + SubresourceBinding = "binding" + // SubresourceDriver is the synthetic subresource used for per-driver + // authorization of updates to status.devices. + SubresourceDriver = "driver" + // VerbPrefixAssociatedNode is the verb prefix for requests from a service account + // on the same node as the claim's allocation. The full verb is + // "associated-node:", e.g. "associated-node:update". + VerbPrefixAssociatedNode = "associated-node:" + // VerbPrefixArbitraryNode is the verb prefix for requests not associated + // with a specific node (controllers, etc.). The full verb is + // "arbitrary-node:", e.g. "arbitrary-node:update". + VerbPrefixArbitraryNode = "arbitrary-node:" ) // +genclient @@ -70,9 +92,6 @@ const ( // // For resources that are not local to a node, the node name is not set. Instead, // the driver may use a node selector to specify where the devices are available. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceSlice struct { metav1.TypeMeta `json:",inline"` // Standard object metadata @@ -82,6 +101,7 @@ type ResourceSlice struct { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required Spec ResourceSliceSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -155,7 +175,7 @@ type ResourceSliceSpec struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType Devices []Device `json:"devices,omitempty" protobuf:"bytes,6,name=devices"` @@ -181,14 +201,14 @@ type ResourceSliceSpec struct { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 SharedCounters []CounterSet `json:"sharedCounters,omitempty" protobuf:"bytes,8,name=sharedCounters"` } @@ -205,8 +225,8 @@ type CounterSet struct { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name Name string `json:"name" protobuf:"bytes,1,name=name"` // Counters defines the set of counters for this CounterSet @@ -215,6 +235,8 @@ type CounterSet struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,name=counters"` } @@ -261,7 +283,14 @@ type ResourcePool struct { const ResourceSliceMaxSharedCapacity = 128 const ResourceSliceMaxDevices = 128 -const ResourceSliceMaxDevicesWithTaintsOrConsumesCounters = 64 + +// ResourceSliceMaxDevicesWithAdvancedFeatures defines the maximum number of devices in a ResourceSlice +// if any of those devices uses advanced features: +// - device taints (DRADeviceTaints feature gate) +// - consuming counters (DRAPartitionableDevices feature gate) +// - list attributes (DRAListTypeAttributes feature gate) +const ResourceSliceMaxDevicesWithAdvancedFeatures = 64 + const PoolNameMaxLength = validation.DNS1123SubdomainMaxLength // Same as for a single node name. const BindingConditionsMaxSize = 4 const BindingFailureConditionsMaxSize = 4 @@ -298,6 +327,7 @@ type Device struct { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Attributes map[QualifiedName]DeviceAttribute `json:"attributes,omitempty" protobuf:"bytes,2,rep,name=attributes"` // Capacity defines the set of capacities for this device. @@ -318,13 +348,13 @@ type Device struct { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 ConsumesCounters []DeviceCounterConsumption `json:"consumesCounters,omitempty" protobuf:"bytes,4,rep,name=consumesCounters"` // NodeName identifies the node where the device is available. @@ -365,12 +395,13 @@ type Device struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Taints []DeviceTaint `json:"taints,omitempty" protobuf:"bytes,8,rep,name=taints"` // BindsToNode indicates if the usage of an allocation involving this device @@ -378,7 +409,7 @@ type Device struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -394,14 +425,14 @@ type Device struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,10,rep,name=bindingConditions"` // BindingFailureConditions defines the conditions for binding failure. @@ -412,14 +443,14 @@ type Device struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,11,rep,name=bindingFailureConditions"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -430,6 +461,59 @@ type Device struct { // +optional // +featureGate=DRAConsumableCapacity AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty" protobuf:"bytes,12,opt,name=allowMultipleAllocations"` + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + NodeAllocatableResourceMappings map[v1.ResourceName]NodeAllocatableResourceMapping `json:"nodeAllocatableResourceMappings,omitempty" protobuf:"bytes,13,opt,name=nodeAllocatableResourceMappings"` +} + +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMapping struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + CapacityKey *QualifiedName `json:"capacityKey,omitempty" protobuf:"bytes,1,opt,name=capacityKey"` + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty" protobuf:"bytes,2,opt,name=allocationMultiplier"` } // DeviceCounterConsumption defines a set of counters that @@ -439,8 +523,8 @@ type DeviceCounterConsumption struct { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name CounterSet string `json:"counterSet" protobuf:"bytes,1,opt,name=counterSet"` // Counters defines the counters that will be consumed by the device. @@ -448,6 +532,8 @@ type DeviceCounterConsumption struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,opt,name=counters"` } @@ -568,6 +654,10 @@ type CapacityRequestPolicyRange struct { // Limit for the sum of the number of entries in both attributes and capacity. const ResourceSliceMaxAttributesAndCapacitiesPerDevice = 32 +// Limit per device for the total number of string, version, bool or int values +// in list and non-list attributes. +const ResourceSliceMaxAttributeValuesPerDevice = 48 + // QualifiedName is the name of a device attribute or capacity. // // Attributes and capacities are defined either by the owner of the specific @@ -607,31 +697,79 @@ type DeviceAttribute struct { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember IntValue *int64 `json:"int,omitempty" protobuf:"varint,2,opt,name=int"` // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember BoolValue *bool `json:"bool,omitempty" protobuf:"varint,3,opt,name=bool"` // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember StringValue *string `json:"string,omitempty" protobuf:"bytes,4,opt,name=string"` // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember VersionValue *string `json:"version,omitempty" protobuf:"bytes,5,opt,name=version"` + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + IntValues []int64 `json:"ints,omitempty" protobuf:"varint,6,opt,name=ints"` + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + BoolValues []bool `json:"bools,omitempty" protobuf:"varint,7,opt,name=bools"` + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + StringValues []string `json:"strings,omitempty" protobuf:"bytes,8,opt,name=strings"` + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + VersionValues []string `json:"versions,omitempty" protobuf:"bytes,9,opt,name=versions"` } // DeviceAttributeMaxValueLength is the maximum length of a string or version attribute value. @@ -666,7 +804,7 @@ type DeviceTaint struct { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Effect DeviceTaintEffect `json:"effect" protobuf:"bytes,3,name=effect,casttype=DeviceTaintEffect"` // ^^^^ @@ -682,9 +820,18 @@ type DeviceTaint struct { // which will enable adding new enums within a single release without // ratcheting. - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional TimeAdded *metav1.Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` @@ -696,7 +843,7 @@ type DeviceTaint struct { } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTaintEffect string const ( @@ -729,16 +876,13 @@ type ResourceSliceList struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.34 -// +k8s:supportsSubresource=/status +// +k8s:supportsSubresource="/status" // ResourceClaim describes a request for access to resources in the cluster, // for use by workloads. For example, if a workload needs an accelerator device // with specific properties, this is how that request is expressed. The status // stanza tracks whether this claim has been satisfied and what specific // resources have been allocated. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceClaim struct { metav1.TypeMeta `json:",inline"` // Standard object metadata @@ -747,7 +891,7 @@ type ResourceClaim struct { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable Spec ResourceClaimSpec `json:"spec" protobuf:"bytes,2,name=spec"` // Status describes whether the claim is ready to use and what has been allocated. @@ -775,11 +919,11 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []DeviceRequest `json:"requests" protobuf:"bytes,1,name=requests"` // These constraints must be satisfied by the set of devices that get @@ -787,8 +931,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Constraints []DeviceConstraint `json:"constraints,omitempty" protobuf:"bytes,2,opt,name=constraints"` // This field holds configuration for multiple potential drivers which @@ -797,8 +941,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClaimConfiguration `json:"config,omitempty" protobuf:"bytes,3,opt,name=config"` // Potential future extension, ignored by older schedulers. This is @@ -849,7 +993,7 @@ type DeviceRequest struct { // // +optional // +oneOf=deviceRequestType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional Exactly *ExactDeviceRequest `json:"exactly,omitempty" protobuf:"bytes,2,name=exactly"` // FirstAvailable contains subrequests, of which exactly one will be @@ -870,11 +1014,11 @@ type DeviceRequest struct { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 FirstAvailable []DeviceSubRequest `json:"firstAvailable,omitempty" protobuf:"bytes,3,name=firstAvailable"` } @@ -902,8 +1046,8 @@ type ExactDeviceRequest struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,2,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -926,7 +1070,7 @@ type ExactDeviceRequest struct { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,3,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -942,8 +1086,7 @@ type ExactDeviceRequest struct { // all ordinary claims to the device with respect to access modes and // any resource allocations. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. // // +optional @@ -965,12 +1108,13 @@ type ExactDeviceRequest struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1022,8 +1166,8 @@ type DeviceSubRequest struct { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name DeviceClassName string `json:"deviceClassName" protobuf:"bytes,2,name=deviceClassName"` // Selectors define criteria which must be satisfied by a specific @@ -1033,8 +1177,8 @@ type DeviceSubRequest struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -1056,6 +1200,7 @@ type DeviceSubRequest struct { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1080,12 +1225,13 @@ type DeviceSubRequest struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1142,7 +1288,7 @@ const ( ) // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceAllocationMode string // Valid [DeviceRequest.CountMode] values. @@ -1211,6 +1357,14 @@ type CELDeviceSelector struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -1261,10 +1415,10 @@ type DeviceConstraint struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` // MatchAttribute requires that all devices in question have this @@ -1278,12 +1432,17 @@ type DeviceConstraint struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as single-element lists for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name MatchAttribute *FullyQualifiedName `json:"matchAttribute,omitempty" protobuf:"bytes,2,opt,name=matchAttribute"` // Potential future extension, not part of the current design: @@ -1299,6 +1458,11 @@ type DeviceConstraint struct { // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -1324,10 +1488,10 @@ type DeviceClaimConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,2,name=deviceConfiguration"` @@ -1341,7 +1505,7 @@ type DeviceConfiguration struct { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional Opaque *OpaqueDeviceConfiguration `json:"opaque,omitempty" protobuf:"bytes,1,opt,name=opaque"` } @@ -1358,8 +1522,9 @@ type OpaqueDeviceConfiguration struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Driver string `json:"driver" protobuf:"bytes,1,name=driver"` // Parameters can contain arbitrary data. It is the responsibility of @@ -1385,8 +1550,8 @@ type DeviceToleration struct { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"` // Operator represents a key's relationship to the value. @@ -1396,6 +1561,7 @@ type DeviceToleration struct { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional Operator DeviceTolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=DeviceTolerationOperator"` // Value is the taint value the toleration matches to. @@ -1409,6 +1575,7 @@ type DeviceToleration struct { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Effect DeviceTaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=DeviceTaintEffect"` // TolerationSeconds represents the period of time the toleration (which must be @@ -1425,7 +1592,7 @@ type DeviceToleration struct { // A toleration operator is the set of operators that can be used in a toleration. // // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTolerationOperator string const ( @@ -1439,8 +1606,8 @@ type ResourceClaimStatus struct { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify Allocation *AllocationResult `json:"allocation,omitempty" protobuf:"bytes,1,opt,name=allocation"` // ReservedFor indicates which entities are currently allowed to use @@ -1468,10 +1635,10 @@ type ResourceClaimStatus struct { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 ReservedFor []ResourceClaimConsumerReference `json:"reservedFor,omitempty" protobuf:"bytes,2,opt,name=reservedFor" patchStrategy:"merge" patchMergeKey:"uid"` // DeallocationRequested is tombstoned since Kubernetes 1.32 where @@ -1484,18 +1651,18 @@ type ResourceClaimStatus struct { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID Devices []AllocatedDeviceStatus `json:"devices,omitempty" protobuf:"bytes,4,opt,name=devices"` } @@ -1544,7 +1711,7 @@ type AllocationResult struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -1558,8 +1725,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Results []DeviceRequestAllocationResult `json:"results,omitempty" protobuf:"bytes,1,opt,name=results"` // This field is a combination of all the claim and class configuration parameters. @@ -1572,8 +1739,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 Config []DeviceAllocationConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` } @@ -1602,8 +1769,9 @@ type DeviceRequestAllocationResult struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Driver string `json:"driver" protobuf:"bytes,2,name=driver"` // This name together with the driver name and the device name field @@ -1613,8 +1781,8 @@ type DeviceRequestAllocationResult struct { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name Pool string `json:"pool" protobuf:"bytes,3,name=pool"` // Device references one device instance via its name in the driver's @@ -1627,8 +1795,7 @@ type DeviceRequestAllocationResult struct { // administrative access. See the corresponding request field // for a definition of mode. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. // // +optional @@ -1640,38 +1807,39 @@ type DeviceRequestAllocationResult struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,7,rep,name=bindingConditions"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,8,rep,name=bindingFailureConditions"` // ShareID uniquely identifies an individual allocation share of the device, @@ -1681,8 +1849,8 @@ type DeviceRequestAllocationResult struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *types.UID `json:"shareID,omitempty" protobuf:"bytes,9,opt,name=shareID"` // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1706,7 +1874,7 @@ type DeviceAllocationConfiguration struct { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Source AllocationConfigSource `json:"source" protobuf:"bytes,1,name=source"` // Requests lists the names of requests where the configuration applies. @@ -1718,17 +1886,17 @@ type DeviceAllocationConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,2,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,3,name=deviceConfiguration"` } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type AllocationConfigSource string // Valid [DeviceAllocationConfiguration.Source] values. @@ -1760,15 +1928,12 @@ type ResourceClaimList struct { // device configuration and selectors. It can be referenced in // the device requests of a claim to apply these presets. // Cluster scoped. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type DeviceClass struct { metav1.TypeMeta `json:",inline"` // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec defines what can be allocated and how to configure it. @@ -1789,8 +1954,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,1,opt,name=selectors"` // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -1801,8 +1966,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClassConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` // SuitableNodes is tombstoned since Kubernetes 1.32 where @@ -1819,11 +1984,11 @@ type DeviceClassSpec struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name ExtendedResourceName *string `json:"extendedResourceName,omitempty" protobuf:"bytes,4,opt,name=extendedResourceName"` } @@ -1851,9 +2016,6 @@ type DeviceClassList struct { // +k8s:prerelease-lifecycle-gen:introduced=1.34 // ResourceClaimTemplate is used to produce ResourceClaim objects. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceClaimTemplate struct { metav1.TypeMeta `json:",inline"` // Standard object metadata @@ -1949,8 +2111,8 @@ type AllocatedDeviceStatus struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *string `json:"shareID,omitempty" protobuf:"bytes,7,opt,name=shareID"` // Conditions contains the latest observation of the device's state. @@ -1974,7 +2136,7 @@ type AllocatedDeviceStatus struct { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional NetworkData *NetworkDeviceData `json:"networkData,omitempty" protobuf:"bytes,6,opt,name=networkData"` } @@ -1986,11 +2148,11 @@ type NetworkDeviceData struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"` // IPs lists the network addresses assigned to the device's network interface. @@ -2001,18 +2163,18 @@ type NetworkDeviceData struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 IPs []string `json:"ips,omitempty" protobuf:"bytes,2,opt,name=ips"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"` } diff --git a/vendor/k8s.io/api/resource/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1/types_swagger_doc_generated.go index 6ba5f598c6..51915d3e20 100644 --- a/vendor/k8s.io/api/resource/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/resource/v1/types_swagger_doc_generated.go @@ -46,7 +46,7 @@ var map_AllocationResult = map[string]string{ "": "AllocationResult contains attributes of an allocated resource.", "devices": "Devices is the result of allocating devices.", "nodeSelector": "NodeSelector defines where the allocated resources are available. If unset, they are available everywhere.", - "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", + "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", } func (AllocationResult) SwaggerDoc() map[string]string { @@ -55,7 +55,7 @@ func (AllocationResult) SwaggerDoc() map[string]string { var map_CELDeviceSelector = map[string]string{ "": "CELDeviceSelector contains a CEL expression for selecting a device.", - "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", + "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nWhen the DRAListTypeAttributes feature gate is enabled, the includes() helper is available and it can work for both scalar and list-type attributes. It was introduced to support smooth migration from scalar attributes to list-type attributes while keeping CEL expressions simple. For example:\n\n device.attributes[\"dra.example.com\"].models.includes(\"some-model\")\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", } func (CELDeviceSelector) SwaggerDoc() map[string]string { @@ -113,19 +113,20 @@ func (CounterSet) SwaggerDoc() map[string]string { } var map_Device = map[string]string{ - "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", - "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", - "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", - "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is set to \"True\", a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", + "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", + "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", + "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is set to \"True\", a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "nodeAllocatableResourceMappings": "NodeAllocatableResourceMappings defines the mapping of node resources that are managed by the DRA driver exposing this device. This includes resources currently reported in v1.Node `status.allocatable` that are not extended resources (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). Examples include \"cpu\", \"memory\", \"ephemeral-storage\", and hugepages. In addition to standard requests made through the Pod `spec`, these resources can also be requested through claims and allocated by the DRA driver. For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory dependencies of an accelerator device. The keys of this map are the node-allocatable resource names (e.g., \"cpu\", \"memory\"). Extended resource names are not permitted as keys.", } func (Device) SwaggerDoc() map[string]string { @@ -153,11 +154,15 @@ func (DeviceAllocationResult) SwaggerDoc() map[string]string { } var map_DeviceAttribute = map[string]string{ - "": "DeviceAttribute must have exactly one field set.", - "int": "IntValue is a number.", - "bool": "BoolValue is a true/false value.", - "string": "StringValue is a string. Must not be longer than 64 characters.", - "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "": "DeviceAttribute must have exactly one field set.", + "int": "IntValue is a number.", + "bool": "BoolValue is a true/false value.", + "string": "StringValue is a string. Must not be longer than 64 characters.", + "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "ints": "IntValues is a non-empty list of numbers.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "bools": "BoolValues is a non-empty list of true/false values.", + "strings": "StringValues is a non-empty list of strings. Each string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "versions": "VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. Each version string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", } func (DeviceAttribute) SwaggerDoc() map[string]string { @@ -195,7 +200,7 @@ func (DeviceClaimConfiguration) SwaggerDoc() map[string]string { } var map_DeviceClass = map[string]string{ - "": "DeviceClass is a vendor- or admin-provided resource that contains device configuration and selectors. It can be referenced in the device requests of a claim to apply these presets. Cluster scoped.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "": "DeviceClass is a vendor- or admin-provided resource that contains device configuration and selectors. It can be referenced in the device requests of a claim to apply these presets. Cluster scoped.", "metadata": "Standard object metadata", "spec": "Spec defines what can be allocated and how to configure it.\n\nThis is mutable. Consumers have to be prepared for classes changing at any time, either because they get updated or replaced. Claim allocations are done once based on whatever was set in classes at the time of allocation.\n\nChanging the spec automatically increments the metadata.generation number.", } @@ -226,7 +231,7 @@ var map_DeviceClassSpec = map[string]string{ "": "DeviceClassSpec is used in a [DeviceClass] to define what can be allocated and how to configure it.", "selectors": "Each selector must be satisfied by a device which is claimed via this class.", "config": "Config defines configuration parameters that apply to each device that is claimed via this class. Some classses may potentially be satisfied by multiple drivers, so each instance of a vendor configuration applies to exactly one driver.\n\nThey are passed to the driver, but are not considered while allocating the claim.", - "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is an alpha field.", + "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is a beta field.", } func (DeviceClassSpec) SwaggerDoc() map[string]string { @@ -245,8 +250,8 @@ func (DeviceConfiguration) SwaggerDoc() map[string]string { var map_DeviceConstraint = map[string]string{ "": "DeviceConstraint must have exactly one field set besides Requests.", "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", - "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nMust include the domain qualifier.", - "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", + "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics(i.e., element order and duplicates are ignored): list-valued attributes match when the intersection across all devices is non-empty. Scalar values are treated as single-element lists for backward compatibility.\n\nMust include the domain qualifier.", + "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics (i.e., element order and duplicates are ignored): list-valued attributes must be pairwise disjoint across devices. Scalar values are treated as singleton sets for backward compatibility.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", } func (DeviceConstraint) SwaggerDoc() map[string]string { @@ -280,10 +285,10 @@ var map_DeviceRequestAllocationResult = map[string]string{ "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", - "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", - "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nAdmin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", "shareID": "ShareID uniquely identifies an individual allocation share of the device, used when the device supports multiple simultaneous allocations. It serves as an additional map key to differentiate concurrent shares of the same device.", "consumedCapacity": "ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. The consumed amount may differ from the requested amount: it is rounded up to the nearest valid value based on the device’s requestPolicy if applicable (i.e., may not be less than the requested amount).\n\nThe total consumed capacity for each device must not exceed the DeviceCapacity's Value.\n\nThis field is populated only for devices that allow multiple allocations. All capacity entries are included, even if the consumed amount is zero.", } @@ -308,7 +313,7 @@ var map_DeviceSubRequest = map[string]string{ "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this subrequest. All selectors must be satisfied for a device to be considered.", "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this subrequest. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This subrequest is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other subrequests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -321,7 +326,7 @@ var map_DeviceTaint = map[string]string{ "key": "The taint key to be applied to a device. Must be a label name.", "value": "The taint value corresponding to the taint key. Must be a label value.", "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them.\n\nValid effects are None, NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here. More effects may get added in the future. Consumers must treat unknown effects like None.", - "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", + "timeAdded": "TimeAdded represents the time at which the taint was added or (only in a DeviceTaintRule) the effect was modified. Added automatically during create or update if not set.\n\nIn addition, in a DeviceTaintRule a value provided during an update gets replaced with the current time if the provided value is the same as the old one and the new effect is different. Changing the key and/or value while keeping the effect unchanged is possible and does not update the time stamp because the eviction which uses it is either already started (NoExecute) or not started yet (NoEffect, NoSchedule).", } func (DeviceTaint) SwaggerDoc() map[string]string { @@ -347,8 +352,8 @@ var map_ExactDeviceRequest = map[string]string{ "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n At least one device must exist on the node for the allocation to succeed.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nAdmin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -358,15 +363,25 @@ func (ExactDeviceRequest) SwaggerDoc() map[string]string { var map_NetworkDeviceData = map[string]string{ "": "NetworkDeviceData provides network-related details for the allocated device. This information may be filled by drivers or other components to configure or identify the device within a network context.", - "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 characters.", + "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 bytes.", "ips": "IPs lists the network addresses assigned to the device's network interface. This can include both IPv4 and IPv6 addresses. The IPs are in the CIDR notation, which includes both the address and the associated subnet mask. e.g.: \"192.0.2.5/24\" for IPv4 and \"2001:db8::5/64\" for IPv6.", - "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 characters.", + "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 bytes.", } func (NetworkDeviceData) SwaggerDoc() map[string]string { return map_NetworkDeviceData } +var map_NodeAllocatableResourceMapping = map[string]string{ + "": "NodeAllocatableResourceMapping defines the translation between the DRA device/capacity units requested to the corresponding quantity of the node allocatable resource.", + "capacityKey": "CapacityKey references a capacity name defined as a key in the `spec.devices[*].capacity` map. When this field is set, the value associated with this key in the `status.allocation.devices.results[*].consumedCapacity` map (for a specific claim allocation) determines the base quantity for the node allocatable resource. If `allocationMultiplier` is also set, it is multiplied with the base quantity. For example, if `spec.devices[*].capacity` has an entry \"dra.example.com/memory\": \"128Gi\", and this field is set to \"dra.example.com/memory\", then for a claim allocation that consumes { \"dra.example.com/memory\": \"4Gi\" } the base quantity for the node allocatable resource mapping will be \"4Gi\", and `allocationMultiplier` should be omitted or set to \"1\".", + "allocationMultiplier": "AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim.\n\t a. A DRA driver representing each CPU core as a device would have\n {ResourceName: \"cpu\", allocationMultiplier: \"2\"} in its\n `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim,\n\t\t 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity.\n b. A GPU device that needs additional node memory per GPU allocation would\n have {ResourceName: \"memory\", allocationMultiplier: \"2Gi\"}. Each allocated\n\t\t GPU device instance of this type will account for 2Gi of memory.\n\n2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed.\n\t The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`.\n For example, if a Device's capacity \"dra.example.com/cores\" is consumed,\n and each \"core\" provides 2 \"cpu\"s, the mapping would be:\n {ResourceName: \"cpu\", capacityKey: \"dra.example.com/cores\", allocationMultiplier: \"2\"}.\n If a claim consumes 8 \"dra.example.com/cores\", the CPU footprint is 8 * 2 = 16.", +} + +func (NodeAllocatableResourceMapping) SwaggerDoc() map[string]string { + return map_NodeAllocatableResourceMapping +} + var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", @@ -378,7 +393,7 @@ func (OpaqueDeviceConfiguration) SwaggerDoc() map[string]string { } var map_ResourceClaim = map[string]string{ - "": "ResourceClaim describes a request for access to resources in the cluster, for use by workloads. For example, if a workload needs an accelerator device with specific properties, this is how that request is expressed. The status stanza tracks whether this claim has been satisfied and what specific resources have been allocated.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "": "ResourceClaim describes a request for access to resources in the cluster, for use by workloads. For example, if a workload needs an accelerator device with specific properties, this is how that request is expressed. The status stanza tracks whether this claim has been satisfied and what specific resources have been allocated.", "metadata": "Standard object metadata", "spec": "Spec describes what is being requested and how to configure it. The spec is immutable.", "status": "Status describes whether the claim is ready to use and what has been allocated.", @@ -431,7 +446,7 @@ func (ResourceClaimStatus) SwaggerDoc() map[string]string { } var map_ResourceClaimTemplate = map[string]string{ - "": "ResourceClaimTemplate is used to produce ResourceClaim objects.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "": "ResourceClaimTemplate is used to produce ResourceClaim objects.", "metadata": "Standard object metadata", "spec": "Describes the ResourceClaim that is to be generated.\n\nThis field is immutable. A ResourceClaim will get created by the control plane for a Pod when needed and then not get updated anymore.", } @@ -472,7 +487,7 @@ func (ResourcePool) SwaggerDoc() map[string]string { } var map_ResourceSlice = map[string]string{ - "": "ResourceSlice represents one or more resources in a pool of similar resources, managed by a common driver. A pool may span more than one ResourceSlice, and exactly how many ResourceSlices comprise a pool is determined by the driver.\n\nAt the moment, the only supported resources are devices with attributes and capacities. Each device in a given pool, regardless of how many ResourceSlices, must have a unique name. The ResourceSlice in which a device gets published may change over time. The unique identifier for a device is the tuple , , .\n\nWhenever a driver needs to update a pool, it increments the pool.Spec.Pool.Generation number and updates all ResourceSlices with that new number and new resource definitions. A consumer must only use ResourceSlices with the highest generation number and ignore all others.\n\nWhen allocating all resources in a pool matching certain criteria or when looking for the best solution among several different alternatives, a consumer should check the number of ResourceSlices in a pool (included in each ResourceSlice) to determine whether its view of a pool is complete and if not, should wait until the driver has completed updating the pool.\n\nFor resources that are not local to a node, the node name is not set. Instead, the driver may use a node selector to specify where the devices are available.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", + "": "ResourceSlice represents one or more resources in a pool of similar resources, managed by a common driver. A pool may span more than one ResourceSlice, and exactly how many ResourceSlices comprise a pool is determined by the driver.\n\nAt the moment, the only supported resources are devices with attributes and capacities. Each device in a given pool, regardless of how many ResourceSlices, must have a unique name. The ResourceSlice in which a device gets published may change over time. The unique identifier for a device is the tuple , , .\n\nWhenever a driver needs to update a pool, it increments the pool.Spec.Pool.Generation number and updates all ResourceSlices with that new number and new resource definitions. A consumer must only use ResourceSlices with the highest generation number and ignore all others.\n\nWhen allocating all resources in a pool matching certain criteria or when looking for the best solution among several different alternatives, a consumer should check the number of ResourceSlices in a pool (included in each ResourceSlice) to determine whether its view of a pool is complete and if not, should wait until the driver has completed updating the pool.\n\nFor resources that are not local to a node, the node name is not set. Instead, the driver may use a node selector to specify where the devices are available.", "metadata": "Standard object metadata", "spec": "Contains the information published by the driver.\n\nChanging the spec automatically increments the metadata.generation number.", } diff --git a/vendor/k8s.io/api/resource/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1/zz_generated.deepcopy.go index 580ba64875..0c488a05ae 100644 --- a/vendor/k8s.io/api/resource/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/resource/v1/zz_generated.deepcopy.go @@ -302,6 +302,13 @@ func (in *Device) DeepCopyInto(out *Device) { *out = new(bool) **out = **in } + if in.NodeAllocatableResourceMappings != nil { + in, out := &in.NodeAllocatableResourceMappings, &out.NodeAllocatableResourceMappings + *out = make(map[corev1.ResourceName]NodeAllocatableResourceMapping, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } return } @@ -390,6 +397,26 @@ func (in *DeviceAttribute) DeepCopyInto(out *DeviceAttribute) { *out = new(string) **out = **in } + if in.IntValues != nil { + in, out := &in.IntValues, &out.IntValues + *out = make([]int64, len(*in)) + copy(*out, *in) + } + if in.BoolValues != nil { + in, out := &in.BoolValues, &out.BoolValues + *out = make([]bool, len(*in)) + copy(*out, *in) + } + if in.StringValues != nil { + in, out := &in.StringValues, &out.StringValues + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.VersionValues != nil { + in, out := &in.VersionValues, &out.VersionValues + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -907,6 +934,32 @@ func (in *NetworkDeviceData) DeepCopy() *NetworkDeviceData { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeAllocatableResourceMapping) DeepCopyInto(out *NodeAllocatableResourceMapping) { + *out = *in + if in.CapacityKey != nil { + in, out := &in.CapacityKey, &out.CapacityKey + *out = new(QualifiedName) + **out = **in + } + if in.AllocationMultiplier != nil { + in, out := &in.AllocationMultiplier, &out.AllocationMultiplier + x := (*in).DeepCopy() + *out = &x + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAllocatableResourceMapping. +func (in *NodeAllocatableResourceMapping) DeepCopy() *NodeAllocatableResourceMapping { + if in == nil { + return nil + } + out := new(NodeAllocatableResourceMapping) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpaqueDeviceConfiguration) DeepCopyInto(out *OpaqueDeviceConfiguration) { *out = *in diff --git a/vendor/k8s.io/api/resource/v1/zz_generated.model_name.go b/vendor/k8s.io/api/resource/v1/zz_generated.model_name.go index c0de4f9e9d..f163c61ed1 100644 --- a/vendor/k8s.io/api/resource/v1/zz_generated.model_name.go +++ b/vendor/k8s.io/api/resource/v1/zz_generated.model_name.go @@ -171,6 +171,11 @@ func (in NetworkDeviceData) OpenAPIModelName() string { return "io.k8s.api.resource.v1.NetworkDeviceData" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in NodeAllocatableResourceMapping) OpenAPIModelName() string { + return "io.k8s.api.resource.v1.NodeAllocatableResourceMapping" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in OpaqueDeviceConfiguration) OpenAPIModelName() string { return "io.k8s.api.resource.v1.OpaqueDeviceConfiguration" diff --git a/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go b/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go index 66b9f8f620..fa1f5f4710 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go +++ b/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go @@ -47,6 +47,16 @@ func (m *DeviceTaintRuleStatus) Reset() { *m = DeviceTaintRuleStatus{} } func (m *DeviceTaintSelector) Reset() { *m = DeviceTaintSelector{} } +func (m *PoolStatus) Reset() { *m = PoolStatus{} } + +func (m *ResourcePoolStatusRequest) Reset() { *m = ResourcePoolStatusRequest{} } + +func (m *ResourcePoolStatusRequestList) Reset() { *m = ResourcePoolStatusRequestList{} } + +func (m *ResourcePoolStatusRequestSpec) Reset() { *m = ResourcePoolStatusRequestSpec{} } + +func (m *ResourcePoolStatusRequestStatus) Reset() { *m = ResourcePoolStatusRequestStatus{} } + func (m *CELDeviceSelector) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -386,6 +396,279 @@ func (m *DeviceTaintSelector) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PoolStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PoolStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PoolStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ValidationError != nil { + i -= len(*m.ValidationError) + copy(dAtA[i:], *m.ValidationError) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ValidationError))) + i-- + dAtA[i] = 0x52 + } + i = encodeVarintGenerated(dAtA, i, uint64(m.Generation)) + i-- + dAtA[i] = 0x48 + if m.ResourceSliceCount != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.ResourceSliceCount)) + i-- + dAtA[i] = 0x40 + } + if m.UnavailableDevices != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.UnavailableDevices)) + i-- + dAtA[i] = 0x38 + } + if m.AvailableDevices != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.AvailableDevices)) + i-- + dAtA[i] = 0x30 + } + if m.AllocatedDevices != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.AllocatedDevices)) + i-- + dAtA[i] = 0x28 + } + if m.TotalDevices != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TotalDevices)) + i-- + dAtA[i] = 0x20 + } + if m.NodeName != nil { + i -= len(*m.NodeName) + copy(dAtA[i:], *m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.NodeName))) + i-- + dAtA[i] = 0x1a + } + i -= len(m.PoolName) + copy(dAtA[i:], m.PoolName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PoolName))) + i-- + dAtA[i] = 0x12 + i -= len(m.Driver) + copy(dAtA[i:], m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourcePoolStatusRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourcePoolStatusRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourcePoolStatusRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Status != nil { + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourcePoolStatusRequestList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourcePoolStatusRequestList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourcePoolStatusRequestList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourcePoolStatusRequestSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourcePoolStatusRequestSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourcePoolStatusRequestSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Limit != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Limit)) + i-- + dAtA[i] = 0x18 + } + if m.PoolName != nil { + i -= len(*m.PoolName) + copy(dAtA[i:], *m.PoolName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PoolName))) + i-- + dAtA[i] = 0x12 + } + i -= len(m.Driver) + copy(dAtA[i:], m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourcePoolStatusRequestStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourcePoolStatusRequestStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourcePoolStatusRequestStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PoolCount != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.PoolCount)) + i-- + dAtA[i] = 0x30 + } + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Pools) > 0 { + for iNdEx := len(m.Pools) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Pools[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + return len(dAtA) - i, nil +} + func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -523,35 +806,148 @@ func (m *DeviceTaintSelector) Size() (n int) { return n } -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *CELDeviceSelector) String() string { - if this == nil { - return "nil" +func (m *PoolStatus) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&CELDeviceSelector{`, - `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, - `}`, - }, "") - return s -} -func (this *DeviceSelector) String() string { - if this == nil { - return "nil" + var l int + _ = l + l = len(m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.PoolName) + n += 1 + l + sovGenerated(uint64(l)) + if m.NodeName != nil { + l = len(*m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) } - s := strings.Join([]string{`&DeviceSelector{`, - `CEL:` + strings.Replace(this.CEL.String(), "CELDeviceSelector", "CELDeviceSelector", 1) + `,`, - `}`, - }, "") - return s + if m.TotalDevices != nil { + n += 1 + sovGenerated(uint64(*m.TotalDevices)) + } + if m.AllocatedDevices != nil { + n += 1 + sovGenerated(uint64(*m.AllocatedDevices)) + } + if m.AvailableDevices != nil { + n += 1 + sovGenerated(uint64(*m.AvailableDevices)) + } + if m.UnavailableDevices != nil { + n += 1 + sovGenerated(uint64(*m.UnavailableDevices)) + } + if m.ResourceSliceCount != nil { + n += 1 + sovGenerated(uint64(*m.ResourceSliceCount)) + } + n += 1 + sovGenerated(uint64(m.Generation)) + if m.ValidationError != nil { + l = len(*m.ValidationError) + n += 1 + l + sovGenerated(uint64(l)) + } + return n } -func (this *DeviceTaintRule) String() string { - if this == nil { - return "nil" + +func (m *ResourcePoolStatusRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.Status != nil { + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *ResourcePoolStatusRequestList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourcePoolStatusRequestSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + if m.PoolName != nil { + l = len(*m.PoolName) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Limit != nil { + n += 1 + sovGenerated(uint64(*m.Limit)) + } + return n +} + +func (m *ResourcePoolStatusRequestStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Pools) > 0 { + for _, e := range m.Pools { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.PoolCount != nil { + n += 1 + sovGenerated(uint64(*m.PoolCount)) + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *CELDeviceSelector) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CELDeviceSelector{`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceSelector) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceSelector{`, + `CEL:` + strings.Replace(this.CEL.String(), "CELDeviceSelector", "CELDeviceSelector", 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRule) String() string { + if this == nil { + return "nil" } s := strings.Join([]string{`&DeviceTaintRule{`, `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, @@ -615,6 +1011,87 @@ func (this *DeviceTaintSelector) String() string { }, "") return s } +func (this *PoolStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PoolStatus{`, + `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, + `PoolName:` + fmt.Sprintf("%v", this.PoolName) + `,`, + `NodeName:` + valueToStringGenerated(this.NodeName) + `,`, + `TotalDevices:` + valueToStringGenerated(this.TotalDevices) + `,`, + `AllocatedDevices:` + valueToStringGenerated(this.AllocatedDevices) + `,`, + `AvailableDevices:` + valueToStringGenerated(this.AvailableDevices) + `,`, + `UnavailableDevices:` + valueToStringGenerated(this.UnavailableDevices) + `,`, + `ResourceSliceCount:` + valueToStringGenerated(this.ResourceSliceCount) + `,`, + `Generation:` + fmt.Sprintf("%v", this.Generation) + `,`, + `ValidationError:` + valueToStringGenerated(this.ValidationError) + `,`, + `}`, + }, "") + return s +} +func (this *ResourcePoolStatusRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourcePoolStatusRequest{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ResourcePoolStatusRequestSpec", "ResourcePoolStatusRequestSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(this.Status.String(), "ResourcePoolStatusRequestStatus", "ResourcePoolStatusRequestStatus", 1) + `,`, + `}`, + }, "") + return s +} +func (this *ResourcePoolStatusRequestList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ResourcePoolStatusRequest{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ResourcePoolStatusRequest", "ResourcePoolStatusRequest", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ResourcePoolStatusRequestList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ResourcePoolStatusRequestSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourcePoolStatusRequestSpec{`, + `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, + `PoolName:` + valueToStringGenerated(this.PoolName) + `,`, + `Limit:` + valueToStringGenerated(this.Limit) + `,`, + `}`, + }, "") + return s +} +func (this *ResourcePoolStatusRequestStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForPools := "[]PoolStatus{" + for _, f := range this.Pools { + repeatedStringForPools += strings.Replace(strings.Replace(f.String(), "PoolStatus", "PoolStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForPools += "}" + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&ResourcePoolStatusRequestStatus{`, + `Pools:` + repeatedStringForPools + `,`, + `Conditions:` + repeatedStringForConditions + `,`, + `PoolCount:` + valueToStringGenerated(this.PoolCount) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -824,7 +1301,924 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } - var stringLen uint64 + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeAdded", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TimeAdded == nil { + m.TimeAdded = &v1.Time{} + } + if err := m.TimeAdded.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRuleList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRuleList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, DeviceTaintRule{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRuleSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRuleSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DeviceSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DeviceSelector == nil { + m.DeviceSelector = &DeviceTaintSelector{} + } + if err := m.DeviceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Taint", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Taint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRuleStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRuleStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRuleStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintSelector: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintSelector: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Driver = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Pool = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Device = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PoolStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PoolStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PoolStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Driver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PoolName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PoolName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.NodeName = &s + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalDevices", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TotalDevices = &v + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocatedDevices", wireType) + } + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -834,29 +2228,17 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Key = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + m.AllocatedDevices = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AvailableDevices", wireType) } - var stringLen uint64 + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -866,29 +2248,37 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + m.AvailableDevices = &v + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UnavailableDevices", wireType) } - if postIndex > l { - return io.ErrUnexpectedEOF + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - m.Value = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + m.UnavailableDevices = &v + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceSliceCount", wireType) } - var stringLen uint64 + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -898,29 +2288,36 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + m.ResourceSliceCount = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Generation", wireType) } - if postIndex > l { - return io.ErrUnexpectedEOF + m.Generation = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Generation |= int64(b&0x7F) << shift + if b < 0x80 { + break + } } - m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TimeAdded", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValidationError", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -930,27 +2327,24 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.TimeAdded == nil { - m.TimeAdded = &v1.Time{} - } - if err := m.TimeAdded.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.ValidationError = &s iNdEx = postIndex default: iNdEx = preIndex @@ -973,7 +2367,7 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { +func (m *ResourcePoolStatusRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -996,10 +2390,10 @@ func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceTaintRule: wiretype end group for non-group") + return fmt.Errorf("proto: ResourcePoolStatusRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaintRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResourcePoolStatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1097,6 +2491,9 @@ func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.Status == nil { + m.Status = &ResourcePoolStatusRequestStatus{} + } if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1122,7 +2519,7 @@ func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { +func (m *ResourcePoolStatusRequestList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1145,10 +2542,10 @@ func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceTaintRuleList: wiretype end group for non-group") + return fmt.Errorf("proto: ResourcePoolStatusRequestList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaintRuleList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResourcePoolStatusRequestList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1213,7 +2610,7 @@ func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, DeviceTaintRule{}) + m.Items = append(m.Items, ResourcePoolStatusRequest{}) if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1239,7 +2636,7 @@ func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { +func (m *ResourcePoolStatusRequestSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1262,17 +2659,17 @@ func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceTaintRuleSpec: wiretype end group for non-group") + return fmt.Errorf("proto: ResourcePoolStatusRequestSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaintRuleSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResourcePoolStatusRequestSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1282,33 +2679,29 @@ func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.DeviceSelector == nil { - m.DeviceSelector = &DeviceTaintSelector{} - } - if err := m.DeviceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Driver = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Taint", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PoolName", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1318,80 +2711,30 @@ func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Taint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.PoolName = &s iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceTaintRuleStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceTaintRuleStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaintRuleStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) } - var msglen int + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1401,26 +2744,12 @@ func (m *DeviceTaintRuleStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Conditions = append(m.Conditions, v1.Condition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + m.Limit = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -1442,7 +2771,7 @@ func (m *DeviceTaintRuleStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { +func (m *ResourcePoolStatusRequestStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1465,17 +2794,17 @@ func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceTaintSelector: wiretype end group for non-group") + return fmt.Errorf("proto: ResourcePoolStatusRequestStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaintSelector: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResourcePoolStatusRequestStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pools", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1485,30 +2814,31 @@ func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Driver = &s + m.Pools = append(m.Pools, PoolStatus{}) + if err := m.Pools[len(m.Pools)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1518,30 +2848,31 @@ func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Pool = &s + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PoolCount", wireType) } - var stringLen uint64 + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -1551,25 +2882,12 @@ func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Device = &s - iNdEx = postIndex + m.PoolCount = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/resource/v1alpha3/generated.proto b/vendor/k8s.io/api/resource/v1alpha3/generated.proto index 6414216db2..d6ee310806 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/generated.proto +++ b/vendor/k8s.io/api/resource/v1alpha3/generated.proto @@ -120,11 +120,21 @@ message DeviceTaint { // Consumers must treat unknown effects like None. // // +required + // +k8s:required optional string effect = 3; - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; } @@ -140,6 +150,7 @@ message DeviceTaintRule { // Spec specifies the selector and one taint. // // Changing the spec automatically increments the metadata.generation number. + // +required optional DeviceTaintRuleSpec spec = 2; // Status provides information about what was requested in the spec. @@ -237,3 +248,210 @@ message DeviceTaintSelector { optional string device = 4; } +// PoolStatus contains status information for a single resource pool. +message PoolStatus { + // Driver is the DRA driver name for this pool. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name-caseless + optional string driver = 1; + + // PoolName is the name of the pool. + // Must be a valid resource pool name (DNS subdomains separated by "/"). + // + // +required + // +k8s:required + // +k8s:format=k8s-resource-pool-name + optional string poolName = 2; + + // Generation is the pool generation observed across all ResourceSlices + // in this pool. Only the latest generation is reported. During a generation + // rollout, if not all slices at the latest generation have been published, + // the pool is included with a validationError and device counts unset. + // + // +required + // +k8s:required + // +k8s:minimum=0 + optional int64 generation = 9; + + // ResourceSliceCount is the number of ResourceSlices that make up this pool. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=1 + optional int32 resourceSliceCount = 8; + + // TotalDevices is the total number of devices in the pool across all slices. + // A value of 0 means the pool has no devices. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + optional int32 totalDevices = 4; + + // AllocatedDevices is the number of devices currently allocated to claims. + // A value of 0 means no devices are allocated. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + optional int32 allocatedDevices = 5; + + // AvailableDevices is the number of devices available for allocation. + // This equals TotalDevices - AllocatedDevices - UnavailableDevices. + // A value of 0 means no devices are currently available. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + optional int32 availableDevices = 6; + + // UnavailableDevices is the number of devices that are not available + // due to taints or other conditions, but are not allocated. + // A value of 0 means all unallocated devices are available. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + optional int32 unavailableDevices = 7; + + // NodeName is the node this pool is associated with. + // When omitted, the pool is not associated with a specific node. + // Must be a valid DNS subdomain name (RFC1123). + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + optional string nodeName = 3; + + // ValidationError is set when the pool's data could not be fully + // validated (e.g., incomplete slice publication). When set, device + // count fields and ResourceSliceCount may be unset. + // + // +optional + // +k8s:optional + // +k8s:maxBytes=256 + optional string validationError = 10; +} + +// ResourcePoolStatusRequest triggers a one-time calculation of resource pool status +// based on the provided filters. Once status is set, the request is considered complete and will not be reprocessed. +// Users should delete and recreate requests to get updated information. +message ResourcePoolStatusRequest { + // Standard object metadata + // +required + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec defines the filters for which pools to include in the status. + // The spec is immutable once created. + // + // +required + // +k8s:immutable + optional ResourcePoolStatusRequestSpec spec = 2; + + // Status is populated by the controller with the calculated pool status. + // When status is non-nil, the request is considered complete and the + // entire object becomes immutable. + // + // +optional + // +k8s:optional + optional ResourcePoolStatusRequestStatus status = 3; +} + +// ResourcePoolStatusRequestList is a collection of ResourcePoolStatusRequests. +message ResourcePoolStatusRequestList { + // Standard list metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of ResourcePoolStatusRequests. + repeated ResourcePoolStatusRequest items = 2; +} + +// ResourcePoolStatusRequestSpec defines the filters for the pool status request. +message ResourcePoolStatusRequestSpec { + // Driver specifies the DRA driver name to filter pools. + // Only pools from ResourceSlices with this driver will be included. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name-caseless + optional string driver = 1; + + // PoolName optionally filters to a specific pool name. + // If not specified, all pools from the specified driver are included. + // When specified, must be a non-empty valid resource pool name + // (DNS subdomains separated by "/"). + // + // +optional + // +k8s:optional + // +k8s:format=k8s-resource-pool-name + optional string poolName = 2; + + // Limit optionally specifies the maximum number of pools to return in the status. + // If more pools match the filter criteria, the response will be truncated + // (i.e., len(status.pools) < status.poolCount). + // + // Default: 100 + // Minimum: 1 + // Maximum: 1000 + // + // +optional + // +k8s:optional + // +default=100 + // +k8s:minimum=1 + // +k8s:maximum=1000 + optional int32 limit = 3; +} + +// ResourcePoolStatusRequestStatus contains the calculated pool status information. +message ResourcePoolStatusRequestStatus { + // PoolCount is the total number of pools that matched the filter criteria, + // regardless of truncation. This helps users understand how many pools exist + // even when the response is truncated. A value of 0 means no pools matched + // the filter criteria. + // + // +required + // +k8s:required + // +k8s:minimum=0 + optional int32 poolCount = 6; + + // Pools contains the first `spec.limit` matching pools, sorted by driver + // then pool name. If `len(pools) < poolCount`, the list was truncated. + // When omitted, no pools matched the request filters. + // + // +optional + // +k8s:optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:maxItems=1000 + repeated PoolStatus pools = 2; + + // Conditions provide information about the state of the request. + // A condition with type=Complete or type=Failed will always be set + // when the status is populated. + // + // Known condition types: + // - "Complete": True when the request has been processed successfully + // - "Failed": True when the request could not be processed + // + // +optional + // +k8s:optional + // +listType=map + // +k8s:listType=map + // +listMapKey=type + // +k8s:listMapKey=type + // +patchStrategy=merge + // +patchMergeKey=type + // +k8s:maxItems=10 + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 3; +} + diff --git a/vendor/k8s.io/api/resource/v1alpha3/generated.protomessage.pb.go b/vendor/k8s.io/api/resource/v1alpha3/generated.protomessage.pb.go deleted file mode 100644 index aba6231f3d..0000000000 --- a/vendor/k8s.io/api/resource/v1alpha3/generated.protomessage.pb.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha3 - -func (*CELDeviceSelector) ProtoMessage() {} - -func (*DeviceSelector) ProtoMessage() {} - -func (*DeviceTaint) ProtoMessage() {} - -func (*DeviceTaintRule) ProtoMessage() {} - -func (*DeviceTaintRuleList) ProtoMessage() {} - -func (*DeviceTaintRuleSpec) ProtoMessage() {} - -func (*DeviceTaintRuleStatus) ProtoMessage() {} - -func (*DeviceTaintSelector) ProtoMessage() {} diff --git a/vendor/k8s.io/api/resource/v1alpha3/register.go b/vendor/k8s.io/api/resource/v1alpha3/register.go index dd79ec341e..ab20bd05fb 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/register.go +++ b/vendor/k8s.io/api/resource/v1alpha3/register.go @@ -46,6 +46,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &DeviceTaintRule{}, &DeviceTaintRuleList{}, + &ResourcePoolStatusRequest{}, + &ResourcePoolStatusRequestList{}, ) // Add the watch version that applies diff --git a/vendor/k8s.io/api/resource/v1alpha3/types.go b/vendor/k8s.io/api/resource/v1alpha3/types.go index ba02edabaa..1757c86150 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/types.go +++ b/vendor/k8s.io/api/resource/v1alpha3/types.go @@ -140,6 +140,7 @@ type DeviceTaint struct { // Consumers must treat unknown effects like None. // // +required + // +k8s:required Effect DeviceTaintEffect `json:"effect" protobuf:"bytes,3,name=effect,casttype=DeviceTaintEffect"` // ^^^^ @@ -155,9 +156,18 @@ type DeviceTaint struct { // which will enable adding new enums within a single release without // ratcheting. - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional TimeAdded *metav1.Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` @@ -169,6 +179,7 @@ type DeviceTaint struct { } // +enum +// +k8s:enum type DeviceTaintEffect string const ( @@ -201,6 +212,7 @@ type DeviceTaintRule struct { // Spec specifies the selector and one taint. // // Changing the spec automatically increments the metadata.generation number. + // +required Spec DeviceTaintRuleSpec `json:"spec" protobuf:"bytes,2,name=spec"` // Status provides information about what was requested in the spec. @@ -332,3 +344,233 @@ type DeviceTaintRuleList struct { // Items is the list of DeviceTaintRules. Items []DeviceTaintRule `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 +// +k8s:supportsSubresource="/status" + +// ResourcePoolStatusRequest triggers a one-time calculation of resource pool status +// based on the provided filters. Once status is set, the request is considered complete and will not be reprocessed. +// Users should delete and recreate requests to get updated information. +type ResourcePoolStatusRequest struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +required + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec defines the filters for which pools to include in the status. + // The spec is immutable once created. + // + // +required + // +k8s:immutable + Spec ResourcePoolStatusRequestSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // Status is populated by the controller with the calculated pool status. + // When status is non-nil, the request is considered complete and the + // entire object becomes immutable. + // + // +optional + // +k8s:optional + Status *ResourcePoolStatusRequestStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// ResourcePoolStatusRequestSpec defines the filters for the pool status request. +type ResourcePoolStatusRequestSpec struct { + // Driver specifies the DRA driver name to filter pools. + // Only pools from ResourceSlices with this driver will be included. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name-caseless + Driver string `json:"driver" protobuf:"bytes,1,name=driver"` + + // PoolName optionally filters to a specific pool name. + // If not specified, all pools from the specified driver are included. + // When specified, must be a non-empty valid resource pool name + // (DNS subdomains separated by "/"). + // + // +optional + // +k8s:optional + // +k8s:format=k8s-resource-pool-name + PoolName *string `json:"poolName,omitempty" protobuf:"bytes,2,opt,name=poolName"` + + // Limit optionally specifies the maximum number of pools to return in the status. + // If more pools match the filter criteria, the response will be truncated + // (i.e., len(status.pools) < status.poolCount). + // + // Default: 100 + // Minimum: 1 + // Maximum: 1000 + // + // +optional + // +k8s:optional + // +default=100 + // +k8s:minimum=1 + // +k8s:maximum=1000 + Limit *int32 `json:"limit,omitempty" protobuf:"varint,3,opt,name=limit"` +} + +// ResourcePoolStatusRequestLimitDefault is the default value for spec.limit. +const ResourcePoolStatusRequestLimitDefault int32 = 100 + +// ResourcePoolStatusRequestLimitMax is the maximum allowed value for spec.limit. +const ResourcePoolStatusRequestLimitMax int32 = 1000 + +// ResourcePoolStatusRequestStatus contains the calculated pool status information. +type ResourcePoolStatusRequestStatus struct { + // PoolCount is the total number of pools that matched the filter criteria, + // regardless of truncation. This helps users understand how many pools exist + // even when the response is truncated. A value of 0 means no pools matched + // the filter criteria. + // + // +required + // +k8s:required + // +k8s:minimum=0 + PoolCount *int32 `json:"poolCount,omitempty" protobuf:"varint,6,opt,name=poolCount"` + + // Pools contains the first `spec.limit` matching pools, sorted by driver + // then pool name. If `len(pools) < poolCount`, the list was truncated. + // When omitted, no pools matched the request filters. + // + // +optional + // +k8s:optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:maxItems=1000 + Pools []PoolStatus `json:"pools,omitempty" protobuf:"bytes,2,rep,name=pools"` + + // Conditions provide information about the state of the request. + // A condition with type=Complete or type=Failed will always be set + // when the status is populated. + // + // Known condition types: + // - "Complete": True when the request has been processed successfully + // - "Failed": True when the request could not be processed + // + // +optional + // +k8s:optional + // +listType=map + // +k8s:listType=map + // +listMapKey=type + // +k8s:listMapKey=type + // +patchStrategy=merge + // +patchMergeKey=type + // +k8s:maxItems=10 + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,3,rep,name=conditions"` +} + +// PoolStatus contains status information for a single resource pool. +type PoolStatus struct { + // Driver is the DRA driver name for this pool. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name-caseless + Driver string `json:"driver,omitempty" protobuf:"bytes,1,name=driver"` + + // PoolName is the name of the pool. + // Must be a valid resource pool name (DNS subdomains separated by "/"). + // + // +required + // +k8s:required + // +k8s:format=k8s-resource-pool-name + PoolName string `json:"poolName,omitempty" protobuf:"bytes,2,name=poolName"` + + // Generation is the pool generation observed across all ResourceSlices + // in this pool. Only the latest generation is reported. During a generation + // rollout, if not all slices at the latest generation have been published, + // the pool is included with a validationError and device counts unset. + // + // +required + // +k8s:required + // +k8s:minimum=0 + Generation int64 `json:"generation" protobuf:"varint,9,opt,name=generation"` + + // ResourceSliceCount is the number of ResourceSlices that make up this pool. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=1 + ResourceSliceCount *int32 `json:"resourceSliceCount,omitempty" protobuf:"varint,8,opt,name=resourceSliceCount"` + + // TotalDevices is the total number of devices in the pool across all slices. + // A value of 0 means the pool has no devices. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + TotalDevices *int32 `json:"totalDevices,omitempty" protobuf:"varint,4,opt,name=totalDevices"` + + // AllocatedDevices is the number of devices currently allocated to claims. + // A value of 0 means no devices are allocated. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + AllocatedDevices *int32 `json:"allocatedDevices,omitempty" protobuf:"varint,5,opt,name=allocatedDevices"` + + // AvailableDevices is the number of devices available for allocation. + // This equals TotalDevices - AllocatedDevices - UnavailableDevices. + // A value of 0 means no devices are currently available. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + AvailableDevices *int32 `json:"availableDevices,omitempty" protobuf:"varint,6,opt,name=availableDevices"` + + // UnavailableDevices is the number of devices that are not available + // due to taints or other conditions, but are not allocated. + // A value of 0 means all unallocated devices are available. + // May be unset when validationError is set. + // + // +optional + // +k8s:optional + // +k8s:minimum=0 + UnavailableDevices *int32 `json:"unavailableDevices,omitempty" protobuf:"varint,7,opt,name=unavailableDevices"` + + // NodeName is the node this pool is associated with. + // When omitted, the pool is not associated with a specific node. + // Must be a valid DNS subdomain name (RFC1123). + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,3,opt,name=nodeName"` + + // ValidationError is set when the pool's data could not be fully + // validated (e.g., incomplete slice publication). When set, device + // count fields and ResourceSliceCount may be unset. + // + // +optional + // +k8s:optional + // +k8s:maxBytes=256 + ValidationError *string `json:"validationError,omitempty" protobuf:"bytes,10,opt,name=validationError"` +} + +// ResourcePoolStatusRequestConditionComplete is the condition type for completed requests. +const ResourcePoolStatusRequestConditionComplete = "Complete" + +// ResourcePoolStatusRequestConditionFailed is the condition type for failed requests. +const ResourcePoolStatusRequestConditionFailed = "Failed" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// ResourcePoolStatusRequestList is a collection of ResourcePoolStatusRequests. +type ResourcePoolStatusRequestList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of ResourcePoolStatusRequests. + Items []ResourcePoolStatusRequest `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go index 30981bd7e6..49ff642fea 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go @@ -50,7 +50,7 @@ var map_DeviceTaint = map[string]string{ "key": "The taint key to be applied to a device. Must be a label name.", "value": "The taint value corresponding to the taint key. Must be a label value.", "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them.\n\nValid effects are None, NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here. More effects may get added in the future. Consumers must treat unknown effects like None.", - "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", + "timeAdded": "TimeAdded represents the time at which the taint was added or (only in a DeviceTaintRule) the effect was modified. Added automatically during create or update if not set.\n\nIn addition, in a DeviceTaintRule a value provided during an update gets replaced with the current time if the provided value is the same as the old one and the new effect is different. Changing the key and/or value while keeping the effect unchanged is possible and does not update the time stamp because the eviction which uses it is either already started (NoExecute) or not started yet (NoEffect, NoSchedule).", } func (DeviceTaint) SwaggerDoc() map[string]string { @@ -108,4 +108,65 @@ func (DeviceTaintSelector) SwaggerDoc() map[string]string { return map_DeviceTaintSelector } +var map_PoolStatus = map[string]string{ + "": "PoolStatus contains status information for a single resource pool.", + "driver": "Driver is the DRA driver name for this pool. Must be a DNS subdomain (e.g., \"gpu.example.com\").", + "poolName": "PoolName is the name of the pool. Must be a valid resource pool name (DNS subdomains separated by \"/\").", + "generation": "Generation is the pool generation observed across all ResourceSlices in this pool. Only the latest generation is reported. During a generation rollout, if not all slices at the latest generation have been published, the pool is included with a validationError and device counts unset.", + "resourceSliceCount": "ResourceSliceCount is the number of ResourceSlices that make up this pool. May be unset when validationError is set.", + "totalDevices": "TotalDevices is the total number of devices in the pool across all slices. A value of 0 means the pool has no devices. May be unset when validationError is set.", + "allocatedDevices": "AllocatedDevices is the number of devices currently allocated to claims. A value of 0 means no devices are allocated. May be unset when validationError is set.", + "availableDevices": "AvailableDevices is the number of devices available for allocation. This equals TotalDevices - AllocatedDevices - UnavailableDevices. A value of 0 means no devices are currently available. May be unset when validationError is set.", + "unavailableDevices": "UnavailableDevices is the number of devices that are not available due to taints or other conditions, but are not allocated. A value of 0 means all unallocated devices are available. May be unset when validationError is set.", + "nodeName": "NodeName is the node this pool is associated with. When omitted, the pool is not associated with a specific node. Must be a valid DNS subdomain name (RFC1123).", + "validationError": "ValidationError is set when the pool's data could not be fully validated (e.g., incomplete slice publication). When set, device count fields and ResourceSliceCount may be unset.", +} + +func (PoolStatus) SwaggerDoc() map[string]string { + return map_PoolStatus +} + +var map_ResourcePoolStatusRequest = map[string]string{ + "": "ResourcePoolStatusRequest triggers a one-time calculation of resource pool status based on the provided filters. Once status is set, the request is considered complete and will not be reprocessed. Users should delete and recreate requests to get updated information.", + "metadata": "Standard object metadata", + "spec": "Spec defines the filters for which pools to include in the status. The spec is immutable once created.", + "status": "Status is populated by the controller with the calculated pool status. When status is non-nil, the request is considered complete and the entire object becomes immutable.", +} + +func (ResourcePoolStatusRequest) SwaggerDoc() map[string]string { + return map_ResourcePoolStatusRequest +} + +var map_ResourcePoolStatusRequestList = map[string]string{ + "": "ResourcePoolStatusRequestList is a collection of ResourcePoolStatusRequests.", + "metadata": "Standard list metadata", + "items": "Items is the list of ResourcePoolStatusRequests.", +} + +func (ResourcePoolStatusRequestList) SwaggerDoc() map[string]string { + return map_ResourcePoolStatusRequestList +} + +var map_ResourcePoolStatusRequestSpec = map[string]string{ + "": "ResourcePoolStatusRequestSpec defines the filters for the pool status request.", + "driver": "Driver specifies the DRA driver name to filter pools. Only pools from ResourceSlices with this driver will be included. Must be a DNS subdomain (e.g., \"gpu.example.com\").", + "poolName": "PoolName optionally filters to a specific pool name. If not specified, all pools from the specified driver are included. When specified, must be a non-empty valid resource pool name (DNS subdomains separated by \"/\").", + "limit": "Limit optionally specifies the maximum number of pools to return in the status. If more pools match the filter criteria, the response will be truncated (i.e., len(status.pools) < status.poolCount).\n\nDefault: 100 Minimum: 1 Maximum: 1000", +} + +func (ResourcePoolStatusRequestSpec) SwaggerDoc() map[string]string { + return map_ResourcePoolStatusRequestSpec +} + +var map_ResourcePoolStatusRequestStatus = map[string]string{ + "": "ResourcePoolStatusRequestStatus contains the calculated pool status information.", + "poolCount": "PoolCount is the total number of pools that matched the filter criteria, regardless of truncation. This helps users understand how many pools exist even when the response is truncated. A value of 0 means no pools matched the filter criteria.", + "pools": "Pools contains the first `spec.limit` matching pools, sorted by driver then pool name. If `len(pools) < poolCount`, the list was truncated. When omitted, no pools matched the request filters.", + "conditions": "Conditions provide information about the state of the request. A condition with type=Complete or type=Failed will always be set when the status is populated.\n\nKnown condition types: - \"Complete\": True when the request has been processed successfully - \"Failed\": True when the request could not be processed", +} + +func (ResourcePoolStatusRequestStatus) SwaggerDoc() map[string]string { + return map_ResourcePoolStatusRequestStatus +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.deepcopy.go index 6813ab043c..32ec2ad8e2 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.deepcopy.go @@ -219,3 +219,180 @@ func (in *DeviceTaintSelector) DeepCopy() *DeviceTaintSelector { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolStatus) DeepCopyInto(out *PoolStatus) { + *out = *in + if in.ResourceSliceCount != nil { + in, out := &in.ResourceSliceCount, &out.ResourceSliceCount + *out = new(int32) + **out = **in + } + if in.TotalDevices != nil { + in, out := &in.TotalDevices, &out.TotalDevices + *out = new(int32) + **out = **in + } + if in.AllocatedDevices != nil { + in, out := &in.AllocatedDevices, &out.AllocatedDevices + *out = new(int32) + **out = **in + } + if in.AvailableDevices != nil { + in, out := &in.AvailableDevices, &out.AvailableDevices + *out = new(int32) + **out = **in + } + if in.UnavailableDevices != nil { + in, out := &in.UnavailableDevices, &out.UnavailableDevices + *out = new(int32) + **out = **in + } + if in.NodeName != nil { + in, out := &in.NodeName, &out.NodeName + *out = new(string) + **out = **in + } + if in.ValidationError != nil { + in, out := &in.ValidationError, &out.ValidationError + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolStatus. +func (in *PoolStatus) DeepCopy() *PoolStatus { + if in == nil { + return nil + } + out := new(PoolStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePoolStatusRequest) DeepCopyInto(out *ResourcePoolStatusRequest) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(ResourcePoolStatusRequestStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolStatusRequest. +func (in *ResourcePoolStatusRequest) DeepCopy() *ResourcePoolStatusRequest { + if in == nil { + return nil + } + out := new(ResourcePoolStatusRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourcePoolStatusRequest) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePoolStatusRequestList) DeepCopyInto(out *ResourcePoolStatusRequestList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ResourcePoolStatusRequest, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolStatusRequestList. +func (in *ResourcePoolStatusRequestList) DeepCopy() *ResourcePoolStatusRequestList { + if in == nil { + return nil + } + out := new(ResourcePoolStatusRequestList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ResourcePoolStatusRequestList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePoolStatusRequestSpec) DeepCopyInto(out *ResourcePoolStatusRequestSpec) { + *out = *in + if in.PoolName != nil { + in, out := &in.PoolName, &out.PoolName + *out = new(string) + **out = **in + } + if in.Limit != nil { + in, out := &in.Limit, &out.Limit + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolStatusRequestSpec. +func (in *ResourcePoolStatusRequestSpec) DeepCopy() *ResourcePoolStatusRequestSpec { + if in == nil { + return nil + } + out := new(ResourcePoolStatusRequestSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcePoolStatusRequestStatus) DeepCopyInto(out *ResourcePoolStatusRequestStatus) { + *out = *in + if in.PoolCount != nil { + in, out := &in.PoolCount, &out.PoolCount + *out = new(int32) + **out = **in + } + if in.Pools != nil { + in, out := &in.Pools, &out.Pools + *out = make([]PoolStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePoolStatusRequestStatus. +func (in *ResourcePoolStatusRequestStatus) DeepCopy() *ResourcePoolStatusRequestStatus { + if in == nil { + return nil + } + out := new(ResourcePoolStatusRequestStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.model_name.go b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.model_name.go index 1c1672b4d6..3ef712c223 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.model_name.go +++ b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.model_name.go @@ -60,3 +60,28 @@ func (in DeviceTaintRuleStatus) OpenAPIModelName() string { func (in DeviceTaintSelector) OpenAPIModelName() string { return "io.k8s.api.resource.v1alpha3.DeviceTaintSelector" } + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PoolStatus) OpenAPIModelName() string { + return "io.k8s.api.resource.v1alpha3.PoolStatus" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ResourcePoolStatusRequest) OpenAPIModelName() string { + return "io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequest" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ResourcePoolStatusRequestList) OpenAPIModelName() string { + return "io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ResourcePoolStatusRequestSpec) OpenAPIModelName() string { + return "io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestSpec" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ResourcePoolStatusRequestStatus) OpenAPIModelName() string { + return "io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestStatus" +} diff --git a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.prerelease-lifecycle.go index 08e8b6040f..5b74f40736 100644 --- a/vendor/k8s.io/api/resource/v1alpha3/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/resource/v1alpha3/zz_generated.prerelease-lifecycle.go @@ -56,3 +56,39 @@ func (in *DeviceTaintRuleList) APILifecycleDeprecated() (major, minor int) { func (in *DeviceTaintRuleList) APILifecycleRemoved() (major, minor int) { return 1, 39 } + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ResourcePoolStatusRequest) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ResourcePoolStatusRequest) APILifecycleDeprecated() (major, minor int) { + return 1, 39 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ResourcePoolStatusRequest) APILifecycleRemoved() (major, minor int) { + return 1, 42 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ResourcePoolStatusRequestList) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ResourcePoolStatusRequestList) APILifecycleDeprecated() (major, minor int) { + return 1, 39 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ResourcePoolStatusRequestList) APILifecycleRemoved() (major, minor int) { + return 1, 42 +} diff --git a/vendor/k8s.io/api/resource/v1beta1/generated.pb.go b/vendor/k8s.io/api/resource/v1beta1/generated.pb.go index 1ac7de8a8f..4170f77802 100644 --- a/vendor/k8s.io/api/resource/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/resource/v1beta1/generated.pb.go @@ -25,6 +25,7 @@ import ( io "io" "sort" + k8s_io_api_core_v1 "k8s.io/api/core/v1" v11 "k8s.io/api/core/v1" resource "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -97,6 +98,8 @@ func (m *DeviceToleration) Reset() { *m = DeviceToleration{} } func (m *NetworkDeviceData) Reset() { *m = NetworkDeviceData{} } +func (m *NodeAllocatableResourceMapping) Reset() { *m = NodeAllocatableResourceMapping{} } + func (m *OpaqueDeviceConfiguration) Reset() { *m = OpaqueDeviceConfiguration{} } func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } @@ -283,6 +286,35 @@ func (m *BasicDevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.NodeAllocatableResourceMappings) > 0 { + keysForNodeAllocatableResourceMappings := make([]string, 0, len(m.NodeAllocatableResourceMappings)) + for k := range m.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + for iNdEx := len(keysForNodeAllocatableResourceMappings) - 1; iNdEx >= 0; iNdEx-- { + v := m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(keysForNodeAllocatableResourceMappings[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForNodeAllocatableResourceMappings[iNdEx]) + copy(dAtA[i:], keysForNodeAllocatableResourceMappings[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForNodeAllocatableResourceMappings[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x62 + } + } if m.AllowMultipleAllocations != nil { i-- if *m.AllowMultipleAllocations { @@ -887,6 +919,43 @@ func (m *DeviceAttribute) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.VersionValues) > 0 { + for iNdEx := len(m.VersionValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.VersionValues[iNdEx]) + copy(dAtA[i:], m.VersionValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.VersionValues[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(m.StringValues) > 0 { + for iNdEx := len(m.StringValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.StringValues[iNdEx]) + copy(dAtA[i:], m.StringValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.StringValues[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.BoolValues) > 0 { + for iNdEx := len(m.BoolValues) - 1; iNdEx >= 0; iNdEx-- { + i-- + if m.BoolValues[iNdEx] { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + } + if len(m.IntValues) > 0 { + for iNdEx := len(m.IntValues) - 1; iNdEx >= 0; iNdEx-- { + i = encodeVarintGenerated(dAtA, i, uint64(m.IntValues[iNdEx])) + i-- + dAtA[i] = 0x30 + } + } if m.VersionValue != nil { i -= len(*m.VersionValue) copy(dAtA[i:], *m.VersionValue) @@ -1872,6 +1941,48 @@ func (m *NetworkDeviceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NodeAllocatableResourceMapping) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeAllocatableResourceMapping) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeAllocatableResourceMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AllocationMultiplier != nil { + { + size, err := m.AllocationMultiplier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.CapacityKey != nil { + i -= len(*m.CapacityKey) + copy(dAtA[i:], *m.CapacityKey) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.CapacityKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2635,6 +2746,15 @@ func (m *BasicDevice) Size() (n int) { if m.AllowMultipleAllocations != nil { n += 2 } + if len(m.NodeAllocatableResourceMappings) > 0 { + for k, v := range m.NodeAllocatableResourceMappings { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } return n } @@ -2817,6 +2937,26 @@ func (m *DeviceAttribute) Size() (n int) { l = len(*m.VersionValue) n += 1 + l + sovGenerated(uint64(l)) } + if len(m.IntValues) > 0 { + for _, e := range m.IntValues { + n += 1 + sovGenerated(uint64(e)) + } + } + if len(m.BoolValues) > 0 { + n += 2 * len(m.BoolValues) + } + if len(m.StringValues) > 0 { + for _, s := range m.StringValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.VersionValues) > 0 { + for _, s := range m.VersionValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -3196,6 +3336,23 @@ func (m *NetworkDeviceData) Size() (n int) { return n } +func (m *NodeAllocatableResourceMapping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CapacityKey != nil { + l = len(*m.CapacityKey) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.AllocationMultiplier != nil { + l = m.AllocationMultiplier.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *OpaqueDeviceConfiguration) Size() (n int) { if m == nil { return 0 @@ -3488,6 +3645,16 @@ func (this *BasicDevice) String() string { mapStringForCapacity += fmt.Sprintf("%v: %v,", k, this.Capacity[QualifiedName(k)]) } mapStringForCapacity += "}" + keysForNodeAllocatableResourceMappings := make([]string, 0, len(this.NodeAllocatableResourceMappings)) + for k := range this.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + mapStringForNodeAllocatableResourceMappings := "map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping{" + for _, k := range keysForNodeAllocatableResourceMappings { + mapStringForNodeAllocatableResourceMappings += fmt.Sprintf("%v: %v,", k, this.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(k)]) + } + mapStringForNodeAllocatableResourceMappings += "}" s := strings.Join([]string{`&BasicDevice{`, `Attributes:` + mapStringForAttributes + `,`, `Capacity:` + mapStringForCapacity + `,`, @@ -3500,6 +3667,7 @@ func (this *BasicDevice) String() string { `BindingConditions:` + fmt.Sprintf("%v", this.BindingConditions) + `,`, `BindingFailureConditions:` + fmt.Sprintf("%v", this.BindingFailureConditions) + `,`, `AllowMultipleAllocations:` + valueToStringGenerated(this.AllowMultipleAllocations) + `,`, + `NodeAllocatableResourceMappings:` + mapStringForNodeAllocatableResourceMappings + `,`, `}`, }, "") return s @@ -3647,6 +3815,10 @@ func (this *DeviceAttribute) String() string { `BoolValue:` + valueToStringGenerated(this.BoolValue) + `,`, `StringValue:` + valueToStringGenerated(this.StringValue) + `,`, `VersionValue:` + valueToStringGenerated(this.VersionValue) + `,`, + `IntValues:` + fmt.Sprintf("%v", this.IntValues) + `,`, + `BoolValues:` + fmt.Sprintf("%v", this.BoolValues) + `,`, + `StringValues:` + fmt.Sprintf("%v", this.StringValues) + `,`, + `VersionValues:` + fmt.Sprintf("%v", this.VersionValues) + `,`, `}`, }, "") return s @@ -3931,6 +4103,17 @@ func (this *NetworkDeviceData) String() string { }, "") return s } +func (this *NodeAllocatableResourceMapping) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeAllocatableResourceMapping{`, + `CapacityKey:` + valueToStringGenerated(this.CapacityKey) + `,`, + `AllocationMultiplier:` + strings.Replace(fmt.Sprintf("%v", this.AllocationMultiplier), "Quantity", "resource.Quantity", 1) + `,`, + `}`, + }, "") + return s +} func (this *OpaqueDeviceConfiguration) String() string { if this == nil { return "nil" @@ -5118,6 +5301,135 @@ func (m *BasicDevice) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.AllowMultipleAllocations = &b + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeAllocatableResourceMappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeAllocatableResourceMappings == nil { + m.NodeAllocatableResourceMappings = make(map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping) + } + var mapkey k8s_io_api_core_v1.ResourceName + mapvalue := &NodeAllocatableResourceMapping{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &NodeAllocatableResourceMapping{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -6527,6 +6839,216 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.VersionValue = &s iNdEx = postIndex + case 6: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValues = append(m.IntValues, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.IntValues) == 0 { + m.IntValues = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValues = append(m.IntValues, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field IntValues", wireType) + } + case 7: + if wireType == 0 { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + elementCount = packedLen + if elementCount != 0 && len(m.BoolValues) == 0 { + m.BoolValues = make([]bool, 0, elementCount) + } + for iNdEx < postIndex { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field BoolValues", wireType) + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StringValues = append(m.StringValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VersionValues = append(m.VersionValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9510,6 +10032,125 @@ func (m *NetworkDeviceData) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeAllocatableResourceMapping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CapacityKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := QualifiedName(dAtA[iNdEx:postIndex]) + m.CapacityKey = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMultiplier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AllocationMultiplier == nil { + m.AllocationMultiplier = &resource.Quantity{} + } + if err := m.AllocationMultiplier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *OpaqueDeviceConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/resource/v1beta1/generated.proto b/vendor/k8s.io/api/resource/v1beta1/generated.proto index fe2397a879..79a51ee2c8 100644 --- a/vendor/k8s.io/api/resource/v1beta1/generated.proto +++ b/vendor/k8s.io/api/resource/v1beta1/generated.proto @@ -65,8 +65,8 @@ message AllocatedDeviceStatus { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 7; // Conditions contains the latest observation of the device's state. @@ -90,7 +90,7 @@ message AllocatedDeviceStatus { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional NetworkDeviceData networkData = 6; } @@ -110,7 +110,7 @@ message AllocationResult { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -126,6 +126,7 @@ message BasicDevice { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional map attributes = 1; // Capacity defines the set of capacities for this device. @@ -146,13 +147,13 @@ message BasicDevice { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 repeated DeviceCounterConsumption consumesCounters = 3; // NodeName identifies the node where the device is available. @@ -192,12 +193,13 @@ message BasicDevice { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceTaint taints = 7; // BindsToNode indicates if the usage of an allocation involving this device @@ -205,7 +207,7 @@ message BasicDevice { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -221,14 +223,14 @@ message BasicDevice { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 9; // BindingFailureConditions defines the conditions for binding failure. @@ -239,14 +241,14 @@ message BasicDevice { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 10; // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -257,6 +259,21 @@ message BasicDevice { // +optional // +featureGate=DRAConsumableCapacity optional bool allowMultipleAllocations = 11; + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + map nodeAllocatableResourceMappings = 12; } // CELDeviceSelector contains a CEL expression for selecting a device. @@ -310,6 +327,14 @@ message CELDeviceSelector { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -448,8 +473,8 @@ message CounterSet { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string name = 1; // Counters defines the set of counters for this CounterSet @@ -458,6 +483,8 @@ message CounterSet { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -474,6 +501,7 @@ message Device { // // +optional // +oneOf=deviceType + // +k8s:alpha(since: "1.36")=+k8s:optional optional BasicDevice basic = 2; } @@ -484,7 +512,7 @@ message DeviceAllocationConfiguration { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string source = 1; // Requests lists the names of requests where the configuration applies. @@ -496,10 +524,10 @@ message DeviceAllocationConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 2; optional DeviceConfiguration deviceConfiguration = 3; @@ -511,8 +539,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequestAllocationResult results = 1; // This field is a combination of all the claim and class configuration parameters. @@ -525,8 +553,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 repeated DeviceAllocationConfiguration config = 2; } @@ -535,31 +563,75 @@ message DeviceAttribute { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional int64 int = 2; // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional bool bool = 3; // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string string = 4; // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string version = 5; + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated int64 ints = 6; + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated bool bools = 7; + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string strings = 8; + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string versions = 9; } // DeviceCapacity describes a quantity associated with a device. @@ -595,11 +667,11 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequest requests = 1; // These constraints must be satisfied by the set of devices that get @@ -607,8 +679,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceConstraint constraints = 2; // This field holds configuration for multiple potential drivers which @@ -617,8 +689,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClaimConfiguration config = 3; } @@ -633,10 +705,10 @@ message DeviceClaimConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; optional DeviceConfiguration deviceConfiguration = 2; @@ -652,8 +724,8 @@ message DeviceClaimConfiguration { message DeviceClass { // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec defines what can be allocated and how to configure it. @@ -689,8 +761,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 1; // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -701,8 +773,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClassConfiguration config = 2; // ExtendedResourceName is the extended resource name for the devices of this class. @@ -714,11 +786,11 @@ message DeviceClassSpec { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name optional string extendedResourceName = 4; } @@ -730,7 +802,7 @@ message DeviceConfiguration { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional OpaqueDeviceConfiguration opaque = 1; } @@ -748,10 +820,10 @@ message DeviceConstraint { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; // MatchAttribute requires that all devices in question have this @@ -765,17 +837,27 @@ message DeviceConstraint { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name optional string matchAttribute = 2; // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -797,8 +879,8 @@ message DeviceCounterConsumption { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string counterSet = 1; // Counters defines the counters that will be consumed by the device. @@ -806,6 +888,8 @@ message DeviceCounterConsumption { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -851,8 +935,8 @@ message DeviceRequest { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 3; // AllocationMode and its related fields define how devices are allocated @@ -878,7 +962,7 @@ message DeviceRequest { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 4; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -928,11 +1012,11 @@ message DeviceRequest { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated DeviceSubRequest firstAvailable = 7; // If specified, the request's tolerations. @@ -953,12 +1037,13 @@ message DeviceRequest { // This field can only be set when deviceClassName is set and no subrequests // are specified in the firstAvailable list. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 8; // Capacity define resource requirements against each capacity. @@ -1000,8 +1085,9 @@ message DeviceRequestAllocationResult { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string driver = 2; // This name together with the driver name and the device name field @@ -1011,8 +1097,8 @@ message DeviceRequestAllocationResult { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name optional string pool = 3; // Device references one device instance via its name in the driver's @@ -1038,40 +1124,40 @@ message DeviceRequestAllocationResult { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints - // +k8s:optional - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 repeated DeviceToleration tolerations = 6; // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 7; // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 8; // ShareID uniquely identifies an individual allocation share of the device, @@ -1081,8 +1167,8 @@ message DeviceRequestAllocationResult { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 9; // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1140,8 +1226,8 @@ message DeviceSubRequest { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name optional string deviceClassName = 2; // Selectors define criteria which must be satisfied by a specific @@ -1151,7 +1237,8 @@ message DeviceSubRequest { // // +optional // +listType=atomic - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceSelector selectors = 3; // AllocationMode and its related fields define how devices are allocated @@ -1173,6 +1260,7 @@ message DeviceSubRequest { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 4; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1197,12 +1285,13 @@ message DeviceSubRequest { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 7; // Capacity define resource requirements against each capacity. @@ -1249,12 +1338,21 @@ message DeviceTaint { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string effect = 3; - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; } @@ -1267,8 +1365,8 @@ message DeviceToleration { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key optional string key = 1; // Operator represents a key's relationship to the value. @@ -1278,6 +1376,7 @@ message DeviceToleration { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional optional string operator = 2; // Value is the taint value the toleration matches to. @@ -1291,6 +1390,7 @@ message DeviceToleration { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string effect = 4; // TolerationSeconds represents the period of time the toleration (which must be @@ -1312,11 +1412,11 @@ message NetworkDeviceData { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 optional string interfaceName = 1; // IPs lists the network addresses assigned to the device's network interface. @@ -1329,22 +1429,60 @@ message NetworkDeviceData { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 repeated string ips = 2; // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 optional string hardwareAddress = 3; } +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +message NodeAllocatableResourceMapping { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + optional string capacityKey = 1; + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + optional .k8s.io.apimachinery.pkg.api.resource.Quantity allocationMultiplier = 2; +} + // OpaqueDeviceConfiguration contains configuration parameters for a driver // in a format defined by the driver vendor. message OpaqueDeviceConfiguration { @@ -1358,8 +1496,9 @@ message OpaqueDeviceConfiguration { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless optional string driver = 1; // Parameters can contain arbitrary data. It is the responsibility of @@ -1388,7 +1527,7 @@ message ResourceClaim { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable optional ResourceClaimSpec spec = 2; // Status describes whether the claim is ready to use and what has been allocated. @@ -1443,8 +1582,8 @@ message ResourceClaimStatus { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify optional AllocationResult allocation = 1; // ReservedFor indicates which entities are currently allowed to use @@ -1472,10 +1611,10 @@ message ResourceClaimStatus { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 repeated ResourceClaimConsumerReference reservedFor = 2; // Devices contains the status of each device allocated for this @@ -1483,18 +1622,18 @@ message ResourceClaimStatus { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID repeated AllocatedDeviceStatus devices = 4; } @@ -1608,6 +1747,7 @@ message ResourceSlice { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required optional ResourceSliceSpec spec = 2; } @@ -1682,7 +1822,7 @@ message ResourceSliceSpec { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType repeated Device devices = 6; @@ -1708,14 +1848,14 @@ message ResourceSliceSpec { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated CounterSet sharedCounters = 8; } diff --git a/vendor/k8s.io/api/resource/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/resource/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index e47160fb83..0000000000 --- a/vendor/k8s.io/api/resource/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*AllocatedDeviceStatus) ProtoMessage() {} - -func (*AllocationResult) ProtoMessage() {} - -func (*BasicDevice) ProtoMessage() {} - -func (*CELDeviceSelector) ProtoMessage() {} - -func (*CapacityRequestPolicy) ProtoMessage() {} - -func (*CapacityRequestPolicyRange) ProtoMessage() {} - -func (*CapacityRequirements) ProtoMessage() {} - -func (*Counter) ProtoMessage() {} - -func (*CounterSet) ProtoMessage() {} - -func (*Device) ProtoMessage() {} - -func (*DeviceAllocationConfiguration) ProtoMessage() {} - -func (*DeviceAllocationResult) ProtoMessage() {} - -func (*DeviceAttribute) ProtoMessage() {} - -func (*DeviceCapacity) ProtoMessage() {} - -func (*DeviceClaim) ProtoMessage() {} - -func (*DeviceClaimConfiguration) ProtoMessage() {} - -func (*DeviceClass) ProtoMessage() {} - -func (*DeviceClassConfiguration) ProtoMessage() {} - -func (*DeviceClassList) ProtoMessage() {} - -func (*DeviceClassSpec) ProtoMessage() {} - -func (*DeviceConfiguration) ProtoMessage() {} - -func (*DeviceConstraint) ProtoMessage() {} - -func (*DeviceCounterConsumption) ProtoMessage() {} - -func (*DeviceRequest) ProtoMessage() {} - -func (*DeviceRequestAllocationResult) ProtoMessage() {} - -func (*DeviceSelector) ProtoMessage() {} - -func (*DeviceSubRequest) ProtoMessage() {} - -func (*DeviceTaint) ProtoMessage() {} - -func (*DeviceToleration) ProtoMessage() {} - -func (*NetworkDeviceData) ProtoMessage() {} - -func (*OpaqueDeviceConfiguration) ProtoMessage() {} - -func (*ResourceClaim) ProtoMessage() {} - -func (*ResourceClaimConsumerReference) ProtoMessage() {} - -func (*ResourceClaimList) ProtoMessage() {} - -func (*ResourceClaimSpec) ProtoMessage() {} - -func (*ResourceClaimStatus) ProtoMessage() {} - -func (*ResourceClaimTemplate) ProtoMessage() {} - -func (*ResourceClaimTemplateList) ProtoMessage() {} - -func (*ResourceClaimTemplateSpec) ProtoMessage() {} - -func (*ResourcePool) ProtoMessage() {} - -func (*ResourceSlice) ProtoMessage() {} - -func (*ResourceSliceList) ProtoMessage() {} - -func (*ResourceSliceSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/resource/v1beta1/types.go b/vendor/k8s.io/api/resource/v1beta1/types.go index c55e2e92c9..0d35ac9895 100644 --- a/vendor/k8s.io/api/resource/v1beta1/types.go +++ b/vendor/k8s.io/api/resource/v1beta1/types.go @@ -35,6 +35,10 @@ const ( // special ResourceClaim. Its single valid value is "true". // This is used only inside the scheduler. ExtendedResourceClaimAnnotation = "resource.kubernetes.io/extended-resource-claim" + // PodResourceClaimAnnotation is the annotation set on template-generated + // ResourceClaims by the ResourceClaim controller. Its value is the + // pod.spec.resourceClaims[].name for which the claim was generated. + PodResourceClaimAnnotation = "resource.kubernetes.io/pod-claim-name" // Resource device class prefix is for generating implicit extended resource // name for a device class when its ExtendedResourceName field is not // specified. The generated name is this prefix + the device class name. @@ -82,6 +86,7 @@ type ResourceSlice struct { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required Spec ResourceSliceSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -155,7 +160,7 @@ type ResourceSliceSpec struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType Devices []Device `json:"devices,omitempty" protobuf:"bytes,6,name=devices"` @@ -181,14 +186,14 @@ type ResourceSliceSpec struct { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 SharedCounters []CounterSet `json:"sharedCounters,omitempty" protobuf:"bytes,8,name=sharedCounters"` } @@ -205,8 +210,8 @@ type CounterSet struct { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name Name string `json:"name" protobuf:"bytes,1,name=name"` // Counters defines the set of counters for this CounterSet @@ -215,6 +220,8 @@ type CounterSet struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,name=counters"` } @@ -269,7 +276,14 @@ type ResourcePool struct { const ResourceSliceMaxSharedCapacity = 128 const ResourceSliceMaxDevices = 128 -const ResourceSliceMaxDevicesWithTaintsOrConsumesCounters = 64 + +// ResourceSliceMaxDevicesWithAdvancedFeatures defines the maximum number of devices in a ResourceSlice +// if any of those devices uses advanced features: +// - device taints (DRADeviceTaints feature gate) +// - consuming counters (DRAPartitionableDevices feature gate) +// - list attributes (DRAListTypeAttributes feature gate) +const ResourceSliceMaxDevicesWithAdvancedFeatures = 64 + const PoolNameMaxLength = validation.DNS1123SubdomainMaxLength // Same as for a single node name. const BindingConditionsMaxSize = 4 const BindingFailureConditionsMaxSize = 4 @@ -304,6 +318,7 @@ type Device struct { // // +optional // +oneOf=deviceType + // +k8s:alpha(since: "1.36")=+k8s:optional Basic *BasicDevice `json:"basic,omitempty" protobuf:"bytes,2,opt,name=basic"` } @@ -315,6 +330,7 @@ type BasicDevice struct { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Attributes map[QualifiedName]DeviceAttribute `json:"attributes,omitempty" protobuf:"bytes,1,rep,name=attributes"` // Capacity defines the set of capacities for this device. @@ -335,13 +351,13 @@ type BasicDevice struct { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 ConsumesCounters []DeviceCounterConsumption `json:"consumesCounters,omitempty" protobuf:"bytes,3,rep,name=consumesCounters"` // NodeName identifies the node where the device is available. @@ -381,12 +397,13 @@ type BasicDevice struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Taints []DeviceTaint `json:"taints,omitempty" protobuf:"bytes,7,rep,name=taints"` // BindsToNode indicates if the usage of an allocation involving this device @@ -394,7 +411,7 @@ type BasicDevice struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -410,14 +427,14 @@ type BasicDevice struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,9,rep,name=bindingConditions"` // BindingFailureConditions defines the conditions for binding failure. @@ -428,14 +445,14 @@ type BasicDevice struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,10,rep,name=bindingFailureConditions"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -446,6 +463,59 @@ type BasicDevice struct { // +optional // +featureGate=DRAConsumableCapacity AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty" protobuf:"bytes,11,opt,name=allowMultipleAllocations"` + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + NodeAllocatableResourceMappings map[v1.ResourceName]NodeAllocatableResourceMapping `json:"nodeAllocatableResourceMappings,omitempty" protobuf:"bytes,12,opt,name=nodeAllocatableResourceMappings"` +} + +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMapping struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + CapacityKey *QualifiedName `json:"capacityKey,omitempty" protobuf:"bytes,1,opt,name=capacityKey"` + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty" protobuf:"bytes,2,opt,name=allocationMultiplier"` } // DeviceCounterConsumption defines a set of counters that @@ -455,8 +525,8 @@ type DeviceCounterConsumption struct { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name CounterSet string `json:"counterSet" protobuf:"bytes,1,opt,name=counterSet"` // Counters defines the counters that will be consumed by the device. @@ -464,6 +534,8 @@ type DeviceCounterConsumption struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,opt,name=counters"` } @@ -576,6 +648,10 @@ type CapacityRequestPolicyRange struct { // Limit for the sum of the number of entries in both attributes and capacity. const ResourceSliceMaxAttributesAndCapacitiesPerDevice = 32 +// Limit per device for the total number of string, version, bool or int values +// in list and non-list attributes. +const ResourceSliceMaxAttributeValuesPerDevice = 48 + // QualifiedName is the name of a device attribute or capacity. // // Attributes and capacities are defined either by the owner of the specific @@ -615,31 +691,75 @@ type DeviceAttribute struct { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember IntValue *int64 `json:"int,omitempty" protobuf:"varint,2,opt,name=int"` // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember BoolValue *bool `json:"bool,omitempty" protobuf:"varint,3,opt,name=bool"` // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember StringValue *string `json:"string,omitempty" protobuf:"bytes,4,opt,name=string"` // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember VersionValue *string `json:"version,omitempty" protobuf:"bytes,5,opt,name=version"` + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + IntValues []int64 `json:"ints,omitempty" protobuf:"varint,6,opt,name=ints"` + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + BoolValues []bool `json:"bools,omitempty" protobuf:"varint,7,opt,name=bools"` + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + StringValues []string `json:"strings,omitempty" protobuf:"bytes,8,opt,name=strings"` + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + VersionValues []string `json:"versions,omitempty" protobuf:"bytes,9,opt,name=versions"` } // DeviceAttributeMaxValueLength is the maximum length of a string or version attribute value. @@ -674,7 +794,7 @@ type DeviceTaint struct { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Effect DeviceTaintEffect `json:"effect" protobuf:"bytes,3,name=effect,casttype=DeviceTaintEffect"` // ^^^^ @@ -690,9 +810,18 @@ type DeviceTaint struct { // which will enable adding new enums within a single release without // ratcheting. - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional TimeAdded *metav1.Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` @@ -704,7 +833,7 @@ type DeviceTaint struct { } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTaintEffect string const ( @@ -737,7 +866,7 @@ type ResourceSliceList struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.32 -// +k8s:supportsSubresource=/status +// +k8s:supportsSubresource="/status" // ResourceClaim describes a request for access to resources in the cluster, // for use by workloads. For example, if a workload needs an accelerator device @@ -755,7 +884,7 @@ type ResourceClaim struct { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable Spec ResourceClaimSpec `json:"spec" protobuf:"bytes,2,name=spec"` // Status describes whether the claim is ready to use and what has been allocated. @@ -783,11 +912,11 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []DeviceRequest `json:"requests" protobuf:"bytes,1,name=requests"` // These constraints must be satisfied by the set of devices that get @@ -795,8 +924,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Constraints []DeviceConstraint `json:"constraints,omitempty" protobuf:"bytes,2,opt,name=constraints"` // This field holds configuration for multiple potential drivers which @@ -805,8 +934,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClaimConfiguration `json:"config,omitempty" protobuf:"bytes,3,opt,name=config"` // Potential future extension, ignored by older schedulers. This is @@ -873,8 +1002,8 @@ type DeviceRequest struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -900,7 +1029,7 @@ type DeviceRequest struct { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -950,11 +1079,11 @@ type DeviceRequest struct { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 FirstAvailable []DeviceSubRequest `json:"firstAvailable,omitempty" protobuf:"bytes,7,name=firstAvailable"` // If specified, the request's tolerations. @@ -975,12 +1104,13 @@ type DeviceRequest struct { // This field can only be set when deviceClassName is set and no subrequests // are specified in the firstAvailable list. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,8,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1033,8 +1163,8 @@ type DeviceSubRequest struct { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name DeviceClassName string `json:"deviceClassName" protobuf:"bytes,2,name=deviceClassName"` // Selectors define criteria which must be satisfied by a specific @@ -1044,7 +1174,8 @@ type DeviceSubRequest struct { // // +optional // +listType=atomic - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -1066,6 +1197,7 @@ type DeviceSubRequest struct { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1090,12 +1222,13 @@ type DeviceSubRequest struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,7,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1152,7 +1285,7 @@ const ( ) // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceAllocationMode string // Valid [DeviceRequest.CountMode] values. @@ -1221,6 +1354,14 @@ type CELDeviceSelector struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -1271,10 +1412,10 @@ type DeviceConstraint struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` // MatchAttribute requires that all devices in question have this @@ -1288,12 +1429,17 @@ type DeviceConstraint struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name MatchAttribute *FullyQualifiedName `json:"matchAttribute,omitempty" protobuf:"bytes,2,opt,name=matchAttribute"` // Potential future extension, not part of the current design: @@ -1309,6 +1455,11 @@ type DeviceConstraint struct { // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -1334,10 +1485,10 @@ type DeviceClaimConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,2,name=deviceConfiguration"` @@ -1351,7 +1502,7 @@ type DeviceConfiguration struct { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional Opaque *OpaqueDeviceConfiguration `json:"opaque,omitempty" protobuf:"bytes,1,opt,name=opaque"` } @@ -1368,8 +1519,9 @@ type OpaqueDeviceConfiguration struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless Driver string `json:"driver" protobuf:"bytes,1,name=driver"` // Parameters can contain arbitrary data. It is the responsibility of @@ -1395,8 +1547,8 @@ type DeviceToleration struct { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"` // Operator represents a key's relationship to the value. @@ -1406,6 +1558,7 @@ type DeviceToleration struct { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional Operator DeviceTolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=DeviceTolerationOperator"` // Value is the taint value the toleration matches to. @@ -1419,6 +1572,7 @@ type DeviceToleration struct { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Effect DeviceTaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=DeviceTaintEffect"` // TolerationSeconds represents the period of time the toleration (which must be @@ -1435,7 +1589,7 @@ type DeviceToleration struct { // A toleration operator is the set of operators that can be used in a toleration. // // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTolerationOperator string const ( @@ -1449,8 +1603,8 @@ type ResourceClaimStatus struct { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify Allocation *AllocationResult `json:"allocation,omitempty" protobuf:"bytes,1,opt,name=allocation"` // ReservedFor indicates which entities are currently allowed to use @@ -1478,10 +1632,10 @@ type ResourceClaimStatus struct { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 ReservedFor []ResourceClaimConsumerReference `json:"reservedFor,omitempty" protobuf:"bytes,2,opt,name=reservedFor" patchStrategy:"merge" patchMergeKey:"uid"` // DeallocationRequested is tombstoned since Kubernetes 1.32 where @@ -1494,18 +1648,18 @@ type ResourceClaimStatus struct { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID Devices []AllocatedDeviceStatus `json:"devices,omitempty" protobuf:"bytes,4,opt,name=devices"` } @@ -1554,7 +1708,7 @@ type AllocationResult struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -1568,8 +1722,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Results []DeviceRequestAllocationResult `json:"results,omitempty" protobuf:"bytes,1,opt,name=results"` // This field is a combination of all the claim and class configuration parameters. @@ -1582,8 +1736,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 Config []DeviceAllocationConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` } @@ -1612,8 +1766,9 @@ type DeviceRequestAllocationResult struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Driver string `json:"driver" protobuf:"bytes,2,name=driver"` // This name together with the driver name and the device name field @@ -1623,8 +1778,8 @@ type DeviceRequestAllocationResult struct { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name Pool string `json:"pool" protobuf:"bytes,3,name=pool"` // Device references one device instance via its name in the driver's @@ -1650,40 +1805,40 @@ type DeviceRequestAllocationResult struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints - // +k8s:optional - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,7,rep,name=bindingConditions"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,8,rep,name=bindingFailureConditions"` // ShareID uniquely identifies an individual allocation share of the device, @@ -1693,8 +1848,8 @@ type DeviceRequestAllocationResult struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *types.UID `json:"shareID,omitempty" protobuf:"bytes,9,opt,name=shareID"` // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1718,7 +1873,7 @@ type DeviceAllocationConfiguration struct { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Source AllocationConfigSource `json:"source" protobuf:"bytes,1,name=source"` // Requests lists the names of requests where the configuration applies. @@ -1730,17 +1885,17 @@ type DeviceAllocationConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,2,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,3,name=deviceConfiguration"` } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type AllocationConfigSource string // Valid [DeviceAllocationConfiguration.Source] values. @@ -1779,8 +1934,8 @@ type DeviceClass struct { metav1.TypeMeta `json:",inline"` // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec defines what can be allocated and how to configure it. @@ -1801,8 +1956,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,1,opt,name=selectors"` // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -1813,8 +1968,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClassConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` // SuitableNodes is tombstoned since Kubernetes 1.32 where @@ -1831,11 +1986,11 @@ type DeviceClassSpec struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name ExtendedResourceName *string `json:"extendedResourceName,omitempty" protobuf:"bytes,4,opt,name=extendedResourceName"` } @@ -1961,8 +2116,8 @@ type AllocatedDeviceStatus struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *string `json:"shareID,omitempty" protobuf:"bytes,7,opt,name=shareID"` // Conditions contains the latest observation of the device's state. @@ -1986,7 +2141,7 @@ type AllocatedDeviceStatus struct { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional NetworkData *NetworkDeviceData `json:"networkData,omitempty" protobuf:"bytes,6,opt,name=networkData"` } @@ -1998,11 +2153,11 @@ type NetworkDeviceData struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"` // IPs lists the network addresses assigned to the device's network interface. @@ -2015,18 +2170,18 @@ type NetworkDeviceData struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 IPs []string `json:"ips,omitempty" protobuf:"bytes,2,opt,name=ips"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"` } diff --git a/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go index 070536e67f..4b147a3f3e 100644 --- a/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go @@ -46,7 +46,7 @@ var map_AllocationResult = map[string]string{ "": "AllocationResult contains attributes of an allocated resource.", "devices": "Devices is the result of allocating devices.", "nodeSelector": "NodeSelector defines where the allocated resources are available. If unset, they are available everywhere.", - "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", + "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", } func (AllocationResult) SwaggerDoc() map[string]string { @@ -54,18 +54,19 @@ func (AllocationResult) SwaggerDoc() map[string]string { } var map_BasicDevice = map[string]string{ - "": "BasicDevice defines one device instance.", - "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", - "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is true, a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "": "BasicDevice defines one device instance.", + "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", + "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is true, a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "nodeAllocatableResourceMappings": "NodeAllocatableResourceMappings defines the mapping of node resources that are managed by the DRA driver exposing this device. This includes resources currently reported in v1.Node `status.allocatable` that are not extended resources (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). Examples include \"cpu\", \"memory\", \"ephemeral-storage\", and hugepages. In addition to standard requests made through the Pod `spec`, these resources can also be requested through claims and allocated by the DRA driver. For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory dependencies of an accelerator device. The keys of this map are the node-allocatable resource names (e.g., \"cpu\", \"memory\"). Extended resource names are not permitted as keys.", } func (BasicDevice) SwaggerDoc() map[string]string { @@ -74,7 +75,7 @@ func (BasicDevice) SwaggerDoc() map[string]string { var map_CELDeviceSelector = map[string]string{ "": "CELDeviceSelector contains a CEL expression for selecting a device.", - "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", + "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nWhen the DRAListTypeAttributes feature gate is enabled, the includes() helper is available and it can work for both scalar and list-type attributes. It was introduced to support smooth migration from scalar attributes to list-type attributes while keeping CEL expressions simple. For example:\n\n device.attributes[\"dra.example.com\"].models.includes(\"some-model\")\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", } func (CELDeviceSelector) SwaggerDoc() map[string]string { @@ -162,11 +163,15 @@ func (DeviceAllocationResult) SwaggerDoc() map[string]string { } var map_DeviceAttribute = map[string]string{ - "": "DeviceAttribute must have exactly one field set.", - "int": "IntValue is a number.", - "bool": "BoolValue is a true/false value.", - "string": "StringValue is a string. Must not be longer than 64 characters.", - "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "": "DeviceAttribute must have exactly one field set.", + "int": "IntValue is a number.", + "bool": "BoolValue is a true/false value.", + "string": "StringValue is a string. Must not be longer than 64 characters.", + "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "ints": "IntValues is a non-empty list of numbers.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "bools": "BoolValues is a non-empty list of true/false values.", + "strings": "StringValues is a non-empty list of strings. Each string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "versions": "VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. Each version string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", } func (DeviceAttribute) SwaggerDoc() map[string]string { @@ -235,7 +240,7 @@ var map_DeviceClassSpec = map[string]string{ "": "DeviceClassSpec is used in a [DeviceClass] to define what can be allocated and how to configure it.", "selectors": "Each selector must be satisfied by a device which is claimed via this class.", "config": "Config defines configuration parameters that apply to each device that is claimed via this class. Some classses may potentially be satisfied by multiple drivers, so each instance of a vendor configuration applies to exactly one driver.\n\nThey are passed to the driver, but are not considered while allocating the claim.", - "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is an alpha field.", + "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is a beta field.", } func (DeviceClassSpec) SwaggerDoc() map[string]string { @@ -254,8 +259,8 @@ func (DeviceConfiguration) SwaggerDoc() map[string]string { var map_DeviceConstraint = map[string]string{ "": "DeviceConstraint must have exactly one field set besides Requests.", "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", - "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nMust include the domain qualifier.", - "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", + "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics(i.e., element order and duplicates are ignored): list-valued attributes match when the intersection across all devices is non-empty. Scalar values are treated as singleton sets for backward compatibility.\n\nMust include the domain qualifier.", + "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics (i.e., element order and duplicates are ignored): list-valued attributes must be pairwise disjoint across devices. Scalar values are treated as singleton sets for backward compatibility.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", } func (DeviceConstraint) SwaggerDoc() map[string]string { @@ -281,7 +286,7 @@ var map_DeviceRequest = map[string]string{ "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", "firstAvailable": "FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.\n\nThis field may only be set in the entries of DeviceClaim.Requests.\n\nDRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -296,9 +301,9 @@ var map_DeviceRequestAllocationResult = map[string]string{ "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", - "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", "shareID": "ShareID uniquely identifies an individual allocation share of the device, used when the device supports multiple simultaneous allocations. It serves as an additional map key to differentiate concurrent shares of the same device.", "consumedCapacity": "ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. The consumed amount may differ from the requested amount: it is rounded up to the nearest valid value based on the device’s requestPolicy if applicable (i.e., may not be less than the requested amount).\n\nThe total consumed capacity for each device must not exceed the DeviceCapacity's Value.\n\nThis field is populated only for devices that allow multiple allocations. All capacity entries are included, even if the consumed amount is zero.", } @@ -323,7 +328,7 @@ var map_DeviceSubRequest = map[string]string{ "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this subrequest. All selectors must be satisfied for a device to be considered.", "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this subrequest. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This subrequest is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other subrequests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -336,7 +341,7 @@ var map_DeviceTaint = map[string]string{ "key": "The taint key to be applied to a device. Must be a label name.", "value": "The taint value corresponding to the taint key. Must be a label value.", "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them.\n\nValid effects are None, NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here. More effects may get added in the future. Consumers must treat unknown effects like None.", - "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", + "timeAdded": "TimeAdded represents the time at which the taint was added or (only in a DeviceTaintRule) the effect was modified. Added automatically during create or update if not set.\n\nIn addition, in a DeviceTaintRule a value provided during an update gets replaced with the current time if the provided value is the same as the old one and the new effect is different. Changing the key and/or value while keeping the effect unchanged is possible and does not update the time stamp because the eviction which uses it is either already started (NoExecute) or not started yet (NoEffect, NoSchedule).", } func (DeviceTaint) SwaggerDoc() map[string]string { @@ -358,15 +363,25 @@ func (DeviceToleration) SwaggerDoc() map[string]string { var map_NetworkDeviceData = map[string]string{ "": "NetworkDeviceData provides network-related details for the allocated device. This information may be filled by drivers or other components to configure or identify the device within a network context.", - "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 characters.", + "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 bytes.", "ips": "IPs lists the network addresses assigned to the device's network interface. This can include both IPv4 and IPv6 addresses. The IPs are in the CIDR notation, which includes both the address and the associated subnet mask. e.g.: \"192.0.2.5/24\" for IPv4 and \"2001:db8::5/64\" for IPv6.\n\nMust not contain more than 16 entries.", - "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 characters.", + "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 bytes.", } func (NetworkDeviceData) SwaggerDoc() map[string]string { return map_NetworkDeviceData } +var map_NodeAllocatableResourceMapping = map[string]string{ + "": "NodeAllocatableResourceMapping defines the translation between the DRA device/capacity units requested to the corresponding quantity of the node allocatable resource.", + "capacityKey": "CapacityKey references a capacity name defined as a key in the `spec.devices[*].capacity` map. When this field is set, the value associated with this key in the `status.allocation.devices.results[*].consumedCapacity` map (for a specific claim allocation) determines the base quantity for the node allocatable resource. If `allocationMultiplier` is also set, it is multiplied with the base quantity. For example, if `spec.devices[*].capacity` has an entry \"dra.example.com/memory\": \"128Gi\", and this field is set to \"dra.example.com/memory\", then for a claim allocation that consumes { \"dra.example.com/memory\": \"4Gi\" } the base quantity for the node allocatable resource mapping will be \"4Gi\", and `allocationMultiplier` should be omitted or set to \"1\".", + "allocationMultiplier": "AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim.\n\t a. A DRA driver representing each CPU core as a device would have\n {ResourceName: \"cpu\", allocationMultiplier: \"2\"} in its\n `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim,\n\t\t 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity.\n b. A GPU device that needs additional node memory per GPU allocation would\n have {ResourceName: \"memory\", allocationMultiplier: \"2Gi\"}. Each allocated\n\t\t GPU device instance of this type will account for 2Gi of memory.\n\n2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed.\n\t The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`.\n For example, if a Device's capacity \"dra.example.com/cores\" is consumed,\n and each \"core\" provides 2 \"cpu\"s, the mapping would be:\n {ResourceName: \"cpu\", capacityKey: \"dra.example.com/cores\", allocationMultiplier: \"2\"}.\n If a claim consumes 8 \"dra.example.com/cores\", the CPU footprint is 8 * 2 = 16.", +} + +func (NodeAllocatableResourceMapping) SwaggerDoc() map[string]string { + return map_NodeAllocatableResourceMapping +} + var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", diff --git a/vendor/k8s.io/api/resource/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1beta1/zz_generated.deepcopy.go index 156fea79ba..78ec7b0d58 100644 --- a/vendor/k8s.io/api/resource/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/resource/v1beta1/zz_generated.deepcopy.go @@ -159,6 +159,13 @@ func (in *BasicDevice) DeepCopyInto(out *BasicDevice) { *out = new(bool) **out = **in } + if in.NodeAllocatableResourceMappings != nil { + in, out := &in.NodeAllocatableResourceMappings, &out.NodeAllocatableResourceMappings + *out = make(map[corev1.ResourceName]NodeAllocatableResourceMapping, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } return } @@ -411,6 +418,26 @@ func (in *DeviceAttribute) DeepCopyInto(out *DeviceAttribute) { *out = new(string) **out = **in } + if in.IntValues != nil { + in, out := &in.IntValues, &out.IntValues + *out = make([]int64, len(*in)) + copy(*out, *in) + } + if in.BoolValues != nil { + in, out := &in.BoolValues, &out.BoolValues + *out = make([]bool, len(*in)) + copy(*out, *in) + } + if in.StringValues != nil { + in, out := &in.StringValues, &out.StringValues + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.VersionValues != nil { + in, out := &in.VersionValues, &out.VersionValues + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -907,6 +934,32 @@ func (in *NetworkDeviceData) DeepCopy() *NetworkDeviceData { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeAllocatableResourceMapping) DeepCopyInto(out *NodeAllocatableResourceMapping) { + *out = *in + if in.CapacityKey != nil { + in, out := &in.CapacityKey, &out.CapacityKey + *out = new(QualifiedName) + **out = **in + } + if in.AllocationMultiplier != nil { + in, out := &in.AllocationMultiplier, &out.AllocationMultiplier + x := (*in).DeepCopy() + *out = &x + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAllocatableResourceMapping. +func (in *NodeAllocatableResourceMapping) DeepCopy() *NodeAllocatableResourceMapping { + if in == nil { + return nil + } + out := new(NodeAllocatableResourceMapping) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpaqueDeviceConfiguration) DeepCopyInto(out *OpaqueDeviceConfiguration) { *out = *in diff --git a/vendor/k8s.io/api/resource/v1beta1/zz_generated.model_name.go b/vendor/k8s.io/api/resource/v1beta1/zz_generated.model_name.go index 0d4983d34e..a2887e7534 100644 --- a/vendor/k8s.io/api/resource/v1beta1/zz_generated.model_name.go +++ b/vendor/k8s.io/api/resource/v1beta1/zz_generated.model_name.go @@ -171,6 +171,11 @@ func (in NetworkDeviceData) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta1.NetworkDeviceData" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in NodeAllocatableResourceMapping) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta1.NodeAllocatableResourceMapping" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in OpaqueDeviceConfiguration) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration" diff --git a/vendor/k8s.io/api/resource/v1beta2/generated.pb.go b/vendor/k8s.io/api/resource/v1beta2/generated.pb.go index 5a36e6d2b5..6b59098807 100644 --- a/vendor/k8s.io/api/resource/v1beta2/generated.pb.go +++ b/vendor/k8s.io/api/resource/v1beta2/generated.pb.go @@ -25,6 +25,7 @@ import ( io "io" "sort" + k8s_io_api_core_v1 "k8s.io/api/core/v1" v11 "k8s.io/api/core/v1" resource "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -91,12 +92,24 @@ func (m *DeviceSubRequest) Reset() { *m = DeviceSubRequest{} } func (m *DeviceTaint) Reset() { *m = DeviceTaint{} } +func (m *DeviceTaintRule) Reset() { *m = DeviceTaintRule{} } + +func (m *DeviceTaintRuleList) Reset() { *m = DeviceTaintRuleList{} } + +func (m *DeviceTaintRuleSpec) Reset() { *m = DeviceTaintRuleSpec{} } + +func (m *DeviceTaintRuleStatus) Reset() { *m = DeviceTaintRuleStatus{} } + +func (m *DeviceTaintSelector) Reset() { *m = DeviceTaintSelector{} } + func (m *DeviceToleration) Reset() { *m = DeviceToleration{} } func (m *ExactDeviceRequest) Reset() { *m = ExactDeviceRequest{} } func (m *NetworkDeviceData) Reset() { *m = NetworkDeviceData{} } +func (m *NodeAllocatableResourceMapping) Reset() { *m = NodeAllocatableResourceMapping{} } + func (m *OpaqueDeviceConfiguration) Reset() { *m = OpaqueDeviceConfiguration{} } func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } @@ -573,6 +586,35 @@ func (m *Device) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.NodeAllocatableResourceMappings) > 0 { + keysForNodeAllocatableResourceMappings := make([]string, 0, len(m.NodeAllocatableResourceMappings)) + for k := range m.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + for iNdEx := len(keysForNodeAllocatableResourceMappings) - 1; iNdEx >= 0; iNdEx-- { + v := m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(keysForNodeAllocatableResourceMappings[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForNodeAllocatableResourceMappings[iNdEx]) + copy(dAtA[i:], keysForNodeAllocatableResourceMappings[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForNodeAllocatableResourceMappings[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x6a + } + } if m.AllowMultipleAllocations != nil { i-- if *m.AllowMultipleAllocations { @@ -852,6 +894,43 @@ func (m *DeviceAttribute) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.VersionValues) > 0 { + for iNdEx := len(m.VersionValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.VersionValues[iNdEx]) + copy(dAtA[i:], m.VersionValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.VersionValues[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(m.StringValues) > 0 { + for iNdEx := len(m.StringValues) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.StringValues[iNdEx]) + copy(dAtA[i:], m.StringValues[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.StringValues[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.BoolValues) > 0 { + for iNdEx := len(m.BoolValues) - 1; iNdEx >= 0; iNdEx-- { + i-- + if m.BoolValues[iNdEx] { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + } + if len(m.IntValues) > 0 { + for iNdEx := len(m.IntValues) - 1; iNdEx >= 0; iNdEx-- { + i = encodeVarintGenerated(dAtA, i, uint64(m.IntValues[iNdEx])) + i-- + dAtA[i] = 0x30 + } + } if m.VersionValue != nil { i -= len(*m.VersionValue) copy(dAtA[i:], *m.VersionValue) @@ -1696,6 +1775,232 @@ func (m *DeviceTaint) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *DeviceTaintRule) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceTaintRule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceTaintRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DeviceTaintRuleList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceTaintRuleList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceTaintRuleList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DeviceTaintRuleSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceTaintRuleSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceTaintRuleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Taint.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.DeviceSelector != nil { + { + size, err := m.DeviceSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DeviceTaintRuleStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceTaintRuleStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceTaintRuleStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *DeviceTaintSelector) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceTaintSelector) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceTaintSelector) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Device != nil { + i -= len(*m.Device) + copy(dAtA[i:], *m.Device) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Device))) + i-- + dAtA[i] = 0x22 + } + if m.Pool != nil { + i -= len(*m.Pool) + copy(dAtA[i:], *m.Pool) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Pool))) + i-- + dAtA[i] = 0x1a + } + if m.Driver != nil { + i -= len(*m.Driver) + copy(dAtA[i:], *m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Driver))) + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} + func (m *DeviceToleration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1872,7 +2177,7 @@ func (m *NetworkDeviceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { +func (m *NodeAllocatableResourceMapping) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1882,29 +2187,71 @@ func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *OpaqueDeviceConfiguration) MarshalTo(dAtA []byte) (int, error) { +func (m *NodeAllocatableResourceMapping) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *OpaqueDeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *NodeAllocatableResourceMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Parameters.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.AllocationMultiplier != nil { + { + size, err := m.AllocationMultiplier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } - i-- - dAtA[i] = 0x12 - i -= len(m.Driver) - copy(dAtA[i:], m.Driver) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + if m.CapacityKey != nil { + i -= len(*m.CapacityKey) + copy(dAtA[i:], *m.CapacityKey) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.CapacityKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OpaqueDeviceConfiguration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OpaqueDeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Parameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.Driver) + copy(dAtA[i:], m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -2745,6 +3092,15 @@ func (m *Device) Size() (n int) { if m.AllowMultipleAllocations != nil { n += 2 } + if len(m.NodeAllocatableResourceMappings) > 0 { + for k, v := range m.NodeAllocatableResourceMappings { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } return n } @@ -2808,6 +3164,26 @@ func (m *DeviceAttribute) Size() (n int) { l = len(*m.VersionValue) n += 1 + l + sovGenerated(uint64(l)) } + if len(m.IntValues) > 0 { + for _, e := range m.IntValues { + n += 1 + sovGenerated(uint64(e)) + } + } + if len(m.BoolValues) > 0 { + n += 2 * len(m.BoolValues) + } + if len(m.StringValues) > 0 { + for _, s := range m.StringValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.VersionValues) > 0 { + for _, s := range m.VersionValues { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -3128,6 +3504,89 @@ func (m *DeviceTaint) Size() (n int) { return n } +func (m *DeviceTaintRule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *DeviceTaintRuleList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *DeviceTaintRuleSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.DeviceSelector != nil { + l = m.DeviceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = m.Taint.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *DeviceTaintRuleStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *DeviceTaintSelector) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Driver != nil { + l = len(*m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Pool != nil { + l = len(*m.Pool) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Device != nil { + l = len(*m.Device) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *DeviceToleration) Size() (n int) { if m == nil { return 0 @@ -3200,6 +3659,23 @@ func (m *NetworkDeviceData) Size() (n int) { return n } +func (m *NodeAllocatableResourceMapping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CapacityKey != nil { + l = len(*m.CapacityKey) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.AllocationMultiplier != nil { + l = m.AllocationMultiplier.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *OpaqueDeviceConfiguration) Size() (n int) { if m == nil { return 0 @@ -3586,6 +4062,16 @@ func (this *Device) String() string { mapStringForCapacity += fmt.Sprintf("%v: %v,", k, this.Capacity[QualifiedName(k)]) } mapStringForCapacity += "}" + keysForNodeAllocatableResourceMappings := make([]string, 0, len(this.NodeAllocatableResourceMappings)) + for k := range this.NodeAllocatableResourceMappings { + keysForNodeAllocatableResourceMappings = append(keysForNodeAllocatableResourceMappings, string(k)) + } + sort.Strings(keysForNodeAllocatableResourceMappings) + mapStringForNodeAllocatableResourceMappings := "map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping{" + for _, k := range keysForNodeAllocatableResourceMappings { + mapStringForNodeAllocatableResourceMappings += fmt.Sprintf("%v: %v,", k, this.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(k)]) + } + mapStringForNodeAllocatableResourceMappings += "}" s := strings.Join([]string{`&Device{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Attributes:` + mapStringForAttributes + `,`, @@ -3599,6 +4085,7 @@ func (this *Device) String() string { `BindingConditions:` + fmt.Sprintf("%v", this.BindingConditions) + `,`, `BindingFailureConditions:` + fmt.Sprintf("%v", this.BindingFailureConditions) + `,`, `AllowMultipleAllocations:` + valueToStringGenerated(this.AllowMultipleAllocations) + `,`, + `NodeAllocatableResourceMappings:` + mapStringForNodeAllocatableResourceMappings + `,`, `}`, }, "") return s @@ -3645,6 +4132,10 @@ func (this *DeviceAttribute) String() string { `BoolValue:` + valueToStringGenerated(this.BoolValue) + `,`, `StringValue:` + valueToStringGenerated(this.StringValue) + `,`, `VersionValue:` + valueToStringGenerated(this.VersionValue) + `,`, + `IntValues:` + fmt.Sprintf("%v", this.IntValues) + `,`, + `BoolValues:` + fmt.Sprintf("%v", this.BoolValues) + `,`, + `StringValues:` + fmt.Sprintf("%v", this.StringValues) + `,`, + `VersionValues:` + fmt.Sprintf("%v", this.VersionValues) + `,`, `}`, }, "") return s @@ -3887,6 +4378,72 @@ func (this *DeviceSubRequest) String() string { }, "") return s } +func (this *DeviceTaintRule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaintRule{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "DeviceTaintRuleSpec", "DeviceTaintRuleSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "DeviceTaintRuleStatus", "DeviceTaintRuleStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRuleList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]DeviceTaintRule{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "DeviceTaintRule", "DeviceTaintRule", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&DeviceTaintRuleList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRuleSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaintRuleSpec{`, + `DeviceSelector:` + strings.Replace(this.DeviceSelector.String(), "DeviceTaintSelector", "DeviceTaintSelector", 1) + `,`, + `Taint:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Taint), "DeviceTaint", "DeviceTaint", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRuleStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&DeviceTaintRuleStatus{`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintSelector) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaintSelector{`, + `Driver:` + valueToStringGenerated(this.Driver) + `,`, + `Pool:` + valueToStringGenerated(this.Pool) + `,`, + `Device:` + valueToStringGenerated(this.Device) + `,`, + `}`, + }, "") + return s +} func (this *DeviceToleration) String() string { if this == nil { return "nil" @@ -3939,6 +4496,17 @@ func (this *NetworkDeviceData) String() string { }, "") return s } +func (this *NodeAllocatableResourceMapping) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeAllocatableResourceMapping{`, + `CapacityKey:` + valueToStringGenerated(this.CapacityKey) + `,`, + `AllocationMultiplier:` + strings.Replace(fmt.Sprintf("%v", this.AllocationMultiplier), "Quantity", "resource.Quantity", 1) + `,`, + `}`, + }, "") + return s +} func (this *OpaqueDeviceConfiguration) String() string { if this == nil { return "nil" @@ -6027,61 +6595,11 @@ func (m *Device) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.AllowMultipleAllocations = &b - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceAllocationConfiguration: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceAllocationConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NodeAllocatableResourceMappings", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6091,23 +6609,202 @@ func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = AllocationConfigSource(dAtA[iNdEx:postIndex]) + if m.NodeAllocatableResourceMappings == nil { + m.NodeAllocatableResourceMappings = make(map[k8s_io_api_core_v1.ResourceName]NodeAllocatableResourceMapping) + } + var mapkey k8s_io_api_core_v1.ResourceName + mapvalue := &NodeAllocatableResourceMapping{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &NodeAllocatableResourceMapping{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.NodeAllocatableResourceMappings[k8s_io_api_core_v1.ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceAllocationConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceAllocationConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = AllocationConfigSource(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -6449,76 +7146,286 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.VersionValue = &s iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceCapacity) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceCapacity: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceCapacity: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break + case 6: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } } - } - if msglen < 0 { + m.IntValues = append(m.IntValues, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.IntValues) == 0 { + m.IntValues = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValues = append(m.IntValues, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field IntValues", wireType) + } + case 7: + if wireType == 0 { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + elementCount = packedLen + if elementCount != 0 && len(m.BoolValues) == 0 { + m.BoolValues = make([]bool, 0, elementCount) + } + for iNdEx < postIndex { + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.BoolValues = append(m.BoolValues, bool(v != 0)) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field BoolValues", wireType) + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StringValues = append(m.StringValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionValues", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VersionValues = append(m.VersionValues, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceCapacity) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceCapacity: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceCapacity: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { return ErrInvalidLengthGenerated } postIndex := iNdEx + msglen @@ -8619,33 +9526,601 @@ func (m *DeviceSubRequest) Unmarshal(dAtA []byte) error { if postIndex < 0 { return ErrInvalidLengthGenerated } - if postIndex > l { + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllocationMode = DeviceAllocationMode(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tolerations = append(m.Tolerations, DeviceToleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Capacity == nil { + m.Capacity = &CapacityRequirements{} + } + if err := m.Capacity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaint) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaint: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaint: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeAdded", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TimeAdded == nil { + m.TimeAdded = &v1.Time{} + } + if err := m.TimeAdded.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRuleList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRuleList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, DeviceTaintRule{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.AllocationMode = DeviceAllocationMode(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) - } - m.Count = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Count |= int64(b&0x7F) << shift - if b < 0x80 { - break - } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - case 6: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintRuleSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintRuleSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceSelector", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8672,14 +10147,16 @@ func (m *DeviceSubRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Tolerations = append(m.Tolerations, DeviceToleration{}) - if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.DeviceSelector == nil { + m.DeviceSelector = &DeviceTaintSelector{} + } + if err := m.DeviceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Taint", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8706,10 +10183,7 @@ func (m *DeviceSubRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Capacity == nil { - m.Capacity = &CapacityRequirements{} - } - if err := m.Capacity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Taint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -8734,7 +10208,7 @@ func (m *DeviceSubRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceTaint) Unmarshal(dAtA []byte) error { +func (m *DeviceTaintRuleStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8757,17 +10231,17 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceTaint: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaintRuleStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceTaint: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaintRuleStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -8777,27 +10251,79 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = string(dAtA[iNdEx:postIndex]) + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceTaintSelector: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceTaintSelector: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8825,11 +10351,12 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = string(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.Driver = &s iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8857,13 +10384,14 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.Pool = &s iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TimeAdded", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -8873,27 +10401,24 @@ func (m *DeviceTaint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.TimeAdded == nil { - m.TimeAdded = &v1.Time{} - } - if err := m.TimeAdded.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.Device = &s iNdEx = postIndex default: iNdEx = preIndex @@ -9518,6 +11043,125 @@ func (m *NetworkDeviceData) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeAllocatableResourceMapping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeAllocatableResourceMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CapacityKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := QualifiedName(dAtA[iNdEx:postIndex]) + m.CapacityKey = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMultiplier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AllocationMultiplier == nil { + m.AllocationMultiplier = &resource.Quantity{} + } + if err := m.AllocationMultiplier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *OpaqueDeviceConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/resource/v1beta2/generated.proto b/vendor/k8s.io/api/resource/v1beta2/generated.proto index 76af5aa4e2..82bb033b3e 100644 --- a/vendor/k8s.io/api/resource/v1beta2/generated.proto +++ b/vendor/k8s.io/api/resource/v1beta2/generated.proto @@ -65,8 +65,8 @@ message AllocatedDeviceStatus { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 7; // Conditions contains the latest observation of the device's state. @@ -90,7 +90,7 @@ message AllocatedDeviceStatus { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional NetworkDeviceData networkData = 6; } @@ -110,7 +110,7 @@ message AllocationResult { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -169,6 +169,14 @@ message CELDeviceSelector { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -307,8 +315,8 @@ message CounterSet { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string name = 1; // Counters defines the set of counters for this CounterSet @@ -317,6 +325,8 @@ message CounterSet { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -335,6 +345,7 @@ message Device { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional map attributes = 2; // Capacity defines the set of capacities for this device. @@ -355,13 +366,13 @@ message Device { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 repeated DeviceCounterConsumption consumesCounters = 4; // NodeName identifies the node where the device is available. @@ -402,12 +413,13 @@ message Device { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceTaint taints = 8; // BindsToNode indicates if the usage of an allocation involving this device @@ -415,7 +427,7 @@ message Device { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -431,14 +443,14 @@ message Device { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 10; // BindingFailureConditions defines the conditions for binding failure. @@ -449,14 +461,14 @@ message Device { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 11; // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -467,6 +479,21 @@ message Device { // +optional // +featureGate=DRAConsumableCapacity optional bool allowMultipleAllocations = 12; + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + map nodeAllocatableResourceMappings = 13; } // DeviceAllocationConfiguration gets embedded in an AllocationResult. @@ -476,7 +503,7 @@ message DeviceAllocationConfiguration { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string source = 1; // Requests lists the names of requests where the configuration applies. @@ -488,10 +515,10 @@ message DeviceAllocationConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 2; optional DeviceConfiguration deviceConfiguration = 3; @@ -503,8 +530,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequestAllocationResult results = 1; // This field is a combination of all the claim and class configuration parameters. @@ -517,8 +544,8 @@ message DeviceAllocationResult { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 repeated DeviceAllocationConfiguration config = 2; } @@ -527,31 +554,79 @@ message DeviceAttribute { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional int64 int = 2; // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional bool bool = 3; // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string string = 4; // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember optional string version = 5; + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated int64 ints = 6; + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated bool bools = 7; + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string strings = 8; + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + repeated string versions = 9; } // DeviceCapacity describes a quantity associated with a device. @@ -587,11 +662,11 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceRequest requests = 1; // These constraints must be satisfied by the set of devices that get @@ -599,8 +674,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceConstraint constraints = 2; // This field holds configuration for multiple potential drivers which @@ -609,8 +684,8 @@ message DeviceClaim { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClaimConfiguration config = 3; } @@ -625,10 +700,10 @@ message DeviceClaimConfiguration { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; optional DeviceConfiguration deviceConfiguration = 2; @@ -644,8 +719,8 @@ message DeviceClaimConfiguration { message DeviceClass { // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec defines what can be allocated and how to configure it. @@ -681,8 +756,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 1; // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -693,8 +768,8 @@ message DeviceClassSpec { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceClassConfiguration config = 2; // ExtendedResourceName is the extended resource name for the devices of this class. @@ -706,11 +781,11 @@ message DeviceClassSpec { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name optional string extendedResourceName = 4; } @@ -722,7 +797,7 @@ message DeviceConfiguration { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional OpaqueDeviceConfiguration opaque = 1; } @@ -740,10 +815,10 @@ message DeviceConstraint { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated string requests = 1; // MatchAttribute requires that all devices in question have this @@ -757,17 +832,27 @@ message DeviceConstraint { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name optional string matchAttribute = 2; // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -789,8 +874,8 @@ message DeviceCounterConsumption { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name optional string counterSet = 1; // Counters defines the counters that will be consumed by the device. @@ -798,6 +883,8 @@ message DeviceCounterConsumption { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name map counters = 2; } @@ -827,7 +914,7 @@ message DeviceRequest { // // +optional // +oneOf=deviceRequestType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional ExactDeviceRequest exactly = 2; // FirstAvailable contains subrequests, of which exactly one will be @@ -848,11 +935,11 @@ message DeviceRequest { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated DeviceSubRequest firstAvailable = 3; } @@ -877,8 +964,9 @@ message DeviceRequestAllocationResult { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:required optional string driver = 2; // This name together with the driver name and the device name field @@ -888,8 +976,8 @@ message DeviceRequestAllocationResult { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name optional string pool = 3; // Device references one device instance via its name in the driver's @@ -915,38 +1003,39 @@ message DeviceRequestAllocationResult { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingConditions = 7; // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 repeated string bindingFailureConditions = 8; // ShareID uniquely identifies an individual allocation share of the device, @@ -956,8 +1045,8 @@ message DeviceRequestAllocationResult { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid optional string shareID = 9; // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1014,8 +1103,8 @@ message DeviceSubRequest { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name optional string deviceClassName = 2; // Selectors define criteria which must be satisfied by a specific @@ -1025,8 +1114,8 @@ message DeviceSubRequest { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 3; // AllocationMode and its related fields define how devices are allocated @@ -1048,6 +1137,7 @@ message DeviceSubRequest { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 4; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1072,12 +1162,13 @@ message DeviceSubRequest { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // Capacity define resource requirements against each capacity. @@ -1124,16 +1215,134 @@ message DeviceTaint { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required optional string effect = 3; - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; } +// DeviceTaintRule adds one taint to all devices which match the selector. +// This has the same effect as if the taint was specified directly +// in the ResourceSlice by the DRA driver. +message DeviceTaintRule { + // Standard object metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec specifies the selector and one taint. + // + // Changing the spec automatically increments the metadata.generation number. + // +required + optional DeviceTaintRuleSpec spec = 2; + + // Status provides information about what was requested in the spec. + // + // +optional + optional DeviceTaintRuleStatus status = 3; +} + +// DeviceTaintRuleList is a collection of DeviceTaintRules. +message DeviceTaintRuleList { + // Standard list metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of DeviceTaintRules. + repeated DeviceTaintRule items = 2; +} + +// DeviceTaintRuleSpec specifies the selector and one taint. +message DeviceTaintRuleSpec { + // DeviceSelector defines which device(s) the taint is applied to. + // All selector criteria must be satisfied for a device to + // match. The empty selector matches all devices. Without + // a selector, no devices are matches. + // + // +optional + optional DeviceTaintSelector deviceSelector = 1; + + // The taint that gets applied to matching devices. + // + // +required + optional DeviceTaint taint = 2; +} + +// DeviceTaintRuleStatus provides information about an on-going pod eviction. +message DeviceTaintRuleStatus { + // Conditions provide information about the state of the DeviceTaintRule + // and the cluster at some point in time, + // in a machine-readable and human-readable format. + // + // The following condition is currently defined as part of this API, more may + // get added: + // - Type: EvictionInProgress + // - Status: True if there are currently pods which need to be evicted, False otherwise + // (includes the effects which don't cause eviction). + // - Reason: not specified, may change + // - Message: includes information about number of pending pods and already evicted pods + // in a human-readable format, updated periodically, may change + // + // For `effect: None`, the condition above gets set once for each change to + // the spec, with the message containing information about what would happen + // if the effect was `NoExecute`. This feedback can be used to decide whether + // changing the effect to `NoExecute` will work as intended. It only gets + // set once to avoid having to constantly update the status. + // + // Must have 8 or fewer entries. + // + // +optional + // +listType=map + // +listMapKey=type + // +patchStrategy=merge + // +patchMergeKey=type + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1; +} + +// DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. +// The empty selector matches all devices. Without a selector, no devices +// are matched. +message DeviceTaintSelector { + // If driver is set, only devices from that driver are selected. + // This fields corresponds to slice.spec.driver. + // + // +optional + optional string driver = 2; + + // If pool is set, only devices in that pool are selected. + // + // Also setting the driver name may be useful to avoid + // ambiguity when different drivers use the same pool name, + // but this is not required because selecting pools from + // different drivers may also be useful, for example when + // drivers with node-local devices use the node name as + // their pool name. + // + // +optional + optional string pool = 3; + + // If device is set, only devices with that name are selected. + // This field corresponds to slice.spec.devices[].name. + // + // Setting also driver and pool may be required to avoid ambiguity, + // but is not required. + // + // +optional + optional string device = 4; +} + // The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches // the triple using the matching operator . message DeviceToleration { @@ -1142,8 +1351,8 @@ message DeviceToleration { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key optional string key = 1; // Operator represents a key's relationship to the value. @@ -1153,6 +1362,7 @@ message DeviceToleration { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional optional string operator = 2; // Value is the taint value the toleration matches to. @@ -1166,6 +1376,7 @@ message DeviceToleration { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string effect = 4; // TolerationSeconds represents the period of time the toleration (which must be @@ -1203,8 +1414,8 @@ message ExactDeviceRequest { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 repeated DeviceSelector selectors = 2; // AllocationMode and its related fields define how devices are allocated @@ -1227,7 +1438,7 @@ message ExactDeviceRequest { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional optional string allocationMode = 3; // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1266,12 +1477,13 @@ message ExactDeviceRequest { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional repeated DeviceToleration tolerations = 6; // Capacity define resource requirements against each capacity. @@ -1300,11 +1512,11 @@ message NetworkDeviceData { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 optional string interfaceName = 1; // IPs lists the network addresses assigned to the device's network interface. @@ -1315,22 +1527,60 @@ message NetworkDeviceData { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 repeated string ips = 2; // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 optional string hardwareAddress = 3; } +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +message NodeAllocatableResourceMapping { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + optional string capacityKey = 1; + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + optional .k8s.io.apimachinery.pkg.api.resource.Quantity allocationMultiplier = 2; +} + // OpaqueDeviceConfiguration contains configuration parameters for a driver // in a format defined by the driver vendor. message OpaqueDeviceConfiguration { @@ -1344,8 +1594,9 @@ message OpaqueDeviceConfiguration { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless optional string driver = 1; // Parameters can contain arbitrary data. It is the responsibility of @@ -1374,7 +1625,7 @@ message ResourceClaim { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable optional ResourceClaimSpec spec = 2; // Status describes whether the claim is ready to use and what has been allocated. @@ -1429,8 +1680,8 @@ message ResourceClaimStatus { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify optional AllocationResult allocation = 1; // ReservedFor indicates which entities are currently allowed to use @@ -1458,10 +1709,10 @@ message ResourceClaimStatus { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 repeated ResourceClaimConsumerReference reservedFor = 2; // Devices contains the status of each device allocated for this @@ -1469,18 +1720,18 @@ message ResourceClaimStatus { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID repeated AllocatedDeviceStatus devices = 4; } @@ -1594,6 +1845,7 @@ message ResourceSlice { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required optional ResourceSliceSpec spec = 2; } @@ -1668,7 +1920,7 @@ message ResourceSliceSpec { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType repeated Device devices = 6; @@ -1694,14 +1946,14 @@ message ResourceSliceSpec { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 repeated CounterSet sharedCounters = 8; } diff --git a/vendor/k8s.io/api/resource/v1beta2/generated.protomessage.pb.go b/vendor/k8s.io/api/resource/v1beta2/generated.protomessage.pb.go deleted file mode 100644 index b6417d18c2..0000000000 --- a/vendor/k8s.io/api/resource/v1beta2/generated.protomessage.pb.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta2 - -func (*AllocatedDeviceStatus) ProtoMessage() {} - -func (*AllocationResult) ProtoMessage() {} - -func (*CELDeviceSelector) ProtoMessage() {} - -func (*CapacityRequestPolicy) ProtoMessage() {} - -func (*CapacityRequestPolicyRange) ProtoMessage() {} - -func (*CapacityRequirements) ProtoMessage() {} - -func (*Counter) ProtoMessage() {} - -func (*CounterSet) ProtoMessage() {} - -func (*Device) ProtoMessage() {} - -func (*DeviceAllocationConfiguration) ProtoMessage() {} - -func (*DeviceAllocationResult) ProtoMessage() {} - -func (*DeviceAttribute) ProtoMessage() {} - -func (*DeviceCapacity) ProtoMessage() {} - -func (*DeviceClaim) ProtoMessage() {} - -func (*DeviceClaimConfiguration) ProtoMessage() {} - -func (*DeviceClass) ProtoMessage() {} - -func (*DeviceClassConfiguration) ProtoMessage() {} - -func (*DeviceClassList) ProtoMessage() {} - -func (*DeviceClassSpec) ProtoMessage() {} - -func (*DeviceConfiguration) ProtoMessage() {} - -func (*DeviceConstraint) ProtoMessage() {} - -func (*DeviceCounterConsumption) ProtoMessage() {} - -func (*DeviceRequest) ProtoMessage() {} - -func (*DeviceRequestAllocationResult) ProtoMessage() {} - -func (*DeviceSelector) ProtoMessage() {} - -func (*DeviceSubRequest) ProtoMessage() {} - -func (*DeviceTaint) ProtoMessage() {} - -func (*DeviceToleration) ProtoMessage() {} - -func (*ExactDeviceRequest) ProtoMessage() {} - -func (*NetworkDeviceData) ProtoMessage() {} - -func (*OpaqueDeviceConfiguration) ProtoMessage() {} - -func (*ResourceClaim) ProtoMessage() {} - -func (*ResourceClaimConsumerReference) ProtoMessage() {} - -func (*ResourceClaimList) ProtoMessage() {} - -func (*ResourceClaimSpec) ProtoMessage() {} - -func (*ResourceClaimStatus) ProtoMessage() {} - -func (*ResourceClaimTemplate) ProtoMessage() {} - -func (*ResourceClaimTemplateList) ProtoMessage() {} - -func (*ResourceClaimTemplateSpec) ProtoMessage() {} - -func (*ResourcePool) ProtoMessage() {} - -func (*ResourceSlice) ProtoMessage() {} - -func (*ResourceSliceList) ProtoMessage() {} - -func (*ResourceSliceSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/resource/v1beta2/register.go b/vendor/k8s.io/api/resource/v1beta2/register.go index 5e676a0549..d08534c9e0 100644 --- a/vendor/k8s.io/api/resource/v1beta2/register.go +++ b/vendor/k8s.io/api/resource/v1beta2/register.go @@ -46,6 +46,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &DeviceClass{}, &DeviceClassList{}, + &DeviceTaintRule{}, + &DeviceTaintRuleList{}, &ResourceClaim{}, &ResourceClaimList{}, &ResourceClaimTemplate{}, diff --git a/vendor/k8s.io/api/resource/v1beta2/types.go b/vendor/k8s.io/api/resource/v1beta2/types.go index 4953434884..47a46355f0 100644 --- a/vendor/k8s.io/api/resource/v1beta2/types.go +++ b/vendor/k8s.io/api/resource/v1beta2/types.go @@ -35,6 +35,10 @@ const ( // special ResourceClaim. Its single valid value is "true". // This is used only inside the scheduler. ExtendedResourceClaimAnnotation = "resource.kubernetes.io/extended-resource-claim" + // PodResourceClaimAnnotation is the annotation set on template-generated + // ResourceClaims by the ResourceClaim controller. Its value is the + // pod.spec.resourceClaims[].name for which the claim was generated. + PodResourceClaimAnnotation = "resource.kubernetes.io/pod-claim-name" // Resource device class prefix is for generating implicit extended resource // name for a device class when its ExtendedResourceName field is not // specified. The generated name is this prefix + the device class name. @@ -82,6 +86,7 @@ type ResourceSlice struct { // Contains the information published by the driver. // // Changing the spec automatically increments the metadata.generation number. + // +required Spec ResourceSliceSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -155,7 +160,7 @@ type ResourceSliceSpec struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +zeroOrOneOf=ResourceSliceType Devices []Device `json:"devices,omitempty" protobuf:"bytes,6,name=devices"` @@ -181,14 +186,14 @@ type ResourceSliceSpec struct { // The maximum number of counter sets is 8. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name // +featureGate=DRAPartitionableDevices // +zeroOrOneOf=ResourceSliceType - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 SharedCounters []CounterSet `json:"sharedCounters,omitempty" protobuf:"bytes,8,name=sharedCounters"` } @@ -205,8 +210,8 @@ type CounterSet struct { // It must be a DNS label. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name Name string `json:"name" protobuf:"bytes,1,name=name"` // Counters defines the set of counters for this CounterSet @@ -215,6 +220,8 @@ type CounterSet struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,name=counters"` } @@ -261,7 +268,14 @@ type ResourcePool struct { const ResourceSliceMaxSharedCapacity = 128 const ResourceSliceMaxDevices = 128 -const ResourceSliceMaxDevicesWithTaintsOrConsumesCounters = 64 + +// ResourceSliceMaxDevicesWithAdvancedFeatures defines the maximum number of devices in a ResourceSlice +// if any of those devices uses advanced features: +// - device taints (DRADeviceTaints feature gate) +// - consuming counters (DRAPartitionableDevices feature gate) +// - list attributes (DRAListTypeAttributes feature gate) +const ResourceSliceMaxDevicesWithAdvancedFeatures = 64 + const PoolNameMaxLength = validation.DNS1123SubdomainMaxLength // Same as for a single node name. const BindingConditionsMaxSize = 4 const BindingFailureConditionsMaxSize = 4 @@ -298,6 +312,7 @@ type Device struct { // The maximum number of attributes and capacities combined is 32. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Attributes map[QualifiedName]DeviceAttribute `json:"attributes,omitempty" protobuf:"bytes,2,rep,name=attributes"` // Capacity defines the set of capacities for this device. @@ -318,13 +333,13 @@ type Device struct { // device is 2. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=atomic // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=counterSet + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=counterSet // +featureGate=DRAPartitionableDevices - // +k8s:maxItems=2 + // +k8s:alpha(since: "1.36")=+k8s:maxItems=2 ConsumesCounters []DeviceCounterConsumption `json:"consumesCounters,omitempty" protobuf:"bytes,4,rep,name=consumesCounters"` // NodeName identifies the node where the device is available. @@ -365,12 +380,13 @@ type Device struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Taints []DeviceTaint `json:"taints,omitempty" protobuf:"bytes,8,rep,name=taints"` // BindsToNode indicates if the usage of an allocation involving this device @@ -378,7 +394,7 @@ type Device struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional @@ -394,14 +410,14 @@ type Device struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,10,rep,name=bindingConditions"` // BindingFailureConditions defines the conditions for binding failure. @@ -412,14 +428,14 @@ type Device struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,11,rep,name=bindingFailureConditions"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -430,6 +446,59 @@ type Device struct { // +optional // +featureGate=DRAConsumableCapacity AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty" protobuf:"bytes,12,opt,name=allowMultipleAllocations"` + + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + // +optional + // +featureGate=DRANodeAllocatableResources + NodeAllocatableResourceMappings map[v1.ResourceName]NodeAllocatableResourceMapping `json:"nodeAllocatableResourceMappings,omitempty" protobuf:"bytes,13,opt,name=nodeAllocatableResourceMappings"` +} + +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMapping struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + // +optional + CapacityKey *QualifiedName `json:"capacityKey,omitempty" protobuf:"bytes,1,opt,name=capacityKey"` + + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + // +optional + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty" protobuf:"bytes,2,opt,name=allocationMultiplier"` } // DeviceCounterConsumption defines a set of counters that @@ -439,8 +508,8 @@ type DeviceCounterConsumption struct { // counters defined will be consumed. // // +required - // +k8s:required - // +k8s:format=k8s-short-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-short-name CounterSet string `json:"counterSet" protobuf:"bytes,1,opt,name=counterSet"` // Counters defines the counters that will be consumed by the device. @@ -448,6 +517,8 @@ type DeviceCounterConsumption struct { // The maximum number of counters is 32. // // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:eachKey=+k8s:format=k8s-short-name Counters map[string]Counter `json:"counters,omitempty" protobuf:"bytes,2,opt,name=counters"` } @@ -568,6 +639,10 @@ type CapacityRequestPolicyRange struct { // Limit for the sum of the number of entries in both attributes and capacity. const ResourceSliceMaxAttributesAndCapacitiesPerDevice = 32 +// Limit per device for the total number of string, version, bool or int values +// in list and non-list attributes. +const ResourceSliceMaxAttributeValuesPerDevice = 48 + // QualifiedName is the name of a device attribute or capacity. // // Attributes and capacities are defined either by the owner of the specific @@ -607,31 +682,79 @@ type DeviceAttribute struct { // IntValue is a number. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember IntValue *int64 `json:"int,omitempty" protobuf:"varint,2,opt,name=int"` // BoolValue is a true/false value. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember BoolValue *bool `json:"bool,omitempty" protobuf:"varint,3,opt,name=bool"` // StringValue is a string. Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember StringValue *string `json:"string,omitempty" protobuf:"bytes,4,opt,name=string"` // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. // // +optional - // +k8s:optional - // +k8s:unionMember + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember VersionValue *string `json:"version,omitempty" protobuf:"bytes,5,opt,name=version"` + + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + IntValues []int64 `json:"ints,omitempty" protobuf:"varint,6,opt,name=ints"` + + // BoolValues is a non-empty list of true/false values. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + BoolValues []bool `json:"bools,omitempty" protobuf:"varint,7,opt,name=bools"` + + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + StringValues []string `json:"strings,omitempty" protobuf:"bytes,8,opt,name=strings"` + + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + // + // +optional + // +listType=atomic + // +k8s:listType=atomic + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:unionMember + // +featureGate=DRAListTypeAttributes + VersionValues []string `json:"versions,omitempty" protobuf:"bytes,9,opt,name=versions"` } // DeviceAttributeMaxValueLength is the maximum length of a string or version attribute value. @@ -666,7 +789,7 @@ type DeviceTaint struct { // Consumers must treat unknown effects like None. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Effect DeviceTaintEffect `json:"effect" protobuf:"bytes,3,name=effect,casttype=DeviceTaintEffect"` // ^^^^ @@ -682,9 +805,18 @@ type DeviceTaint struct { // which will enable adding new enums within a single release without // ratcheting. - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). + // // +optional TimeAdded *metav1.Time `json:"timeAdded,omitempty" protobuf:"bytes,4,opt,name=timeAdded"` @@ -696,7 +828,7 @@ type DeviceTaint struct { } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTaintEffect string const ( @@ -712,6 +844,156 @@ const ( DeviceTaintEffectNoExecute DeviceTaintEffect = "NoExecute" ) +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// DeviceTaintRule adds one taint to all devices which match the selector. +// This has the same effect as if the taint was specified directly +// in the ResourceSlice by the DRA driver. +type DeviceTaintRule struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec specifies the selector and one taint. + // + // Changing the spec automatically increments the metadata.generation number. + // +required + Spec DeviceTaintRuleSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // Status provides information about what was requested in the spec. + // + // +optional + Status DeviceTaintRuleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// DeviceTaintRuleSpec specifies the selector and one taint. +type DeviceTaintRuleSpec struct { + // DeviceSelector defines which device(s) the taint is applied to. + // All selector criteria must be satisfied for a device to + // match. The empty selector matches all devices. Without + // a selector, no devices are matches. + // + // +optional + DeviceSelector *DeviceTaintSelector `json:"deviceSelector,omitempty" protobuf:"bytes,1,opt,name=deviceSelector"` + + // The taint that gets applied to matching devices. + // + // +required + Taint DeviceTaint `json:"taint,omitempty" protobuf:"bytes,2,rep,name=taint"` +} + +// DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. +// The empty selector matches all devices. Without a selector, no devices +// are matched. +type DeviceTaintSelector struct { + // If DeviceClassName is set, the selectors defined there must be + // satisfied by a device to be selected. This field corresponds + // to class.metadata.name. + // + // +optional + // + // Tombstoned since 1.35 because it turned out that supporting this in all cases + // would depend on copying the device attributes into the ResourceClaim allocation + // result. Without that the eviction controller cannot evaluate these CEL expressions. + // + // DeviceClassName *string `json:"deviceClassName,omitempty" protobuf:"bytes,1,opt,name=deviceClassName"` + + // If driver is set, only devices from that driver are selected. + // This fields corresponds to slice.spec.driver. + // + // +optional + Driver *string `json:"driver,omitempty" protobuf:"bytes,2,opt,name=driver"` + + // If pool is set, only devices in that pool are selected. + // + // Also setting the driver name may be useful to avoid + // ambiguity when different drivers use the same pool name, + // but this is not required because selecting pools from + // different drivers may also be useful, for example when + // drivers with node-local devices use the node name as + // their pool name. + // + // +optional + Pool *string `json:"pool,omitempty" protobuf:"bytes,3,opt,name=pool"` + + // If device is set, only devices with that name are selected. + // This field corresponds to slice.spec.devices[].name. + // + // Setting also driver and pool may be required to avoid ambiguity, + // but is not required. + // + // +optional + Device *string `json:"device,omitempty" protobuf:"bytes,4,opt,name=device"` + + // Selectors contains the same selection criteria as a ResourceClaim. + // Currently, CEL expressions are supported. All of these selectors + // must be satisfied. + // + // +optional + // +listType=atomic + // + // Tombstoned since 1.35 because it turned out that supporting this in all cases + // would depend on copying the device attributes into the ResourceClaim allocation + // result. Without that the eviction controller cannot evaluate these CEL expressions. + // + // Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,5,rep,name=selectors"` +} + +// DeviceTaintRuleStatus provides information about an on-going pod eviction. +type DeviceTaintRuleStatus struct { + // Conditions provide information about the state of the DeviceTaintRule + // and the cluster at some point in time, + // in a machine-readable and human-readable format. + // + // The following condition is currently defined as part of this API, more may + // get added: + // - Type: EvictionInProgress + // - Status: True if there are currently pods which need to be evicted, False otherwise + // (includes the effects which don't cause eviction). + // - Reason: not specified, may change + // - Message: includes information about number of pending pods and already evicted pods + // in a human-readable format, updated periodically, may change + // + // For `effect: None`, the condition above gets set once for each change to + // the spec, with the message containing information about what would happen + // if the effect was `NoExecute`. This feedback can be used to decide whether + // changing the effect to `NoExecute` will work as intended. It only gets + // set once to avoid having to constantly update the status. + // + // Must have 8 or fewer entries. + // + // +optional + // +listType=map + // +listMapKey=type + // +patchStrategy=merge + // +patchMergeKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// DeviceTaintRuleStatusMaxConditions is the maximum number of conditions in DeviceTaintRuleStatus. +const DeviceTaintRuleStatusMaxConditions = 8 + +// DeviceTaintConditionEvictionInProgress is the publicly documented condition type for the DeviceTaintRuleStatus. +const DeviceTaintConditionEvictionInProgress = "EvictionInProgress" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.36 + +// DeviceTaintRuleList is a collection of DeviceTaintRules. +type DeviceTaintRuleList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of DeviceTaintRules. + Items []DeviceTaintRule `json:"items" protobuf:"bytes,2,rep,name=items"` +} + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.33 @@ -729,7 +1011,7 @@ type ResourceSliceList struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.33 -// +k8s:supportsSubresource=/status +// +k8s:supportsSubresource="/status" // ResourceClaim describes a request for access to resources in the cluster, // for use by workloads. For example, if a workload needs an accelerator device @@ -747,7 +1029,7 @@ type ResourceClaim struct { // Spec describes what is being requested and how to configure it. // The spec is immutable. - // +k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:immutable Spec ResourceClaimSpec `json:"spec" protobuf:"bytes,2,name=spec"` // Status describes whether the claim is ready to use and what has been allocated. @@ -775,11 +1057,11 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []DeviceRequest `json:"requests" protobuf:"bytes,1,name=requests"` // These constraints must be satisfied by the set of devices that get @@ -787,8 +1069,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Constraints []DeviceConstraint `json:"constraints,omitempty" protobuf:"bytes,2,opt,name=constraints"` // This field holds configuration for multiple potential drivers which @@ -797,8 +1079,8 @@ type DeviceClaim struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClaimConfiguration `json:"config,omitempty" protobuf:"bytes,3,opt,name=config"` // Potential future extension, ignored by older schedulers. This is @@ -849,7 +1131,7 @@ type DeviceRequest struct { // // +optional // +oneOf=deviceRequestType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional Exactly *ExactDeviceRequest `json:"exactly,omitempty" protobuf:"bytes,2,name=exactly"` // FirstAvailable contains subrequests, of which exactly one will be @@ -870,11 +1152,11 @@ type DeviceRequest struct { // +oneOf=deviceRequestType // +listType=atomic // +featureGate=DRAPrioritizedList - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=map - // +k8s:listMapKey=name - // +k8s:maxItems=8 + // +k8s:alpha(since: "1.36")=+k8s:unique=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=name + // +k8s:alpha(since: "1.36")=+k8s:maxItems=8 FirstAvailable []DeviceSubRequest `json:"firstAvailable,omitempty" protobuf:"bytes,3,name=firstAvailable"` } @@ -902,8 +1184,8 @@ type ExactDeviceRequest struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,2,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -926,7 +1208,7 @@ type ExactDeviceRequest struct { // requests with unknown modes. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,3,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -965,12 +1247,13 @@ type ExactDeviceRequest struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1022,8 +1305,8 @@ type DeviceSubRequest struct { // to reference. // // +required - // +k8s:required - // +k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name DeviceClassName string `json:"deviceClassName" protobuf:"bytes,2,name=deviceClassName"` // Selectors define criteria which must be satisfied by a specific @@ -1033,8 +1316,8 @@ type DeviceSubRequest struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` // AllocationMode and its related fields define how devices are allocated @@ -1056,6 +1339,7 @@ type DeviceSubRequest struct { // requests with unknown modes. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` // Count is used only when the count mode is "ExactCount". Must be greater than zero. @@ -1080,12 +1364,13 @@ type DeviceSubRequest struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // Capacity define resource requirements against each capacity. @@ -1142,7 +1427,7 @@ const ( ) // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceAllocationMode string // Valid [DeviceRequest.CountMode] values. @@ -1211,6 +1496,14 @@ type CELDeviceSelector struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. @@ -1261,10 +1554,10 @@ type DeviceConstraint struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` // MatchAttribute requires that all devices in question have this @@ -1278,12 +1571,17 @@ type DeviceConstraint struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. // // +optional // +oneOf=ConstraintType - // +k8s:optional - // +k8s:format=k8s-resource-fully-qualified-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-fully-qualified-name MatchAttribute *FullyQualifiedName `json:"matchAttribute,omitempty" protobuf:"bytes,2,opt,name=matchAttribute"` // Potential future extension, not part of the current design: @@ -1299,6 +1597,11 @@ type DeviceConstraint struct { // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device @@ -1324,10 +1627,10 @@ type DeviceClaimConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,2,name=deviceConfiguration"` @@ -1341,7 +1644,7 @@ type DeviceConfiguration struct { // // +optional // +oneOf=ConfigurationType - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional Opaque *OpaqueDeviceConfiguration `json:"opaque,omitempty" protobuf:"bytes,1,opt,name=opaque"` } @@ -1358,8 +1661,9 @@ type OpaqueDeviceConfiguration struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:required - // +k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless Driver string `json:"driver" protobuf:"bytes,1,name=driver"` // Parameters can contain arbitrary data. It is the responsibility of @@ -1385,8 +1689,8 @@ type DeviceToleration struct { // Must be a label name. // // +optional - // +k8s:optional - // +k8s:format=k8s-label-key + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-label-key Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"` // Operator represents a key's relationship to the value. @@ -1396,6 +1700,7 @@ type DeviceToleration struct { // // +optional // +default="Equal" + // +k8s:alpha(since: "1.36")=+k8s:optional Operator DeviceTolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=DeviceTolerationOperator"` // Value is the taint value the toleration matches to. @@ -1409,6 +1714,7 @@ type DeviceToleration struct { // When specified, allowed values are NoSchedule and NoExecute. // // +optional + // +k8s:alpha(since: "1.36")=+k8s:optional Effect DeviceTaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=DeviceTaintEffect"` // TolerationSeconds represents the period of time the toleration (which must be @@ -1425,7 +1731,7 @@ type DeviceToleration struct { // A toleration operator is the set of operators that can be used in a toleration. // // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type DeviceTolerationOperator string const ( @@ -1439,8 +1745,8 @@ type ResourceClaimStatus struct { // Allocation is set once the claim has been allocated successfully. // // +optional - // +k8s:optional - // +k8s:update=NoModify + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:update=NoModify Allocation *AllocationResult `json:"allocation,omitempty" protobuf:"bytes,1,opt,name=allocation"` // ReservedFor indicates which entities are currently allowed to use @@ -1468,10 +1774,10 @@ type ResourceClaimStatus struct { // +listMapKey=uid // +patchStrategy=merge // +patchMergeKey=uid - // +k8s:optional - // +k8s:listType=map - // +k8s:listMapKey=uid - // +k8s:maxItems=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=uid + // +k8s:alpha(since: "1.36")=+k8s:maxItems=256 ReservedFor []ResourceClaimConsumerReference `json:"reservedFor,omitempty" protobuf:"bytes,2,opt,name=reservedFor" patchStrategy:"merge" patchMergeKey:"uid"` // DeallocationRequested is tombstoned since Kubernetes 1.32 where @@ -1484,18 +1790,18 @@ type ResourceClaimStatus struct { // information. Entries are owned by their respective drivers. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +listType=map // +listMapKey=driver // +listMapKey=device // +listMapKey=pool // +listMapKey=shareID // +featureGate=DRAResourceClaimDeviceStatus - // +k8s:listType=map - // +k8s:listMapKey=driver - // +k8s:listMapKey=device - // +k8s:listMapKey=pool - // +k8s:listMapKey=shareID + // +k8s:alpha(since: "1.36")=+k8s:listType=map + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=driver + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=device + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=pool + // +k8s:alpha(since: "1.36")=+k8s:listMapKey=shareID Devices []AllocatedDeviceStatus `json:"devices,omitempty" protobuf:"bytes,4,opt,name=devices"` } @@ -1544,7 +1850,7 @@ type AllocationResult struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. // // +optional @@ -1558,8 +1864,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Results []DeviceRequestAllocationResult `json:"results,omitempty" protobuf:"bytes,1,opt,name=results"` // This field is a combination of all the claim and class configuration parameters. @@ -1572,8 +1878,8 @@ type DeviceAllocationResult struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=64 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=64 Config []DeviceAllocationConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` } @@ -1602,8 +1908,9 @@ type DeviceRequestAllocationResult struct { // vendor of the driver. It should use only lower case characters. // // +required - // +k8s:format=k8s-long-name-caseless - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-long-name-caseless + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 + // +k8s:alpha(since: "1.36")=+k8s:required Driver string `json:"driver" protobuf:"bytes,2,name=driver"` // This name together with the driver name and the device name field @@ -1613,8 +1920,8 @@ type DeviceRequestAllocationResult struct { // DNS sub-domains separated by slashes. // // +required - // +k8s:required - // +k8s:format=k8s-resource-pool-name + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-resource-pool-name Pool string `json:"pool" protobuf:"bytes,3,name=pool"` // Device references one device instance via its name in the driver's @@ -1640,38 +1947,39 @@ type DeviceRequestAllocationResult struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. // // +optional // +listType=atomic // +featureGate=DRADeviceTaints + // +k8s:alpha(since: "1.36")=+k8s:optional Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingConditions []string `json:"bindingConditions,omitempty" protobuf:"bytes,7,rep,name=bindingConditions"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. // // +optional // +listType=atomic // +featureGate=DRADeviceBindingConditions,DRAResourceClaimDeviceStatus - // +k8s:optional - // +k8s:maxItems=4 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=4 BindingFailureConditions []string `json:"bindingFailureConditions,omitempty" protobuf:"bytes,8,rep,name=bindingFailureConditions"` // ShareID uniquely identifies an individual allocation share of the device, @@ -1681,8 +1989,8 @@ type DeviceRequestAllocationResult struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *types.UID `json:"shareID,omitempty" protobuf:"bytes,9,opt,name=shareID"` // ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. @@ -1706,7 +2014,7 @@ type DeviceAllocationConfiguration struct { // or from a claim. // // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required Source AllocationConfigSource `json:"source" protobuf:"bytes,1,name=source"` // Requests lists the names of requests where the configuration applies. @@ -1718,17 +2026,17 @@ type DeviceAllocationConfiguration struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Requests []string `json:"requests,omitempty" protobuf:"bytes,2,opt,name=requests"` DeviceConfiguration `json:",inline" protobuf:"bytes,3,name=deviceConfiguration"` } // +enum -// +k8s:enum +// +k8s:alpha(since: "1.36")=+k8s:enum type AllocationConfigSource string // Valid [DeviceAllocationConfiguration.Source] values. @@ -1767,8 +2075,8 @@ type DeviceClass struct { metav1.TypeMeta `json:",inline"` // Standard object metadata // +optional - // +k8s:subfield(name)=+k8s:optional - // +k8s:subfield(name)=+k8s:format=k8s-long-name + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:subfield(name)=+k8s:format=k8s-long-name metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec defines what can be allocated and how to configure it. @@ -1789,8 +2097,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,1,opt,name=selectors"` // Config defines configuration parameters that apply to each device that is claimed via this class. @@ -1801,8 +2109,8 @@ type DeviceClassSpec struct { // // +optional // +listType=atomic - // +k8s:optional - // +k8s:maxItems=32 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxItems=32 Config []DeviceClassConfiguration `json:"config,omitempty" protobuf:"bytes,2,opt,name=config"` // SuitableNodes is tombstoned since Kubernetes 1.32 where @@ -1819,11 +2127,11 @@ type DeviceClassSpec struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. // +optional // +featureGate=DRAExtendedResource - // +k8s:optional - // +k8s:format=k8s-extended-resource-name + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-extended-resource-name ExtendedResourceName *string `json:"extendedResourceName,omitempty" protobuf:"bytes,4,opt,name=extendedResourceName"` } @@ -1949,8 +2257,8 @@ type AllocatedDeviceStatus struct { // // +optional // +featureGate=DRAConsumableCapacity - // +k8s:optional - // +k8s:format=k8s-uuid + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:format=k8s-uuid ShareID *string `json:"shareID,omitempty" protobuf:"bytes,7,opt,name=shareID"` // Conditions contains the latest observation of the device's state. @@ -1974,7 +2282,7 @@ type AllocatedDeviceStatus struct { // NetworkData contains network-related information specific to the device. // // +optional - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional NetworkData *NetworkDeviceData `json:"networkData,omitempty" protobuf:"bytes,6,opt,name=networkData"` } @@ -1986,11 +2294,11 @@ type NetworkDeviceData struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=256 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=256 InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"` // IPs lists the network addresses assigned to the device's network interface. @@ -2001,18 +2309,18 @@ type NetworkDeviceData struct { // // +optional // +listType=atomic - // +k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:optional // +k8s:listType=atomic - // +k8s:unique=set - // +k8s:maxItems=16 + // +k8s:alpha(since: "1.36")=+k8s:unique=set + // +k8s:alpha(since: "1.36")=+k8s:maxItems=16 IPs []string `json:"ips,omitempty" protobuf:"bytes,2,opt,name=ips"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. // // +optional - // +k8s:optional - // +k8s:maxLength=128 + // +k8s:alpha(since: "1.36")=+k8s:optional + // +k8s:alpha(since: "1.36")=+k8s:maxBytes=128 HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"` } diff --git a/vendor/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go index a086f9bf23..122170ec25 100644 --- a/vendor/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go @@ -46,7 +46,7 @@ var map_AllocationResult = map[string]string{ "": "AllocationResult contains attributes of an allocated resource.", "devices": "Devices is the result of allocating devices.", "nodeSelector": "NodeSelector defines where the allocated resources are available. If unset, they are available everywhere.", - "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", + "allocationTimestamp": "AllocationTimestamp stores the time when the resources were allocated. This field is not guaranteed to be set, in which case that time is unknown.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gate.", } func (AllocationResult) SwaggerDoc() map[string]string { @@ -55,7 +55,7 @@ func (AllocationResult) SwaggerDoc() map[string]string { var map_CELDeviceSelector = map[string]string{ "": "CELDeviceSelector contains a CEL expression for selecting a device.", - "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", + "expression": "Expression is a CEL expression which evaluates a single device. It must evaluate to true when the device under consideration satisfies the desired criteria, and false when it does not. Any other result is an error and causes allocation of devices to abort.\n\nThe expression's input is an object named \"device\", which carries the following properties:\n - driver (string): the name of the driver which defines this device.\n - attributes (map[string]object): the device's attributes, grouped by prefix\n (e.g. device.attributes[\"dra.example.com\"] evaluates to an object with all\n of the attributes which were prefixed by \"dra.example.com\".\n - capacity (map[string]object): the device's capacities, grouped by prefix.\n - allowMultipleAllocations (bool): the allowMultipleAllocations property of the device\n (v1.34+ with the DRAConsumableCapacity feature enabled).\n\nExample: Consider a device with driver=\"dra.example.com\", which exposes two attributes named \"model\" and \"ext.example.com/family\" and which exposes one capacity named \"modules\". This input to this expression would have the following fields:\n\n device.driver\n device.attributes[\"dra.example.com\"].model\n device.attributes[\"ext.example.com\"].family\n device.capacity[\"dra.example.com\"].modules\n\nThe device.driver field can be used to check for a specific driver, either as a high-level precondition (i.e. you only want to consider devices from this driver) or as part of a multi-clause expression that is meant to consider devices from different drivers.\n\nThe value type of each attribute is defined by the device definition, and users who write these expressions must consult the documentation for their specific drivers. The value type of each capacity is Quantity.\n\nIf an unknown prefix is used as a lookup in either device.attributes or device.capacity, an empty map will be returned. Any reference to an unknown field will cause an evaluation error and allocation to abort.\n\nA robust expression should check for the existence of attributes before referencing them.\n\nFor ease of use, the cel.bind() function is enabled, and can be used to simplify expressions that access multiple attributes with the same domain. For example:\n\n cel.bind(dra, device.attributes[\"dra.example.com\"], dra.someBool && dra.anotherBool)\n\nWhen the DRAListTypeAttributes feature gate is enabled, the includes() helper is available and it can work for both scalar and list-type attributes. It was introduced to support smooth migration from scalar attributes to list-type attributes while keeping CEL expressions simple. For example:\n\n device.attributes[\"dra.example.com\"].models.includes(\"some-model\")\n\nThe length of the expression must be smaller or equal to 10 Ki. The cost of evaluating it is also limited based on the estimated number of logical steps.", } func (CELDeviceSelector) SwaggerDoc() map[string]string { @@ -113,19 +113,20 @@ func (CounterSet) SwaggerDoc() map[string]string { } var map_Device = map[string]string{ - "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", - "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", - "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", - "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", - "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is set to \"True\", a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", + "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", + "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe maximum number of device counter consumptions per device is 2.", + "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 16. If taints are set for any device in a ResourceSlice, then the maximum number of allowed devices per ResourceSlice is 64 instead of 128.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindsToNode": "BindsToNode indicates if the usage of an allocation involving this device has to be limited to exactly the node that was chosen when allocating the claim. If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector to match the node where the allocation was made.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingConditions": "BindingConditions defines the conditions for proceeding with binding. All of these conditions must be set in the per-device status conditions with a value of True to proceed with binding the pod to the node while scheduling the pod.\n\nThe maximum number of binding conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions defines the conditions for binding failure. They may be set in the per-device status conditions. If any is set to \"True\", a binding failure occurred.\n\nThe maximum number of binding failure conditions is 4.\n\nThe conditions must be a valid condition type string.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "allowMultipleAllocations": "AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests.\n\nIf AllowMultipleAllocations is set to true, the device can be allocated more than once, and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not.", + "nodeAllocatableResourceMappings": "NodeAllocatableResourceMappings defines the mapping of node resources that are managed by the DRA driver exposing this device. This includes resources currently reported in v1.Node `status.allocatable` that are not extended resources (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). Examples include \"cpu\", \"memory\", \"ephemeral-storage\", and hugepages. In addition to standard requests made through the Pod `spec`, these resources can also be requested through claims and allocated by the DRA driver. For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory dependencies of an accelerator device. The keys of this map are the node-allocatable resource names (e.g., \"cpu\", \"memory\"). Extended resource names are not permitted as keys.", } func (Device) SwaggerDoc() map[string]string { @@ -153,11 +154,15 @@ func (DeviceAllocationResult) SwaggerDoc() map[string]string { } var map_DeviceAttribute = map[string]string{ - "": "DeviceAttribute must have exactly one field set.", - "int": "IntValue is a number.", - "bool": "BoolValue is a true/false value.", - "string": "StringValue is a string. Must not be longer than 64 characters.", - "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "": "DeviceAttribute must have exactly one field set.", + "int": "IntValue is a number.", + "bool": "BoolValue is a true/false value.", + "string": "StringValue is a string. Must not be longer than 64 characters.", + "version": "VersionValue is a semantic version according to semver.org spec 2.0.0. Must not be longer than 64 characters.", + "ints": "IntValues is a non-empty list of numbers.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "bools": "BoolValues is a non-empty list of true/false values.", + "strings": "StringValues is a non-empty list of strings. Each string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", + "versions": "VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. Each version string must not be longer than 64 characters.\n\nThis is an alpha field and requires enabling the DRAListTypeAttributes feature gate.", } func (DeviceAttribute) SwaggerDoc() map[string]string { @@ -226,7 +231,7 @@ var map_DeviceClassSpec = map[string]string{ "": "DeviceClassSpec is used in a [DeviceClass] to define what can be allocated and how to configure it.", "selectors": "Each selector must be satisfied by a device which is claimed via this class.", "config": "Config defines configuration parameters that apply to each device that is claimed via this class. Some classses may potentially be satisfied by multiple drivers, so each instance of a vendor configuration applies to exactly one driver.\n\nThey are passed to the driver, but are not considered while allocating the claim.", - "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is an alpha field.", + "extendedResourceName": "ExtendedResourceName is the extended resource name for the devices of this class. The devices of this class can be used to satisfy a pod's extended resource requests. It has the same format as the name of a pod's extended resource. It should be unique among all the device classes in a cluster. If two device classes have the same name, then the class created later is picked to satisfy a pod's extended resource requests. If two classes are created at the same time, then the name of the class lexicographically sorted first is picked.\n\nThis is a beta field.", } func (DeviceClassSpec) SwaggerDoc() map[string]string { @@ -245,8 +250,8 @@ func (DeviceConfiguration) SwaggerDoc() map[string]string { var map_DeviceConstraint = map[string]string{ "": "DeviceConstraint must have exactly one field set besides Requests.", "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", - "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nMust include the domain qualifier.", - "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", + "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics(i.e., element order and duplicates are ignored): list-valued attributes match when the intersection across all devices is non-empty. Scalar values are treated as singleton sets for backward compatibility.\n\nMust include the domain qualifier.", + "distinctAttribute": "DistinctAttribute requires that all devices in question have this attribute and that its type and value are unique across those devices.\n\nWhen the DRAListTypeAttributes feature gate is enabled, comparison uses set semantics (i.e., element order and duplicates are ignored): list-valued attributes must be pairwise disjoint across devices. Scalar values are treated as singleton sets for backward compatibility.\n\nThis acts as the inverse of MatchAttribute.\n\nThis constraint is used to avoid allocating multiple requests to the same device by ensuring attribute-level differentiation.\n\nThis is useful for scenarios where resource requests must be fulfilled by separate physical devices. For example, a container requests two network interfaces that must be allocated from two different physical NICs.", } func (DeviceConstraint) SwaggerDoc() map[string]string { @@ -281,9 +286,9 @@ var map_DeviceRequestAllocationResult = map[string]string{ "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", - "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", - "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", - "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", + "bindingConditions": "BindingConditions contains a copy of the BindingConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", + "bindingFailureConditions": "BindingFailureConditions contains a copy of the BindingFailureConditions from the corresponding ResourceSlice at the time of allocation.\n\nThis is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus feature gates.", "shareID": "ShareID uniquely identifies an individual allocation share of the device, used when the device supports multiple simultaneous allocations. It serves as an additional map key to differentiate concurrent shares of the same device.", "consumedCapacity": "ConsumedCapacity tracks the amount of capacity consumed per device as part of the claim request. The consumed amount may differ from the requested amount: it is rounded up to the nearest valid value based on the device’s requestPolicy if applicable (i.e., may not be less than the requested amount).\n\nThe total consumed capacity for each device must not exceed the DeviceCapacity's Value.\n\nThis field is populated only for devices that allow multiple allocations. All capacity entries are included, even if the consumed amount is zero.", } @@ -308,7 +313,7 @@ var map_DeviceSubRequest = map[string]string{ "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this subrequest. All selectors must be satisfied for a device to be considered.", "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this subrequest. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This subrequest is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other subrequests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -321,13 +326,64 @@ var map_DeviceTaint = map[string]string{ "key": "The taint key to be applied to a device. Must be a label name.", "value": "The taint value corresponding to the taint key. Must be a label value.", "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them.\n\nValid effects are None, NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here. More effects may get added in the future. Consumers must treat unknown effects like None.", - "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", + "timeAdded": "TimeAdded represents the time at which the taint was added or (only in a DeviceTaintRule) the effect was modified. Added automatically during create or update if not set.\n\nIn addition, in a DeviceTaintRule a value provided during an update gets replaced with the current time if the provided value is the same as the old one and the new effect is different. Changing the key and/or value while keeping the effect unchanged is possible and does not update the time stamp because the eviction which uses it is either already started (NoExecute) or not started yet (NoEffect, NoSchedule).", } func (DeviceTaint) SwaggerDoc() map[string]string { return map_DeviceTaint } +var map_DeviceTaintRule = map[string]string{ + "": "DeviceTaintRule adds one taint to all devices which match the selector. This has the same effect as if the taint was specified directly in the ResourceSlice by the DRA driver.", + "metadata": "Standard object metadata", + "spec": "Spec specifies the selector and one taint.\n\nChanging the spec automatically increments the metadata.generation number.", + "status": "Status provides information about what was requested in the spec.", +} + +func (DeviceTaintRule) SwaggerDoc() map[string]string { + return map_DeviceTaintRule +} + +var map_DeviceTaintRuleList = map[string]string{ + "": "DeviceTaintRuleList is a collection of DeviceTaintRules.", + "metadata": "Standard list metadata", + "items": "Items is the list of DeviceTaintRules.", +} + +func (DeviceTaintRuleList) SwaggerDoc() map[string]string { + return map_DeviceTaintRuleList +} + +var map_DeviceTaintRuleSpec = map[string]string{ + "": "DeviceTaintRuleSpec specifies the selector and one taint.", + "deviceSelector": "DeviceSelector defines which device(s) the taint is applied to. All selector criteria must be satisfied for a device to match. The empty selector matches all devices. Without a selector, no devices are matches.", + "taint": "The taint that gets applied to matching devices.", +} + +func (DeviceTaintRuleSpec) SwaggerDoc() map[string]string { + return map_DeviceTaintRuleSpec +} + +var map_DeviceTaintRuleStatus = map[string]string{ + "": "DeviceTaintRuleStatus provides information about an on-going pod eviction.", + "conditions": "Conditions provide information about the state of the DeviceTaintRule and the cluster at some point in time, in a machine-readable and human-readable format.\n\nThe following condition is currently defined as part of this API, more may get added: - Type: EvictionInProgress - Status: True if there are currently pods which need to be evicted, False otherwise\n (includes the effects which don't cause eviction).\n- Reason: not specified, may change - Message: includes information about number of pending pods and already evicted pods\n in a human-readable format, updated periodically, may change\n\nFor `effect: None`, the condition above gets set once for each change to the spec, with the message containing information about what would happen if the effect was `NoExecute`. This feedback can be used to decide whether changing the effect to `NoExecute` will work as intended. It only gets set once to avoid having to constantly update the status.\n\nMust have 8 or fewer entries.", +} + +func (DeviceTaintRuleStatus) SwaggerDoc() map[string]string { + return map_DeviceTaintRuleStatus +} + +var map_DeviceTaintSelector = map[string]string{ + "": "DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. The empty selector matches all devices. Without a selector, no devices are matched.", + "driver": "If driver is set, only devices from that driver are selected. This fields corresponds to slice.spec.driver.", + "pool": "If pool is set, only devices in that pool are selected.\n\nAlso setting the driver name may be useful to avoid ambiguity when different drivers use the same pool name, but this is not required because selecting pools from different drivers may also be useful, for example when drivers with node-local devices use the node name as their pool name.", + "device": "If device is set, only devices with that name are selected. This field corresponds to slice.spec.devices[].name.\n\nSetting also driver and pool may be required to avoid ambiguity, but is not required.", +} + +func (DeviceTaintSelector) SwaggerDoc() map[string]string { + return map_DeviceTaintSelector +} + var map_DeviceToleration = map[string]string{ "": "The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches the triple using the matching operator .", "key": "Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. Must be a label name.", @@ -348,7 +404,7 @@ var map_ExactDeviceRequest = map[string]string{ "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n At least one device must exist on the node for the allocation to succeed.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", - "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.", "capacity": "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.", } @@ -358,15 +414,25 @@ func (ExactDeviceRequest) SwaggerDoc() map[string]string { var map_NetworkDeviceData = map[string]string{ "": "NetworkDeviceData provides network-related details for the allocated device. This information may be filled by drivers or other components to configure or identify the device within a network context.", - "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 characters.", + "interfaceName": "InterfaceName specifies the name of the network interface associated with the allocated device. This might be the name of a physical or virtual network interface being configured in the pod.\n\nMust not be longer than 256 bytes.", "ips": "IPs lists the network addresses assigned to the device's network interface. This can include both IPv4 and IPv6 addresses. The IPs are in the CIDR notation, which includes both the address and the associated subnet mask. e.g.: \"192.0.2.5/24\" for IPv4 and \"2001:db8::5/64\" for IPv6.", - "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 characters.", + "hardwareAddress": "HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.\n\nMust not be longer than 128 bytes.", } func (NetworkDeviceData) SwaggerDoc() map[string]string { return map_NetworkDeviceData } +var map_NodeAllocatableResourceMapping = map[string]string{ + "": "NodeAllocatableResourceMapping defines the translation between the DRA device/capacity units requested to the corresponding quantity of the node allocatable resource.", + "capacityKey": "CapacityKey references a capacity name defined as a key in the `spec.devices[*].capacity` map. When this field is set, the value associated with this key in the `status.allocation.devices.results[*].consumedCapacity` map (for a specific claim allocation) determines the base quantity for the node allocatable resource. If `allocationMultiplier` is also set, it is multiplied with the base quantity. For example, if `spec.devices[*].capacity` has an entry \"dra.example.com/memory\": \"128Gi\", and this field is set to \"dra.example.com/memory\", then for a claim allocation that consumes { \"dra.example.com/memory\": \"4Gi\" } the base quantity for the node allocatable resource mapping will be \"4Gi\", and `allocationMultiplier` should be omitted or set to \"1\".", + "allocationMultiplier": "AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim.\n\t a. A DRA driver representing each CPU core as a device would have\n {ResourceName: \"cpu\", allocationMultiplier: \"2\"} in its\n `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim,\n\t\t 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity.\n b. A GPU device that needs additional node memory per GPU allocation would\n have {ResourceName: \"memory\", allocationMultiplier: \"2Gi\"}. Each allocated\n\t\t GPU device instance of this type will account for 2Gi of memory.\n\n2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed.\n\t The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`.\n For example, if a Device's capacity \"dra.example.com/cores\" is consumed,\n and each \"core\" provides 2 \"cpu\"s, the mapping would be:\n {ResourceName: \"cpu\", capacityKey: \"dra.example.com/cores\", allocationMultiplier: \"2\"}.\n If a claim consumes 8 \"dra.example.com/cores\", the CPU footprint is 8 * 2 = 16.", +} + +func (NodeAllocatableResourceMapping) SwaggerDoc() map[string]string { + return map_NodeAllocatableResourceMapping +} + var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", diff --git a/vendor/k8s.io/api/resource/v1beta2/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1beta2/zz_generated.deepcopy.go index 3af5c43c78..820ad2af61 100644 --- a/vendor/k8s.io/api/resource/v1beta2/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/resource/v1beta2/zz_generated.deepcopy.go @@ -302,6 +302,13 @@ func (in *Device) DeepCopyInto(out *Device) { *out = new(bool) **out = **in } + if in.NodeAllocatableResourceMappings != nil { + in, out := &in.NodeAllocatableResourceMappings, &out.NodeAllocatableResourceMappings + *out = make(map[corev1.ResourceName]NodeAllocatableResourceMapping, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } return } @@ -390,6 +397,26 @@ func (in *DeviceAttribute) DeepCopyInto(out *DeviceAttribute) { *out = new(string) **out = **in } + if in.IntValues != nil { + in, out := &in.IntValues, &out.IntValues + *out = make([]int64, len(*in)) + copy(*out, *in) + } + if in.BoolValues != nil { + in, out := &in.BoolValues, &out.BoolValues + *out = make([]bool, len(*in)) + copy(*out, *in) + } + if in.StringValues != nil { + in, out := &in.StringValues, &out.StringValues + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.VersionValues != nil { + in, out := &in.VersionValues, &out.VersionValues + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -825,6 +852,143 @@ func (in *DeviceTaint) DeepCopy() *DeviceTaint { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceTaintRule) DeepCopyInto(out *DeviceTaintRule) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceTaintRule. +func (in *DeviceTaintRule) DeepCopy() *DeviceTaintRule { + if in == nil { + return nil + } + out := new(DeviceTaintRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DeviceTaintRule) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceTaintRuleList) DeepCopyInto(out *DeviceTaintRuleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DeviceTaintRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceTaintRuleList. +func (in *DeviceTaintRuleList) DeepCopy() *DeviceTaintRuleList { + if in == nil { + return nil + } + out := new(DeviceTaintRuleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DeviceTaintRuleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceTaintRuleSpec) DeepCopyInto(out *DeviceTaintRuleSpec) { + *out = *in + if in.DeviceSelector != nil { + in, out := &in.DeviceSelector, &out.DeviceSelector + *out = new(DeviceTaintSelector) + (*in).DeepCopyInto(*out) + } + in.Taint.DeepCopyInto(&out.Taint) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceTaintRuleSpec. +func (in *DeviceTaintRuleSpec) DeepCopy() *DeviceTaintRuleSpec { + if in == nil { + return nil + } + out := new(DeviceTaintRuleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceTaintRuleStatus) DeepCopyInto(out *DeviceTaintRuleStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceTaintRuleStatus. +func (in *DeviceTaintRuleStatus) DeepCopy() *DeviceTaintRuleStatus { + if in == nil { + return nil + } + out := new(DeviceTaintRuleStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceTaintSelector) DeepCopyInto(out *DeviceTaintSelector) { + *out = *in + if in.Driver != nil { + in, out := &in.Driver, &out.Driver + *out = new(string) + **out = **in + } + if in.Pool != nil { + in, out := &in.Pool, &out.Pool + *out = new(string) + **out = **in + } + if in.Device != nil { + in, out := &in.Device, &out.Device + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceTaintSelector. +func (in *DeviceTaintSelector) DeepCopy() *DeviceTaintSelector { + if in == nil { + return nil + } + out := new(DeviceTaintSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeviceToleration) DeepCopyInto(out *DeviceToleration) { *out = *in @@ -907,6 +1071,32 @@ func (in *NetworkDeviceData) DeepCopy() *NetworkDeviceData { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeAllocatableResourceMapping) DeepCopyInto(out *NodeAllocatableResourceMapping) { + *out = *in + if in.CapacityKey != nil { + in, out := &in.CapacityKey, &out.CapacityKey + *out = new(QualifiedName) + **out = **in + } + if in.AllocationMultiplier != nil { + in, out := &in.AllocationMultiplier, &out.AllocationMultiplier + x := (*in).DeepCopy() + *out = &x + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAllocatableResourceMapping. +func (in *NodeAllocatableResourceMapping) DeepCopy() *NodeAllocatableResourceMapping { + if in == nil { + return nil + } + out := new(NodeAllocatableResourceMapping) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpaqueDeviceConfiguration) DeepCopyInto(out *OpaqueDeviceConfiguration) { *out = *in diff --git a/vendor/k8s.io/api/resource/v1beta2/zz_generated.model_name.go b/vendor/k8s.io/api/resource/v1beta2/zz_generated.model_name.go index 0518ff73ce..ce388ffd2e 100644 --- a/vendor/k8s.io/api/resource/v1beta2/zz_generated.model_name.go +++ b/vendor/k8s.io/api/resource/v1beta2/zz_generated.model_name.go @@ -156,6 +156,31 @@ func (in DeviceTaint) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta2.DeviceTaint" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in DeviceTaintRule) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.DeviceTaintRule" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in DeviceTaintRuleList) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.DeviceTaintRuleList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in DeviceTaintRuleSpec) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.DeviceTaintRuleSpec" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in DeviceTaintRuleStatus) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.DeviceTaintRuleStatus" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in DeviceTaintSelector) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.DeviceTaintSelector" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in DeviceToleration) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta2.DeviceToleration" @@ -171,6 +196,11 @@ func (in NetworkDeviceData) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta2.NetworkDeviceData" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in NodeAllocatableResourceMapping) OpenAPIModelName() string { + return "io.k8s.api.resource.v1beta2.NodeAllocatableResourceMapping" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in OpaqueDeviceConfiguration) OpenAPIModelName() string { return "io.k8s.api.resource.v1beta2.OpaqueDeviceConfiguration" diff --git a/vendor/k8s.io/api/resource/v1beta2/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/resource/v1beta2/zz_generated.prerelease-lifecycle.go index 898b1aed35..c28687b870 100644 --- a/vendor/k8s.io/api/resource/v1beta2/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/resource/v1beta2/zz_generated.prerelease-lifecycle.go @@ -57,6 +57,42 @@ func (in *DeviceClassList) APILifecycleRemoved() (major, minor int) { return 1, 39 } +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *DeviceTaintRule) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *DeviceTaintRule) APILifecycleDeprecated() (major, minor int) { + return 1, 39 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *DeviceTaintRule) APILifecycleRemoved() (major, minor int) { + return 1, 42 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *DeviceTaintRuleList) APILifecycleIntroduced() (major, minor int) { + return 1, 36 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *DeviceTaintRuleList) APILifecycleDeprecated() (major, minor int) { + return 1, 39 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *DeviceTaintRuleList) APILifecycleRemoved() (major, minor int) { + return 1, 42 +} + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *ResourceClaim) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/scheduling/v1/generated.proto b/vendor/k8s.io/api/scheduling/v1/generated.proto index 374e68238b..6be7204de1 100644 --- a/vendor/k8s.io/api/scheduling/v1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1/generated.proto @@ -39,6 +39,7 @@ message PriorityClass { // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. + // +optional optional int32 value = 2; // globalDefault specifies whether this PriorityClass should be considered as diff --git a/vendor/k8s.io/api/scheduling/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/scheduling/v1/generated.protomessage.pb.go deleted file mode 100644 index 261d4903e7..0000000000 --- a/vendor/k8s.io/api/scheduling/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*PriorityClass) ProtoMessage() {} - -func (*PriorityClassList) ProtoMessage() {} diff --git a/vendor/k8s.io/api/scheduling/v1/types.go b/vendor/k8s.io/api/scheduling/v1/types.go index 019dbcd00e..655b5eb159 100644 --- a/vendor/k8s.io/api/scheduling/v1/types.go +++ b/vendor/k8s.io/api/scheduling/v1/types.go @@ -37,6 +37,7 @@ type PriorityClass struct { // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. + // +optional Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` // globalDefault specifies whether this PriorityClass should be considered as diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/generated.pb.go b/vendor/k8s.io/api/scheduling/v1alpha1/generated.pb.go deleted file mode 100644 index 64c39b4c35..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/generated.pb.go +++ /dev/null @@ -1,2010 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: k8s.io/api/scheduling/v1alpha1/generated.proto - -package v1alpha1 - -import ( - fmt "fmt" - - io "io" - - k8s_io_api_core_v1 "k8s.io/api/core/v1" - - math_bits "math/bits" - reflect "reflect" - strings "strings" -) - -func (m *BasicSchedulingPolicy) Reset() { *m = BasicSchedulingPolicy{} } - -func (m *GangSchedulingPolicy) Reset() { *m = GangSchedulingPolicy{} } - -func (m *PodGroup) Reset() { *m = PodGroup{} } - -func (m *PodGroupPolicy) Reset() { *m = PodGroupPolicy{} } - -func (m *PriorityClass) Reset() { *m = PriorityClass{} } - -func (m *PriorityClassList) Reset() { *m = PriorityClassList{} } - -func (m *TypedLocalObjectReference) Reset() { *m = TypedLocalObjectReference{} } - -func (m *Workload) Reset() { *m = Workload{} } - -func (m *WorkloadList) Reset() { *m = WorkloadList{} } - -func (m *WorkloadSpec) Reset() { *m = WorkloadSpec{} } - -func (m *BasicSchedulingPolicy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *BasicSchedulingPolicy) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *BasicSchedulingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *GangSchedulingPolicy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GangSchedulingPolicy) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GangSchedulingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.MinCount)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - -func (m *PodGroup) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodGroup) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Policy.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PodGroupPolicy) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PodGroupPolicy) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodGroupPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Gang != nil { - { - size, err := m.Gang.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Basic != nil { - { - size, err := m.Basic.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} - -func (m *PriorityClass) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PriorityClass) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PriorityClass) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.PreemptionPolicy != nil { - i -= len(*m.PreemptionPolicy) - copy(dAtA[i:], *m.PreemptionPolicy) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PreemptionPolicy))) - i-- - dAtA[i] = 0x2a - } - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Description))) - i-- - dAtA[i] = 0x22 - i-- - if m.GlobalDefault { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x18 - i = encodeVarintGenerated(dAtA, i, uint64(m.Value)) - i-- - dAtA[i] = 0x10 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *PriorityClassList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PriorityClassList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PriorityClassList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *TypedLocalObjectReference) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TypedLocalObjectReference) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *TypedLocalObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x1a - i -= len(m.Kind) - copy(dAtA[i:], m.Kind) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) - i-- - dAtA[i] = 0x12 - i -= len(m.APIGroup) - copy(dAtA[i:], m.APIGroup) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *Workload) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Workload) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Workload) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *WorkloadList) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *WorkloadList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *WorkloadList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *WorkloadSpec) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *WorkloadSpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *WorkloadSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.PodGroups) > 0 { - for iNdEx := len(m.PodGroups) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.PodGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.ControllerRef != nil { - { - size, err := m.ControllerRef.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *BasicSchedulingPolicy) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *GangSchedulingPolicy) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.MinCount)) - return n -} - -func (m *PodGroup) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Policy.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *PodGroupPolicy) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Basic != nil { - l = m.Basic.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Gang != nil { - l = m.Gang.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *PriorityClass) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.Value)) - n += 2 - l = len(m.Description) - n += 1 + l + sovGenerated(uint64(l)) - if m.PreemptionPolicy != nil { - l = len(*m.PreemptionPolicy) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *PriorityClassList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *TypedLocalObjectReference) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.APIGroup) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Kind) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *Workload) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *WorkloadList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *WorkloadSpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ControllerRef != nil { - l = m.ControllerRef.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if len(m.PodGroups) > 0 { - for _, e := range m.PodGroups { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *BasicSchedulingPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&BasicSchedulingPolicy{`, - `}`, - }, "") - return s -} -func (this *GangSchedulingPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&GangSchedulingPolicy{`, - `MinCount:` + fmt.Sprintf("%v", this.MinCount) + `,`, - `}`, - }, "") - return s -} -func (this *PodGroup) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodGroup{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Policy:` + strings.Replace(strings.Replace(this.Policy.String(), "PodGroupPolicy", "PodGroupPolicy", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodGroupPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodGroupPolicy{`, - `Basic:` + strings.Replace(this.Basic.String(), "BasicSchedulingPolicy", "BasicSchedulingPolicy", 1) + `,`, - `Gang:` + strings.Replace(this.Gang.String(), "GangSchedulingPolicy", "GangSchedulingPolicy", 1) + `,`, - `}`, - }, "") - return s -} -func (this *PriorityClass) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PriorityClass{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Value:` + fmt.Sprintf("%v", this.Value) + `,`, - `GlobalDefault:` + fmt.Sprintf("%v", this.GlobalDefault) + `,`, - `Description:` + fmt.Sprintf("%v", this.Description) + `,`, - `PreemptionPolicy:` + valueToStringGenerated(this.PreemptionPolicy) + `,`, - `}`, - }, "") - return s -} -func (this *PriorityClassList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]PriorityClass{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PriorityClass", "PriorityClass", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&PriorityClassList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *TypedLocalObjectReference) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&TypedLocalObjectReference{`, - `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`, - `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} -func (this *Workload) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Workload{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "WorkloadSpec", "WorkloadSpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *WorkloadList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]Workload{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "Workload", "Workload", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&WorkloadList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *WorkloadSpec) String() string { - if this == nil { - return "nil" - } - repeatedStringForPodGroups := "[]PodGroup{" - for _, f := range this.PodGroups { - repeatedStringForPodGroups += strings.Replace(strings.Replace(f.String(), "PodGroup", "PodGroup", 1), `&`, ``, 1) + "," - } - repeatedStringForPodGroups += "}" - s := strings.Join([]string{`&WorkloadSpec{`, - `ControllerRef:` + strings.Replace(this.ControllerRef.String(), "TypedLocalObjectReference", "TypedLocalObjectReference", 1) + `,`, - `PodGroups:` + repeatedStringForPodGroups + `,`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *BasicSchedulingPolicy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: BasicSchedulingPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BasicSchedulingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *GangSchedulingPolicy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GangSchedulingPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GangSchedulingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinCount", wireType) - } - m.MinCount = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MinCount |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodGroup) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodGroup: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodGroup: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Policy", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Policy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PodGroupPolicy) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PodGroupPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodGroupPolicy: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Basic", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Basic == nil { - m.Basic = &BasicSchedulingPolicy{} - } - if err := m.Basic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Gang", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Gang == nil { - m.Gang = &GangSchedulingPolicy{} - } - if err := m.Gang.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PriorityClass) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PriorityClass: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PriorityClass: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) - } - m.Value = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Value |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GlobalDefault", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.GlobalDefault = bool(v != 0) - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptionPolicy", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := k8s_io_api_core_v1.PreemptionPolicy(dAtA[iNdEx:postIndex]) - m.PreemptionPolicy = &s - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PriorityClassList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PriorityClassList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PriorityClassList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, PriorityClass{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *TypedLocalObjectReference) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TypedLocalObjectReference: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TypedLocalObjectReference: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.APIGroup = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Workload) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Workload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Workload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *WorkloadList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: WorkloadList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: WorkloadList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, Workload{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *WorkloadSpec) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: WorkloadSpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: WorkloadSpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ControllerRef", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ControllerRef == nil { - m.ControllerRef = &TypedLocalObjectReference{} - } - if err := m.ControllerRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodGroups", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PodGroups = append(m.PodGroups, PodGroup{}) - if err := m.PodGroups[len(m.PodGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenerated - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenerated - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto b/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto deleted file mode 100644 index 6014f60e20..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto +++ /dev/null @@ -1,190 +0,0 @@ -/* -Copyright 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. -*/ - - -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -syntax = "proto2"; - -package k8s.io.api.scheduling.v1alpha1; - -import "k8s.io/api/core/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/generated.proto"; -import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; - -// Package-wide variables from generator "generated". -option go_package = "k8s.io/api/scheduling/v1alpha1"; - -// BasicSchedulingPolicy indicates that standard Kubernetes -// scheduling behavior should be used. -message BasicSchedulingPolicy { -} - -// GangSchedulingPolicy defines the parameters for gang scheduling. -message GangSchedulingPolicy { - // MinCount is the minimum number of pods that must be schedulable or scheduled - // at the same time for the scheduler to admit the entire group. - // It must be a positive integer. - // - // +required - optional int32 minCount = 1; -} - -// PodGroup represents a set of pods with a common scheduling policy. -message PodGroup { - // Name is a unique identifier for the PodGroup within the Workload. - // It must be a DNS label. This field is immutable. - // - // +required - optional string name = 1; - - // Policy defines the scheduling policy for this PodGroup. - // - // +required - optional PodGroupPolicy policy = 3; -} - -// PodGroupPolicy defines the scheduling configuration for a PodGroup. -message PodGroupPolicy { - // Basic specifies that the pods in this group should be scheduled using - // standard Kubernetes scheduling behavior. - // - // +optional - // +oneOf=PolicySelection - optional BasicSchedulingPolicy basic = 2; - - // Gang specifies that the pods in this group should be scheduled using - // all-or-nothing semantics. - // - // +optional - // +oneOf=PolicySelection - optional GangSchedulingPolicy gang = 3; -} - -// DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. -// PriorityClass defines mapping from a priority class name to the priority -// integer value. The value can be any valid integer. -message PriorityClass { - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // value represents the integer value of this priority class. This is the actual priority that pods - // receive when they have the name of this class in their pod spec. - optional int32 value = 2; - - // globalDefault specifies whether this PriorityClass should be considered as - // the default priority for pods that do not have any priority class. - // Only one PriorityClass can be marked as `globalDefault`. However, if more than - // one PriorityClasses exists with their `globalDefault` field set to true, - // the smallest value of such global default PriorityClasses will be used as the default priority. - // +optional - optional bool globalDefault = 3; - - // description is an arbitrary string that usually provides guidelines on - // when this priority class should be used. - // +optional - optional string description = 4; - - // preemptionPolicy is the Policy for preempting pods with lower priority. - // One of Never, PreemptLowerPriority. - // Defaults to PreemptLowerPriority if unset. - // +optional - optional string preemptionPolicy = 5; -} - -// PriorityClassList is a collection of priority classes. -message PriorityClassList { - // Standard list metadata - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // items is the list of PriorityClasses - repeated PriorityClass items = 2; -} - -// TypedLocalObjectReference allows to reference typed object inside the same namespace. -message TypedLocalObjectReference { - // APIGroup is the group for the resource being referenced. - // If APIGroup is empty, the specified Kind must be in the core API group. - // For any other third-party types, setting APIGroup is required. - // It must be a DNS subdomain. - // - // +optional - optional string apiGroup = 1; - - // Kind is the type of resource being referenced. - // It must be a path segment name. - // - // +required - optional string kind = 2; - - // Name is the name of resource being referenced. - // It must be a path segment name. - // - // +required - optional string name = 3; -} - -// Workload allows for expressing scheduling constraints that should be used -// when managing lifecycle of workloads from scheduling perspective, -// including scheduling, preemption, eviction and other phases. -message Workload { - // Standard object's metadata. - // Name must be a DNS subdomain. - // - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - - // Spec defines the desired behavior of a Workload. - // - // +required - optional WorkloadSpec spec = 2; -} - -// WorkloadList contains a list of Workload resources. -message WorkloadList { - // Standard list metadata. - // - // +optional - optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - - // Items is the list of Workloads. - repeated Workload items = 2; -} - -// WorkloadSpec defines the desired state of a Workload. -message WorkloadSpec { - // ControllerRef is an optional reference to the controlling object, such as a - // Deployment or Job. This field is intended for use by tools like CLIs - // to provide a link back to the original workload definition. - // When set, it cannot be changed. - // - // +optional - optional TypedLocalObjectReference controllerRef = 1; - - // PodGroups is the list of pod groups that make up the Workload. - // The maximum number of pod groups is 8. This field is immutable. - // - // +required - // +listType=map - // +listMapKey=name - repeated PodGroup podGroups = 2; -} - diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/scheduling/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index a92e57b1e7..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*BasicSchedulingPolicy) ProtoMessage() {} - -func (*GangSchedulingPolicy) ProtoMessage() {} - -func (*PodGroup) ProtoMessage() {} - -func (*PodGroupPolicy) ProtoMessage() {} - -func (*PriorityClass) ProtoMessage() {} - -func (*PriorityClassList) ProtoMessage() {} - -func (*TypedLocalObjectReference) ProtoMessage() {} - -func (*Workload) ProtoMessage() {} - -func (*WorkloadList) ProtoMessage() {} - -func (*WorkloadSpec) ProtoMessage() {} diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types.go b/vendor/k8s.io/api/scheduling/v1alpha1/types.go deleted file mode 100644 index 480b53da01..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types.go +++ /dev/null @@ -1,201 +0,0 @@ -/* -Copyright 2017 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 v1alpha1 - -import ( - apiv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. -// PriorityClass defines mapping from a priority class name to the priority -// integer value. The value can be any valid integer. -type PriorityClass struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // value represents the integer value of this priority class. This is the actual priority that pods - // receive when they have the name of this class in their pod spec. - Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` - - // globalDefault specifies whether this PriorityClass should be considered as - // the default priority for pods that do not have any priority class. - // Only one PriorityClass can be marked as `globalDefault`. However, if more than - // one PriorityClasses exists with their `globalDefault` field set to true, - // the smallest value of such global default PriorityClasses will be used as the default priority. - // +optional - GlobalDefault bool `json:"globalDefault,omitempty" protobuf:"bytes,3,opt,name=globalDefault"` - - // description is an arbitrary string that usually provides guidelines on - // when this priority class should be used. - // +optional - Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - - // preemptionPolicy is the Policy for preempting pods with lower priority. - // One of Never, PreemptLowerPriority. - // Defaults to PreemptLowerPriority if unset. - // +optional - PreemptionPolicy *apiv1.PreemptionPolicy `json:"preemptionPolicy,omitempty" protobuf:"bytes,5,opt,name=preemptionPolicy"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PriorityClassList is a collection of priority classes. -type PriorityClassList struct { - metav1.TypeMeta `json:",inline"` - // Standard list metadata - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // items is the list of PriorityClasses - Items []PriorityClass `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Workload allows for expressing scheduling constraints that should be used -// when managing lifecycle of workloads from scheduling perspective, -// including scheduling, preemption, eviction and other phases. -type Workload struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata. - // Name must be a DNS subdomain. - // - // +optional - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // Spec defines the desired behavior of a Workload. - // - // +required - Spec WorkloadSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// WorkloadList contains a list of Workload resources. -type WorkloadList struct { - metav1.TypeMeta `json:",inline"` - // Standard list metadata. - // - // +optional - metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - // Items is the list of Workloads. - Items []Workload `json:"items" protobuf:"bytes,2,rep,name=items"` -} - -// WorkloadMaxPodGroups is the maximum number of pod groups per Workload. -const WorkloadMaxPodGroups = 8 - -// WorkloadSpec defines the desired state of a Workload. -type WorkloadSpec struct { - // ControllerRef is an optional reference to the controlling object, such as a - // Deployment or Job. This field is intended for use by tools like CLIs - // to provide a link back to the original workload definition. - // When set, it cannot be changed. - // - // +optional - ControllerRef *TypedLocalObjectReference `json:"controllerRef,omitempty" protobuf:"bytes,1,opt,name=controllerRef"` - - // PodGroups is the list of pod groups that make up the Workload. - // The maximum number of pod groups is 8. This field is immutable. - // - // +required - // +listType=map - // +listMapKey=name - PodGroups []PodGroup `json:"podGroups" protobuf:"bytes,2,rep,name=podGroups"` -} - -// TypedLocalObjectReference allows to reference typed object inside the same namespace. -type TypedLocalObjectReference struct { - // APIGroup is the group for the resource being referenced. - // If APIGroup is empty, the specified Kind must be in the core API group. - // For any other third-party types, setting APIGroup is required. - // It must be a DNS subdomain. - // - // +optional - APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=apiGroup"` - // Kind is the type of resource being referenced. - // It must be a path segment name. - // - // +required - Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - // Name is the name of resource being referenced. - // It must be a path segment name. - // - // +required - Name string `json:"name" protobuf:"bytes,3,opt,name=name"` -} - -// PodGroup represents a set of pods with a common scheduling policy. -type PodGroup struct { - // Name is a unique identifier for the PodGroup within the Workload. - // It must be a DNS label. This field is immutable. - // - // +required - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - - // Policy defines the scheduling policy for this PodGroup. - // - // +required - Policy PodGroupPolicy `json:"policy" protobuf:"bytes,3,opt,name=policy"` -} - -// PodGroupPolicy defines the scheduling configuration for a PodGroup. -type PodGroupPolicy struct { - // Basic specifies that the pods in this group should be scheduled using - // standard Kubernetes scheduling behavior. - // - // +optional - // +oneOf=PolicySelection - Basic *BasicSchedulingPolicy `json:"basic,omitempty" protobuf:"bytes,2,opt,name=basic"` - - // Gang specifies that the pods in this group should be scheduled using - // all-or-nothing semantics. - // - // +optional - // +oneOf=PolicySelection - Gang *GangSchedulingPolicy `json:"gang,omitempty" protobuf:"bytes,3,opt,name=gang"` -} - -// BasicSchedulingPolicy indicates that standard Kubernetes -// scheduling behavior should be used. -type BasicSchedulingPolicy struct { - // This is intentionally empty. Its presence indicates that the basic - // scheduling policy should be applied. In the future, new fields may appear, - // describing such constraints on a pod group level without "all or nothing" - // (gang) scheduling. -} - -// GangSchedulingPolicy defines the parameters for gang scheduling. -type GangSchedulingPolicy struct { - // MinCount is the minimum number of pods that must be schedulable or scheduled - // at the same time for the scheduler to admit the entire group. - // It must be a positive integer. - // - // +required - MinCount int32 `json:"minCount" protobuf:"varint,1,opt,name=minCount"` -} diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go deleted file mode 100644 index a2915bff44..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 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 v1alpha1 - -// This file contains a collection of methods that can be used from go-restful to -// generate Swagger API documentation for its models. Please read this PR for more -// information on the implementation: https://github.com/emicklei/go-restful/pull/215 -// -// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if -// they are on one line! For multiple line or blocks that you want to ignore use ---. -// Any context after a --- is ignored. -// -// Those methods can be generated by using hack/update-codegen.sh - -// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. -var map_BasicSchedulingPolicy = map[string]string{ - "": "BasicSchedulingPolicy indicates that standard Kubernetes scheduling behavior should be used.", -} - -func (BasicSchedulingPolicy) SwaggerDoc() map[string]string { - return map_BasicSchedulingPolicy -} - -var map_GangSchedulingPolicy = map[string]string{ - "": "GangSchedulingPolicy defines the parameters for gang scheduling.", - "minCount": "MinCount is the minimum number of pods that must be schedulable or scheduled at the same time for the scheduler to admit the entire group. It must be a positive integer.", -} - -func (GangSchedulingPolicy) SwaggerDoc() map[string]string { - return map_GangSchedulingPolicy -} - -var map_PodGroup = map[string]string{ - "": "PodGroup represents a set of pods with a common scheduling policy.", - "name": "Name is a unique identifier for the PodGroup within the Workload. It must be a DNS label. This field is immutable.", - "policy": "Policy defines the scheduling policy for this PodGroup.", -} - -func (PodGroup) SwaggerDoc() map[string]string { - return map_PodGroup -} - -var map_PodGroupPolicy = map[string]string{ - "": "PodGroupPolicy defines the scheduling configuration for a PodGroup.", - "basic": "Basic specifies that the pods in this group should be scheduled using standard Kubernetes scheduling behavior.", - "gang": "Gang specifies that the pods in this group should be scheduled using all-or-nothing semantics.", -} - -func (PodGroupPolicy) SwaggerDoc() map[string]string { - return map_PodGroupPolicy -} - -var map_PriorityClass = map[string]string{ - "": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", - "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", - "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", -} - -func (PriorityClass) SwaggerDoc() map[string]string { - return map_PriorityClass -} - -var map_PriorityClassList = map[string]string{ - "": "PriorityClassList is a collection of priority classes.", - "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "items is the list of PriorityClasses", -} - -func (PriorityClassList) SwaggerDoc() map[string]string { - return map_PriorityClassList -} - -var map_TypedLocalObjectReference = map[string]string{ - "": "TypedLocalObjectReference allows to reference typed object inside the same namespace.", - "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is empty, the specified Kind must be in the core API group. For any other third-party types, setting APIGroup is required. It must be a DNS subdomain.", - "kind": "Kind is the type of resource being referenced. It must be a path segment name.", - "name": "Name is the name of resource being referenced. It must be a path segment name.", -} - -func (TypedLocalObjectReference) SwaggerDoc() map[string]string { - return map_TypedLocalObjectReference -} - -var map_Workload = map[string]string{ - "": "Workload allows for expressing scheduling constraints that should be used when managing lifecycle of workloads from scheduling perspective, including scheduling, preemption, eviction and other phases.", - "metadata": "Standard object's metadata. Name must be a DNS subdomain.", - "spec": "Spec defines the desired behavior of a Workload.", -} - -func (Workload) SwaggerDoc() map[string]string { - return map_Workload -} - -var map_WorkloadList = map[string]string{ - "": "WorkloadList contains a list of Workload resources.", - "metadata": "Standard list metadata.", - "items": "Items is the list of Workloads.", -} - -func (WorkloadList) SwaggerDoc() map[string]string { - return map_WorkloadList -} - -var map_WorkloadSpec = map[string]string{ - "": "WorkloadSpec defines the desired state of a Workload.", - "controllerRef": "ControllerRef is an optional reference to the controlling object, such as a Deployment or Job. This field is intended for use by tools like CLIs to provide a link back to the original workload definition. When set, it cannot be changed.", - "podGroups": "PodGroups is the list of pod groups that make up the Workload. The maximum number of pod groups is 8. This field is immutable.", -} - -func (WorkloadSpec) SwaggerDoc() map[string]string { - return map_WorkloadSpec -} - -// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index ccaf45d72c..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,270 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BasicSchedulingPolicy) DeepCopyInto(out *BasicSchedulingPolicy) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicSchedulingPolicy. -func (in *BasicSchedulingPolicy) DeepCopy() *BasicSchedulingPolicy { - if in == nil { - return nil - } - out := new(BasicSchedulingPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GangSchedulingPolicy) DeepCopyInto(out *GangSchedulingPolicy) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GangSchedulingPolicy. -func (in *GangSchedulingPolicy) DeepCopy() *GangSchedulingPolicy { - if in == nil { - return nil - } - out := new(GangSchedulingPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodGroup) DeepCopyInto(out *PodGroup) { - *out = *in - in.Policy.DeepCopyInto(&out.Policy) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroup. -func (in *PodGroup) DeepCopy() *PodGroup { - if in == nil { - return nil - } - out := new(PodGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodGroupPolicy) DeepCopyInto(out *PodGroupPolicy) { - *out = *in - if in.Basic != nil { - in, out := &in.Basic, &out.Basic - *out = new(BasicSchedulingPolicy) - **out = **in - } - if in.Gang != nil { - in, out := &in.Gang, &out.Gang - *out = new(GangSchedulingPolicy) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupPolicy. -func (in *PodGroupPolicy) DeepCopy() *PodGroupPolicy { - if in == nil { - return nil - } - out := new(PodGroupPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PriorityClass) DeepCopyInto(out *PriorityClass) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - if in.PreemptionPolicy != nil { - in, out := &in.PreemptionPolicy, &out.PreemptionPolicy - *out = new(v1.PreemptionPolicy) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClass. -func (in *PriorityClass) DeepCopy() *PriorityClass { - if in == nil { - return nil - } - out := new(PriorityClass) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PriorityClass) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PriorityClassList) DeepCopyInto(out *PriorityClassList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PriorityClass, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClassList. -func (in *PriorityClassList) DeepCopy() *PriorityClassList { - if in == nil { - return nil - } - out := new(PriorityClassList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PriorityClassList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TypedLocalObjectReference) DeepCopyInto(out *TypedLocalObjectReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TypedLocalObjectReference. -func (in *TypedLocalObjectReference) DeepCopy() *TypedLocalObjectReference { - if in == nil { - return nil - } - out := new(TypedLocalObjectReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Workload) DeepCopyInto(out *Workload) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workload. -func (in *Workload) DeepCopy() *Workload { - if in == nil { - return nil - } - out := new(Workload) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Workload) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkloadList) DeepCopyInto(out *WorkloadList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Workload, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadList. -func (in *WorkloadList) DeepCopy() *WorkloadList { - if in == nil { - return nil - } - out := new(WorkloadList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WorkloadList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkloadSpec) DeepCopyInto(out *WorkloadSpec) { - *out = *in - if in.ControllerRef != nil { - in, out := &in.ControllerRef, &out.ControllerRef - *out = new(TypedLocalObjectReference) - **out = **in - } - if in.PodGroups != nil { - in, out := &in.PodGroups, &out.PodGroups - *out = make([]PodGroup, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadSpec. -func (in *WorkloadSpec) DeepCopy() *WorkloadSpec { - if in == nil { - return nil - } - out := new(WorkloadSpec) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.model_name.go b/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.model_name.go deleted file mode 100644 index 25844f419a..0000000000 --- a/vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.model_name.go +++ /dev/null @@ -1,72 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by openapi-gen. DO NOT EDIT. - -package v1alpha1 - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in BasicSchedulingPolicy) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.BasicSchedulingPolicy" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in GangSchedulingPolicy) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.GangSchedulingPolicy" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodGroup) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.PodGroup" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PodGroupPolicy) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.PodGroupPolicy" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PriorityClass) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.PriorityClass" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in PriorityClassList) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.PriorityClassList" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in TypedLocalObjectReference) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.TypedLocalObjectReference" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in Workload) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.Workload" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in WorkloadList) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.WorkloadList" -} - -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in WorkloadSpec) OpenAPIModelName() string { - return "io.k8s.api.scheduling.v1alpha1.WorkloadSpec" -} diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/doc.go b/vendor/k8s.io/api/scheduling/v1alpha2/doc.go similarity index 84% rename from vendor/k8s.io/api/scheduling/v1alpha1/doc.go rename to vendor/k8s.io/api/scheduling/v1alpha2/doc.go index 2b6182e864..24ba23e72c 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/doc.go +++ b/vendor/k8s.io/api/scheduling/v1alpha2/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +Copyright 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. @@ -17,8 +17,8 @@ limitations under the License. // +k8s:deepcopy-gen=package // +k8s:protobuf-gen=package // +k8s:openapi-gen=true -// +k8s:openapi-model-package=io.k8s.api.scheduling.v1alpha1 +// +k8s:openapi-model-package=io.k8s.api.scheduling.v1alpha2 // +groupName=scheduling.k8s.io -package v1alpha1 +package v1alpha2 diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/generated.pb.go b/vendor/k8s.io/api/scheduling/v1alpha2/generated.pb.go new file mode 100644 index 0000000000..12402df3d2 --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/generated.pb.go @@ -0,0 +1,3828 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/api/scheduling/v1alpha2/generated.proto + +package v1alpha2 + +import ( + fmt "fmt" + + io "io" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +func (m *BasicSchedulingPolicy) Reset() { *m = BasicSchedulingPolicy{} } + +func (m *GangSchedulingPolicy) Reset() { *m = GangSchedulingPolicy{} } + +func (m *PodGroup) Reset() { *m = PodGroup{} } + +func (m *PodGroupList) Reset() { *m = PodGroupList{} } + +func (m *PodGroupResourceClaim) Reset() { *m = PodGroupResourceClaim{} } + +func (m *PodGroupResourceClaimStatus) Reset() { *m = PodGroupResourceClaimStatus{} } + +func (m *PodGroupSchedulingConstraints) Reset() { *m = PodGroupSchedulingConstraints{} } + +func (m *PodGroupSchedulingPolicy) Reset() { *m = PodGroupSchedulingPolicy{} } + +func (m *PodGroupSpec) Reset() { *m = PodGroupSpec{} } + +func (m *PodGroupStatus) Reset() { *m = PodGroupStatus{} } + +func (m *PodGroupTemplate) Reset() { *m = PodGroupTemplate{} } + +func (m *PodGroupTemplateReference) Reset() { *m = PodGroupTemplateReference{} } + +func (m *TopologyConstraint) Reset() { *m = TopologyConstraint{} } + +func (m *TypedLocalObjectReference) Reset() { *m = TypedLocalObjectReference{} } + +func (m *Workload) Reset() { *m = Workload{} } + +func (m *WorkloadList) Reset() { *m = WorkloadList{} } + +func (m *WorkloadPodGroupTemplateReference) Reset() { *m = WorkloadPodGroupTemplateReference{} } + +func (m *WorkloadSpec) Reset() { *m = WorkloadSpec{} } + +func (m *BasicSchedulingPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BasicSchedulingPolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BasicSchedulingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *GangSchedulingPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GangSchedulingPolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GangSchedulingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.MinCount)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func (m *PodGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodGroupList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodGroupResourceClaim) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupResourceClaim) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ResourceClaimTemplateName != nil { + i -= len(*m.ResourceClaimTemplateName) + copy(dAtA[i:], *m.ResourceClaimTemplateName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ResourceClaimTemplateName))) + i-- + dAtA[i] = 0x1a + } + if m.ResourceClaimName != nil { + i -= len(*m.ResourceClaimName) + copy(dAtA[i:], *m.ResourceClaimName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ResourceClaimName))) + i-- + dAtA[i] = 0x12 + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodGroupResourceClaimStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupResourceClaimStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ResourceClaimName != nil { + i -= len(*m.ResourceClaimName) + copy(dAtA[i:], *m.ResourceClaimName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ResourceClaimName))) + i-- + dAtA[i] = 0x12 + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodGroupSchedulingConstraints) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupSchedulingConstraints) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupSchedulingConstraints) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Topology) > 0 { + for iNdEx := len(m.Topology) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Topology[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PodGroupSchedulingPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupSchedulingPolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupSchedulingPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Gang != nil { + { + size, err := m.Gang.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Basic != nil { + { + size, err := m.Basic.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PodGroupSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Priority != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Priority)) + i-- + dAtA[i] = 0x38 + } + i -= len(m.PriorityClassName) + copy(dAtA[i:], m.PriorityClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PriorityClassName))) + i-- + dAtA[i] = 0x32 + if m.DisruptionMode != nil { + i -= len(*m.DisruptionMode) + copy(dAtA[i:], *m.DisruptionMode) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.DisruptionMode))) + i-- + dAtA[i] = 0x2a + } + if len(m.ResourceClaims) > 0 { + for iNdEx := len(m.ResourceClaims) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceClaims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.SchedulingConstraints != nil { + { + size, err := m.SchedulingConstraints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + { + size, err := m.SchedulingPolicy.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.PodGroupTemplateRef != nil { + { + size, err := m.PodGroupTemplateRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PodGroupStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ResourceClaimStatuses) > 0 { + for iNdEx := len(m.ResourceClaimStatuses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceClaimStatuses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PodGroupTemplate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupTemplate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Priority != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Priority)) + i-- + dAtA[i] = 0x38 + } + i -= len(m.PriorityClassName) + copy(dAtA[i:], m.PriorityClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PriorityClassName))) + i-- + dAtA[i] = 0x32 + if m.DisruptionMode != nil { + i -= len(*m.DisruptionMode) + copy(dAtA[i:], *m.DisruptionMode) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.DisruptionMode))) + i-- + dAtA[i] = 0x2a + } + if len(m.ResourceClaims) > 0 { + for iNdEx := len(m.ResourceClaims) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceClaims[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.SchedulingConstraints != nil { + { + size, err := m.SchedulingConstraints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + { + size, err := m.SchedulingPolicy.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PodGroupTemplateReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PodGroupTemplateReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PodGroupTemplateReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Workload != nil { + { + size, err := m.Workload.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TopologyConstraint) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TopologyConstraint) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TopologyConstraint) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *TypedLocalObjectReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TypedLocalObjectReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TypedLocalObjectReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIGroup) + copy(dAtA[i:], m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Workload) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Workload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Workload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadPodGroupTemplateReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadPodGroupTemplateReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadPodGroupTemplateReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.PodGroupTemplateName) + copy(dAtA[i:], m.PodGroupTemplateName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PodGroupTemplateName))) + i-- + dAtA[i] = 0x12 + i -= len(m.WorkloadName) + copy(dAtA[i:], m.WorkloadName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.WorkloadName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *WorkloadSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkloadSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WorkloadSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PodGroupTemplates) > 0 { + for iNdEx := len(m.PodGroupTemplates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PodGroupTemplates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.ControllerRef != nil { + { + size, err := m.ControllerRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *BasicSchedulingPolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *GangSchedulingPolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.MinCount)) + return n +} + +func (m *PodGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PodGroupList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PodGroupResourceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.ResourceClaimName != nil { + l = len(*m.ResourceClaimName) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.ResourceClaimTemplateName != nil { + l = len(*m.ResourceClaimTemplateName) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *PodGroupResourceClaimStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.ResourceClaimName != nil { + l = len(*m.ResourceClaimName) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *PodGroupSchedulingConstraints) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Topology) > 0 { + for _, e := range m.Topology { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PodGroupSchedulingPolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Basic != nil { + l = m.Basic.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Gang != nil { + l = m.Gang.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *PodGroupSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PodGroupTemplateRef != nil { + l = m.PodGroupTemplateRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = m.SchedulingPolicy.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.SchedulingConstraints != nil { + l = m.SchedulingConstraints.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ResourceClaims) > 0 { + for _, e := range m.ResourceClaims { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.DisruptionMode != nil { + l = len(*m.DisruptionMode) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.PriorityClassName) + n += 1 + l + sovGenerated(uint64(l)) + if m.Priority != nil { + n += 1 + sovGenerated(uint64(*m.Priority)) + } + return n +} + +func (m *PodGroupStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.ResourceClaimStatuses) > 0 { + for _, e := range m.ResourceClaimStatuses { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *PodGroupTemplate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = m.SchedulingPolicy.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.SchedulingConstraints != nil { + l = m.SchedulingConstraints.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ResourceClaims) > 0 { + for _, e := range m.ResourceClaims { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.DisruptionMode != nil { + l = len(*m.DisruptionMode) + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.PriorityClassName) + n += 1 + l + sovGenerated(uint64(l)) + if m.Priority != nil { + n += 1 + sovGenerated(uint64(*m.Priority)) + } + return n +} + +func (m *PodGroupTemplateReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Workload != nil { + l = m.Workload.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *TopologyConstraint) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *TypedLocalObjectReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Workload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *WorkloadList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *WorkloadPodGroupTemplateReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.WorkloadName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.PodGroupTemplateName) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *WorkloadSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ControllerRef != nil { + l = m.ControllerRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.PodGroupTemplates) > 0 { + for _, e := range m.PodGroupTemplates { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *BasicSchedulingPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&BasicSchedulingPolicy{`, + `}`, + }, "") + return s +} +func (this *GangSchedulingPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GangSchedulingPolicy{`, + `MinCount:` + fmt.Sprintf("%v", this.MinCount) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroup) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodGroup{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodGroupSpec", "PodGroupSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "PodGroupStatus", "PodGroupStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]PodGroup{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodGroup", "PodGroup", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&PodGroupList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupResourceClaim) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodGroupResourceClaim{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `ResourceClaimName:` + valueToStringGenerated(this.ResourceClaimName) + `,`, + `ResourceClaimTemplateName:` + valueToStringGenerated(this.ResourceClaimTemplateName) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupResourceClaimStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodGroupResourceClaimStatus{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `ResourceClaimName:` + valueToStringGenerated(this.ResourceClaimName) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupSchedulingConstraints) String() string { + if this == nil { + return "nil" + } + repeatedStringForTopology := "[]TopologyConstraint{" + for _, f := range this.Topology { + repeatedStringForTopology += strings.Replace(strings.Replace(f.String(), "TopologyConstraint", "TopologyConstraint", 1), `&`, ``, 1) + "," + } + repeatedStringForTopology += "}" + s := strings.Join([]string{`&PodGroupSchedulingConstraints{`, + `Topology:` + repeatedStringForTopology + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupSchedulingPolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodGroupSchedulingPolicy{`, + `Basic:` + strings.Replace(this.Basic.String(), "BasicSchedulingPolicy", "BasicSchedulingPolicy", 1) + `,`, + `Gang:` + strings.Replace(this.Gang.String(), "GangSchedulingPolicy", "GangSchedulingPolicy", 1) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupSpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForResourceClaims := "[]PodGroupResourceClaim{" + for _, f := range this.ResourceClaims { + repeatedStringForResourceClaims += strings.Replace(strings.Replace(f.String(), "PodGroupResourceClaim", "PodGroupResourceClaim", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceClaims += "}" + s := strings.Join([]string{`&PodGroupSpec{`, + `PodGroupTemplateRef:` + strings.Replace(this.PodGroupTemplateRef.String(), "PodGroupTemplateReference", "PodGroupTemplateReference", 1) + `,`, + `SchedulingPolicy:` + strings.Replace(strings.Replace(this.SchedulingPolicy.String(), "PodGroupSchedulingPolicy", "PodGroupSchedulingPolicy", 1), `&`, ``, 1) + `,`, + `SchedulingConstraints:` + strings.Replace(this.SchedulingConstraints.String(), "PodGroupSchedulingConstraints", "PodGroupSchedulingConstraints", 1) + `,`, + `ResourceClaims:` + repeatedStringForResourceClaims + `,`, + `DisruptionMode:` + valueToStringGenerated(this.DisruptionMode) + `,`, + `PriorityClassName:` + fmt.Sprintf("%v", this.PriorityClassName) + `,`, + `Priority:` + valueToStringGenerated(this.Priority) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + repeatedStringForResourceClaimStatuses := "[]PodGroupResourceClaimStatus{" + for _, f := range this.ResourceClaimStatuses { + repeatedStringForResourceClaimStatuses += strings.Replace(strings.Replace(f.String(), "PodGroupResourceClaimStatus", "PodGroupResourceClaimStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceClaimStatuses += "}" + s := strings.Join([]string{`&PodGroupStatus{`, + `Conditions:` + repeatedStringForConditions + `,`, + `ResourceClaimStatuses:` + repeatedStringForResourceClaimStatuses + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupTemplate) String() string { + if this == nil { + return "nil" + } + repeatedStringForResourceClaims := "[]PodGroupResourceClaim{" + for _, f := range this.ResourceClaims { + repeatedStringForResourceClaims += strings.Replace(strings.Replace(f.String(), "PodGroupResourceClaim", "PodGroupResourceClaim", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceClaims += "}" + s := strings.Join([]string{`&PodGroupTemplate{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `SchedulingPolicy:` + strings.Replace(strings.Replace(this.SchedulingPolicy.String(), "PodGroupSchedulingPolicy", "PodGroupSchedulingPolicy", 1), `&`, ``, 1) + `,`, + `SchedulingConstraints:` + strings.Replace(this.SchedulingConstraints.String(), "PodGroupSchedulingConstraints", "PodGroupSchedulingConstraints", 1) + `,`, + `ResourceClaims:` + repeatedStringForResourceClaims + `,`, + `DisruptionMode:` + valueToStringGenerated(this.DisruptionMode) + `,`, + `PriorityClassName:` + fmt.Sprintf("%v", this.PriorityClassName) + `,`, + `Priority:` + valueToStringGenerated(this.Priority) + `,`, + `}`, + }, "") + return s +} +func (this *PodGroupTemplateReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PodGroupTemplateReference{`, + `Workload:` + strings.Replace(this.Workload.String(), "WorkloadPodGroupTemplateReference", "WorkloadPodGroupTemplateReference", 1) + `,`, + `}`, + }, "") + return s +} +func (this *TopologyConstraint) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TopologyConstraint{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `}`, + }, "") + return s +} +func (this *TypedLocalObjectReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TypedLocalObjectReference{`, + `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *Workload) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Workload{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "WorkloadSpec", "WorkloadSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *WorkloadList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]Workload{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "Workload", "Workload", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&WorkloadList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *WorkloadPodGroupTemplateReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WorkloadPodGroupTemplateReference{`, + `WorkloadName:` + fmt.Sprintf("%v", this.WorkloadName) + `,`, + `PodGroupTemplateName:` + fmt.Sprintf("%v", this.PodGroupTemplateName) + `,`, + `}`, + }, "") + return s +} +func (this *WorkloadSpec) String() string { + if this == nil { + return "nil" + } + repeatedStringForPodGroupTemplates := "[]PodGroupTemplate{" + for _, f := range this.PodGroupTemplates { + repeatedStringForPodGroupTemplates += strings.Replace(strings.Replace(f.String(), "PodGroupTemplate", "PodGroupTemplate", 1), `&`, ``, 1) + "," + } + repeatedStringForPodGroupTemplates += "}" + s := strings.Join([]string{`&WorkloadSpec{`, + `ControllerRef:` + strings.Replace(this.ControllerRef.String(), "TypedLocalObjectReference", "TypedLocalObjectReference", 1) + `,`, + `PodGroupTemplates:` + repeatedStringForPodGroupTemplates + `,`, + `}`, + }, "") + return s +} +func valueToStringGenerated(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *BasicSchedulingPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BasicSchedulingPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BasicSchedulingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GangSchedulingPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GangSchedulingPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GangSchedulingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinCount", wireType) + } + m.MinCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinCount |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, PodGroup{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupResourceClaim) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupResourceClaim: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupResourceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimName = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimTemplateName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimTemplateName = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupResourceClaimStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupResourceClaimStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupResourceClaimStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceClaimName = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupSchedulingConstraints) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupSchedulingConstraints: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupSchedulingConstraints: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Topology", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Topology = append(m.Topology, TopologyConstraint{}) + if err := m.Topology[len(m.Topology)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupSchedulingPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupSchedulingPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupSchedulingPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Basic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Basic == nil { + m.Basic = &BasicSchedulingPolicy{} + } + if err := m.Basic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Gang", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Gang == nil { + m.Gang = &GangSchedulingPolicy{} + } + if err := m.Gang.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodGroupTemplateRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PodGroupTemplateRef == nil { + m.PodGroupTemplateRef = &PodGroupTemplateReference{} + } + if err := m.PodGroupTemplateRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingPolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SchedulingPolicy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingConstraints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SchedulingConstraints == nil { + m.SchedulingConstraints = &PodGroupSchedulingConstraints{} + } + if err := m.SchedulingConstraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaims = append(m.ResourceClaims, PodGroupResourceClaim{}) + if err := m.ResourceClaims[len(m.ResourceClaims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DisruptionMode", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := DisruptionMode(dAtA[iNdEx:postIndex]) + m.DisruptionMode = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriorityClassName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriorityClassName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Priority = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaimStatuses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaimStatuses = append(m.ResourceClaimStatuses, PodGroupResourceClaimStatus{}) + if err := m.ResourceClaimStatuses[len(m.ResourceClaimStatuses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupTemplate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupTemplate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingPolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SchedulingPolicy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingConstraints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SchedulingConstraints == nil { + m.SchedulingConstraints = &PodGroupSchedulingConstraints{} + } + if err := m.SchedulingConstraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceClaims", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceClaims = append(m.ResourceClaims, PodGroupResourceClaim{}) + if err := m.ResourceClaims[len(m.ResourceClaims)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DisruptionMode", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := DisruptionMode(dAtA[iNdEx:postIndex]) + m.DisruptionMode = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriorityClassName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriorityClassName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Priority = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PodGroupTemplateReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodGroupTemplateReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodGroupTemplateReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Workload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Workload == nil { + m.Workload = &WorkloadPodGroupTemplateReference{} + } + if err := m.Workload.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TopologyConstraint) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TopologyConstraint: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TopologyConstraint: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TypedLocalObjectReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TypedLocalObjectReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TypedLocalObjectReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIGroup = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Workload) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Workload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Workload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkloadList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkloadList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkloadList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, Workload{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkloadPodGroupTemplateReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkloadPodGroupTemplateReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkloadPodGroupTemplateReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WorkloadName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodGroupTemplateName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PodGroupTemplateName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkloadSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkloadSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkloadSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ControllerRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ControllerRef == nil { + m.ControllerRef = &TypedLocalObjectReference{} + } + if err := m.ControllerRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodGroupTemplates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PodGroupTemplates = append(m.PodGroupTemplates, PodGroupTemplate{}) + if err := m.PodGroupTemplates[len(m.PodGroupTemplates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/generated.proto b/vendor/k8s.io/api/scheduling/v1alpha2/generated.proto new file mode 100644 index 0000000000..73b3308e38 --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/generated.proto @@ -0,0 +1,550 @@ +/* +Copyright 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. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.scheduling.v1alpha2; + +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/scheduling/v1alpha2"; + +// BasicSchedulingPolicy indicates that standard Kubernetes +// scheduling behavior should be used. +message BasicSchedulingPolicy { +} + +// GangSchedulingPolicy defines the parameters for gang scheduling. +message GangSchedulingPolicy { + // MinCount is the minimum number of pods that must be schedulable or scheduled + // at the same time for the scheduler to admit the entire group. + // It must be a positive integer. + // + // +required + // +k8s:required + // +k8s:minimum=1 + optional int32 minCount = 1; +} + +// PodGroup represents a runtime instance of pods grouped together. +// PodGroups are created by workload controllers (Job, LWS, JobSet, etc...) from +// Workload.podGroupTemplates. +// PodGroup API enablement is toggled by the GenericWorkload feature gate. +message PodGroup { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec defines the desired state of the PodGroup. + // + // +required + optional PodGroupSpec spec = 2; + + // Status represents the current observed state of the PodGroup. + // + // +optional + optional PodGroupStatus status = 3; +} + +// PodGroupList contains a list of PodGroup resources. +message PodGroupList { + // Standard list metadata. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of PodGroups. + repeated PodGroup items = 2; +} + +// PodGroupResourceClaim references exactly one ResourceClaim, either directly +// or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim +// for the PodGroup. +// +// It adds a name to it that uniquely identifies the ResourceClaim inside the PodGroup. +// Pods that need access to the ResourceClaim define a matching reference in its +// own Spec.ResourceClaims. The Pod's claim must match all fields of the +// PodGroup's claim exactly. +message PodGroupResourceClaim { + // Name uniquely identifies this resource claim inside the PodGroup. + // This must be a DNS_LABEL. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + optional string name = 1; + + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this PodGroup. The ResourceClaim will be reserved for the + // PodGroup instead of its individual pods. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + // +k8s:optional + // +k8s:unionMember + // +k8s:format=k8s-long-name + optional string resourceClaimName = 2; + + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this PodGroup. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this PodGroup. When this PodGroup is deleted, the ResourceClaim + // will also be deleted. The PodGroup name and resource name, along with a + // generated component, will be used to form a unique name for the + // ResourceClaim, which will be recorded in podgroup.status.resourceClaimStatuses. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + // +k8s:optional + // +k8s:unionMember + // +k8s:format=k8s-long-name + optional string resourceClaimTemplateName = 3; +} + +// PodGroupResourceClaimStatus is stored in the PodGroupStatus for each +// PodGroupResourceClaim which references a ResourceClaimTemplate. It stores the +// generated name for the corresponding ResourceClaim. +message PodGroupResourceClaimStatus { + // Name uniquely identifies this resource claim inside the PodGroup. This + // must match the name of an entry in podgroup.spec.resourceClaims, which + // implies that the string must be a DNS_LABEL. + // + // +required + optional string name = 1; + + // ResourceClaimName is the name of the ResourceClaim that was generated for + // the PodGroup in the namespace of the PodGroup. If this is unset, then + // generating a ResourceClaim was not necessary. The + // podgroup.spec.resourceClaims entry can be ignored in this case. + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + optional string resourceClaimName = 2; +} + +// PodGroupSchedulingConstraints defines scheduling constraints (e.g. topology) for a PodGroup. +message PodGroupSchedulingConstraints { + // Topology defines the topology constraints for the pod group. + // Currently only a single topology constraint can be specified. This may change in the future. + // + // +optional + // +k8s:optional + // +k8s:maxItems=1 + // +listType=atomic + // +k8s:listType=atomic + repeated TopologyConstraint topology = 1; +} + +// PodGroupSchedulingPolicy defines the scheduling configuration for a PodGroup. +// Exactly one policy must be set. +// +union +message PodGroupSchedulingPolicy { + // Basic specifies that the pods in this group should be scheduled using + // standard Kubernetes scheduling behavior. + // + // +optional + // +k8s:optional + // +k8s:unionMember + optional BasicSchedulingPolicy basic = 1; + + // Gang specifies that the pods in this group should be scheduled using + // all-or-nothing semantics. + // + // +optional + // +k8s:optional + // +k8s:unionMember + optional GangSchedulingPolicy gang = 2; +} + +// PodGroupSpec defines the desired state of a PodGroup. +message PodGroupSpec { + // PodGroupTemplateRef references an optional PodGroup template within other object + // (e.g. Workload) that was used to create the PodGroup. This field is immutable. + // + // +optional + // +k8s:optional + // +k8s:immutable + optional PodGroupTemplateReference podGroupTemplateRef = 1; + + // SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // + // +required + // +k8s:immutable + optional PodGroupSchedulingPolicy schedulingPolicy = 2; + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +featureGate=TopologyAwareWorkloadScheduling + // +optional + // +k8s:ifDisabled(TopologyAwareWorkloadScheduling)=+k8s:forbidden + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:optional + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:immutable + optional PodGroupSchedulingConstraints schedulingConstraints = 3; + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +k8s:immutable + // +featureGate=DRAWorkloadResourceClaims + repeated PodGroupResourceClaim resourceClaims = 4; + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // One of Pod, PodGroup. Defaults to Pod if unset. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +default="Pod" + optional string disruptionMode = 5; + + // PriorityClassName defines the priority that should be considered when scheduling this pod group. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate + // (i.e. if no priority class is specified, admission control can set this to the global default + // priority class if it exists. Otherwise, the pod group's priority will be zero). + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + optional string priorityClassName = 6; + + // Priority is the value of priority of this pod group. Various system components + // use this field to find the priority of the pod group. When Priority Admission + // Controller is enabled, it prevents users from setting this field. The admission + // controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:minimum=-2147483648 + optional int32 priority = 7; +} + +// PodGroupStatus represents information about the status of a pod group. +message PodGroupStatus { + // Conditions represent the latest observations of the PodGroup's state. + // + // Known condition types: + // - "PodGroupScheduled": Indicates whether the scheduling requirement has been satisfied. + // - "DisruptionTarget": Indicates whether the PodGroup is about to be terminated + // due to disruption such as preemption. + // + // Known reasons for the PodGroupScheduled condition: + // - "Unschedulable": The PodGroup cannot be scheduled due to resource constraints, + // affinity/anti-affinity rules, or insufficient capacity for the gang. + // - "SchedulerError": The PodGroup cannot be scheduled due to some internal error + // that happened during scheduling, for example due to nodeAffinity parsing errors. + // + // Known reasons for the DisruptionTarget condition: + // - "PreemptionByScheduler": The PodGroup was preempted by the scheduler to make room for + // higher-priority PodGroups or Pods. + // + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1; + + // Status of resource claims. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +featureGate=DRAWorkloadResourceClaims + repeated PodGroupResourceClaimStatus resourceClaimStatuses = 2; +} + +// PodGroupTemplate represents a template for a set of pods with a scheduling policy. +message PodGroupTemplate { + // Name is a unique identifier for the PodGroupTemplate within the Workload. + // It must be a DNS label. This field is immutable. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + optional string name = 1; + + // SchedulingPolicy defines the scheduling policy for this PodGroupTemplate. + // + // +required + optional PodGroupSchedulingPolicy schedulingPolicy = 2; + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +featureGate=TopologyAwareWorkloadScheduling + // +optional + // +k8s:ifDisabled(TopologyAwareWorkloadScheduling)=+k8s:forbidden + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:optional + optional PodGroupSchedulingConstraints schedulingConstraints = 3; + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +k8s:immutable + // +featureGate=DRAWorkloadResourceClaims + repeated PodGroupResourceClaim resourceClaims = 4; + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // One of Pod, PodGroup. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + optional string disruptionMode = 5; + + // PriorityClassName indicates the priority that should be considered when scheduling + // a pod group created from this template. If no priority class is specified, admission + // control can set this to the global default priority class if it exists. Otherwise, + // pod groups created from this template will have the priority set to zero. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + optional string priorityClassName = 6; + + // Priority is the value of priority of pod groups created from this template. Various + // system components use this field to find the priority of the pod group. When + // Priority Admission Controller is enabled, it prevents users from setting this field. + // The admission controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:minimum=-2147483648 + optional int32 priority = 7; +} + +// PodGroupTemplateReference references a PodGroup template defined in some object (e.g. Workload). +// Exactly one reference must be set. +// +union +message PodGroupTemplateReference { + // Workload references the PodGroupTemplate within the Workload object that was used to create + // the PodGroup. + // + // +optional + // +k8s:optional + // +k8s:unionMember + optional WorkloadPodGroupTemplateReference workload = 1; +} + +// TopologyConstraint defines a topology constraint for a PodGroup. +message TopologyConstraint { + // Key specifies the key of the node label representing the topology domain. + // All pods within the PodGroup must be colocated within the same domain instance. + // Different PodGroups can land on different domain instances even if they derive from the same PodGroupTemplate. + // Examples: "topology.kubernetes.io/rack" + // + // +required + // +k8s:required + // +k8s:format=k8s-label-key + optional string key = 1; +} + +// TypedLocalObjectReference allows to reference typed object inside the same namespace. +message TypedLocalObjectReference { + // APIGroup is the group for the resource being referenced. + // If APIGroup is empty, the specified Kind must be in the core API group. + // For any other third-party types, setting APIGroup is required. + // It must be a DNS subdomain. + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + optional string apiGroup = 1; + + // Kind is the type of resource being referenced. + // It must be a path segment name. + // + // +required + // +k8s:required + // +k8s:format=k8s-path-segment-name + optional string kind = 2; + + // Name is the name of resource being referenced. + // It must be a path segment name. + // + // +required + // +k8s:required + // +k8s:format=k8s-path-segment-name + optional string name = 3; +} + +// Workload allows for expressing scheduling constraints that should be used +// when managing the lifecycle of workloads from the scheduling perspective, +// including scheduling, preemption, eviction and other phases. +// Workload API enablement is toggled by the GenericWorkload feature gate. +message Workload { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec defines the desired behavior of a Workload. + // + // +required + optional WorkloadSpec spec = 2; +} + +// WorkloadList contains a list of Workload resources. +message WorkloadList { + // Standard list metadata. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of Workloads. + repeated Workload items = 2; +} + +// WorkloadPodGroupTemplateReference references the PodGroupTemplate within the Workload object. +message WorkloadPodGroupTemplateReference { + // WorkloadName defines the name of the Workload object. + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name + optional string workloadName = 1; + + // PodGroupTemplateName defines the PodGroupTemplate name within the Workload object. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + optional string podGroupTemplateName = 2; +} + +// WorkloadSpec defines the desired state of a Workload. +message WorkloadSpec { + // ControllerRef is an optional reference to the controlling object, such as a + // Deployment or Job. This field is intended for use by tools like CLIs + // to provide a link back to the original workload definition. + // This field is immutable. + // + // +optional + // +k8s:optional + // +k8s:immutable + optional TypedLocalObjectReference controllerRef = 1; + + // PodGroupTemplates is the list of templates that make up the Workload. + // The maximum number of templates is 8. This field is immutable. + // + // +required + // +listType=map + // +listMapKey=name + // +k8s:required + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=8 + // +k8s:immutable + repeated PodGroupTemplate podGroupTemplates = 2; +} + diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/register.go b/vendor/k8s.io/api/scheduling/v1alpha2/register.go similarity index 90% rename from vendor/k8s.io/api/scheduling/v1alpha1/register.go rename to vendor/k8s.io/api/scheduling/v1alpha2/register.go index 25de55d308..fc03ae5ec9 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/register.go +++ b/vendor/k8s.io/api/scheduling/v1alpha2/register.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +Copyright 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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1alpha2 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,7 +26,7 @@ import ( const GroupName = "scheduling.k8s.io" // SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} // Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { @@ -43,11 +43,12 @@ var ( // Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &PriorityClass{}, - &PriorityClassList{}, + scheme.AddKnownTypes( + SchemeGroupVersion, &Workload{}, &WorkloadList{}, + &PodGroup{}, + &PodGroupList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/types.go b/vendor/k8s.io/api/scheduling/v1alpha2/types.go new file mode 100644 index 0000000000..1f84f2c43d --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/types.go @@ -0,0 +1,601 @@ +/* +Copyright 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 v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Workload allows for expressing scheduling constraints that should be used +// when managing the lifecycle of workloads from the scheduling perspective, +// including scheduling, preemption, eviction and other phases. +// Workload API enablement is toggled by the GenericWorkload feature gate. +type Workload struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec defines the desired behavior of a Workload. + // + // +required + Spec WorkloadSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkloadList contains a list of Workload resources. +type WorkloadList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of Workloads. + Items []Workload `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// WorkloadMaxPodGroupTemplates is the maximum number of pod group templates per Workload. +const WorkloadMaxPodGroupTemplates = 8 + +// WorkloadSpec defines the desired state of a Workload. +type WorkloadSpec struct { + // ControllerRef is an optional reference to the controlling object, such as a + // Deployment or Job. This field is intended for use by tools like CLIs + // to provide a link back to the original workload definition. + // This field is immutable. + // + // +optional + // +k8s:optional + // +k8s:immutable + ControllerRef *TypedLocalObjectReference `json:"controllerRef,omitempty" protobuf:"bytes,1,opt,name=controllerRef"` + + // PodGroupTemplates is the list of templates that make up the Workload. + // The maximum number of templates is 8. This field is immutable. + // + // +required + // +listType=map + // +listMapKey=name + // +k8s:required + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=8 + // +k8s:immutable + PodGroupTemplates []PodGroupTemplate `json:"podGroupTemplates" protobuf:"bytes,2,rep,name=podGroupTemplates"` +} + +// TypedLocalObjectReference allows to reference typed object inside the same namespace. +type TypedLocalObjectReference struct { + // APIGroup is the group for the resource being referenced. + // If APIGroup is empty, the specified Kind must be in the core API group. + // For any other third-party types, setting APIGroup is required. + // It must be a DNS subdomain. + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=apiGroup"` + // Kind is the type of resource being referenced. + // It must be a path segment name. + // + // +required + // +k8s:required + // +k8s:format=k8s-path-segment-name + Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` + // Name is the name of resource being referenced. + // It must be a path segment name. + // + // +required + // +k8s:required + // +k8s:format=k8s-path-segment-name + Name string `json:"name" protobuf:"bytes,3,opt,name=name"` +} + +// MaxPodGroupResourceClaims is the maximum number of resource claims for a +// PodGroup or a Workload's PodGroupTemplate. +const MaxPodGroupResourceClaims = 4 + +// PodGroupTemplate represents a template for a set of pods with a scheduling policy. +type PodGroupTemplate struct { + // Name is a unique identifier for the PodGroupTemplate within the Workload. + // It must be a DNS label. This field is immutable. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // SchedulingPolicy defines the scheduling policy for this PodGroupTemplate. + // + // +required + SchedulingPolicy PodGroupSchedulingPolicy `json:"schedulingPolicy" protobuf:"bytes,2,opt,name=schedulingPolicy"` + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +featureGate=TopologyAwareWorkloadScheduling + // +optional + // +k8s:ifDisabled(TopologyAwareWorkloadScheduling)=+k8s:forbidden + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:optional + SchedulingConstraints *PodGroupSchedulingConstraints `json:"schedulingConstraints" protobuf:"bytes,3,opt,name=schedulingConstraints"` + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +k8s:immutable + // +featureGate=DRAWorkloadResourceClaims + ResourceClaims []PodGroupResourceClaim `json:"resourceClaims,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,4,rep,name=resourceClaims"` + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // One of Pod, PodGroup. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + DisruptionMode *DisruptionMode `json:"disruptionMode,omitempty" protobuf:"bytes,5,opt,name=disruptionMode,casttype=DisruptionMode"` + + // PriorityClassName indicates the priority that should be considered when scheduling + // a pod group created from this template. If no priority class is specified, admission + // control can set this to the global default priority class if it exists. Otherwise, + // pod groups created from this template will have the priority set to zero. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + PriorityClassName string `json:"priorityClassName,omitempty" protobuf:"bytes,6,opt,name=priorityClassName"` + + // Priority is the value of priority of pod groups created from this template. Various + // system components use this field to find the priority of the pod group. When + // Priority Admission Controller is enabled, it prevents users from setting this field. + // The admission controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:minimum=-2147483648 + Priority *int32 `json:"priority,omitempty" protobuf:"varint,7,opt,name=priority"` +} + +// PodGroupSchedulingPolicy defines the scheduling configuration for a PodGroup. +// Exactly one policy must be set. +// +union +type PodGroupSchedulingPolicy struct { + // Basic specifies that the pods in this group should be scheduled using + // standard Kubernetes scheduling behavior. + // + // +optional + // +k8s:optional + // +k8s:unionMember + Basic *BasicSchedulingPolicy `json:"basic,omitempty" protobuf:"bytes,1,opt,name=basic"` + + // Gang specifies that the pods in this group should be scheduled using + // all-or-nothing semantics. + // + // +optional + // +k8s:optional + // +k8s:unionMember + Gang *GangSchedulingPolicy `json:"gang,omitempty" protobuf:"bytes,2,opt,name=gang"` +} + +// BasicSchedulingPolicy indicates that standard Kubernetes +// scheduling behavior should be used. +type BasicSchedulingPolicy struct { + // This is intentionally empty. Its presence indicates that the basic + // scheduling policy should be applied. In the future, new fields may appear, + // describing such constraints on a pod group level without "all or nothing" + // (gang) scheduling. +} + +// GangSchedulingPolicy defines the parameters for gang scheduling. +type GangSchedulingPolicy struct { + // MinCount is the minimum number of pods that must be schedulable or scheduled + // at the same time for the scheduler to admit the entire group. + // It must be a positive integer. + // + // +required + // +k8s:required + // +k8s:minimum=1 + MinCount int32 `json:"minCount" protobuf:"varint,1,opt,name=minCount"` +} + +// PodGroupResourceClaim references exactly one ResourceClaim, either directly +// or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim +// for the PodGroup. +// +// It adds a name to it that uniquely identifies the ResourceClaim inside the PodGroup. +// Pods that need access to the ResourceClaim define a matching reference in its +// own Spec.ResourceClaims. The Pod's claim must match all fields of the +// PodGroup's claim exactly. +type PodGroupResourceClaim struct { + // Name uniquely identifies this resource claim inside the PodGroup. + // This must be a DNS_LABEL. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this PodGroup. The ResourceClaim will be reserved for the + // PodGroup instead of its individual pods. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + // +k8s:optional + // +k8s:unionMember + // +k8s:format=k8s-long-name + ResourceClaimName *string `json:"resourceClaimName,omitempty" protobuf:"bytes,2,opt,name=resourceClaimName"` + + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this PodGroup. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this PodGroup. When this PodGroup is deleted, the ResourceClaim + // will also be deleted. The PodGroup name and resource name, along with a + // generated component, will be used to form a unique name for the + // ResourceClaim, which will be recorded in podgroup.status.resourceClaimStatuses. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + // +k8s:optional + // +k8s:unionMember + // +k8s:format=k8s-long-name + ResourceClaimTemplateName *string `json:"resourceClaimTemplateName,omitempty" protobuf:"bytes,3,opt,name=resourceClaimTemplateName"` +} + +// DisruptionMode describes the mode in which a PodGroup can be disrupted (e.g. preempted). +// +enum +// +k8s:enum +type DisruptionMode string + +const ( + // DisruptionModePod means that individual pods can be disrupted or preempted independently. + // It doesn't depend on exact set of pods currently running in this PodGroup. + DisruptionModePod DisruptionMode = "Pod" + // DisruptionModePodGroup means that the whole PodGroup needs to be disrupted + // or preempted together. + DisruptionModePodGroup DisruptionMode = "PodGroup" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:supportsSubresource="/status" + +// PodGroup represents a runtime instance of pods grouped together. +// PodGroups are created by workload controllers (Job, LWS, JobSet, etc...) from +// Workload.podGroupTemplates. +// PodGroup API enablement is toggled by the GenericWorkload feature gate. +type PodGroup struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec defines the desired state of the PodGroup. + // + // +required + Spec PodGroupSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` + + // Status represents the current observed state of the PodGroup. + // + // +optional + Status PodGroupStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodGroupList contains a list of PodGroup resources. +type PodGroupList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of PodGroups. + Items []PodGroup `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// PodGroupSpec defines the desired state of a PodGroup. +type PodGroupSpec struct { + // PodGroupTemplateRef references an optional PodGroup template within other object + // (e.g. Workload) that was used to create the PodGroup. This field is immutable. + // + // +optional + // +k8s:optional + // +k8s:immutable + PodGroupTemplateRef *PodGroupTemplateReference `json:"podGroupTemplateRef" protobuf:"bytes,1,opt,name=podGroupTemplateRef"` + + // SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // + // +required + // +k8s:immutable + SchedulingPolicy PodGroupSchedulingPolicy `json:"schedulingPolicy" protobuf:"bytes,2,opt,name=schedulingPolicy"` + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +featureGate=TopologyAwareWorkloadScheduling + // +optional + // +k8s:ifDisabled(TopologyAwareWorkloadScheduling)=+k8s:forbidden + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:optional + // +k8s:ifEnabled(TopologyAwareWorkloadScheduling)=+k8s:immutable + SchedulingConstraints *PodGroupSchedulingConstraints `json:"schedulingConstraints,omitempty" protobuf:"bytes,3,opt,name=schedulingConstraints"` + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +k8s:immutable + // +featureGate=DRAWorkloadResourceClaims + ResourceClaims []PodGroupResourceClaim `json:"resourceClaims,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,4,rep,name=resourceClaims"` + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // One of Pod, PodGroup. Defaults to Pod if unset. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +default="Pod" + DisruptionMode *DisruptionMode `json:"disruptionMode,omitempty" protobuf:"bytes,5,opt,name=disruptionMode,casttype=DisruptionMode"` + + // PriorityClassName defines the priority that should be considered when scheduling this pod group. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate + // (i.e. if no priority class is specified, admission control can set this to the global default + // priority class if it exists. Otherwise, the pod group's priority will be zero). + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + PriorityClassName string `json:"priorityClassName,omitempty" protobuf:"bytes,6,opt,name=priorityClassName"` + + // Priority is the value of priority of this pod group. Various system components + // use this field to find the priority of the pod group. When Priority Admission + // Controller is enabled, it prevents users from setting this field. The admission + // controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:minimum=-2147483648 + Priority *int32 `json:"priority,omitempty" protobuf:"varint,7,opt,name=priority"` +} + +// PodGroupStatus represents information about the status of a pod group. +type PodGroupStatus struct { + // Conditions represent the latest observations of the PodGroup's state. + // + // Known condition types: + // - "PodGroupScheduled": Indicates whether the scheduling requirement has been satisfied. + // - "DisruptionTarget": Indicates whether the PodGroup is about to be terminated + // due to disruption such as preemption. + // + // Known reasons for the PodGroupScheduled condition: + // - "Unschedulable": The PodGroup cannot be scheduled due to resource constraints, + // affinity/anti-affinity rules, or insufficient capacity for the gang. + // - "SchedulerError": The PodGroup cannot be scheduled due to some internal error + // that happened during scheduling, for example due to nodeAffinity parsing errors. + // + // Known reasons for the DisruptionTarget condition: + // - "PreemptionByScheduler": The PodGroup was preempted by the scheduler to make room for + // higher-priority PodGroups or Pods. + // + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + // Status of resource claims. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +k8s:optional + // +k8s:listType=map + // +k8s:listMapKey=name + // +k8s:maxItems=4 + // +featureGate=DRAWorkloadResourceClaims + ResourceClaimStatuses []PodGroupResourceClaimStatus `json:"resourceClaimStatuses,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,2,rep,name=resourceClaimStatuses"` +} + +// Well-known condition types for PodGroups. +const ( + // PodGroupScheduled represents status of the scheduling process for this PodGroup. + PodGroupScheduled string = "PodGroupScheduled" + // DisruptionTarget indicates the PodGroup is about to be terminated due to disruption + // such as preemption. + DisruptionTarget string = "DisruptionTarget" +) + +// Well-known condition reasons for PodGroups. +const ( + // Unschedulable reason in the PodGroupScheduled condition indicates that the PodGroup cannot be scheduled + // due to resource constraints, affinity/anti-affinity rules, or insufficient capacity for the PodGroup. + PodGroupReasonUnschedulable string = "Unschedulable" + // SchedulerError reason in the PodGroupScheduled condition means that some internal error happens + // during scheduling, for example due to nodeAffinity parsing errors. + PodGroupReasonSchedulerError string = "SchedulerError" + // PreemptionByScheduler reason in the DisruptionTarget condition indicates the PodGroup was preempted + // to make room for higher-priority PodGroups or Pods. + PodGroupReasonPreemptionByScheduler string = "PreemptionByScheduler" +) + +// PodGroupResourceClaimStatus is stored in the PodGroupStatus for each +// PodGroupResourceClaim which references a ResourceClaimTemplate. It stores the +// generated name for the corresponding ResourceClaim. +type PodGroupResourceClaimStatus struct { + // Name uniquely identifies this resource claim inside the PodGroup. This + // must match the name of an entry in podgroup.spec.resourceClaims, which + // implies that the string must be a DNS_LABEL. + // + // +required + Name string `json:"name" protobuf:"bytes,1,name=name"` + + // ResourceClaimName is the name of the ResourceClaim that was generated for + // the PodGroup in the namespace of the PodGroup. If this is unset, then + // generating a ResourceClaim was not necessary. The + // podgroup.spec.resourceClaims entry can be ignored in this case. + // + // +optional + // +k8s:optional + // +k8s:format=k8s-long-name + ResourceClaimName *string `json:"resourceClaimName,omitempty" protobuf:"bytes,2,opt,name=resourceClaimName"` +} + +// PodGroupTemplateReference references a PodGroup template defined in some object (e.g. Workload). +// Exactly one reference must be set. +// +union +type PodGroupTemplateReference struct { + // Workload references the PodGroupTemplate within the Workload object that was used to create + // the PodGroup. + // + // +optional + // +k8s:optional + // +k8s:unionMember + Workload *WorkloadPodGroupTemplateReference `json:"workload" protobuf:"bytes,1,opt,name=workload"` +} + +// WorkloadPodGroupTemplateReference references the PodGroupTemplate within the Workload object. +type WorkloadPodGroupTemplateReference struct { + // WorkloadName defines the name of the Workload object. + // + // +required + // +k8s:required + // +k8s:format=k8s-long-name + WorkloadName string `json:"workloadName" protobuf:"bytes,1,opt,name=workloadName"` + + // PodGroupTemplateName defines the PodGroupTemplate name within the Workload object. + // + // +required + // +k8s:required + // +k8s:format=k8s-short-name + PodGroupTemplateName string `json:"podGroupTemplateName" protobuf:"bytes,2,opt,name=podGroupTemplateName"` +} + +// PodGroupSchedulingConstraints defines scheduling constraints (e.g. topology) for a PodGroup. +type PodGroupSchedulingConstraints struct { + // Topology defines the topology constraints for the pod group. + // Currently only a single topology constraint can be specified. This may change in the future. + // + // +optional + // +k8s:optional + // +k8s:maxItems=1 + // +listType=atomic + // +k8s:listType=atomic + Topology []TopologyConstraint `json:"topology,omitempty" protobuf:"bytes,1,rep,name=topology"` +} + +// TopologyConstraint defines a topology constraint for a PodGroup. +type TopologyConstraint struct { + // Key specifies the key of the node label representing the topology domain. + // All pods within the PodGroup must be colocated within the same domain instance. + // Different PodGroups can land on different domain instances even if they derive from the same PodGroupTemplate. + // Examples: "topology.kubernetes.io/rack" + // + // +required + // +k8s:required + // +k8s:format=k8s-label-key + Key string `json:"key" protobuf:"bytes,1,opt,name=key"` +} diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1alpha2/types_swagger_doc_generated.go new file mode 100644 index 0000000000..2dc06b1c6f --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/types_swagger_doc_generated.go @@ -0,0 +1,217 @@ +/* +Copyright 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 v1alpha2 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_BasicSchedulingPolicy = map[string]string{ + "": "BasicSchedulingPolicy indicates that standard Kubernetes scheduling behavior should be used.", +} + +func (BasicSchedulingPolicy) SwaggerDoc() map[string]string { + return map_BasicSchedulingPolicy +} + +var map_GangSchedulingPolicy = map[string]string{ + "": "GangSchedulingPolicy defines the parameters for gang scheduling.", + "minCount": "MinCount is the minimum number of pods that must be schedulable or scheduled at the same time for the scheduler to admit the entire group. It must be a positive integer.", +} + +func (GangSchedulingPolicy) SwaggerDoc() map[string]string { + return map_GangSchedulingPolicy +} + +var map_PodGroup = map[string]string{ + "": "PodGroup represents a runtime instance of pods grouped together. PodGroups are created by workload controllers (Job, LWS, JobSet, etc...) from Workload.podGroupTemplates. PodGroup API enablement is toggled by the GenericWorkload feature gate.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "Spec defines the desired state of the PodGroup.", + "status": "Status represents the current observed state of the PodGroup.", +} + +func (PodGroup) SwaggerDoc() map[string]string { + return map_PodGroup +} + +var map_PodGroupList = map[string]string{ + "": "PodGroupList contains a list of PodGroup resources.", + "metadata": "Standard list metadata.", + "items": "Items is the list of PodGroups.", +} + +func (PodGroupList) SwaggerDoc() map[string]string { + return map_PodGroupList +} + +var map_PodGroupResourceClaim = map[string]string{ + "": "PodGroupResourceClaim references exactly one ResourceClaim, either directly or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim for the PodGroup.\n\nIt adds a name to it that uniquely identifies the ResourceClaim inside the PodGroup. Pods that need access to the ResourceClaim define a matching reference in its own Spec.ResourceClaims. The Pod's claim must match all fields of the PodGroup's claim exactly.", + "name": "Name uniquely identifies this resource claim inside the PodGroup. This must be a DNS_LABEL.", + "resourceClaimName": "ResourceClaimName is the name of a ResourceClaim object in the same namespace as this PodGroup. The ResourceClaim will be reserved for the PodGroup instead of its individual pods.\n\nExactly one of ResourceClaimName and ResourceClaimTemplateName must be set.", + "resourceClaimTemplateName": "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this PodGroup.\n\nThe template will be used to create a new ResourceClaim, which will be bound to this PodGroup. When this PodGroup is deleted, the ResourceClaim will also be deleted. The PodGroup name and resource name, along with a generated component, will be used to form a unique name for the ResourceClaim, which will be recorded in podgroup.status.resourceClaimStatuses.\n\nThis field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim.\n\nExactly one of ResourceClaimName and ResourceClaimTemplateName must be set.", +} + +func (PodGroupResourceClaim) SwaggerDoc() map[string]string { + return map_PodGroupResourceClaim +} + +var map_PodGroupResourceClaimStatus = map[string]string{ + "": "PodGroupResourceClaimStatus is stored in the PodGroupStatus for each PodGroupResourceClaim which references a ResourceClaimTemplate. It stores the generated name for the corresponding ResourceClaim.", + "name": "Name uniquely identifies this resource claim inside the PodGroup. This must match the name of an entry in podgroup.spec.resourceClaims, which implies that the string must be a DNS_LABEL.", + "resourceClaimName": "ResourceClaimName is the name of the ResourceClaim that was generated for the PodGroup in the namespace of the PodGroup. If this is unset, then generating a ResourceClaim was not necessary. The podgroup.spec.resourceClaims entry can be ignored in this case.", +} + +func (PodGroupResourceClaimStatus) SwaggerDoc() map[string]string { + return map_PodGroupResourceClaimStatus +} + +var map_PodGroupSchedulingConstraints = map[string]string{ + "": "PodGroupSchedulingConstraints defines scheduling constraints (e.g. topology) for a PodGroup.", + "topology": "Topology defines the topology constraints for the pod group. Currently only a single topology constraint can be specified. This may change in the future.", +} + +func (PodGroupSchedulingConstraints) SwaggerDoc() map[string]string { + return map_PodGroupSchedulingConstraints +} + +var map_PodGroupSchedulingPolicy = map[string]string{ + "": "PodGroupSchedulingPolicy defines the scheduling configuration for a PodGroup. Exactly one policy must be set.", + "basic": "Basic specifies that the pods in this group should be scheduled using standard Kubernetes scheduling behavior.", + "gang": "Gang specifies that the pods in this group should be scheduled using all-or-nothing semantics.", +} + +func (PodGroupSchedulingPolicy) SwaggerDoc() map[string]string { + return map_PodGroupSchedulingPolicy +} + +var map_PodGroupSpec = map[string]string{ + "": "PodGroupSpec defines the desired state of a PodGroup.", + "podGroupTemplateRef": "PodGroupTemplateRef references an optional PodGroup template within other object (e.g. Workload) that was used to create the PodGroup. This field is immutable.", + "schedulingPolicy": "SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. Controllers are expected to fill this field by copying it from a PodGroupTemplate. This field is immutable.", + "schedulingConstraints": "SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. Controllers are expected to fill this field by copying it from a PodGroupTemplate. This field is immutable. This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled.", + "resourceClaims": "ResourceClaims defines which ResourceClaims may be shared among Pods in the group. Pods consume the devices allocated to a PodGroup's claim by defining a claim in its own Spec.ResourceClaims that matches the PodGroup's claim exactly. The claim must have the same name and refer to the same ResourceClaim or ResourceClaimTemplate.\n\nThis is an alpha-level field and requires that the DRAWorkloadResourceClaims feature gate is enabled.\n\nThis field is immutable.", + "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Pod, PodGroup. Defaults to Pod if unset. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "priorityClassName": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "priority": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", +} + +func (PodGroupSpec) SwaggerDoc() map[string]string { + return map_PodGroupSpec +} + +var map_PodGroupStatus = map[string]string{ + "": "PodGroupStatus represents information about the status of a pod group.", + "conditions": "Conditions represent the latest observations of the PodGroup's state.\n\nKnown condition types: - \"PodGroupScheduled\": Indicates whether the scheduling requirement has been satisfied. - \"DisruptionTarget\": Indicates whether the PodGroup is about to be terminated\n due to disruption such as preemption.\n\nKnown reasons for the PodGroupScheduled condition: - \"Unschedulable\": The PodGroup cannot be scheduled due to resource constraints,\n affinity/anti-affinity rules, or insufficient capacity for the gang.\n- \"SchedulerError\": The PodGroup cannot be scheduled due to some internal error\n that happened during scheduling, for example due to nodeAffinity parsing errors.\n\nKnown reasons for the DisruptionTarget condition: - \"PreemptionByScheduler\": The PodGroup was preempted by the scheduler to make room for\n higher-priority PodGroups or Pods.", + "resourceClaimStatuses": "Status of resource claims.", +} + +func (PodGroupStatus) SwaggerDoc() map[string]string { + return map_PodGroupStatus +} + +var map_PodGroupTemplate = map[string]string{ + "": "PodGroupTemplate represents a template for a set of pods with a scheduling policy.", + "name": "Name is a unique identifier for the PodGroupTemplate within the Workload. It must be a DNS label. This field is immutable.", + "schedulingPolicy": "SchedulingPolicy defines the scheduling policy for this PodGroupTemplate.", + "schedulingConstraints": "SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled.", + "resourceClaims": "ResourceClaims defines which ResourceClaims may be shared among Pods in the group. Pods consume the devices allocated to a PodGroup's claim by defining a claim in its own Spec.ResourceClaims that matches the PodGroup's claim exactly. The claim must have the same name and refer to the same ResourceClaim or ResourceClaimTemplate.\n\nThis is an alpha-level field and requires that the DRAWorkloadResourceClaims feature gate is enabled.\n\nThis field is immutable.", + "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Pod, PodGroup. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "priorityClassName": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "priority": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", +} + +func (PodGroupTemplate) SwaggerDoc() map[string]string { + return map_PodGroupTemplate +} + +var map_PodGroupTemplateReference = map[string]string{ + "": "PodGroupTemplateReference references a PodGroup template defined in some object (e.g. Workload). Exactly one reference must be set.", + "workload": "Workload references the PodGroupTemplate within the Workload object that was used to create the PodGroup.", +} + +func (PodGroupTemplateReference) SwaggerDoc() map[string]string { + return map_PodGroupTemplateReference +} + +var map_TopologyConstraint = map[string]string{ + "": "TopologyConstraint defines a topology constraint for a PodGroup.", + "key": "Key specifies the key of the node label representing the topology domain. All pods within the PodGroup must be colocated within the same domain instance. Different PodGroups can land on different domain instances even if they derive from the same PodGroupTemplate. Examples: \"topology.kubernetes.io/rack\"", +} + +func (TopologyConstraint) SwaggerDoc() map[string]string { + return map_TopologyConstraint +} + +var map_TypedLocalObjectReference = map[string]string{ + "": "TypedLocalObjectReference allows to reference typed object inside the same namespace.", + "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is empty, the specified Kind must be in the core API group. For any other third-party types, setting APIGroup is required. It must be a DNS subdomain.", + "kind": "Kind is the type of resource being referenced. It must be a path segment name.", + "name": "Name is the name of resource being referenced. It must be a path segment name.", +} + +func (TypedLocalObjectReference) SwaggerDoc() map[string]string { + return map_TypedLocalObjectReference +} + +var map_Workload = map[string]string{ + "": "Workload allows for expressing scheduling constraints that should be used when managing the lifecycle of workloads from the scheduling perspective, including scheduling, preemption, eviction and other phases. Workload API enablement is toggled by the GenericWorkload feature gate.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "Spec defines the desired behavior of a Workload.", +} + +func (Workload) SwaggerDoc() map[string]string { + return map_Workload +} + +var map_WorkloadList = map[string]string{ + "": "WorkloadList contains a list of Workload resources.", + "metadata": "Standard list metadata.", + "items": "Items is the list of Workloads.", +} + +func (WorkloadList) SwaggerDoc() map[string]string { + return map_WorkloadList +} + +var map_WorkloadPodGroupTemplateReference = map[string]string{ + "": "WorkloadPodGroupTemplateReference references the PodGroupTemplate within the Workload object.", + "workloadName": "WorkloadName defines the name of the Workload object.", + "podGroupTemplateName": "PodGroupTemplateName defines the PodGroupTemplate name within the Workload object.", +} + +func (WorkloadPodGroupTemplateReference) SwaggerDoc() map[string]string { + return map_WorkloadPodGroupTemplateReference +} + +var map_WorkloadSpec = map[string]string{ + "": "WorkloadSpec defines the desired state of a Workload.", + "controllerRef": "ControllerRef is an optional reference to the controlling object, such as a Deployment or Job. This field is intended for use by tools like CLIs to provide a link back to the original workload definition. This field is immutable.", + "podGroupTemplates": "PodGroupTemplates is the list of templates that make up the Workload. The maximum number of templates is 8. This field is immutable.", +} + +func (WorkloadSpec) SwaggerDoc() map[string]string { + return map_WorkloadSpec +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.deepcopy.go b/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 0000000000..901bb0a3ad --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,484 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BasicSchedulingPolicy) DeepCopyInto(out *BasicSchedulingPolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicSchedulingPolicy. +func (in *BasicSchedulingPolicy) DeepCopy() *BasicSchedulingPolicy { + if in == nil { + return nil + } + out := new(BasicSchedulingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GangSchedulingPolicy) DeepCopyInto(out *GangSchedulingPolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GangSchedulingPolicy. +func (in *GangSchedulingPolicy) DeepCopy() *GangSchedulingPolicy { + if in == nil { + return nil + } + out := new(GangSchedulingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroup) DeepCopyInto(out *PodGroup) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroup. +func (in *PodGroup) DeepCopy() *PodGroup { + if in == nil { + return nil + } + out := new(PodGroup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodGroup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupList) DeepCopyInto(out *PodGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupList. +func (in *PodGroupList) DeepCopy() *PodGroupList { + if in == nil { + return nil + } + out := new(PodGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodGroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupResourceClaim) DeepCopyInto(out *PodGroupResourceClaim) { + *out = *in + if in.ResourceClaimName != nil { + in, out := &in.ResourceClaimName, &out.ResourceClaimName + *out = new(string) + **out = **in + } + if in.ResourceClaimTemplateName != nil { + in, out := &in.ResourceClaimTemplateName, &out.ResourceClaimTemplateName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupResourceClaim. +func (in *PodGroupResourceClaim) DeepCopy() *PodGroupResourceClaim { + if in == nil { + return nil + } + out := new(PodGroupResourceClaim) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupResourceClaimStatus) DeepCopyInto(out *PodGroupResourceClaimStatus) { + *out = *in + if in.ResourceClaimName != nil { + in, out := &in.ResourceClaimName, &out.ResourceClaimName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupResourceClaimStatus. +func (in *PodGroupResourceClaimStatus) DeepCopy() *PodGroupResourceClaimStatus { + if in == nil { + return nil + } + out := new(PodGroupResourceClaimStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupSchedulingConstraints) DeepCopyInto(out *PodGroupSchedulingConstraints) { + *out = *in + if in.Topology != nil { + in, out := &in.Topology, &out.Topology + *out = make([]TopologyConstraint, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSchedulingConstraints. +func (in *PodGroupSchedulingConstraints) DeepCopy() *PodGroupSchedulingConstraints { + if in == nil { + return nil + } + out := new(PodGroupSchedulingConstraints) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupSchedulingPolicy) DeepCopyInto(out *PodGroupSchedulingPolicy) { + *out = *in + if in.Basic != nil { + in, out := &in.Basic, &out.Basic + *out = new(BasicSchedulingPolicy) + **out = **in + } + if in.Gang != nil { + in, out := &in.Gang, &out.Gang + *out = new(GangSchedulingPolicy) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSchedulingPolicy. +func (in *PodGroupSchedulingPolicy) DeepCopy() *PodGroupSchedulingPolicy { + if in == nil { + return nil + } + out := new(PodGroupSchedulingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupSpec) DeepCopyInto(out *PodGroupSpec) { + *out = *in + if in.PodGroupTemplateRef != nil { + in, out := &in.PodGroupTemplateRef, &out.PodGroupTemplateRef + *out = new(PodGroupTemplateReference) + (*in).DeepCopyInto(*out) + } + in.SchedulingPolicy.DeepCopyInto(&out.SchedulingPolicy) + if in.SchedulingConstraints != nil { + in, out := &in.SchedulingConstraints, &out.SchedulingConstraints + *out = new(PodGroupSchedulingConstraints) + (*in).DeepCopyInto(*out) + } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]PodGroupResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DisruptionMode != nil { + in, out := &in.DisruptionMode, &out.DisruptionMode + *out = new(DisruptionMode) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSpec. +func (in *PodGroupSpec) DeepCopy() *PodGroupSpec { + if in == nil { + return nil + } + out := new(PodGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupStatus) DeepCopyInto(out *PodGroupStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ResourceClaimStatuses != nil { + in, out := &in.ResourceClaimStatuses, &out.ResourceClaimStatuses + *out = make([]PodGroupResourceClaimStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupStatus. +func (in *PodGroupStatus) DeepCopy() *PodGroupStatus { + if in == nil { + return nil + } + out := new(PodGroupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupTemplate) DeepCopyInto(out *PodGroupTemplate) { + *out = *in + in.SchedulingPolicy.DeepCopyInto(&out.SchedulingPolicy) + if in.SchedulingConstraints != nil { + in, out := &in.SchedulingConstraints, &out.SchedulingConstraints + *out = new(PodGroupSchedulingConstraints) + (*in).DeepCopyInto(*out) + } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]PodGroupResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DisruptionMode != nil { + in, out := &in.DisruptionMode, &out.DisruptionMode + *out = new(DisruptionMode) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupTemplate. +func (in *PodGroupTemplate) DeepCopy() *PodGroupTemplate { + if in == nil { + return nil + } + out := new(PodGroupTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupTemplateReference) DeepCopyInto(out *PodGroupTemplateReference) { + *out = *in + if in.Workload != nil { + in, out := &in.Workload, &out.Workload + *out = new(WorkloadPodGroupTemplateReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupTemplateReference. +func (in *PodGroupTemplateReference) DeepCopy() *PodGroupTemplateReference { + if in == nil { + return nil + } + out := new(PodGroupTemplateReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyConstraint) DeepCopyInto(out *TopologyConstraint) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyConstraint. +func (in *TopologyConstraint) DeepCopy() *TopologyConstraint { + if in == nil { + return nil + } + out := new(TopologyConstraint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TypedLocalObjectReference) DeepCopyInto(out *TypedLocalObjectReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TypedLocalObjectReference. +func (in *TypedLocalObjectReference) DeepCopy() *TypedLocalObjectReference { + if in == nil { + return nil + } + out := new(TypedLocalObjectReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Workload) DeepCopyInto(out *Workload) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workload. +func (in *Workload) DeepCopy() *Workload { + if in == nil { + return nil + } + out := new(Workload) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Workload) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadList) DeepCopyInto(out *WorkloadList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Workload, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadList. +func (in *WorkloadList) DeepCopy() *WorkloadList { + if in == nil { + return nil + } + out := new(WorkloadList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkloadList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadPodGroupTemplateReference) DeepCopyInto(out *WorkloadPodGroupTemplateReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadPodGroupTemplateReference. +func (in *WorkloadPodGroupTemplateReference) DeepCopy() *WorkloadPodGroupTemplateReference { + if in == nil { + return nil + } + out := new(WorkloadPodGroupTemplateReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadSpec) DeepCopyInto(out *WorkloadSpec) { + *out = *in + if in.ControllerRef != nil { + in, out := &in.ControllerRef, &out.ControllerRef + *out = new(TypedLocalObjectReference) + **out = **in + } + if in.PodGroupTemplates != nil { + in, out := &in.PodGroupTemplates, &out.PodGroupTemplates + *out = make([]PodGroupTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadSpec. +func (in *WorkloadSpec) DeepCopy() *WorkloadSpec { + if in == nil { + return nil + } + out := new(WorkloadSpec) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.model_name.go b/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.model_name.go new file mode 100644 index 0000000000..1b7effea96 --- /dev/null +++ b/vendor/k8s.io/api/scheduling/v1alpha2/zz_generated.model_name.go @@ -0,0 +1,112 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by openapi-gen. DO NOT EDIT. + +package v1alpha2 + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in BasicSchedulingPolicy) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.BasicSchedulingPolicy" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in GangSchedulingPolicy) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.GangSchedulingPolicy" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroup) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroup" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupList) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupResourceClaim) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaim" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupResourceClaimStatus) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaimStatus" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupSchedulingConstraints) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingConstraints" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupSchedulingPolicy) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingPolicy" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupSpec) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupSpec" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupStatus) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupStatus" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupTemplate) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupTemplate" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in PodGroupTemplateReference) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.PodGroupTemplateReference" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TopologyConstraint) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.TopologyConstraint" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TypedLocalObjectReference) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.TypedLocalObjectReference" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in Workload) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.Workload" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in WorkloadList) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.WorkloadList" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in WorkloadPodGroupTemplateReference) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.WorkloadPodGroupTemplateReference" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in WorkloadSpec) OpenAPIModelName() string { + return "io.k8s.api.scheduling.v1alpha2.WorkloadSpec" +} diff --git a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto index 7f77b01753..0e701be549 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto @@ -40,6 +40,7 @@ message PriorityClass { // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. + // +optional optional int32 value = 2; // globalDefault specifies whether this PriorityClass should be considered as diff --git a/vendor/k8s.io/api/scheduling/v1beta1/types.go b/vendor/k8s.io/api/scheduling/v1beta1/types.go index 6f88592cf2..8a7a2058f0 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/types.go +++ b/vendor/k8s.io/api/scheduling/v1beta1/types.go @@ -41,6 +41,7 @@ type PriorityClass struct { // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. + // +optional Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` // globalDefault specifies whether this PriorityClass should be considered as diff --git a/vendor/k8s.io/api/storage/v1/generated.pb.go b/vendor/k8s.io/api/storage/v1/generated.pb.go index 52003c3132..5fc7d55a5b 100644 --- a/vendor/k8s.io/api/storage/v1/generated.pb.go +++ b/vendor/k8s.io/api/storage/v1/generated.pb.go @@ -187,6 +187,16 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreventPodSchedulingIfMissing != nil { + i-- + if *m.PreventPodSchedulingIfMissing { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } if m.ServiceAccountTokenInSecrets != nil { i-- if *m.ServiceAccountTokenInSecrets { @@ -1304,6 +1314,9 @@ func (m *CSIDriverSpec) Size() (n int) { if m.ServiceAccountTokenInSecrets != nil { n += 2 } + if m.PreventPodSchedulingIfMissing != nil { + n += 2 + } return n } @@ -1701,6 +1714,7 @@ func (this *CSIDriverSpec) String() string { `SELinuxMount:` + valueToStringGenerated(this.SELinuxMount) + `,`, `NodeAllocatableUpdatePeriodSeconds:` + valueToStringGenerated(this.NodeAllocatableUpdatePeriodSeconds) + `,`, `ServiceAccountTokenInSecrets:` + valueToStringGenerated(this.ServiceAccountTokenInSecrets) + `,`, + `PreventPodSchedulingIfMissing:` + valueToStringGenerated(this.PreventPodSchedulingIfMissing) + `,`, `}`, }, "") return s @@ -2498,6 +2512,27 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.ServiceAccountTokenInSecrets = &b + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreventPodSchedulingIfMissing", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.PreventPodSchedulingIfMissing = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/storage/v1/generated.proto b/vendor/k8s.io/api/storage/v1/generated.proto index d77bea9cc0..d6bc969bb3 100644 --- a/vendor/k8s.io/api/storage/v1/generated.proto +++ b/vendor/k8s.io/api/storage/v1/generated.proto @@ -218,7 +218,7 @@ message CSIDriverSpec { // occur (neither periodic nor upon detecting capacity-related failures), and the // allocatable.count remains static. The minimum allowed value for this field is 10 seconds. // - // This is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled. + // This feature requires the MutableCSINodeAllocatableCount feature gate to be enabled. // // This field is mutable. // @@ -249,6 +249,27 @@ message CSIDriverSpec { // +featureGate=CSIServiceAccountTokenSecrets // +optional optional bool serviceAccountTokenInSecrets = 10; + + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + // +featureGate=VolumeLimitScaling + // +optional + optional bool preventPodSchedulingIfMissing = 11; } // CSINode holds information about all CSI drivers installed on a node. @@ -434,17 +455,22 @@ message StorageClass { // provisioner indicates the type of the provisioner. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional string provisioner = 2; // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional map parameters = 3; // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. // Defaults to Delete. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional optional string reclaimPolicy = 4; // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. @@ -462,6 +488,8 @@ message StorageClass { // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional optional string volumeBindingMode = 7; // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. @@ -509,6 +537,8 @@ message VolumeAttachment { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required optional VolumeAttachmentSpec spec = 2; // status represents status of the VolumeAttachment request. @@ -552,6 +582,10 @@ message VolumeAttachmentSource { message VolumeAttachmentSpec { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string attacher = 1; // source represents the volume that should be attached. @@ -643,7 +677,7 @@ message VolumeError { // errorCode is a numeric gRPC code representing the error encountered during Attach or Detach operations. // - // This is an optional, beta field that requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. + // This field requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. // // +featureGate=MutableCSINodeAllocatableCount // +optional diff --git a/vendor/k8s.io/api/storage/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/storage/v1/generated.protomessage.pb.go deleted file mode 100644 index 3702060422..0000000000 --- a/vendor/k8s.io/api/storage/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*CSIDriver) ProtoMessage() {} - -func (*CSIDriverList) ProtoMessage() {} - -func (*CSIDriverSpec) ProtoMessage() {} - -func (*CSINode) ProtoMessage() {} - -func (*CSINodeDriver) ProtoMessage() {} - -func (*CSINodeList) ProtoMessage() {} - -func (*CSINodeSpec) ProtoMessage() {} - -func (*CSIStorageCapacity) ProtoMessage() {} - -func (*CSIStorageCapacityList) ProtoMessage() {} - -func (*StorageClass) ProtoMessage() {} - -func (*StorageClassList) ProtoMessage() {} - -func (*TokenRequest) ProtoMessage() {} - -func (*VolumeAttachment) ProtoMessage() {} - -func (*VolumeAttachmentList) ProtoMessage() {} - -func (*VolumeAttachmentSource) ProtoMessage() {} - -func (*VolumeAttachmentSpec) ProtoMessage() {} - -func (*VolumeAttachmentStatus) ProtoMessage() {} - -func (*VolumeAttributesClass) ProtoMessage() {} - -func (*VolumeAttributesClassList) ProtoMessage() {} - -func (*VolumeError) ProtoMessage() {} - -func (*VolumeNodeResources) ProtoMessage() {} diff --git a/vendor/k8s.io/api/storage/v1/types.go b/vendor/k8s.io/api/storage/v1/types.go index b198cb7138..c65ebed4ec 100644 --- a/vendor/k8s.io/api/storage/v1/types.go +++ b/vendor/k8s.io/api/storage/v1/types.go @@ -42,17 +42,22 @@ type StorageClass struct { // provisioner indicates the type of the provisioner. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. // Defaults to Delete. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. @@ -70,6 +75,8 @@ type StorageClass struct { // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. @@ -117,6 +124,7 @@ const ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.13 +// +k8s:supportsSubresource="/status" // VolumeAttachment captures the intent to attach or detach the specified volume // to/from the specified node. @@ -132,6 +140,8 @@ type VolumeAttachment struct { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` // status represents status of the VolumeAttachment request. @@ -161,6 +171,10 @@ type VolumeAttachmentList struct { type VolumeAttachmentSpec struct { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` // source represents the volume that should be attached. @@ -231,7 +245,7 @@ type VolumeError struct { // errorCode is a numeric gRPC code representing the error encountered during Attach or Detach operations. // - // This is an optional, beta field that requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. + // This field requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. // // +featureGate=MutableCSINodeAllocatableCount // +optional @@ -438,7 +452,7 @@ type CSIDriverSpec struct { // occur (neither periodic nor upon detecting capacity-related failures), and the // allocatable.count remains static. The minimum allowed value for this field is 10 seconds. // - // This is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled. + // This feature requires the MutableCSINodeAllocatableCount feature gate to be enabled. // // This field is mutable. // @@ -469,6 +483,27 @@ type CSIDriverSpec struct { // +featureGate=CSIServiceAccountTokenSecrets // +optional ServiceAccountTokenInSecrets *bool `json:"serviceAccountTokenInSecrets,omitempty" protobuf:"varint,10,opt,name=serviceAccountTokenInSecrets"` + + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + // +featureGate=VolumeLimitScaling + // +optional + PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty" protobuf:"varint,11,opt,name=preventPodSchedulingIfMissing"` } // FSGroupPolicy specifies if a CSI Driver supports modifying diff --git a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go index 7f06c2744f..47a7e92492 100644 --- a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go @@ -57,8 +57,9 @@ var map_CSIDriverSpec = map[string]string{ "tokenRequests": "tokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", "requiresRepublish": "requiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", - "nodeAllocatableUpdatePeriodSeconds": "nodeAllocatableUpdatePeriodSeconds specifies the interval between periodic updates of the CSINode allocatable capacity for this driver. When set, both periodic updates and updates triggered by capacity-related failures are enabled. If not set, no updates occur (neither periodic nor upon detecting capacity-related failures), and the allocatable.count remains static. The minimum allowed value for this field is 10 seconds.\n\nThis is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled.\n\nThis field is mutable.", + "nodeAllocatableUpdatePeriodSeconds": "nodeAllocatableUpdatePeriodSeconds specifies the interval between periodic updates of the CSINode allocatable capacity for this driver. When set, both periodic updates and updates triggered by capacity-related failures are enabled. If not set, no updates occur (neither periodic nor upon detecting capacity-related failures), and the allocatable.count remains static. The minimum allowed value for this field is 10 seconds.\n\nThis feature requires the MutableCSINodeAllocatableCount feature gate to be enabled.\n\nThis field is mutable.", "serviceAccountTokenInSecrets": "serviceAccountTokenInSecrets is an opt-in for CSI drivers to indicate that service account tokens should be passed via the Secrets field in NodePublishVolumeRequest instead of the VolumeContext field. The CSI specification provides a dedicated Secrets field for sensitive information like tokens, which is the appropriate mechanism for handling credentials. This addresses security concerns where sensitive tokens were being logged as part of volume context.\n\nWhen \"true\", kubelet will pass the tokens only in the Secrets field with the key \"csi.storage.k8s.io/serviceAccount.tokens\". The CSI driver must be updated to read tokens from the Secrets field instead of VolumeContext.\n\nWhen \"false\" or not set, kubelet will pass the tokens in VolumeContext with the key \"csi.storage.k8s.io/serviceAccount.tokens\" (existing behavior). This maintains backward compatibility with existing CSI drivers.\n\nThis field can only be set when TokenRequests is configured. The API server will reject CSIDriver specs that set this field without TokenRequests.\n\nDefault behavior if unset is to pass tokens in the VolumeContext field.", + "preventPodSchedulingIfMissing": "PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { @@ -243,7 +244,7 @@ var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", "time": "time represents the time the error was encountered.", "message": "message represents the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", - "errorCode": "errorCode is a numeric gRPC code representing the error encountered during Attach or Detach operations.\n\nThis is an optional, beta field that requires the MutableCSINodeAllocatableCount feature gate being enabled to be set.", + "errorCode": "errorCode is a numeric gRPC code representing the error encountered during Attach or Detach operations.\n\nThis field requires the MutableCSINodeAllocatableCount feature gate being enabled to be set.", } func (VolumeError) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go index b9e0a7d912..aa3ffd0686 100644 --- a/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go @@ -142,6 +142,11 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) { *out = new(bool) **out = **in } + if in.PreventPodSchedulingIfMissing != nil { + in, out := &in.PreventPodSchedulingIfMissing, &out.PreventPodSchedulingIfMissing + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/api/storage/v1alpha1/generated.proto b/vendor/k8s.io/api/storage/v1alpha1/generated.proto index c1abc3fb36..837d011640 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/storage/v1alpha1/generated.proto @@ -134,6 +134,8 @@ message VolumeAttachment { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required optional VolumeAttachmentSpec spec = 2; // status represents status of the VolumeAttachment request. @@ -177,6 +179,10 @@ message VolumeAttachmentSource { message VolumeAttachmentSpec { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string attacher = 1; // source represents the volume that should be attached. diff --git a/vendor/k8s.io/api/storage/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/storage/v1alpha1/generated.protomessage.pb.go deleted file mode 100644 index d58dcac3c2..0000000000 --- a/vendor/k8s.io/api/storage/v1alpha1/generated.protomessage.pb.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 - -func (*CSIStorageCapacity) ProtoMessage() {} - -func (*CSIStorageCapacityList) ProtoMessage() {} - -func (*VolumeAttachment) ProtoMessage() {} - -func (*VolumeAttachmentList) ProtoMessage() {} - -func (*VolumeAttachmentSource) ProtoMessage() {} - -func (*VolumeAttachmentSpec) ProtoMessage() {} - -func (*VolumeAttachmentStatus) ProtoMessage() {} - -func (*VolumeAttributesClass) ProtoMessage() {} - -func (*VolumeAttributesClassList) ProtoMessage() {} - -func (*VolumeError) ProtoMessage() {} diff --git a/vendor/k8s.io/api/storage/v1alpha1/types.go b/vendor/k8s.io/api/storage/v1alpha1/types.go index 2785b01d4a..286ac42aaa 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/types.go +++ b/vendor/k8s.io/api/storage/v1alpha1/types.go @@ -28,6 +28,7 @@ import ( // +k8s:prerelease-lifecycle-gen:introduced=1.9 // +k8s:prerelease-lifecycle-gen:deprecated=1.21 // +k8s:prerelease-lifecycle-gen:replacement=storage.k8s.io,v1,VolumeAttachment +// +k8s:supportsSubresource="/status" // VolumeAttachment captures the intent to attach or detach the specified volume // to/from the specified node. @@ -43,6 +44,8 @@ type VolumeAttachment struct { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` // status represents status of the VolumeAttachment request. @@ -74,6 +77,10 @@ type VolumeAttachmentList struct { type VolumeAttachmentSpec struct { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` // source represents the volume that should be attached. diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.pb.go b/vendor/k8s.io/api/storage/v1beta1/generated.pb.go index ed03dd5059..7fd08783aa 100644 --- a/vendor/k8s.io/api/storage/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/storage/v1beta1/generated.pb.go @@ -187,6 +187,16 @@ func (m *CSIDriverSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PreventPodSchedulingIfMissing != nil { + i-- + if *m.PreventPodSchedulingIfMissing { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } if m.ServiceAccountTokenInSecrets != nil { i-- if *m.ServiceAccountTokenInSecrets { @@ -1304,6 +1314,9 @@ func (m *CSIDriverSpec) Size() (n int) { if m.ServiceAccountTokenInSecrets != nil { n += 2 } + if m.PreventPodSchedulingIfMissing != nil { + n += 2 + } return n } @@ -1701,6 +1714,7 @@ func (this *CSIDriverSpec) String() string { `SELinuxMount:` + valueToStringGenerated(this.SELinuxMount) + `,`, `NodeAllocatableUpdatePeriodSeconds:` + valueToStringGenerated(this.NodeAllocatableUpdatePeriodSeconds) + `,`, `ServiceAccountTokenInSecrets:` + valueToStringGenerated(this.ServiceAccountTokenInSecrets) + `,`, + `PreventPodSchedulingIfMissing:` + valueToStringGenerated(this.PreventPodSchedulingIfMissing) + `,`, `}`, }, "") return s @@ -2498,6 +2512,27 @@ func (m *CSIDriverSpec) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.ServiceAccountTokenInSecrets = &b + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreventPodSchedulingIfMissing", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.PreventPodSchedulingIfMissing = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.proto b/vendor/k8s.io/api/storage/v1beta1/generated.proto index 33b904ee6d..3cae755fb4 100644 --- a/vendor/k8s.io/api/storage/v1beta1/generated.proto +++ b/vendor/k8s.io/api/storage/v1beta1/generated.proto @@ -251,6 +251,27 @@ message CSIDriverSpec { // +featureGate=CSIServiceAccountTokenSecrets // +optional optional bool serviceAccountTokenInSecrets = 10; + + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + // +featureGate=VolumeLimitScaling + // +optional + optional bool preventPodSchedulingIfMissing = 11; } // DEPRECATED - This group version of CSINode is deprecated by storage/v1/CSINode. @@ -436,17 +457,22 @@ message StorageClass { // provisioner indicates the type of the provisioner. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable optional string provisioner = 2; // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional map parameters = 3; // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. // Defaults to Delete. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional optional string reclaimPolicy = 4; // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. @@ -464,6 +490,8 @@ message StorageClass { // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional optional string volumeBindingMode = 7; // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. @@ -511,6 +539,8 @@ message VolumeAttachment { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required optional VolumeAttachmentSpec spec = 2; // status represents status of the VolumeAttachment request. @@ -554,6 +584,10 @@ message VolumeAttachmentSource { message VolumeAttachmentSpec { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 optional string attacher = 1; // source represents the volume that should be attached. diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/storage/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index a288b7fb6a..0000000000 --- a/vendor/k8s.io/api/storage/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*CSIDriver) ProtoMessage() {} - -func (*CSIDriverList) ProtoMessage() {} - -func (*CSIDriverSpec) ProtoMessage() {} - -func (*CSINode) ProtoMessage() {} - -func (*CSINodeDriver) ProtoMessage() {} - -func (*CSINodeList) ProtoMessage() {} - -func (*CSINodeSpec) ProtoMessage() {} - -func (*CSIStorageCapacity) ProtoMessage() {} - -func (*CSIStorageCapacityList) ProtoMessage() {} - -func (*StorageClass) ProtoMessage() {} - -func (*StorageClassList) ProtoMessage() {} - -func (*TokenRequest) ProtoMessage() {} - -func (*VolumeAttachment) ProtoMessage() {} - -func (*VolumeAttachmentList) ProtoMessage() {} - -func (*VolumeAttachmentSource) ProtoMessage() {} - -func (*VolumeAttachmentSpec) ProtoMessage() {} - -func (*VolumeAttachmentStatus) ProtoMessage() {} - -func (*VolumeAttributesClass) ProtoMessage() {} - -func (*VolumeAttributesClassList) ProtoMessage() {} - -func (*VolumeError) ProtoMessage() {} - -func (*VolumeNodeResources) ProtoMessage() {} diff --git a/vendor/k8s.io/api/storage/v1beta1/types.go b/vendor/k8s.io/api/storage/v1beta1/types.go index b5dde72ad9..0c33e218e7 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types.go +++ b/vendor/k8s.io/api/storage/v1beta1/types.go @@ -44,17 +44,22 @@ type StorageClass struct { // provisioner indicates the type of the provisioner. // +required - // +k8s:required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:immutable Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. // Defaults to Delete. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. @@ -72,6 +77,8 @@ type StorageClass struct { // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +k8s:alpha(since: "1.36")=+k8s:optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. @@ -122,6 +129,7 @@ const ( // +k8s:prerelease-lifecycle-gen:introduced=1.10 // +k8s:prerelease-lifecycle-gen:deprecated=1.19 // +k8s:prerelease-lifecycle-gen:replacement=storage.k8s.io,v1,VolumeAttachment +// +k8s:supportsSubresource="/status" // VolumeAttachment captures the intent to attach or detach the specified volume // to/from the specified node. @@ -137,6 +145,8 @@ type VolumeAttachment struct { // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. + // +k8s:alpha(since: "1.36")=+k8s:immutable + // +required Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` // status represents status of the VolumeAttachment request. @@ -168,6 +178,10 @@ type VolumeAttachmentList struct { type VolumeAttachmentSpec struct { // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). + // +required + // +k8s:alpha(since: "1.36")=+k8s:required + // +k8s:alpha(since: "1.36")=+k8s:format="k8s-long-name-caseless" + // +k8s:alpha(since: "1.36")=+k8s:maxLength=63 Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` // source represents the volume that should be attached. @@ -482,6 +496,27 @@ type CSIDriverSpec struct { // +featureGate=CSIServiceAccountTokenSecrets // +optional ServiceAccountTokenInSecrets *bool `json:"serviceAccountTokenInSecrets,omitempty" protobuf:"varint,10,opt,name=serviceAccountTokenInSecrets"` + + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + // +featureGate=VolumeLimitScaling + // +optional + PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty" protobuf:"varint,11,opt,name=preventPodSchedulingIfMissing"` } // FSGroupPolicy specifies if a CSI Driver supports modifying diff --git a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go index 78da9266e0..80b68839b4 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go @@ -59,6 +59,7 @@ var map_CSIDriverSpec = map[string]string{ "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", "nodeAllocatableUpdatePeriodSeconds": "nodeAllocatableUpdatePeriodSeconds specifies the interval between periodic updates of the CSINode allocatable capacity for this driver. When set, both periodic updates and updates triggered by capacity-related failures are enabled. If not set, no updates occur (neither periodic nor upon detecting capacity-related failures), and the allocatable.count remains static. The minimum allowed value for this field is 10 seconds.\n\nThis is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled.\n\nThis field is mutable.", "serviceAccountTokenInSecrets": "serviceAccountTokenInSecrets is an opt-in for CSI drivers to indicate that service account tokens should be passed via the Secrets field in NodePublishVolumeRequest instead of the VolumeContext field. The CSI specification provides a dedicated Secrets field for sensitive information like tokens, which is the appropriate mechanism for handling credentials. This addresses security concerns where sensitive tokens were being logged as part of volume context.\n\nWhen \"true\", kubelet will pass the tokens only in the Secrets field with the key \"csi.storage.k8s.io/serviceAccount.tokens\". The CSI driver must be updated to read tokens from the Secrets field instead of VolumeContext.\n\nWhen \"false\" or not set, kubelet will pass the tokens in VolumeContext with the key \"csi.storage.k8s.io/serviceAccount.tokens\" (existing behavior). This maintains backward compatibility with existing CSI drivers.\n\nThis field can only be set when TokenRequests is configured. The API server will reject CSIDriver specs that set this field without TokenRequests.\n\nDefault behavior if unset is to pass tokens in the VolumeContext field.", + "preventPodSchedulingIfMissing": "PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod scheduling if the CSI driver on the node is missing.\n\nEnabling this option will prevent the scheduler (or any other component which embeds default scheduler such as cluster-autoscaler) from scheduling pods to nodes where CSI driver is not installed.\n\nFor components(such as cluster-autoscaler) that embed the scheduler and run pod placement simulations using scheduler plugins, they MUST be aware of CSI driver registration information via CSINode object. They must create simulated CSINode objects in addition to Node objects during scheduling simulation, otherwise if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any newly created node may be rejected by the scheduler because of missing CSI driver information from the node.\n\nThis is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. Default is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go index 94cc629da6..ca28e0340c 100644 --- a/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go @@ -142,6 +142,11 @@ func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) { *out = new(bool) **out = **in } + if in.PreventPodSchedulingIfMissing != nil { + in, out := &in.PreventPodSchedulingIfMissing, &out.PreventPodSchedulingIfMissing + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/api/storagemigration/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/storagemigration/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 39cafd8a9e..0000000000 --- a/vendor/k8s.io/api/storagemigration/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*StorageVersionMigration) ProtoMessage() {} - -func (*StorageVersionMigrationList) ProtoMessage() {} - -func (*StorageVersionMigrationSpec) ProtoMessage() {} - -func (*StorageVersionMigrationStatus) ProtoMessage() {} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.protomessage.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.protomessage.pb.go deleted file mode 100644 index 7dc6ed2bc5..0000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*ConversionRequest) ProtoMessage() {} - -func (*ConversionResponse) ProtoMessage() {} - -func (*ConversionReview) ProtoMessage() {} - -func (*CustomResourceColumnDefinition) ProtoMessage() {} - -func (*CustomResourceConversion) ProtoMessage() {} - -func (*CustomResourceDefinition) ProtoMessage() {} - -func (*CustomResourceDefinitionCondition) ProtoMessage() {} - -func (*CustomResourceDefinitionList) ProtoMessage() {} - -func (*CustomResourceDefinitionNames) ProtoMessage() {} - -func (*CustomResourceDefinitionSpec) ProtoMessage() {} - -func (*CustomResourceDefinitionStatus) ProtoMessage() {} - -func (*CustomResourceDefinitionVersion) ProtoMessage() {} - -func (*CustomResourceSubresourceScale) ProtoMessage() {} - -func (*CustomResourceSubresourceStatus) ProtoMessage() {} - -func (*CustomResourceSubresources) ProtoMessage() {} - -func (*CustomResourceValidation) ProtoMessage() {} - -func (*ExternalDocumentation) ProtoMessage() {} - -func (*JSON) ProtoMessage() {} - -func (*JSONSchemaProps) ProtoMessage() {} - -func (*JSONSchemaPropsOrArray) ProtoMessage() {} - -func (*JSONSchemaPropsOrBool) ProtoMessage() {} - -func (*JSONSchemaPropsOrStringArray) ProtoMessage() {} - -func (*SelectableField) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} - -func (*ValidationRule) ProtoMessage() {} - -func (*WebhookClientConfig) ProtoMessage() {} - -func (*WebhookConversion) ProtoMessage() {} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go index 764726b6e9..b3a8ce7ef4 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go @@ -332,6 +332,9 @@ const ( // be true if .metadata.annotations["api-approved.kubernetes.io"] is set to a URL, otherwise it will be false. // See https://github.com/kubernetes/enhancements/pull/1111 for more details. KubernetesAPIApprovalPolicyConformant CustomResourceDefinitionConditionType = "KubernetesAPIApprovalPolicyConformant" + // StorageMigrating indicates that the underlying storage version of the CRD + // is undergoing migration. + StorageMigrating CustomResourceDefinitionConditionType = "StorageMigrating" ) // CustomResourceDefinitionCondition contains details for the current condition of this pod. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 997d32f31e..0000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*ConversionRequest) ProtoMessage() {} - -func (*ConversionResponse) ProtoMessage() {} - -func (*ConversionReview) ProtoMessage() {} - -func (*CustomResourceColumnDefinition) ProtoMessage() {} - -func (*CustomResourceConversion) ProtoMessage() {} - -func (*CustomResourceDefinition) ProtoMessage() {} - -func (*CustomResourceDefinitionCondition) ProtoMessage() {} - -func (*CustomResourceDefinitionList) ProtoMessage() {} - -func (*CustomResourceDefinitionNames) ProtoMessage() {} - -func (*CustomResourceDefinitionSpec) ProtoMessage() {} - -func (*CustomResourceDefinitionStatus) ProtoMessage() {} - -func (*CustomResourceDefinitionVersion) ProtoMessage() {} - -func (*CustomResourceSubresourceScale) ProtoMessage() {} - -func (*CustomResourceSubresourceStatus) ProtoMessage() {} - -func (*CustomResourceSubresources) ProtoMessage() {} - -func (*CustomResourceValidation) ProtoMessage() {} - -func (*ExternalDocumentation) ProtoMessage() {} - -func (*JSON) ProtoMessage() {} - -func (*JSONSchemaProps) ProtoMessage() {} - -func (*JSONSchemaPropsOrArray) ProtoMessage() {} - -func (*JSONSchemaPropsOrBool) ProtoMessage() {} - -func (*JSONSchemaPropsOrStringArray) ProtoMessage() {} - -func (*SelectableField) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} - -func (*ValidationRule) ProtoMessage() {} - -func (*WebhookClientConfig) ProtoMessage() {} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1/customresourcedefinition.go index 7f9c9137e9..36b9c3b71a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1/customresourcedefinition.go @@ -28,6 +28,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -48,48 +49,61 @@ type customResourceDefinitionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCustomResourceDefinitionInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, indexers, nil) + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCustomResourceDefinitionInformer constructs a new informer for CustomResourceDefinition type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCustomResourceDefinitionInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCustomResourceDefinitionInformerWithOptions constructs a new informer for CustomResourceDefinition type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCustomResourceDefinitionInformerWithOptions(client clientset.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1().CustomResourceDefinitions().List(context.Background(), options) + return client.ApiextensionsV1().CustomResourceDefinitions().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1().CustomResourceDefinitions().Watch(context.Background(), options) + return client.ApiextensionsV1().CustomResourceDefinitions().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1().CustomResourceDefinitions().List(ctx, options) + return client.ApiextensionsV1().CustomResourceDefinitions().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1().CustomResourceDefinitions().Watch(ctx, options) + return client.ApiextensionsV1().CustomResourceDefinitions().Watch(ctx, opts) }, }, client), &apisapiextensionsv1.CustomResourceDefinition{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *customResourceDefinitionInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *customResourceDefinitionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go index 140998152c..04a5ee217f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go @@ -28,6 +28,7 @@ import ( apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" ) @@ -48,48 +49,61 @@ type customResourceDefinitionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCustomResourceDefinitionInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, indexers, nil) + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCustomResourceDefinitionInformer constructs a new informer for CustomResourceDefinition type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCustomResourceDefinitionInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCustomResourceDefinitionInformerWithOptions constructs a new informer for CustomResourceDefinition type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCustomResourceDefinitionInformerWithOptions(client clientset.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1beta1", Resource: "customresourcedefinitions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1beta1().CustomResourceDefinitions().List(context.Background(), options) + return client.ApiextensionsV1beta1().CustomResourceDefinitions().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1beta1().CustomResourceDefinitions().Watch(context.Background(), options) + return client.ApiextensionsV1beta1().CustomResourceDefinitions().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1beta1().CustomResourceDefinitions().List(ctx, options) + return client.ApiextensionsV1beta1().CustomResourceDefinitions().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ApiextensionsV1beta1().CustomResourceDefinitions().Watch(ctx, options) + return client.ApiextensionsV1beta1().CustomResourceDefinitions().Watch(ctx, opts) }, }, client), &apisapiextensionsv1beta1.CustomResourceDefinition{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *customResourceDefinitionInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCustomResourceDefinitionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCustomResourceDefinitionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *customResourceDefinitionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go index e8d6e5b264..c0a30f6e99 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go @@ -19,6 +19,7 @@ limitations under the License. package externalversions import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -29,6 +30,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" cache "k8s.io/client-go/tools/cache" ) @@ -43,6 +45,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -89,6 +92,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client clientset.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -123,6 +141,10 @@ func NewSharedInformerFactoryWithOptions(client clientset.Interface, defaultResy } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -132,15 +154,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -153,9 +169,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -169,10 +191,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -194,7 +237,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -211,27 +256,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -246,8 +310,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go index da6eadaa7f..4c60257a41 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -34,7 +34,26 @@ type NewInformerFunc func(clientset.Interface, time.Duration) cache.SharedIndexI type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go index e59d6213f6..13ede31c1b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go @@ -65,6 +65,7 @@ func init() { var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{ CRDObservedGenerationTracking: { {Version: version.MustParse("1.35"), PreRelease: featuregate.Beta, Default: false}, + {Version: version.MustParse("1.36"), PreRelease: featuregate.Beta, Default: true}, }, CRDValidationRatcheting: { {Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha}, diff --git a/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go b/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go index f02fa8e434..cd78c38416 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go +++ b/vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go @@ -40,6 +40,9 @@ var Semantic = conversion.EqualitiesOrDie( func(a, b metav1.Time) bool { return a.UTC() == b.UTC() }, + func(a, b metav1.FieldsV1) bool { + return a.Equal(b) + }, func(a, b labels.Selector) bool { return a.String() == b.String() }, diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/content/errors.go b/vendor/k8s.io/apimachinery/pkg/api/validate/content/errors.go index a4a1b5574c..13eeced1a0 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/content/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/content/errors.go @@ -29,6 +29,12 @@ func MinError[T constraints.Integer](min T) string { return fmt.Sprintf("must be greater than or equal to %d", min) } +// MaxError returns a string explanation of a "must be less than or equal" +// validation failure. +func MaxError[T constraints.Integer](max T) string { + return fmt.Sprintf("must be less than or equal to %d", max) +} + // MaxLenError returns a string explanation of a "string too long" validation // failure. func MaxLenError(length int) string { diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/content/path.go b/vendor/k8s.io/apimachinery/pkg/api/validate/content/path.go new file mode 100644 index 0000000000..c41b1d4731 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/content/path.go @@ -0,0 +1,63 @@ +/* +Copyright 2015 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 content + +import ( + "fmt" + "strings" +) + +// Strings that cannot be used as names specified as path segments (like the +// REST API or etcd store). +var pathSegmentNameMayNotBe = []string{".", ".."} + +// Substrings that cannot be used in names specified as path segments (like the +// REST API or etcd store). +var pathSegmentNameMayNotContain = []string{"/", "%"} + +// IsPathSegmentName validates the name can be safely encoded as a path +// segment. +// +// Note that, for historical reason, this function does not check for +// empty strings or impose a limit on the length of the name. +func IsPathSegmentName(name string) []string { + for _, illegalName := range pathSegmentNameMayNotBe { + if name == illegalName { + return []string{fmt.Sprintf(`may not be '%s'`, illegalName)} + } + } + + return IsPathSegmentPrefix(name) +} + +// IsPathSegmentPrefix validates the name can be used as a prefix for a +// name which will be encoded as a path segment It does not check for exact +// matches with disallowed names, since an arbitrary suffix might make the name +// valid. +// +// Note that, for historical reason, this function does not check for +// empty strings or impose a limit on the length of the name. +func IsPathSegmentPrefix(name string) []string { + var errors []string + for _, illegalContent := range pathSegmentNameMayNotContain { + if strings.Contains(name, illegalContent) { + errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent)) + } + } + + return errors +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go b/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go new file mode 100644 index 0000000000..787ae6b0b7 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go @@ -0,0 +1,71 @@ +/* +Copyright 2025 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 validate + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// DiscriminatedRule defines a validation to apply for a specific discriminator value. +type DiscriminatedRule[Tfield any, Tdisc comparable] struct { + Value Tdisc + Validation ValidateFunc[Tfield] +} + +// Discriminated validates a member field based on a discriminator value. +// It iterates through the rules and applies the first one that matches the discriminator. +// If no rule matches, it applies the defaultValidation if provided. +// +// It performs ratcheting: if the operation is an Update, and neither the discriminator +// nor the value (checked via equiv) have changed, validation is skipped. +func Discriminated[Tfield any, Tdisc comparable, Tstruct any](ctx context.Context, op operation.Operation, structPath *field.Path, + obj, oldObj *Tstruct, fieldName string, getMemberValue func(*Tstruct) Tfield, getDiscriminator func(*Tstruct) Tdisc, + equiv MatchFunc[Tfield], defaultValidation ValidateFunc[Tfield], rules []DiscriminatedRule[Tfield, Tdisc], +) field.ErrorList { + value := getMemberValue(obj) + discriminator := getDiscriminator(obj) + var oldValue Tfield + var oldDiscriminator Tdisc + + if oldObj != nil { + oldValue = getMemberValue(oldObj) + oldDiscriminator = getDiscriminator(oldObj) + } + + if op.Type == operation.Update && oldObj != nil && discriminator == oldDiscriminator && equiv(value, oldValue) { + return nil + } + + fldPath := structPath.Child(fieldName) + for _, rule := range rules { + if rule.Value == discriminator { + if rule.Validation == nil { + return nil + } + return rule.Validation(ctx, op, fldPath, value, oldValue) + } + } + + if defaultValidation != nil { + return defaultValidation(ctx, op, fldPath, value, oldValue) + } + + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go b/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go index b6db5e08cb..dcc7f518d8 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go @@ -18,6 +18,8 @@ package validate import ( "context" + "math" + "unicode/utf8" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/api/validate/constraints" @@ -31,9 +33,40 @@ func MaxLength[T ~string](_ context.Context, _ operation.Operation, fldPath *fie if value == nil { return nil } + + // if the length of the value in bytes is less + // than the maximum size then we can confidently + // say that this value is within the bounds + // enforced by the maximum value regardless + // of the actual makeup of characters in the value + byteLength := len(*value) + if byteLength <= max { + return nil + } + + // because runes are up to 4 byte characters, if we assume all characters + // in the input are runes, the minimum number of characters that + // are specified is len(value)/4. If the minimum multi-byte + // character count is greater than our enforced maximum, we + // can confidently say that the value is invalid without having + // to actually perform the more expensive rune counting step + minimum := int(math.Ceil(float64(byteLength) / 4.0)) + if minimum > max || utf8.RuneCountInString(string(*value)) > max { + return field.ErrorList{field.TooLongCharacters(fldPath, *value, max).WithOrigin("maxLength")} + } + return nil +} + +// MaxBytes verifies that the specified value is not longer than max bytes. +func MaxBytes[T ~string](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, max int) field.ErrorList { + if value == nil { + return nil + } + if len(*value) > max { - return field.ErrorList{field.TooLong(fldPath, *value, max).WithOrigin("maxLength")} + return field.ErrorList{field.TooLong(fldPath, *value, max).WithOrigin("maxBytes")} } + return nil } @@ -45,6 +78,14 @@ func MaxItems[T any](_ context.Context, _ operation.Operation, fldPath *field.Pa return nil } +// MinItems verifies that the specified slice is not shorter than min items. +func MinItems[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []T, min int) field.ErrorList { + if len(value) < min { + return field.ErrorList{field.TooFew(fldPath, len(value), min).WithOrigin("minItems")} + } + return nil +} + // Minimum verifies that the specified value is greater than or equal to min. func Minimum[T constraints.Integer](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, min T) field.ErrorList { if value == nil { @@ -55,3 +96,45 @@ func Minimum[T constraints.Integer](_ context.Context, _ operation.Operation, fl } return nil } + +// Maximum verifies that the specified value is less than or equal to max. +func Maximum[T constraints.Integer](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, max T) field.ErrorList { + if value == nil { + return nil + } + if *value > max { + return field.ErrorList{field.Invalid(fldPath, *value, content.MaxError(max)).WithOrigin("maximum")} + } + return nil +} + +// MinLength verifies that the specified value is at least min characters, if non-nil. +func MinLength[T ~string](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, min int) field.ErrorList { + if value == nil { + return nil + } + + byteLength := len(*value) + + // because runes are up to 4 byte characters, if we assume all characters + // in the input are 4 byte runes, the minimum number of characters that + // are specified is len(value)/4. If the minimum multi-byte + // character count is greater than or equal to our enforced minimum, we + // can confidently say that the value is valid without having + // to actually perform the more expensive rune counting step + if int(math.Ceil(float64(byteLength)/4.0)) >= min { + return nil + } + + // if the length of the value in bytes is less + // than the minimum size then we can confidently + // say that this value is not within the bounds + // enforced by the maximum value regardless + // of the actual makeup of characters in the value. + // Otherwise, perform a rune count to determine if the + // number of characters is less than the minimum. + if byteLength < min || utf8.RuneCountInString(string(*value)) < min { + return field.ErrorList{field.TooShort(fldPath, *value, min).WithOrigin("minLength")} + } + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go b/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go index 9a21473055..190fa8dbe9 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go @@ -133,6 +133,23 @@ func LabelValue[T ~string](_ context.Context, op operation.Operation, fldPath *f return allErrs } +// PathSegmentName verifies that the specified value is a valid path segment name. +// A path segment name can be safely encoded as a path segment in URLs and file paths. +// - must not be exactly "." or ".." +// - must not contain "/" (forward slash) +// - must not contain "%" (percent sign) +// - can contain any other characters including mixed case, numbers, dots, hyphens, underscores, and non-ASCII characters +func PathSegmentName[T ~string](_ context.Context, op operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList { + if value == nil { + return nil + } + var allErrs field.ErrorList + for _, msg := range content.IsPathSegmentName((string)(*value)) { + allErrs = append(allErrs, field.Invalid(fldPath, *value, msg).WithOrigin("format=k8s-path-segment-name")) + } + return allErrs +} + // UUID verifies that the specified value is a valid UUID (RFC 4122). // - must be 36 characters long // - must be in the normalized form `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/union.go b/vendor/k8s.io/apimachinery/pkg/api/validate/union.go index 03f45f8661..753a4a9ee1 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/union.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/union.go @@ -19,6 +19,7 @@ package validate import ( "context" "fmt" + "reflect" "strings" "k8s.io/apimachinery/pkg/api/operation" @@ -60,6 +61,10 @@ type UnionValidationOptions struct { // )...) // return errs // } +// +// Note that T is "any", rather than "comparable", because union-members can be +// slices, meaning T might be a struct with a slice, meaning it is not +// comparable. func Union[T any](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj T, union *UnionMembership, isSetFns ...ExtractorFn[T, bool]) field.ErrorList { options := UnionValidationOptions{ ErrorForEmpty: func(fldPath *field.Path, allFields []string) *field.Error { @@ -72,7 +77,7 @@ func Union[T any](_ context.Context, op operation.Operation, fldPath *field.Path }, } - return unionValidate(op, fldPath, obj, oldObj, union, options, isSetFns...) + return unionValidate(op, fldPath, obj, oldObj, union, options, isSetFns...).WithOrigin("union") } // DiscriminatedUnion verifies specified union member matches the discriminator. @@ -98,6 +103,10 @@ func Union[T any](_ context.Context, op operation.Operation, fldPath *field.Path // // It is not an error for the discriminatorValue to be unknown. That must be // validated on its own. +// +// Note that T is "any", rather than "comparable", because union-members can be +// slices, meaning T might be a struct with a slice, meaning it is not +// comparable. func DiscriminatedUnion[T any, D ~string](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj T, union *UnionMembership, discriminatorExtractor ExtractorFn[T, D], isSetFns ...ExtractorFn[T, bool]) (errs field.ErrorList) { if len(union.members) != len(isSetFns) { return field.ErrorList{ @@ -106,6 +115,7 @@ func DiscriminatedUnion[T any, D ~string](_ context.Context, op operation.Operat len(isSetFns), len(union.members))), } } + hasOldValue := !reflect.ValueOf(oldObj).IsZero() // because T is any, rather than comparable var changed bool discriminatorValue := discriminatorExtractor(obj) if op.Type == operation.Update { @@ -131,10 +141,10 @@ func DiscriminatedUnion[T any, D ~string](_ context.Context, op operation.Operat } // If the union discriminator and membership is unchanged, we don't need to // re-validate. - if op.Type == operation.Update && !changed { + if op.Type == operation.Update && hasOldValue && !changed { return nil } - return errs + return errs.WithOrigin("union") } // UnionMember represents a member of a union. @@ -195,6 +205,7 @@ func unionValidate[T any](op operation.Operation, fldPath *field.Path, } } + hasOldValue := !reflect.ValueOf(oldObj).IsZero() // because T is any, rather than comparable var specifiedFields []string var changed bool for i, fieldIsSet := range isSetFns { @@ -209,7 +220,7 @@ func unionValidate[T any](op operation.Operation, fldPath *field.Path, } // If the union membership is unchanged, we don't need to re-validate. - if op.Type == operation.Update && !changed { + if op.Type == operation.Update && hasOldValue && !changed { return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go index 839fcbc2c1..9a4f378483 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go @@ -46,7 +46,7 @@ func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) fie for k := range annotations { // The rule is QualifiedName except that case doesn't matter, so convert to lowercase before checking. for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) { - allErrs = append(allErrs, field.Invalid(fldPath, k, msg)).WithOrigin("format=k8s-label-key") + allErrs = append(allErrs, field.Invalid(fldPath, k, msg).WithOrigin("format=k8s-label-key")) } } if err := ValidateAnnotationsSize(annotations); err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go b/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go deleted file mode 100644 index ffb9f56d80..0000000000 --- a/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2015 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 path - -import ( - "fmt" - "strings" -) - -// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store) -var NameMayNotBe = []string{".", ".."} - -// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store) -var NameMayNotContain = []string{"/", "%"} - -// IsValidPathSegmentName validates the name can be safely encoded as a path segment -func IsValidPathSegmentName(name string) []string { - for _, illegalName := range NameMayNotBe { - if name == illegalName { - return []string{fmt.Sprintf(`may not be '%s'`, illegalName)} - } - } - - var errors []string - for _, illegalContent := range NameMayNotContain { - if strings.Contains(name, illegalContent) { - errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent)) - } - } - - return errors -} - -// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment -// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid -func IsValidPathSegmentPrefix(name string) []string { - var errors []string - for _, illegalContent := range NameMayNotContain { - if strings.Contains(name, illegalContent) { - errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent)) - } - } - - return errors -} - -// ValidatePathSegmentName validates the name can be safely encoded as a path segment -func ValidatePathSegmentName(name string, prefix bool) []string { - if prefix { - return IsValidPathSegmentPrefix(name) - } - - return IsValidPathSegmentName(name) -} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.defaults.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/conversion.go similarity index 53% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.defaults.go rename to vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/conversion.go index 5070cb91b9..f431157ec4 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.defaults.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/conversion.go @@ -1,6 +1,3 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - /* Copyright The Kubernetes Authors. @@ -17,17 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by defaulter-gen. DO NOT EDIT. - -package v1alpha1 +package internalversion import ( - runtime "k8s.io/apimachinery/pkg/runtime" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/conversion" ) -// RegisterDefaults adds defaulters functions to the given scheme. -// Public to allow building arbitrary schemes. -// All generated defaulters are covering - they call all nested defaulters. -func RegisterDefaults(scheme *runtime.Scheme) error { - return nil +func Convert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error { + return autoConvert_v1_ListOptions_To_internalversion_ListOptions(in, out, s) +} + +func Convert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error { + return autoConvert_internalversion_ListOptions_To_v1_ListOptions(in, out, s) } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go index 8c60e7d2a8..a34a11c3e3 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go @@ -89,6 +89,11 @@ type ListOptions struct { // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward // compatibility reasons) and to false otherwise. SendInitialEvents *bool + + // ShardSelector is the raw shard selector string from the request. + // Parsing is deferred to the apiserver storage layer where the CEL + // parser dependency is available. + ShardSelector string } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go index a6552c276e..f321ad2345 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go @@ -46,12 +46,12 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*ListOptions)(nil), (*v1.ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + if err := s.AddConversionFunc((*ListOptions)(nil), (*v1.ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_internalversion_ListOptions_To_v1_ListOptions(a.(*ListOptions), b.(*v1.ListOptions), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1.ListOptions)(nil), (*ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + if err := s.AddConversionFunc((*v1.ListOptions)(nil), (*ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_ListOptions_To_internalversion_ListOptions(a.(*v1.ListOptions), b.(*ListOptions), scope) }); err != nil { return err @@ -116,14 +116,10 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out.Limit = in.Limit out.Continue = in.Continue out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) + out.ShardSelector = in.ShardSelector return nil } -// Convert_internalversion_ListOptions_To_v1_ListOptions is an autogenerated conversion function. -func Convert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error { - return autoConvert_internalversion_ListOptions_To_v1_ListOptions(in, out, s) -} - func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error { if err := v1.Convert_string_To_labels_Selector(&in.LabelSelector, &out.LabelSelector, s); err != nil { return err @@ -139,10 +135,6 @@ func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOption out.Limit = in.Limit out.Continue = in.Continue out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) + out.ShardSelector = in.ShardSelector return nil } - -// Convert_v1_ListOptions_To_internalversion_ListOptions is an autogenerated conversion function. -func Convert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error { - return autoConvert_v1_ListOptions_To_internalversion_ListOptions(in, out, s) -} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1.go new file mode 100644 index 0000000000..81aca59fac --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1.go @@ -0,0 +1,170 @@ +/* +Copyright 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 v1 + +import ( + "fmt" + "io" +) + +func (FieldsV1) SwaggerDoc() map[string]string { + return map[string]string{ + "": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + } +} + +type FieldsV1Reader interface { + io.Reader + io.ReaderAt + // Size returns the original byte length of the underlying data. Size is the number of bytes available for reading via ReadAt. + Size() int64 +} + +func (f *FieldsV1) DeepCopy() *FieldsV1 { + if f == nil { + return nil + } + out := new(FieldsV1) + f.DeepCopyInto(out) + return out +} + +func (f *FieldsV1) Marshal() (dAtA []byte, err error) { + size := f.Size() + dAtA = make([]byte, size) + n, err := f.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (f *FieldsV1) MarshalTo(dAtA []byte) (int, error) { + size := f.Size() + return f.MarshalToSizedBuffer(dAtA[:size]) +} + +func (f *FieldsV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + rawBytes := f.GetRawBytes() + if len(rawBytes) > 0 { + i -= len(rawBytes) + copy(dAtA[i:], rawBytes) + i = encodeVarintGenerated(dAtA, i, uint64(len(rawBytes))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (f *FieldsV1) Size() (n int) { + if f == nil { + return 0 + } + var l int + _ = l + if l := int(f.GetRawReader().Size()); l > 0 { + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (f *FieldsV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FieldsV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FieldsV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + + f.SetRawBytes(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_byte.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_byte.go new file mode 100644 index 0000000000..66f28e1d9f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_byte.go @@ -0,0 +1,105 @@ +//go:build !fieldsv1string + +/* +Copyright 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 v1 + +import ( + "bytes" +) + +// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format. +// +// Each key is either a '.' representing the field itself, and will always map to an empty set, +// or a string representing a sub-field or item. The string will follow one of these four formats: +// 'f:', where is the name of a field in a struct, or key in a map +// 'v:', where is the exact json formatted value of a list item +// 'i:', where is position of a item in a list +// 'k:', where is a map of a list item's key fields to their unique values +// If a key maps to an empty Fields value, the field that key represents is part of the set. +// +// The exact format is defined in sigs.k8s.io/structured-merge-diff +// +k8s:deepcopy-gen=false +// +protobuf.options.marshal=false +// +protobuf.options.(gogoproto.goproto_stringer)=false +type FieldsV1 struct { + // Raw is the underlying serialization of this object. + // + // Deprecated: Direct access to this field is deprecated. Use GetRawBytes, GetRawString, SetRawBytes, SetRawString, GetRawReader, NewFieldsV1 instead. + Raw []byte `json:"-" protobuf:"bytes,1,opt,name=Raw"` +} + +func (f FieldsV1) String() string { + return string(f.Raw) +} + +func (f FieldsV1) Equal(f2 FieldsV1) bool { + return bytes.Equal(f.Raw, f2.Raw) +} + +func (f *FieldsV1) GetRawReader() FieldsV1Reader { + if f == nil || len(f.Raw) == 0 { + return bytes.NewReader(nil) + } + return bytes.NewReader(f.Raw) +} + +// GetRawBytes returns the raw bytes. +// These may or may not be a copy of the underlying bytes. +// If mutating the underlying bytes is desired, the returned bytes may be mutated and then passed to SetRawBytes(). +// If mutating the underlying bytes is not desired, make a copy of the returned bytes. +func (f *FieldsV1) GetRawBytes() []byte { + if f == nil { + return nil + } + return f.Raw +} + +// GetRawString returns the raw data as a string. +func (f *FieldsV1) GetRawString() string { + if f == nil { + return "" + } + return string(f.Raw) +} + +// SetRawBytes sets the raw bytes. It does not retain the passed-in byte slice. +func (f *FieldsV1) SetRawBytes(b []byte) { + if f != nil { + f.Raw = bytes.Clone(b) + } +} + +// SetRawString sets the raw data from a string. +func (f *FieldsV1) SetRawString(s string) { + if f != nil { + f.Raw = []byte(s) + } +} + +func NewFieldsV1(raw string) *FieldsV1 { + return &FieldsV1{Raw: []byte(raw)} +} + +func (f *FieldsV1) DeepCopyInto(out *FieldsV1) { + *out = *f + if f.Raw != nil { + in, out := &f.Raw, &out.Raw + *out = make([]byte, len(*in)) + copy(*out, *in) + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_string.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_string.go new file mode 100644 index 0000000000..679452ae17 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/fieldsv1_string.go @@ -0,0 +1,113 @@ +//go:build fieldsv1string + +/* +Copyright 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 v1 + +import ( + "strings" + "unique" +) + +// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format. +// +// Each key is either a '.' representing the field itself, and will always map to an empty set, +// or a string representing a sub-field or item. The string will follow one of these four formats: +// 'f:', where is the name of a field in a struct, or key in a map +// 'v:', where is the exact json formatted value of a list item +// 'i:', where is position of a item in a list +// 'k:', where is a map of a list item's key fields to their unique values +// If a key maps to an empty Fields value, the field that key represents is part of the set. +// +// The exact format is defined in sigs.k8s.io/structured-merge-diff +// +k8s:deepcopy-gen=false +// +protobuf.options.marshal=false +// +protobuf.options.(gogoproto.goproto_stringer)=false +type FieldsV1 struct { + // The zero value of a unique.Handle[string] has an uninitialized underlying pointer. + // Calling .Value() on it panics. We must explicitly check for this uninitialized + // state (f.handle == unique.Handle[string]{}) across accessors to safely support + // uninitialized metav1.FieldsV1{} objects. + // See ongoing golang discussion related to this here: https://github.com/golang/go/issues/73344 + handle unique.Handle[string] +} + +func (f FieldsV1) String() string { + if f.handle == (unique.Handle[string]{}) { + return "" + } + return f.handle.Value() +} + +func (f FieldsV1) Equal(f2 FieldsV1) bool { + if f.handle == f2.handle { + return true + } + // An uninitialized FieldsV1 compared to an explicitly empty + // FieldsV1 (unique.Make("") will fail the handle check above. + // Evaluate string contents directly as well to maintain parity with legacy + // bytes.Equal(nil, []byte{}) == true behavior. + return f.GetRawString() == f2.GetRawString() +} + +func (f *FieldsV1) GetRawReader() FieldsV1Reader { + if f == nil || f.handle == (unique.Handle[string]{}) { + return strings.NewReader("") + } + return strings.NewReader(f.handle.Value()) +} + +// GetRawBytes returns the raw bytes. +// These may or may not be a copy of the underlying bytes. +// If mutating the underlying bytes is desired, the returned bytes may be mutated and then passed to SetRawBytes(). +// If mutating the underlying bytes is not desired, make a copy of the returned bytes. +func (f *FieldsV1) GetRawBytes() []byte { + if f == nil || f.handle == (unique.Handle[string]{}) { + return nil + } + return []byte(f.handle.Value()) +} + +// GetRawString returns the raw data as a string. +func (f *FieldsV1) GetRawString() string { + if f == nil || f.handle == (unique.Handle[string]{}) { + return "" + } + return f.handle.Value() +} + +// SetRawBytes sets the raw bytes. It does not retain the passed-in byte slice. +func (f *FieldsV1) SetRawBytes(b []byte) { + if f != nil { + f.handle = unique.Make(string(b)) + } +} + +// SetRawString sets the raw data from a string. +func (f *FieldsV1) SetRawString(s string) { + if f != nil { + f.handle = unique.Make(s) + } +} + +func NewFieldsV1(raw string) *FieldsV1 { + return &FieldsV1{handle: unique.Make(raw)} +} + +func (f *FieldsV1) DeepCopyInto(out *FieldsV1) { + *out = *f +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go index f6b1a6a4e0..293b0223a7 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go @@ -105,6 +105,8 @@ func (m *RootPaths) Reset() { *m = RootPaths{} } func (m *ServerAddressByClientCIDR) Reset() { *m = ServerAddressByClientCIDR{} } +func (m *ShardInfo) Reset() { *m = ShardInfo{} } + func (m *Status) Reset() { *m = Status{} } func (m *StatusCause) Reset() { *m = StatusCause{} } @@ -694,36 +696,6 @@ func (m *FieldSelectorRequirement) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } -func (m *FieldsV1) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *FieldsV1) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *FieldsV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Raw != nil { - i -= len(m.Raw) - copy(dAtA[i:], m.Raw) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func (m *GetOptions) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1130,6 +1102,18 @@ func (m *ListMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ShardInfo != nil { + { + size, err := m.ShardInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } if m.RemainingItemCount != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.RemainingItemCount)) i-- @@ -1173,6 +1157,11 @@ func (m *ListOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.ShardSelector) + copy(dAtA[i:], m.ShardSelector) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ShardSelector))) + i-- + dAtA[i] = 0x7a if m.SendInitialEvents != nil { i-- if *m.SendInitialEvents { @@ -1797,6 +1786,34 @@ func (m *ServerAddressByClientCIDR) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *ShardInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ShardInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ShardInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Selector) + copy(dAtA[i:], m.Selector) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Selector))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *Status) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2405,19 +2422,6 @@ func (m *FieldSelectorRequirement) Size() (n int) { return n } -func (m *FieldsV1) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Raw != nil { - l = len(m.Raw) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *GetOptions) Size() (n int) { if m == nil { return 0 @@ -2585,6 +2589,10 @@ func (m *ListMeta) Size() (n int) { if m.RemainingItemCount != nil { n += 1 + sovGenerated(uint64(*m.RemainingItemCount)) } + if m.ShardInfo != nil { + l = m.ShardInfo.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -2613,6 +2621,8 @@ func (m *ListOptions) Size() (n int) { if m.SendInitialEvents != nil { n += 2 } + l = len(m.ShardSelector) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -2835,6 +2845,17 @@ func (m *ServerAddressByClientCIDR) Size() (n int) { return n } +func (m *ShardInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Selector) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *Status) Size() (n int) { if m == nil { return 0 @@ -3217,6 +3238,7 @@ func (this *ListMeta) String() string { `ResourceVersion:` + fmt.Sprintf("%v", this.ResourceVersion) + `,`, `Continue:` + fmt.Sprintf("%v", this.Continue) + `,`, `RemainingItemCount:` + valueToStringGenerated(this.RemainingItemCount) + `,`, + `ShardInfo:` + strings.Replace(this.ShardInfo.String(), "ShardInfo", "ShardInfo", 1) + `,`, `}`, }, "") return s @@ -3236,6 +3258,7 @@ func (this *ListOptions) String() string { `AllowWatchBookmarks:` + fmt.Sprintf("%v", this.AllowWatchBookmarks) + `,`, `ResourceVersionMatch:` + fmt.Sprintf("%v", this.ResourceVersionMatch) + `,`, `SendInitialEvents:` + valueToStringGenerated(this.SendInitialEvents) + `,`, + `ShardSelector:` + fmt.Sprintf("%v", this.ShardSelector) + `,`, `}`, }, "") return s @@ -3405,6 +3428,16 @@ func (this *ServerAddressByClientCIDR) String() string { }, "") return s } +func (this *ShardInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ShardInfo{`, + `Selector:` + fmt.Sprintf("%v", this.Selector) + `,`, + `}`, + }, "") + return s +} func (this *Status) String() string { if this == nil { return "nil" @@ -5314,90 +5347,6 @@ func (m *FieldSelectorRequirement) Unmarshal(dAtA []byte) error { } return nil } -func (m *FieldsV1) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: FieldsV1: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: FieldsV1: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Raw = append(m.Raw[:0], dAtA[iNdEx:postIndex]...) - if m.Raw == nil { - m.Raw = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *GetOptions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -6847,6 +6796,42 @@ func (m *ListMeta) Unmarshal(dAtA []byte) error { } } m.RemainingItemCount = &v + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShardInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ShardInfo == nil { + m.ShardInfo = &ShardInfo{} + } + if err := m.ShardInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -7157,6 +7142,38 @@ func (m *ListOptions) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.SendInitialEvents = &b + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShardSelector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShardSelector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -9113,6 +9130,88 @@ func (m *ServerAddressByClientCIDR) Unmarshal(dAtA []byte) error { } return nil } +func (m *ShardInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ShardInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ShardInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Status) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index fb21b72368..d03a733141 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -369,9 +369,13 @@ message FieldSelectorRequirement { // If a key maps to an empty Fields value, the field that key represents is part of the set. // // The exact format is defined in sigs.k8s.io/structured-merge-diff +// +k8s:deepcopy-gen=false +// +protobuf.options.marshal=false // +protobuf.options.(gogoproto.goproto_stringer)=false message FieldsV1 { // Raw is the underlying serialization of this object. + // + // Deprecated: Direct access to this field is deprecated. Use GetRawBytes, GetRawString, SetRawBytes, SetRawString, GetRawReader, NewFieldsV1 instead. optional bytes Raw = 1; } @@ -533,6 +537,17 @@ message ListMeta { // should not rely on the remainingItemCount to be set or to be exact. // +optional optional int64 remainingItemCount = 4; + + // shardInfo is set when the list is a filtered subset of the full collection, + // as selected by a shard selector on the request. It echoes back the selector + // so clients can verify which shard they received and merge sharded responses. + // Clients should not cache sharded list responses as a full representation + // of the collection. + // + // This is an alpha field and requires enabling the ShardedListAndWatch feature gate. + // +featureGate=ShardedListAndWatch + // +optional + optional ShardInfo shardInfo = 5; } // ListOptions is the query options to a standard REST list call. @@ -643,6 +658,38 @@ message ListOptions { // compatibility reasons) and to false otherwise. // +optional optional bool sendInitialEvents = 11; + + // shardSelector restricts the list of returned objects using a CEL-based + // shard selector expression. The format uses the shardRange() function + // combined with || (logical OR) to specify one or more hash ranges: + // + // shardRange(object.metadata.uid, '0x0', '0x8000000000000000') + // shardRange(object.metadata.uid, '0x0', '0x8000000000000000') || shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000') + // + // Field paths use CEL-style object-rooted syntax (e.g. "object.metadata.uid"), + // NOT the fieldSelector format ("metadata.uid"). Currently supported paths: + // - object.metadata.uid + // - object.metadata.namespace + // + // hexStart and hexEnd are single-quoted CEL string literals with a '0x' prefix, + // defining the inclusive lower and exclusive upper bounds over the 64-bit FNV-1a + // hash space. The full range is [0x0, 0x10000000000000000), where the exclusive + // upper bound equals 2^64. + // + // Examples: + // 2-shard split: + // shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000') + // shard 1: shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000') + // 4-shard split: + // shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x4000000000000000') + // shard 1: shardRange(object.metadata.uid, '0x4000000000000000', '0x8000000000000000') + // shard 2: shardRange(object.metadata.uid, '0x8000000000000000', '0xc000000000000000') + // shard 3: shardRange(object.metadata.uid, '0xc000000000000000', '0x10000000000000000') + // + // This is an alpha field and requires enabling the ShardedListAndWatch feature gate. + // +featureGate=ShardedListAndWatch + // +optional + optional string shardSelector = 15; } // ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource @@ -1009,6 +1056,15 @@ message ServerAddressByClientCIDR { optional string serverAddress = 2; } +// ShardInfo describes the shard selector that was applied to produce a list response. +// Its presence on a list response indicates the list is a filtered subset. +message ShardInfo { + // selector is the shard selector string from the request, echoed back so clients + // can verify which shard they received and merge responses from multiple shards. + // +required + optional string selector = 1; +} + // Status is a return value for calls that don't return other objects. message Status { // Standard list metadata. diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.protomessage.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.protomessage.pb.go deleted file mode 100644 index 459ae1ad87..0000000000 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,112 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*APIGroup) ProtoMessage() {} - -func (*APIGroupList) ProtoMessage() {} - -func (*APIResource) ProtoMessage() {} - -func (*APIResourceList) ProtoMessage() {} - -func (*APIVersions) ProtoMessage() {} - -func (*ApplyOptions) ProtoMessage() {} - -func (*Condition) ProtoMessage() {} - -func (*CreateOptions) ProtoMessage() {} - -func (*DeleteOptions) ProtoMessage() {} - -func (*Duration) ProtoMessage() {} - -func (*FieldSelectorRequirement) ProtoMessage() {} - -func (*FieldsV1) ProtoMessage() {} - -func (*GetOptions) ProtoMessage() {} - -func (*GroupKind) ProtoMessage() {} - -func (*GroupResource) ProtoMessage() {} - -func (*GroupVersion) ProtoMessage() {} - -func (*GroupVersionForDiscovery) ProtoMessage() {} - -func (*GroupVersionKind) ProtoMessage() {} - -func (*GroupVersionResource) ProtoMessage() {} - -func (*LabelSelector) ProtoMessage() {} - -func (*LabelSelectorRequirement) ProtoMessage() {} - -func (*List) ProtoMessage() {} - -func (*ListMeta) ProtoMessage() {} - -func (*ListOptions) ProtoMessage() {} - -func (*ManagedFieldsEntry) ProtoMessage() {} - -func (*MicroTime) ProtoMessage() {} - -func (*ObjectMeta) ProtoMessage() {} - -func (*OwnerReference) ProtoMessage() {} - -func (*PartialObjectMetadata) ProtoMessage() {} - -func (*PartialObjectMetadataList) ProtoMessage() {} - -func (*Patch) ProtoMessage() {} - -func (*PatchOptions) ProtoMessage() {} - -func (*Preconditions) ProtoMessage() {} - -func (*RootPaths) ProtoMessage() {} - -func (*ServerAddressByClientCIDR) ProtoMessage() {} - -func (*Status) ProtoMessage() {} - -func (*StatusCause) ProtoMessage() {} - -func (*StatusDetails) ProtoMessage() {} - -func (*TableOptions) ProtoMessage() {} - -func (*Time) ProtoMessage() {} - -func (*Timestamp) ProtoMessage() {} - -func (*TypeMeta) ProtoMessage() {} - -func (*UpdateOptions) ProtoMessage() {} - -func (*Verbs) ProtoMessage() {} - -func (*WatchEvent) ProtoMessage() {} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go index c748071ed7..45ed1e9891 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go @@ -279,17 +279,18 @@ func ResetObjectMetaForStatus(meta, existingMeta Object) { // MarshalJSON may get called on pointers or values, so implement MarshalJSON on value. // http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go func (f FieldsV1) MarshalJSON() ([]byte, error) { - if f.Raw == nil { + raw := f.GetRawBytes() + if len(raw) == 0 { return []byte("null"), nil } if f.getContentType() == fieldsV1InvalidOrValidCBORObject { var u map[string]interface{} - if err := cbor.Unmarshal(f.Raw, &u); err != nil { + if err := cbor.Unmarshal(raw, &u); err != nil { return nil, fmt.Errorf("metav1.FieldsV1 cbor invalid: %w", err) } return utiljson.Marshal(u) } - return f.Raw, nil + return raw, nil } // UnmarshalJSON implements json.Unmarshaler @@ -298,7 +299,7 @@ func (f *FieldsV1) UnmarshalJSON(b []byte) error { return errors.New("metav1.FieldsV1: UnmarshalJSON on nil pointer") } if !bytes.Equal(b, []byte("null")) { - f.Raw = append(f.Raw[0:0], b...) + f.SetRawBytes(b) } return nil } @@ -307,17 +308,18 @@ var _ json.Marshaler = FieldsV1{} var _ json.Unmarshaler = &FieldsV1{} func (f FieldsV1) MarshalCBOR() ([]byte, error) { - if f.Raw == nil { + raw := f.GetRawBytes() + if len(raw) == 0 { return cbor.Marshal(nil) } if f.getContentType() == fieldsV1InvalidOrValidJSONObject { var u map[string]interface{} - if err := utiljson.Unmarshal(f.Raw, &u); err != nil { + if err := utiljson.Unmarshal(raw, &u); err != nil { return nil, fmt.Errorf("metav1.FieldsV1 json invalid: %w", err) } return cbor.Marshal(u) } - return f.Raw, nil + return raw, nil } var cborNull = []byte{0xf6} @@ -327,7 +329,7 @@ func (f *FieldsV1) UnmarshalCBOR(b []byte) error { return errors.New("metav1.FieldsV1: UnmarshalCBOR on nil pointer") } if !bytes.Equal(b, cborNull) { - f.Raw = append(f.Raw[0:0], b...) + f.SetRawBytes(b) } return nil } @@ -362,8 +364,13 @@ const ( // or, if a tag-enclosed map, an initial byte with major type "tag" (0xf6, 0xa0...0xbf, or // 0xc6...0xdb). The two sets of valid initial bytes don't intersect. func (f FieldsV1) getContentType() int { - if len(f.Raw) > 0 { - p := f.Raw[0] + reader := f.GetRawReader() + if reader.Size() > 0 { + var buf [1]byte + if _, err := reader.Read(buf[:]); err != nil { + return fieldsV1InvalidOrEmpty + } + p := buf[0] switch p { case 'n', '{', '\t', '\r', '\n', ' ': return fieldsV1InvalidOrValidJSONObject diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go index 92d3ed5e01..6ae1b095fc 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go @@ -94,6 +94,13 @@ type ListInterface interface { SetRemainingItemCount(c *int64) } +// ShardedListInterface can be implemented by list types to indicate that they +// represent a sharded subset of the full collection rather than the complete list. +type ShardedListInterface interface { + GetShardInfo() *ShardInfo + SetShardInfo(*ShardInfo) +} + // Type exposes the type and APIVersion of versioned or internal API objects. // TODO: move this, and TypeMeta and ListMeta, to a different package type Type interface { @@ -113,6 +120,8 @@ func (meta *ListMeta) GetContinue() string { return meta.Continue func (meta *ListMeta) SetContinue(c string) { meta.Continue = c } func (meta *ListMeta) GetRemainingItemCount() *int64 { return meta.RemainingItemCount } func (meta *ListMeta) SetRemainingItemCount(c *int64) { meta.RemainingItemCount = c } +func (meta *ListMeta) GetShardInfo() *ShardInfo { return meta.ShardInfo } +func (meta *ListMeta) SetShardInfo(s *ShardInfo) { meta.ShardInfo = s } func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_fuzz.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_fuzz.go index a5f437b4b3..338ea9be72 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_fuzz.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_fuzz.go @@ -1,5 +1,4 @@ //go:build !notest -// +build !notest /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_fuzz.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_fuzz.go index 48fb978450..14ec5f0586 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_fuzz.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_fuzz.go @@ -1,5 +1,4 @@ //go:build !notest -// +build !notest /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index 9970e877d0..c8b87f20c8 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -92,6 +92,26 @@ type ListMeta struct { // should not rely on the remainingItemCount to be set or to be exact. // +optional RemainingItemCount *int64 `json:"remainingItemCount,omitempty" protobuf:"bytes,4,opt,name=remainingItemCount"` + + // shardInfo is set when the list is a filtered subset of the full collection, + // as selected by a shard selector on the request. It echoes back the selector + // so clients can verify which shard they received and merge sharded responses. + // Clients should not cache sharded list responses as a full representation + // of the collection. + // + // This is an alpha field and requires enabling the ShardedListAndWatch feature gate. + // +featureGate=ShardedListAndWatch + // +optional + ShardInfo *ShardInfo `json:"shardInfo,omitempty" protobuf:"bytes,5,opt,name=shardInfo"` +} + +// ShardInfo describes the shard selector that was applied to produce a list response. +// Its presence on a list response indicates the list is a filtered subset. +type ShardInfo struct { + // selector is the shard selector string from the request, echoed back so clients + // can verify which shard they received and merge responses from multiple shards. + // +required + Selector string `json:"selector" protobuf:"bytes,1,opt,name=selector"` } // Field path constants that are specific to the internal API @@ -430,6 +450,38 @@ type ListOptions struct { // compatibility reasons) and to false otherwise. // +optional SendInitialEvents *bool `json:"sendInitialEvents,omitempty" protobuf:"varint,11,opt,name=sendInitialEvents"` + + // shardSelector restricts the list of returned objects using a CEL-based + // shard selector expression. The format uses the shardRange() function + // combined with || (logical OR) to specify one or more hash ranges: + // + // shardRange(object.metadata.uid, '0x0', '0x8000000000000000') + // shardRange(object.metadata.uid, '0x0', '0x8000000000000000') || shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000') + // + // Field paths use CEL-style object-rooted syntax (e.g. "object.metadata.uid"), + // NOT the fieldSelector format ("metadata.uid"). Currently supported paths: + // - object.metadata.uid + // - object.metadata.namespace + // + // hexStart and hexEnd are single-quoted CEL string literals with a '0x' prefix, + // defining the inclusive lower and exclusive upper bounds over the 64-bit FNV-1a + // hash space. The full range is [0x0, 0x10000000000000000), where the exclusive + // upper bound equals 2^64. + // + // Examples: + // 2-shard split: + // shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000') + // shard 1: shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000') + // 4-shard split: + // shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x4000000000000000') + // shard 1: shardRange(object.metadata.uid, '0x4000000000000000', '0x8000000000000000') + // shard 2: shardRange(object.metadata.uid, '0x8000000000000000', '0xc000000000000000') + // shard 3: shardRange(object.metadata.uid, '0xc000000000000000', '0x10000000000000000') + // + // This is an alpha field and requires enabling the ShardedListAndWatch feature gate. + // +featureGate=ShardedListAndWatch + // +optional + ShardSelector string `json:"shardSelector,omitempty" protobuf:"bytes,15,opt,name=shardSelector"` } const ( @@ -1384,27 +1436,6 @@ const ( ManagedFieldsOperationUpdate ManagedFieldsOperationType = "Update" ) -// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format. -// -// Each key is either a '.' representing the field itself, and will always map to an empty set, -// or a string representing a sub-field or item. The string will follow one of these four formats: -// 'f:', where is the name of a field in a struct, or key in a map -// 'v:', where is the exact json formatted value of a list item -// 'i:', where is position of a item in a list -// 'k:', where is a map of a list item's key fields to their unique values -// If a key maps to an empty Fields value, the field that key represents is part of the set. -// -// The exact format is defined in sigs.k8s.io/structured-merge-diff -// +protobuf.options.(gogoproto.goproto_stringer)=false -type FieldsV1 struct { - // Raw is the underlying serialization of this object. - Raw []byte `json:"-" protobuf:"bytes,1,opt,name=Raw"` -} - -func (f FieldsV1) String() string { - return string(f.Raw) -} - // TODO: Table does not generate to protobuf because of the interface{} - fix protobuf // generation to support a meta type that can accept any valid JSON. This can be introduced // in a v1 because clients a) receive an error if they try to access proto today, and b) diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go index 405496d3df..c45c00f1aa 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go @@ -147,14 +147,6 @@ func (FieldSelectorRequirement) SwaggerDoc() map[string]string { return map_FieldSelectorRequirement } -var map_FieldsV1 = map[string]string{ - "": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", -} - -func (FieldsV1) SwaggerDoc() map[string]string { - return map_FieldsV1 -} - var map_GetOptions = map[string]string{ "": "GetOptions is the standard query options to the standard REST get call.", "resourceVersion": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", @@ -211,6 +203,7 @@ var map_ListMeta = map[string]string{ "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", "continue": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", "remainingItemCount": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", + "shardInfo": "shardInfo is set when the list is a filtered subset of the full collection, as selected by a shard selector on the request. It echoes back the selector so clients can verify which shard they received and merge sharded responses. Clients should not cache sharded list responses as a full representation of the collection.\n\nThis is an alpha field and requires enabling the ShardedListAndWatch feature gate.", } func (ListMeta) SwaggerDoc() map[string]string { @@ -229,6 +222,7 @@ var map_ListOptions = map[string]string{ "limit": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", "continue": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", "sendInitialEvents": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "shardSelector": "shardSelector restricts the list of returned objects using a CEL-based shard selector expression. The format uses the shardRange() function combined with || (logical OR) to specify one or more hash ranges:\n\n shardRange(object.metadata.uid, '0x0', '0x8000000000000000')\n shardRange(object.metadata.uid, '0x0', '0x8000000000000000') || shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000')\n\nField paths use CEL-style object-rooted syntax (e.g. \"object.metadata.uid\"), NOT the fieldSelector format (\"metadata.uid\"). Currently supported paths:\n - object.metadata.uid\n - object.metadata.namespace\n\nhexStart and hexEnd are single-quoted CEL string literals with a '0x' prefix, defining the inclusive lower and exclusive upper bounds over the 64-bit FNV-1a hash space. The full range is [0x0, 0x10000000000000000), where the exclusive upper bound equals 2^64.\n\nExamples:\n 2-shard split:\n shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')\n shard 1: shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000')\n 4-shard split:\n shard 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x4000000000000000')\n shard 1: shardRange(object.metadata.uid, '0x4000000000000000', '0x8000000000000000')\n shard 2: shardRange(object.metadata.uid, '0x8000000000000000', '0xc000000000000000')\n shard 3: shardRange(object.metadata.uid, '0xc000000000000000', '0x10000000000000000')\n\nThis is an alpha field and requires enabling the ShardedListAndWatch feature gate.", } func (ListOptions) SwaggerDoc() map[string]string { @@ -355,6 +349,15 @@ func (ServerAddressByClientCIDR) SwaggerDoc() map[string]string { return map_ServerAddressByClientCIDR } +var map_ShardInfo = map[string]string{ + "": "ShardInfo describes the shard selector that was applied to produce a list response. Its presence on a list response indicates the list is a filtered subset.", + "selector": "selector is the shard selector string from the request, echoed back so clients can verify which shard they received and merge responses from multiple shards.", +} + +func (ShardInfo) SwaggerDoc() map[string]string { + return map_ShardInfo +} + var map_Status = map[string]string{ "": "Status is a return value for calls that don't return other objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go index 82e2722404..735cbcb08f 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go @@ -440,6 +440,13 @@ func autoConvert_url_Values_To_v1_ListOptions(in *url.Values, out *ListOptions, } else { out.SendInitialEvents = nil } + if values, ok := map[string][]string(*in)["shardSelector"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_string(&values, &out.ShardSelector, s); err != nil { + return err + } + } else { + out.ShardSelector = "" + } return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go index 6b0d0dfee9..eb7eb80d9b 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go @@ -353,27 +353,6 @@ func (in *FieldSelectorRequirement) DeepCopy() *FieldSelectorRequirement { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FieldsV1) DeepCopyInto(out *FieldsV1) { - *out = *in - if in.Raw != nil { - in, out := &in.Raw, &out.Raw - *out = make([]byte, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FieldsV1. -func (in *FieldsV1) DeepCopy() *FieldsV1 { - if in == nil { - return nil - } - out := new(FieldsV1) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GetOptions) DeepCopyInto(out *GetOptions) { *out = *in @@ -606,6 +585,11 @@ func (in *ListMeta) DeepCopyInto(out *ListMeta) { *out = new(int64) **out = **in } + if in.ShardInfo != nil { + in, out := &in.ShardInfo, &out.ShardInfo + *out = new(ShardInfo) + **out = **in + } return } @@ -663,8 +647,7 @@ func (in *ManagedFieldsEntry) DeepCopyInto(out *ManagedFieldsEntry) { } if in.FieldsV1 != nil { in, out := &in.FieldsV1, &out.FieldsV1 - *out = new(FieldsV1) - (*in).DeepCopyInto(*out) + *out = (*in).DeepCopy() } return } @@ -947,6 +930,22 @@ func (in *ServerAddressByClientCIDR) DeepCopy() *ServerAddressByClientCIDR { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ShardInfo) DeepCopyInto(out *ShardInfo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShardInfo. +func (in *ShardInfo) DeepCopy() *ShardInfo { + if in == nil { + return nil + } + out := new(ShardInfo) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Status) DeepCopyInto(out *Status) { *out = *in diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.model_name.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.model_name.go index fd6e876ece..3df687707c 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.model_name.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.model_name.go @@ -201,6 +201,11 @@ func (in ServerAddressByClientCIDR) OpenAPIModelName() string { return "io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ShardInfo) OpenAPIModelName() string { + return "io.k8s.apimachinery.pkg.apis.meta.v1.ShardInfo" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in Status) OpenAPIModelName() string { return "io.k8s.apimachinery.pkg.apis.meta.v1.Status" diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/generated.protomessage.pb.go b/vendor/k8s.io/apimachinery/pkg/runtime/generated.protomessage.pb.go deleted file mode 100644 index 1716853ff1..0000000000 --- a/vendor/k8s.io/apimachinery/pkg/runtime/generated.protomessage.pb.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package runtime - -func (*RawExtension) ProtoMessage() {} - -func (*TypeMeta) ProtoMessage() {} - -func (*Unknown) ProtoMessage() {} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.protomessage.pb.go b/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.protomessage.pb.go deleted file mode 100644 index 047437377f..0000000000 --- a/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.protomessage.pb.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package schema diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go index 09d1340f93..6d4f283cae 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/raw.go @@ -50,7 +50,7 @@ var rawTypeTranscodeFuncs = map[reflect.Type]func(reflect.Value) error{ return nil } fields := rv.Addr().Interface().(*metav1.FieldsV1) - if fields.Raw == nil { + if fields.GetRawReader().Size() == 0 { // When Raw is nil it encodes to null. Don't change nil Raw values during // transcoding, they would have unmarshalled from JSON as nil too. return nil @@ -59,7 +59,7 @@ var rawTypeTranscodeFuncs = map[reflect.Type]func(reflect.Value) error{ if err != nil { return fmt.Errorf("failed to transcode FieldsV1 to JSON: %w", err) } - fields.Raw = j + fields.SetRawBytes(j) return nil }, } diff --git a/vendor/k8s.io/apimachinery/pkg/sharding/accessor.go b/vendor/k8s.io/apimachinery/pkg/sharding/accessor.go new file mode 100644 index 0000000000..fab98ffca4 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/sharding/accessor.go @@ -0,0 +1,50 @@ +/* +Copyright 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 sharding + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" +) + +// ResolveFieldValue extracts a metadata field value from a runtime.Object +// based on the given field path. +// +// Field paths use CEL-style object-rooted syntax ("object.metadata."), +// which differs from the fieldSelector format ("metadata."). The +// "object." prefix anchors the path to the resource being filtered. +// +// Supported field paths: +// - "object.metadata.uid" +// - "object.metadata.namespace" +func ResolveFieldValue(obj runtime.Object, fieldPath string) (string, error) { + accessor, err := meta.Accessor(obj) + if err != nil { + return "", fmt.Errorf("failed to access object metadata: %w", err) + } + + switch fieldPath { + case "object.metadata.uid": + return string(accessor.GetUID()), nil + case "object.metadata.namespace": + return accessor.GetNamespace(), nil + default: + return "", fmt.Errorf("unsupported field path: %q", fieldPath) + } +} diff --git a/vendor/k8s.io/api/authentication/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/apimachinery/pkg/sharding/hash.go similarity index 66% rename from vendor/k8s.io/api/authentication/v1alpha1/generated.protomessage.pb.go rename to vendor/k8s.io/apimachinery/pkg/sharding/hash.go index d0e9c4e564..ae4dcfe2f6 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/generated.protomessage.pb.go +++ b/vendor/k8s.io/apimachinery/pkg/sharding/hash.go @@ -1,6 +1,3 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - /* Copyright The Kubernetes Authors. @@ -17,10 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1alpha1 +package sharding -func (*SelfSubjectReview) ProtoMessage() {} +import ( + "fmt" + "hash/fnv" +) -func (*SelfSubjectReviewStatus) ProtoMessage() {} +// HashField computes a hash of value and returns it +// as a 16-character lowercase hex string (no "0x" prefix). +func HashField(value string) string { + h := fnv.New64a() + h.Write([]byte(value)) + return fmt.Sprintf("%016x", h.Sum64()) +} diff --git a/vendor/k8s.io/apimachinery/pkg/sharding/selector.go b/vendor/k8s.io/apimachinery/pkg/sharding/selector.go new file mode 100644 index 0000000000..841388a0d7 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/sharding/selector.go @@ -0,0 +1,137 @@ +/* +Copyright 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 sharding + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" +) + +// Selector represents a shard selector that can match objects based on +// hash ranges of their metadata fields. It follows the labels.Selector +// pattern from the Kubernetes API. +type Selector interface { + // Matches returns true if the given object matches the shard selector. + Matches(obj runtime.Object) (bool, error) + + // Empty returns true if the selector matches everything (no filtering). + Empty() bool + + // String returns the wire-format string representation that can be + // round-tripped through Parse. + String() string + + // Requirements returns the list of shard range requirements. + Requirements() []ShardRangeRequirement + + // DeepCopySelector returns a deep copy of the selector. + DeepCopySelector() Selector +} + +// Everything returns a selector that matches all objects. +func Everything() Selector { + return &everythingSelector{} +} + +type everythingSelector struct{} + +func (s *everythingSelector) Matches(_ runtime.Object) (bool, error) { return true, nil } +func (s *everythingSelector) Empty() bool { return true } +func (s *everythingSelector) String() string { return "" } +func (s *everythingSelector) Requirements() []ShardRangeRequirement { return nil } +func (s *everythingSelector) DeepCopySelector() Selector { return &everythingSelector{} } + +// shardSelector implements Selector with one or more shard range requirements. +type shardSelector struct { + requirements []ShardRangeRequirement +} + +func (s *shardSelector) Matches(obj runtime.Object) (bool, error) { + if len(s.requirements) == 0 { + return true, nil + } + // All requirements must share the same key so we resolve the field value + // and compute the hash once. The parser enforces this, but we verify here + // to guard against selectors constructed through other means. + key := s.requirements[0].Key + for _, req := range s.requirements[1:] { + if req.Key != key { + return false, fmt.Errorf("inconsistent shard keys: %q vs %q", key, req.Key) + } + } + + value, err := ResolveFieldValue(obj, key) + if err != nil { + return false, err + } + hash := "0x" + HashField(value) + + for _, req := range s.requirements { + if !HexLess(hash, req.Start) && HexLess(hash, req.End) { + return true, nil + } + } + return false, nil +} + +// HexLess compares two 0x-prefixed lowercase hex strings numerically. +// Both values must be normalized to 16 hex digits (e.g. "0x0000000000000000"), +// except for the special upper bound "0x10000000000000000" (2^64) which has 17. +func HexLess(a, b string) bool { + if len(a) != len(b) { + return len(a) < len(b) + } + return a < b +} + +func (s *shardSelector) Empty() bool { + return len(s.requirements) == 0 +} + +func (s *shardSelector) String() string { + parts := make([]string, 0, len(s.requirements)) + for _, req := range s.requirements { + parts = append(parts, fmt.Sprintf("shardRange(%s, '%s', '%s')", req.Key, req.Start, req.End)) + } + return strings.Join(parts, " || ") +} + +func (s *shardSelector) Requirements() []ShardRangeRequirement { + result := make([]ShardRangeRequirement, len(s.requirements)) + copy(result, s.requirements) + return result +} + +func (s *shardSelector) DeepCopySelector() Selector { + reqs := make([]ShardRangeRequirement, len(s.requirements)) + copy(reqs, s.requirements) + return &shardSelector{requirements: reqs} +} + +// NewSelector creates a Selector from the given requirements. +// All requirements must use the same Key; this is validated at match time. +// If no requirements are provided, returns Everything(). +func NewSelector(reqs ...ShardRangeRequirement) Selector { + if len(reqs) == 0 { + return Everything() + } + return &shardSelector{ + requirements: reqs, + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/sharding/types.go b/vendor/k8s.io/apimachinery/pkg/sharding/types.go new file mode 100644 index 0000000000..4684fc497f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/sharding/types.go @@ -0,0 +1,32 @@ +/* +Copyright 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 sharding + +// ShardRangeRequirement represents a single shard range requirement. +// It specifies a field path to hash and a hex range [Start, End) for filtering. +// The hash space is FNV-1a 64-bit: [0x0000000000000000, 0x10000000000000000). +// Both Start and End must be specified (no empty/unbounded values). +type ShardRangeRequirement struct { + // Key is the field path, e.g. "object.metadata.uid" + Key string + // Start is the inclusive lower bound as a 0x-prefixed lowercase hex string. + // Minimum value is "0x0000000000000000". + Start string + // End is the exclusive upper bound as a 0x-prefixed lowercase hex string. + // Maximum value is "0x10000000000000000" (2^64). + End string +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go index aed04524b6..7bfa6088bc 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go +++ b/vendor/k8s.io/apimachinery/pkg/util/diff/diff.go @@ -1,6 +1,3 @@ -//go:build !usegocmp -// +build !usegocmp - /* Copyright 2025 The Kubernetes Authors. @@ -25,7 +22,7 @@ import ( "github.com/pmezard/go-difflib/difflib" - "k8s.io/apimachinery/pkg/util/dump" + "k8s.io/utils/dump" ) // Diff returns a string representation of the difference between two objects. diff --git a/vendor/k8s.io/apimachinery/pkg/util/diff/legacy_diff.go b/vendor/k8s.io/apimachinery/pkg/util/diff/legacy_diff.go index 4d32d36adb..9f0dc2f6ad 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/diff/legacy_diff.go +++ b/vendor/k8s.io/apimachinery/pkg/util/diff/legacy_diff.go @@ -22,7 +22,7 @@ import ( "strings" "text/tabwriter" - "k8s.io/apimachinery/pkg/util/dump" + "k8s.io/utils/dump" ) // ObjectGoPrintSideBySide prints a and b as textual dumps side by side, diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go index 1da83f14b1..5fdc7955fa 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package httpstream adds multiplexed streaming support to HTTP requests and -// responses via connection upgrades. +// Package httpstream contains compatibility wrappers for streaming transport APIs. +// +// Deprecated: use k8s.io/streaming/pkg/httpstream directly. package httpstream diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/doc.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/doc.go similarity index 72% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/doc.go rename to vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/doc.go index df51baa4d4..d03acb0eed 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/doc.go +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2015 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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated typed clients. -package v1alpha1 +// Package spdy contains compatibility wrappers for the SPDY transport stack. +// +// Deprecated: use k8s.io/streaming/pkg/httpstream/spdy directly. +package spdy diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/spdy.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/spdy.go new file mode 100644 index 0000000000..37dfe81894 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/spdy.go @@ -0,0 +1,236 @@ +/* +Copyright 2015 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 spdy + +import ( + "crypto/tls" + "net" + "net/http" + "net/url" + "time" + + apihttpstream "k8s.io/apimachinery/pkg/util/httpstream" + streamhttp "k8s.io/streaming/pkg/httpstream" + streamspdy "k8s.io/streaming/pkg/httpstream/spdy" +) + +const HeaderSpdy31 = streamspdy.HeaderSpdy31 + +// SpdyRoundTripper is a compatibility wrapper around the streaming module's +// SPDY round tripper. +type SpdyRoundTripper struct { + delegate *streamspdy.SpdyRoundTripper +} + +func NewRoundTripper(tlsConfig *tls.Config) (*SpdyRoundTripper, error) { + delegate, err := streamspdy.NewRoundTripper(tlsConfig) + if err != nil { + return nil, err + } + return &SpdyRoundTripper{delegate: delegate}, nil +} + +func NewRoundTripperWithProxy(tlsConfig *tls.Config, proxier func(*http.Request) (*url.URL, error)) (*SpdyRoundTripper, error) { + delegate, err := streamspdy.NewRoundTripperWithProxy(tlsConfig, proxier) + if err != nil { + return nil, err + } + return &SpdyRoundTripper{delegate: delegate}, nil +} + +// RoundTripperConfig is a set of options for an SpdyRoundTripper. +type RoundTripperConfig struct { + // TLS configuration used by the round tripper if UpgradeTransport not present. + TLS *tls.Config + // Proxier is a proxy function invoked on each request. Optional. + Proxier func(*http.Request) (*url.URL, error) + // PingPeriod is a period for sending SPDY Pings on the connection. + // Optional. + PingPeriod time.Duration + // UpgradeTransport is a subtitute transport used for dialing. If set, + // this field will be used instead of "TLS" and "Proxier" for connection creation. + // Optional. + UpgradeTransport http.RoundTripper +} + +func NewRoundTripperWithConfig(cfg RoundTripperConfig) (*SpdyRoundTripper, error) { + delegate, err := streamspdy.NewRoundTripperWithConfig(streamspdy.RoundTripperConfig{ + TLS: cfg.TLS, + Proxier: cfg.Proxier, + PingPeriod: cfg.PingPeriod, + UpgradeTransport: cfg.UpgradeTransport, + }) + if err != nil { + return nil, err + } + return &SpdyRoundTripper{delegate: delegate}, nil +} + +// TLSClientConfig implements pkg/util/net.TLSClientConfigHolder for proper TLS checking during +// proxying with a spdy roundtripper. +func (s *SpdyRoundTripper) TLSClientConfig() *tls.Config { + return s.delegate.TLSClientConfig() +} + +// Dial opens a network connection for an upgrade request. +func (s *SpdyRoundTripper) Dial(req *http.Request) (net.Conn, error) { + return s.delegate.Dial(req) +} + +// RoundTrip executes a request and upgrades the connection. +func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return s.delegate.RoundTrip(req) +} + +// NewConnection validates a server upgrade response and prepares the transport. +func (s *SpdyRoundTripper) NewConnection(resp *http.Response) (apihttpstream.Connection, error) { + conn, err := s.delegate.NewConnection(resp) + if err != nil { + return nil, err + } + return wrapConnection(conn), nil +} + +type responseUpgraderAdapter struct { + delegate streamhttp.ResponseUpgrader +} + +func (r *responseUpgraderAdapter) UpgradeResponse(w http.ResponseWriter, req *http.Request, newStreamHandler apihttpstream.NewStreamHandler) apihttpstream.Connection { + conn := r.delegate.UpgradeResponse(w, req, wrapNewStreamHandler(newStreamHandler)) + return wrapConnection(conn) +} + +func NewResponseUpgrader() apihttpstream.ResponseUpgrader { + return &responseUpgraderAdapter{delegate: streamspdy.NewResponseUpgrader()} +} + +func NewResponseUpgraderWithPings(pingPeriod time.Duration) apihttpstream.ResponseUpgrader { + return &responseUpgraderAdapter{delegate: streamspdy.NewResponseUpgraderWithPings(pingPeriod)} +} + +func NewClientConnection(conn net.Conn) (apihttpstream.Connection, error) { + c, err := streamspdy.NewClientConnection(conn) + if err != nil { + return nil, err + } + return wrapConnection(c), nil +} + +func NewClientConnectionWithPings(conn net.Conn, pingPeriod time.Duration) (apihttpstream.Connection, error) { + c, err := streamspdy.NewClientConnectionWithPings(conn, pingPeriod) + if err != nil { + return nil, err + } + return wrapConnection(c), nil +} + +func NewServerConnection(conn net.Conn, newStreamHandler apihttpstream.NewStreamHandler) (apihttpstream.Connection, error) { + c, err := streamspdy.NewServerConnection(conn, wrapNewStreamHandler(newStreamHandler)) + if err != nil { + return nil, err + } + return wrapConnection(c), nil +} + +func NewServerConnectionWithPings(conn net.Conn, newStreamHandler apihttpstream.NewStreamHandler, pingPeriod time.Duration) (apihttpstream.Connection, error) { + c, err := streamspdy.NewServerConnectionWithPings(conn, wrapNewStreamHandler(newStreamHandler), pingPeriod) + if err != nil { + return nil, err + } + return wrapConnection(c), nil +} + +type streamAdapter struct { + delegate streamhttp.Stream +} + +func (s *streamAdapter) Read(p []byte) (int, error) { + return s.delegate.Read(p) +} + +func (s *streamAdapter) Write(p []byte) (int, error) { + return s.delegate.Write(p) +} + +func (s *streamAdapter) Close() error { + return s.delegate.Close() +} + +func (s *streamAdapter) Reset() error { + return s.delegate.Reset() +} + +func (s *streamAdapter) Headers() http.Header { + return s.delegate.Headers() +} + +func (s *streamAdapter) Identifier() uint32 { + return s.delegate.Identifier() +} + +type connectionAdapter struct { + delegate streamhttp.Connection +} + +func (c *connectionAdapter) CreateStream(headers http.Header) (apihttpstream.Stream, error) { + stream, err := c.delegate.CreateStream(headers) + if err != nil { + return nil, err + } + return &streamAdapter{delegate: stream}, nil +} + +func (c *connectionAdapter) Close() error { + return c.delegate.Close() +} + +func (c *connectionAdapter) CloseChan() <-chan bool { + return c.delegate.CloseChan() +} + +func (c *connectionAdapter) SetIdleTimeout(timeout time.Duration) { + c.delegate.SetIdleTimeout(timeout) +} + +func (c *connectionAdapter) RemoveStreams(streams ...apihttpstream.Stream) { + streamingStreams := make([]streamhttp.Stream, 0, len(streams)) + for _, stream := range streams { + if stream == nil { + continue + } + if s, ok := stream.(streamhttp.Stream); ok { + streamingStreams = append(streamingStreams, s) + } + } + c.delegate.RemoveStreams(streamingStreams...) +} + +func wrapConnection(conn streamhttp.Connection) apihttpstream.Connection { + if conn == nil { + return nil + } + return &connectionAdapter{delegate: conn} +} + +func wrapNewStreamHandler(newStreamHandler apihttpstream.NewStreamHandler) streamhttp.NewStreamHandler { + if newStreamHandler == nil { + return nil + } + return func(stream streamhttp.Stream, replySent <-chan struct{}) error { + return newStreamHandler(&streamAdapter{delegate: stream}, replySent) + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/doc.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/doc.go index a57e8df60a..9b07bfbb13 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/doc.go +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/doc.go @@ -14,56 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package wsstream contains utilities for streaming content over WebSockets. -// The Conn type allows callers to multiplex multiple read/write channels over -// a single websocket. +// Package wsstream contains compatibility wrappers for websocket streaming. // -// "channel.k8s.io" -// -// The Websocket RemoteCommand subprotocol "channel.k8s.io" prepends each binary message with a -// byte indicating the channel number (zero indexed) the message was sent on. Messages in both -// directions should prefix their messages with this channel byte. Used for remote execution, -// the channel numbers are by convention defined to match the POSIX file-descriptors assigned -// to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is performed on the raw -// subprotocol - writes are sent as they are received by the server. -// -// Example client session: -// -// CONNECT http://server.com with subprotocol "channel.k8s.io" -// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) -// READ []byte{1, 10} # receive "\n" on channel 1 (STDOUT) -// CLOSE -// -// "v2.channel.k8s.io" -// -// The second Websocket subprotocol version "v2.channel.k8s.io" is the same as version 1, -// but it is the first "versioned" subprotocol. -// -// "v3.channel.k8s.io" -// -// The third version of the Websocket RemoteCommand subprotocol adds another channel -// for terminal resizing events. This channel is prepended with the byte '3', and it -// transmits two window sizes (encoding TerminalSize struct) with integers in the range -// (0,65536]. -// -// "v4.channel.k8s.io" -// -// The fourth version of the Websocket RemoteCommand subprotocol adds a channel for -// errors. This channel returns structured errors containing process exit codes. The -// error is "apierrors.StatusError{}". -// -// "v5.channel.k8s.io" -// -// The fifth version of the Websocket RemoteCommand subprotocol adds a CLOSE signal, -// which is sent as the first byte of the message. The second byte is the channel -// id. This CLOSE signal is handled by the websocket server by closing the stream, -// allowing the other streams to complete transmission if necessary, and gracefully -// shutdown the connection. -// -// Example client session: -// -// CONNECT http://server.com with subprotocol "v5.channel.k8s.io" -// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) -// WRITE []byte{255, 0} # send CLOSE signal (STDIN) -// CLOSE +// Deprecated: use k8s.io/streaming/pkg/httpstream/wsstream directly. package wsstream diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/wsstream.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/wsstream.go new file mode 100644 index 0000000000..7384864f91 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/wsstream.go @@ -0,0 +1,91 @@ +/* +Copyright 2015 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 wsstream + +import ( + "io" + "net/http" + "time" + + "golang.org/x/net/websocket" + + "k8s.io/klog/v2" + streamws "k8s.io/streaming/pkg/httpstream/wsstream" +) + +const ( + WebSocketProtocolHeader = streamws.WebSocketProtocolHeader + ChannelWebSocketProtocol = streamws.ChannelWebSocketProtocol + Base64ChannelWebSocketProtocol = streamws.Base64ChannelWebSocketProtocol +) + +type ChannelType = streamws.ChannelType + +const ( + IgnoreChannel = streamws.IgnoreChannel + ReadChannel = streamws.ReadChannel + WriteChannel = streamws.WriteChannel + ReadWriteChannel = streamws.ReadWriteChannel +) + +func IsWebSocketRequest(req *http.Request) bool { + return streamws.IsWebSocketRequest(req) +} + +func IsWebSocketRequestWithStreamCloseProtocol(req *http.Request) bool { + return streamws.IsWebSocketRequestWithStreamCloseProtocol(req) +} + +func IsWebSocketRequestWithTunnelingProtocol(req *http.Request) bool { + return streamws.IsWebSocketRequestWithTunnelingProtocol(req) +} + +func IgnoreReceives(ws *websocket.Conn, timeout time.Duration) { + streamws.IgnoreReceives(ws, timeout) +} + +func IgnoreReceivesWithLogger(logger klog.Logger, ws *websocket.Conn, timeout time.Duration) { + streamws.IgnoreReceivesWithLogger(logger, ws, timeout) +} + +type ChannelProtocolConfig = streamws.ChannelProtocolConfig + +func NewDefaultChannelProtocols(channels []ChannelType) map[string]ChannelProtocolConfig { + return streamws.NewDefaultChannelProtocols(channels) +} + +type Conn = streamws.Conn + +func NewConn(protocols map[string]ChannelProtocolConfig) *Conn { + return streamws.NewConn(protocols) +} + +type ReaderProtocolConfig = streamws.ReaderProtocolConfig + +func NewDefaultReaderProtocols() map[string]ReaderProtocolConfig { + return streamws.NewDefaultReaderProtocols() +} + +type Reader = streamws.Reader + +func NewReader(r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { + return streamws.NewReader(r, ping, protocols) +} + +func NewReaderWithLogger(logger klog.Logger, r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { + return streamws.NewReaderWithLogger(logger, r, ping, protocols) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/instr_fuzz.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/instr_fuzz.go index 2d6f6a0ccc..494325c1f3 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/intstr/instr_fuzz.go +++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/instr_fuzz.go @@ -1,5 +1,4 @@ //go:build !notest -// +build !notest /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go index aef858b26d..ff7dda1a50 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/extract.go @@ -17,7 +17,6 @@ limitations under the License. package managedfields import ( - "bytes" "fmt" "sigs.k8s.io/structured-merge-diff/v6/fieldpath" @@ -65,7 +64,7 @@ func ExtractInto(object runtime.Object, objectType typed.ParseableType, fieldMan return nil } fieldset := &fieldpath.Set{} - err = fieldset.FromJSON(bytes.NewReader(fieldsEntry.FieldsV1.Raw)) + err = fieldset.FromJSON(fieldsEntry.FieldsV1.GetRawReader()) if err != nil { return fmt.Errorf("error marshalling FieldsV1 to JSON: %w", err) } diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go index 5c47b9c546..549412b41d 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go @@ -17,8 +17,6 @@ limitations under the License. package internal import ( - "bytes" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/structured-merge-diff/v6/fieldpath" @@ -36,12 +34,13 @@ var EmptyFields = func() metav1.FieldsV1 { // FieldsToSet creates a set paths from an input trie of fields func FieldsToSet(f metav1.FieldsV1) (s fieldpath.Set, err error) { - err = s.FromJSON(bytes.NewReader(f.Raw)) + err = s.FromJSON(f.GetRawReader()) return s, err } // SetToFields creates a trie of fields from an input set of paths func SetToFields(s fieldpath.Set) (f metav1.FieldsV1, err error) { - f.Raw, err = s.ToJSON() + raw, err := s.ToJSON() + f.SetRawBytes(raw) return f, err } diff --git a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go index 25626cf3af..46e3bb75dd 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go +++ b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go @@ -20,7 +20,7 @@ import ( "fmt" "reflect" - "k8s.io/apimachinery/pkg/util/dump" + "k8s.io/utils/dump" "sigs.k8s.io/yaml" ) diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/http.go b/vendor/k8s.io/apimachinery/pkg/util/net/http.go index 8cc1810af1..8912804c50 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/net/http.go +++ b/vendor/k8s.io/apimachinery/pkg/util/net/http.go @@ -132,9 +132,11 @@ func SetTransportDefaults(t *http.Transport) *http.Transport { t = SetOldTransportDefaults(t) // Allow clients to disable http2 if needed. if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 { + //nolint:logcheck // Should be rare, not worth converting. klog.Info("HTTP2 has been explicitly disabled") } else if allowsHTTP2(t) { if err := configureHTTP2Transport(t); err != nil { + //nolint:logcheck // Should be rare, not worth converting. klog.Warningf("Transport failed http2 configuration: %v", err) } } @@ -148,6 +150,7 @@ func readIdleTimeoutSeconds() int { if s := os.Getenv("HTTP2_READ_IDLE_TIMEOUT_SECONDS"); len(s) > 0 { i, err := strconv.Atoi(s) if err != nil { + //nolint:logcheck // Should be rare, not worth converting. klog.Warningf("Illegal HTTP2_READ_IDLE_TIMEOUT_SECONDS(%q): %v."+ " Default value %d is used", s, err, ret) return ret @@ -162,6 +165,7 @@ func pingTimeoutSeconds() int { if s := os.Getenv("HTTP2_PING_TIMEOUT_SECONDS"); len(s) > 0 { i, err := strconv.Atoi(s) if err != nil { + //nolint:logcheck // Should be rare, not worth converting. klog.Warningf("Illegal HTTP2_PING_TIMEOUT_SECONDS(%q): %v."+ " Default value %d is used", s, err, ret) return ret @@ -256,6 +260,7 @@ func CloseIdleConnectionsFor(transport http.RoundTripper) { case RoundTripperWrapper: CloseIdleConnectionsFor(transport.WrappedRoundTripper()) default: + //nolint:logcheck // Should be rare, not worth converting. klog.Warningf("unknown transport type: %T", transport) } } diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/interface.go b/vendor/k8s.io/apimachinery/pkg/util/net/interface.go index 01d028e727..3ccf227af0 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/net/interface.go +++ b/vendor/k8s.io/apimachinery/pkg/util/net/interface.go @@ -201,12 +201,12 @@ func parseIP(str string, family AddressFamily) (net.IP, error) { return net.IP(bytes), nil } -func isInterfaceUp(intf *net.Interface) bool { +func isInterfaceUp(logger klog.Logger, intf *net.Interface) bool { if intf == nil { return false } if intf.Flags&net.FlagUp != 0 { - klog.V(4).Infof("Interface %v is up", intf.Name) + logger.V(4).Info("Interface is up", "interface", intf.Name) return true } return false @@ -218,23 +218,23 @@ func isLoopbackOrPointToPoint(intf *net.Interface) bool { // getMatchingGlobalIP returns the first valid global unicast address of the given // 'family' from the list of 'addrs'. -func getMatchingGlobalIP(addrs []net.Addr, family AddressFamily) (net.IP, error) { +func getMatchingGlobalIP(logger klog.Logger, addrs []net.Addr, family AddressFamily) (net.IP, error) { if len(addrs) > 0 { for i := range addrs { - klog.V(4).Infof("Checking addr %s.", addrs[i].String()) + logger.V(4).Info("Checking for matching global IP", "address", addrs[i]) ip, _, err := netutils.ParseCIDRSloppy(addrs[i].String()) if err != nil { return nil, err } if memberOf(ip, family) { if ip.IsGlobalUnicast() { - klog.V(4).Infof("IP found %v", ip) + logger.V(4).Info("IP found", "IP", ip) return ip, nil } else { - klog.V(4).Infof("Non-global unicast address found %v", ip) + logger.V(4).Info("Non-global unicast address found", "IP", ip) } } else { - klog.V(4).Infof("%v is not an IPv%d address", ip, int(family)) + logger.V(4).Info("IP address has wrong version", "IP", ip, "IPVersion", int(family)) } } @@ -244,23 +244,23 @@ func getMatchingGlobalIP(addrs []net.Addr, family AddressFamily) (net.IP, error) // getIPFromInterface gets the IPs on an interface and returns a global unicast address, if any. The // interface must be up, the IP must in the family requested, and the IP must be a global unicast address. -func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) { +func getIPFromInterface(logger klog.Logger, intfName string, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) { intf, err := nw.InterfaceByName(intfName) if err != nil { return nil, err } - if isInterfaceUp(intf) { + if isInterfaceUp(logger, intf) { addrs, err := nw.Addrs(intf) if err != nil { return nil, err } - klog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs) - matchingIP, err := getMatchingGlobalIP(addrs, forFamily) + logger.V(4).Info("Found addresses for interface", "interface", intfName, "numAddresses", len(addrs), "addresses", addrs) + matchingIP, err := getMatchingGlobalIP(logger, addrs, forFamily) if err != nil { return nil, err } if matchingIP != nil { - klog.V(4).Infof("Found valid IPv%d address %v for interface %q.", int(forFamily), matchingIP, intfName) + logger.V(4).Info("Found valid address", "IPVersion", int(forFamily), "IP", matchingIP, "interface", intfName) return matchingIP, nil } } @@ -269,13 +269,13 @@ func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInte // getIPFromLoopbackInterface gets the IPs on a loopback interface and returns a global unicast address, if any. // The loopback interface must be up, the IP must in the family requested, and the IP must be a global unicast address. -func getIPFromLoopbackInterface(forFamily AddressFamily, nw networkInterfacer) (net.IP, error) { +func getIPFromLoopbackInterface(logger klog.Logger, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) { intfs, err := nw.Interfaces() if err != nil { return nil, err } for _, intf := range intfs { - if !isInterfaceUp(&intf) { + if !isInterfaceUp(logger, &intf) { continue } if intf.Flags&(net.FlagLoopback) != 0 { @@ -283,13 +283,13 @@ func getIPFromLoopbackInterface(forFamily AddressFamily, nw networkInterfacer) ( if err != nil { return nil, err } - klog.V(4).Infof("Interface %q has %d addresses :%v.", intf.Name, len(addrs), addrs) - matchingIP, err := getMatchingGlobalIP(addrs, forFamily) + logger.V(4).Info("Found addresses for interface", "interface", intf.Name, "numAddresses", len(addrs), "addresses", addrs) + matchingIP, err := getMatchingGlobalIP(logger, addrs, forFamily) if err != nil { return nil, err } if matchingIP != nil { - klog.V(4).Infof("Found valid IPv%d address %v for interface %q.", int(forFamily), matchingIP, intf.Name) + logger.V(4).Info("Found valid address", "IPVersion", int(forFamily), "IP", matchingIP, "interface", intf.Name) return matchingIP, nil } } @@ -309,7 +309,7 @@ func memberOf(ip net.IP, family AddressFamily) bool { // chooseIPFromHostInterfaces looks at all system interfaces, trying to find one that is up that // has a global unicast address (non-loopback, non-link local, non-point2point), and returns the IP. // addressFamilies determines whether it prefers IPv4 or IPv6 -func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFamilyPreference) (net.IP, error) { +func chooseIPFromHostInterfaces(logger klog.Logger, nw networkInterfacer, addressFamilies AddressFamilyPreference) (net.IP, error) { intfs, err := nw.Interfaces() if err != nil { return nil, err @@ -318,14 +318,14 @@ func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFam return nil, fmt.Errorf("no interfaces found on host.") } for _, family := range addressFamilies { - klog.V(4).Infof("Looking for system interface with a global IPv%d address", uint(family)) + logger.V(4).Info("Looking for system interface with a global address", "IPVersion", uint(family)) for _, intf := range intfs { - if !isInterfaceUp(&intf) { - klog.V(4).Infof("Skipping: down interface %q", intf.Name) + if !isInterfaceUp(logger, &intf) { + logger.V(4).Info("Skipping: interface is down", "interface", intf.Name) continue } if isLoopbackOrPointToPoint(&intf) { - klog.V(4).Infof("Skipping: LB or P2P interface %q", intf.Name) + logger.V(4).Info("Skipping: is LB or P2P", "interface", intf.Name) continue } addrs, err := nw.Addrs(&intf) @@ -333,7 +333,7 @@ func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFam return nil, err } if len(addrs) == 0 { - klog.V(4).Infof("Skipping: no addresses on interface %q", intf.Name) + logger.V(4).Info("Skipping: no addresses", "interface", intf.Name) continue } for _, addr := range addrs { @@ -342,15 +342,15 @@ func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFam return nil, fmt.Errorf("unable to parse CIDR for interface %q: %s", intf.Name, err) } if !memberOf(ip, family) { - klog.V(4).Infof("Skipping: no address family match for %q on interface %q.", ip, intf.Name) + logger.V(4).Info("Skipping: no address family match", "IP", ip, "interface", intf.Name) continue } // TODO: Decide if should open up to allow IPv6 LLAs in future. if !ip.IsGlobalUnicast() { - klog.V(4).Infof("Skipping: non-global address %q on interface %q.", ip, intf.Name) + logger.V(4).Info("Skipping: non-global address", "IP", ip, "interface", intf.Name) continue } - klog.V(4).Infof("Found global unicast address %q on interface %q.", ip, intf.Name) + logger.V(4).Info("Found global unicast address", "IP", ip, "interface", intf.Name) return ip, nil } } @@ -363,20 +363,31 @@ func chooseIPFromHostInterfaces(nw networkInterfacer, addressFamilies AddressFam // interfaces. Otherwise, it will use IPv4 and IPv6 route information to return the // IP of the interface with a gateway on it (with priority given to IPv4). For a node // with no internet connection, it returns error. +// +//logcheck:context // [ChooseHostInterfaceWithLogger] should be used instead of ChooseHostInterface in code which supports contextual logging. func ChooseHostInterface() (net.IP, error) { - return chooseHostInterface(preferIPv4) + return ChooseHostInterfaceWithLogger(klog.Background()) } -func chooseHostInterface(addressFamilies AddressFamilyPreference) (net.IP, error) { +// ChooseHostInterfaceWithLogger is a method used fetch an IP for a daemon. +// If there is no routing info file, it will choose a global IP from the system +// interfaces. Otherwise, it will use IPv4 and IPv6 route information to return the +// IP of the interface with a gateway on it (with priority given to IPv4). For a node +// with no internet connection, it returns error. +func ChooseHostInterfaceWithLogger(logger klog.Logger) (net.IP, error) { + return chooseHostInterface(logger, preferIPv4) +} + +func chooseHostInterface(logger klog.Logger, addressFamilies AddressFamilyPreference) (net.IP, error) { var nw networkInterfacer = networkInterface{} if _, err := os.Stat(ipv4RouteFile); os.IsNotExist(err) { - return chooseIPFromHostInterfaces(nw, addressFamilies) + return chooseIPFromHostInterfaces(logger, nw, addressFamilies) } routes, err := getAllDefaultRoutes() if err != nil { return nil, err } - return chooseHostInterfaceFromRoute(routes, nw, addressFamilies) + return chooseHostInterfaceFromRoute(logger, routes, nw, addressFamilies) } // networkInterfacer defines an interface for several net library functions. Production @@ -427,36 +438,36 @@ func getAllDefaultRoutes() ([]Route, error) { // global IP address from the interface for the route. If there are routes but no global // address is obtained from the interfaces, it checks if the loopback interface has a global address. // addressFamilies determines whether it prefers IPv4 or IPv6 -func chooseHostInterfaceFromRoute(routes []Route, nw networkInterfacer, addressFamilies AddressFamilyPreference) (net.IP, error) { +func chooseHostInterfaceFromRoute(logger klog.Logger, routes []Route, nw networkInterfacer, addressFamilies AddressFamilyPreference) (net.IP, error) { for _, family := range addressFamilies { - klog.V(4).Infof("Looking for default routes with IPv%d addresses", uint(family)) + logger.V(4).Info("Looking for default routes with IP addresses", "IPVersion", uint(family)) for _, route := range routes { if route.Family != family { continue } - klog.V(4).Infof("Default route transits interface %q", route.Interface) - finalIP, err := getIPFromInterface(route.Interface, family, nw) + logger.V(4).Info("Default route transits interface", "interface", route.Interface) + finalIP, err := getIPFromInterface(logger, route.Interface, family, nw) if err != nil { return nil, err } if finalIP != nil { - klog.V(4).Infof("Found active IP %v ", finalIP) + logger.V(4).Info("Found active IP", "IP", finalIP) return finalIP, nil } // In case of network setups where default routes are present, but network // interfaces use only link-local addresses (e.g. as described in RFC5549). // the global IP is assigned to the loopback interface, and we should use it - loopbackIP, err := getIPFromLoopbackInterface(family, nw) + loopbackIP, err := getIPFromLoopbackInterface(logger, family, nw) if err != nil { return nil, err } if loopbackIP != nil { - klog.V(4).Infof("Found active IP %v on Loopback interface", loopbackIP) + logger.V(4).Info("Found active IP on Loopback interface", "IP", loopbackIP) return loopbackIP, nil } } } - klog.V(4).Infof("No active IP found by looking at default routes") + logger.V(4).Info("No active IP found by looking at default routes") return nil, fmt.Errorf("unable to select an IP from default routes.") } @@ -465,14 +476,25 @@ func chooseHostInterfaceFromRoute(routes []Route, nw networkInterfacer, addressF // If bindAddress is unspecified or loopback, it returns the default IP of the same // address family as bindAddress. // Otherwise, it just returns bindAddress. +// +//logcheck:context // [ResolveBindAddressWithLogger] should be used instead of ResolveBindAddress in code which supports contextual logging. func ResolveBindAddress(bindAddress net.IP) (net.IP, error) { + return ResolveBindAddressWithLogger(klog.Background(), bindAddress) +} + +// ResolveBindAddressWithLogger returns the IP address of a daemon, based on the given bindAddress: +// If bindAddress is unset, it returns the host's default IP, as with ChooseHostInterface(). +// If bindAddress is unspecified or loopback, it returns the default IP of the same +// address family as bindAddress. +// Otherwise, it just returns bindAddress. +func ResolveBindAddressWithLogger(logger klog.Logger, bindAddress net.IP) (net.IP, error) { addressFamilies := preferIPv4 if bindAddress != nil && memberOf(bindAddress, familyIPv6) { addressFamilies = preferIPv6 } if bindAddress == nil || bindAddress.IsUnspecified() || bindAddress.IsLoopback() { - hostIP, err := chooseHostInterface(addressFamilies) + hostIP, err := chooseHostInterface(logger, addressFamilies) if err != nil { return nil, err } @@ -485,10 +507,20 @@ func ResolveBindAddress(bindAddress net.IP) (net.IP, error) { // This is required in case of network setups where default routes are present, but network // interfaces use only link-local addresses (e.g. as described in RFC5549). // e.g when using BGP to announce a host IP over link-local ip addresses and this ip address is attached to the lo interface. +// +//logcheck:context // [ChooseBindAddressForInterfaceWithLogger] should be used instead of ChooseBindAddressForInterface in code which supports contextual logging. func ChooseBindAddressForInterface(intfName string) (net.IP, error) { + return ChooseBindAddressForInterfaceWithLogger(klog.Background(), intfName) +} + +// ChooseBindAddressForInterfaceWithLogger choose a global IP for a specific interface, with priority given to IPv4. +// This is required in case of network setups where default routes are present, but network +// interfaces use only link-local addresses (e.g. as described in RFC5549). +// e.g when using BGP to announce a host IP over link-local ip addresses and this ip address is attached to the lo interface. +func ChooseBindAddressForInterfaceWithLogger(logger klog.Logger, intfName string) (net.IP, error) { var nw networkInterfacer = networkInterface{} for _, family := range preferIPv4 { - ip, err := getIPFromInterface(intfName, family, nw) + ip, err := getIPFromInterface(logger, intfName, family, nw) if err != nil { return nil, err } diff --git a/vendor/k8s.io/apimachinery/pkg/util/proxy/dial.go b/vendor/k8s.io/apimachinery/pkg/util/proxy/dial.go index e5196d1ee8..d6ba23d416 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/proxy/dial.go +++ b/vendor/k8s.io/apimachinery/pkg/util/proxy/dial.go @@ -39,7 +39,7 @@ func DialURL(ctx context.Context, url *url.URL, transport http.RoundTripper) (ne dialer, err := utilnet.DialerFor(transport) if err != nil { - klog.V(5).Infof("Unable to unwrap transport %T to get dialer: %v", transport, err) + klog.FromContext(ctx).V(5).Info("Unable to unwrap transport to get dialer", "type", fmt.Sprintf("%T", transport), "err", err) } switch url.Scheme { @@ -53,7 +53,7 @@ func DialURL(ctx context.Context, url *url.URL, transport http.RoundTripper) (ne // Get the tls config from the transport if we recognize it tlsConfig, err := utilnet.TLSClientConfig(transport) if err != nil { - klog.V(5).Infof("Unable to unwrap transport %T to get at TLS config: %v", transport, err) + klog.FromContext(ctx).V(5).Info("Unable to unwrap transport to get at TLS config", "type", fmt.Sprintf("%T", transport), "err", err) } if dialer != nil { @@ -65,7 +65,7 @@ func DialURL(ctx context.Context, url *url.URL, transport http.RoundTripper) (ne } if tlsConfig == nil { // tls.Client requires non-nil config - klog.Warning("using custom dialer with no TLSClientConfig. Defaulting to InsecureSkipVerify") + klog.FromContext(ctx).Info("Warning: using custom dialer with no TLSClientConfig, defaulting to InsecureSkipVerify") // tls.Handshake() requires ServerName or InsecureSkipVerify tlsConfig = &tls.Config{ InsecureSkipVerify: true, diff --git a/vendor/k8s.io/apimachinery/pkg/util/proxy/transport.go b/vendor/k8s.io/apimachinery/pkg/util/proxy/transport.go index 5a2dd6e14c..1c17f53df0 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/proxy/transport.go +++ b/vendor/k8s.io/apimachinery/pkg/util/proxy/transport.go @@ -249,7 +249,7 @@ func (t *Transport) rewriteResponse(req *http.Request, resp *http.Response) (*ht // This is fine default: // Some encoding we don't understand-- don't try to parse this - klog.Errorf("Proxy encountered encoding %v for text/html; can't understand this so not fixing links.", encoding) + klog.FromContext(req.Context()).Error(nil, "Proxy encountered unknown encoding for text/html, can't understand this so not fixing links", "encoding", encoding) return resp, nil } @@ -258,7 +258,7 @@ func (t *Transport) rewriteResponse(req *http.Request, resp *http.Response) (*ht } err := rewriteHTML(reader, writer, urlRewriter) if err != nil { - klog.Errorf("Failed to rewrite URLs: %v", err) + klog.FromContext(req.Context()).Error(err, "Failed to rewrite URLs") return resp, err } diff --git a/vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go b/vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go index 8c30a366de..56f6214834 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go +++ b/vendor/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go @@ -31,9 +31,9 @@ import ( "time" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/util/httpstream" utilnet "k8s.io/apimachinery/pkg/util/net" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/streaming/pkg/httpstream" "github.com/mxk/go-flowrate/flowrate" @@ -307,8 +307,9 @@ func (noSuppressPanicError) Write(p []byte) (n int, err error) { // tryUpgrade returns true if the request was handled. func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Request) bool { + logger := klog.FromContext(req.Context()) if !httpstream.IsUpgradeRequest(req) { - klog.V(6).Infof("Request was not an upgrade") + logger.V(6).Info("Request was not an upgrade") return false } @@ -332,15 +333,15 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // Only append X-Forwarded-For in the upgrade path, since httputil.NewSingleHostReverseProxy // handles this in the non-upgrade path. utilnet.AppendForwardedForHeader(clone) - klog.V(6).Infof("Connecting to backend proxy (direct dial) %s\n Headers: %v", &location, clone.Header) + logger.V(6).Info("Connecting to backend proxy (direct dial)", "location", &location, "headers", clone.Header) if h.UseLocationHost { clone.Host = h.Location.Host } clone.URL = &location - klog.V(6).Infof("UpgradeAwareProxy: dialing for SPDY upgrade with headers: %v", clone.Header) + logger.V(6).Info("UpgradeAwareProxy: dialing for SPDY upgrade with headers", "headers", clone.Header) backendConn, err = h.DialForUpgrade(clone) if err != nil { - klog.V(6).Infof("Proxy connection error: %v", err) + logger.V(6).Info("Proxy connection error", "err", err) h.Responder.Error(w, req, err) return true } @@ -349,7 +350,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // determine the http response code from the backend by reading from rawResponse+backendConn backendHTTPResponse, headerBytes, err := getResponse(io.MultiReader(bytes.NewReader(rawResponse), backendConn)) if err != nil { - klog.V(6).Infof("Proxy connection error: %v", err) + logger.V(6).Info("Proxy connection error", "err", err) h.Responder.Error(w, req, err) return true } @@ -363,7 +364,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // return a generic error here. if backendHTTPResponse.StatusCode != http.StatusSwitchingProtocols && backendHTTPResponse.StatusCode < 400 { err := fmt.Errorf("invalid upgrade response: status code %d", backendHTTPResponse.StatusCode) - klog.Errorf("Proxy upgrade error: %v", err) + logger.Error(err, "Proxy upgrade error") h.Responder.Error(w, req, err) return true } @@ -372,13 +373,13 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // hijacking should be the last step in the upgrade. requestHijacker, ok := w.(http.Hijacker) if !ok { - klog.Errorf("Unable to hijack response writer: %T", w) + logger.Error(nil, "Unable to hijack response writer", "type", fmt.Sprintf("%T", w)) h.Responder.Error(w, req, fmt.Errorf("request connection cannot be hijacked: %T", w)) return true } requestHijackedConn, _, err := requestHijacker.Hijack() if err != nil { - klog.Errorf("Unable to hijack response: %v", err) + logger.Error(err, "Unable to hijack response") h.Responder.Error(w, req, fmt.Errorf("error hijacking connection: %v", err)) return true } @@ -386,7 +387,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques if backendHTTPResponse.StatusCode != http.StatusSwitchingProtocols { // If the backend did not upgrade the request, echo the response from the backend to the client and return, closing the connection. - klog.V(6).Infof("Proxy upgrade error, status code %d", backendHTTPResponse.StatusCode) + logger.V(6).Info("Proxy upgrade error", "statusCode", backendHTTPResponse.StatusCode) // set read/write deadlines deadline := time.Now().Add(10 * time.Second) backendConn.SetReadDeadline(deadline) @@ -394,7 +395,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // write the response to the client err := backendHTTPResponse.Write(requestHijackedConn) if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { - klog.Errorf("Error proxying data from backend to client: %v", err) + logger.Error(err, "Error proxying data from backend to client") } // Indicate we handled the request return true @@ -402,9 +403,9 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques // Forward raw response bytes back to client. if len(rawResponse) > 0 { - klog.V(6).Infof("Writing %d bytes to hijacked connection", len(rawResponse)) + logger.V(6).Info("Writing to hijacked connection", "length", len(rawResponse)) if _, err = requestHijackedConn.Write(rawResponse); err != nil { - utilruntime.HandleError(fmt.Errorf("Error proxying response from backend to client: %v", err)) + utilruntime.HandleErrorWithLogger(logger, err, "Error proxying response from backend to client") } } @@ -424,7 +425,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques } _, err := io.Copy(writer, requestHijackedConn) if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { - klog.Errorf("Error proxying data from client to backend: %v", err) + logger.Error(err, "Error proxying data from client to backend") } close(writerComplete) }() @@ -438,7 +439,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques } _, err := io.Copy(requestHijackedConn, reader) if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { - klog.Errorf("Error proxying data from backend to client: %v", err) + logger.Error(err, "Error proxying data from backend to client") } close(readerComplete) }() @@ -449,7 +450,7 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques case <-writerComplete: case <-readerComplete: } - klog.V(6).Infof("Disconnecting from backend proxy %s\n Headers: %v", &location, clone.Header) + logger.V(6).Info("Disconnecting from backend proxy", "location", &location, "headers", clone.Header) return true } diff --git a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go index cc09bdbc43..38c1f7b03c 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go +++ b/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go @@ -17,14 +17,17 @@ limitations under the License. package runtime import ( + "bytes" "context" "fmt" "net/http" "runtime" + "strings" "sync" "time" "k8s.io/klog/v2" + "k8s.io/klog/v2/textlogger" ) var ( @@ -55,7 +58,6 @@ func HandleCrash(additionalHandlers ...func(interface{})) { if r := recover(); r != nil { additionalHandlersWithContext := make([]func(context.Context, interface{}), len(additionalHandlers)) for i, handler := range additionalHandlers { - handler := handler // capture loop variable additionalHandlersWithContext[i] = func(_ context.Context, r interface{}) { handler(r) } @@ -155,8 +157,37 @@ var ErrorHandlers = []ErrorHandler{ backoffError(1 * time.Millisecond), } +// ErrorHandler is called indirectly through [HandleError], [HandleErrorWithContext] or [HandleErrorWithLogger]. +// It is passed the same parameters that a structured logging backend needs to log a problem. +// It follows the semantic described for [HandleErrorWithContext] and [logr.Logger.Error]: +// - err is optional and may be nil +// - msg is string that describes the problem +// - keysAndValues contains additional information that varies between different occurrences of the problem +// +// [ErrorToString] can be used to convert these parameters into a single string, using the klog text output. type ErrorHandler func(ctx context.Context, err error, msg string, keysAndValues ...interface{}) +// ErrorToString takes the parameters passed to [ErrorHandler] and +// formats them as a string using the klog text output. +// +// If any of the values is a multi-line string, then the resulting +// string also uses line breaks and indention for the sake of readability. +// Does not include a trailing newline. +// +// Use errors.New if an error instead of a string is needed. +func ErrorToString(err error, msg string, keysAndValues ...interface{}) string { + var buffer bytes.Buffer + config := textlogger.NewConfig( + textlogger.Output(&buffer), + textlogger.WithHeader(false), + ) + logger := textlogger.NewLogger(config) + logger.Error(err, msg, keysAndValues...) + result := buffer.String() + result = strings.TrimSpace(result) + return result +} + // HandlerError is a method to invoke when a non-user facing piece of code cannot // return an error and needs to indicate it has been ignored. Invoking this method // is preferable to logging the error - the default behavior is to log but the diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go index 6825a808e6..71f6b5e875 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go @@ -1827,9 +1827,7 @@ func (ss SortableSliceOfMaps) Less(i, j int) bool { } func (ss SortableSliceOfMaps) Swap(i, j int) { - tmp := ss.s[i] - ss.s[i] = ss.s[j] - ss.s[j] = tmp + ss.s[i], ss.s[j] = ss.s[j], ss.s[i] } func deduplicateAndSortScalars(s []interface{}) []interface{} { @@ -1875,9 +1873,7 @@ func (ss SortableSliceOfScalars) Less(i, j int) bool { } func (ss SortableSliceOfScalars) Swap(i, j int) { - tmp := ss.s[i] - ss.s[i] = ss.s[j] - ss.s[j] = tmp + ss.s[i], ss.s[j] = ss.s[j], ss.s[i] } // Returns the type of the elements of N slice(s). If the type is different, diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go index f0264e50c7..1eeb71ff53 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go @@ -40,10 +40,12 @@ type ErrorMatcher struct { matchField bool // TODO(thockin): consider whether value could be assumed - if the // "want" error has a nil value, don't match on value. - matchValue bool - matchOrigin bool - matchDetail func(want, got string) bool - requireOriginWhenInvalid bool + matchValue bool + matchOrigin bool + matchDetail func(want, got string) bool + requireOriginWhenInvalid bool + matchValidationStabilityLevel bool + matchSource bool // normalizationRules holds the pre-compiled regex patterns for path normalization. normalizationRules []NormalizationRule } @@ -86,6 +88,14 @@ func (m ErrorMatcher) Matches(want, got *Error) bool { if m.matchDetail != nil && !m.matchDetail(want.Detail, got.Detail) { return false } + if m.matchValidationStabilityLevel && want.ValidationStabilityLevel != got.ValidationStabilityLevel { + return false + } + + if m.matchSource && want.FromImperative != got.FromImperative { + return false + } + return true } @@ -148,6 +158,14 @@ func (m ErrorMatcher) Render(e *Error) string { comma() buf.WriteString(fmt.Sprintf("Detail=%q", e.Detail)) } + if m.matchValidationStabilityLevel { + comma() + buf.WriteString(fmt.Sprintf("ValidationStabilityLevel=%s", e.ValidationStabilityLevel)) + } + if m.matchSource { + comma() + buf.WriteString(fmt.Sprintf("FromImperative=%t", e.FromImperative)) + } return "{" + buf.String() + "}" } @@ -224,6 +242,20 @@ func (m ErrorMatcher) RequireOriginWhenInvalid() ErrorMatcher { return m } +// BySource returns a derived ErrorMatcher which also matches by the error origination +// value of field errors. +func (m ErrorMatcher) BySource() ErrorMatcher { + m.matchSource = true + return m +} + +// ByValidationStabilityLevel returns a derived ErrorMatcher which also matches by the validation stability level +// value of field errors. +func (m ErrorMatcher) ByValidationStabilityLevel() ErrorMatcher { + m.matchValidationStabilityLevel = true + return m +} + // ByDetailExact returns a derived ErrorMatcher which also matches errors by // the exact detail string. func (m ErrorMatcher) ByDetailExact() ErrorMatcher { diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go index 950d838682..9357fb306c 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go @@ -42,7 +42,7 @@ type Error struct { // The value should be either: // - A simple camelCase identifier (e.g., "maximum", "maxItems") // - A structured format using "format=" for validation errors related to specific formats - // (e.g., "format=dns-label", "format=qualified-name") + // (e.g. "format=k8s-short-name") // // If the Origin corresponds to an existing declarative validation tag or JSON Schema keyword, // use that same name for consistency. @@ -55,10 +55,46 @@ type Error struct { // validation. This field is to identify errors from imperative validation // that should also be caught by declarative validation. CoveredByDeclarative bool + + // FromImperative denotes these errors are originating from the hand written validations. + FromImperative bool + + // ValidationStabilityLevel denotes the validation stability level of the declarative validation from this error is returned. This should be used in the declarative validations only. + ValidationStabilityLevel ValidationStabilityLevel +} + +// ValidationStabilityLevel denotes the stability level of a validation. +type ValidationStabilityLevel int + +const ( + stabilityLevelUnknown ValidationStabilityLevel = iota + stabilityLevelAlpha + stabilityLevelBeta +) + +func (v ValidationStabilityLevel) String() string { + switch v { + case stabilityLevelAlpha: + return "alpha" + case stabilityLevelBeta: + return "beta" + default: + return "unknown" + } } var _ error = &Error{} +// IsAlpha returns true if the error is an alpha validation error. +func (e *Error) IsAlpha() bool { + return e.ValidationStabilityLevel == stabilityLevelAlpha +} + +// IsBeta returns true if the error is a beta validation error. +func (e *Error) IsBeta() bool { + return e.ValidationStabilityLevel == stabilityLevelBeta +} + // Error implements the error interface. func (e *Error) Error() string { return fmt.Sprintf("%s: %s", e.Field, e.ErrorBody()) @@ -73,10 +109,10 @@ var omitValue = OmitValueType{} func (e *Error) ErrorBody() string { var s string switch e.Type { - case ErrorTypeRequired, ErrorTypeForbidden, ErrorTypeTooLong, ErrorTypeInternal: + case ErrorTypeRequired, ErrorTypeForbidden, ErrorTypeTooLong, ErrorTypeTooShort, ErrorTypeInternal: s = e.Type.String() case ErrorTypeInvalid, ErrorTypeTypeInvalid, ErrorTypeNotSupported, - ErrorTypeNotFound, ErrorTypeDuplicate, ErrorTypeTooMany: + ErrorTypeNotFound, ErrorTypeDuplicate, ErrorTypeTooMany, ErrorTypeTooFew: if e.BadValue == omitValue { s = e.Type.String() break @@ -113,6 +149,7 @@ func (e *Error) ErrorBody() string { if len(e.Detail) != 0 { s += fmt.Sprintf(": %s", e.Detail) } + return s } @@ -164,11 +201,18 @@ const ( // report that a given list has too many items. This is similar to FieldValueTooLong, // but the error indicates quantity instead of length. ErrorTypeTooMany ErrorType = "FieldValueTooMany" + // ErrorTypeTooFew is used to report "too few". This is used to + // report that a given list has too few items. This is similar to FieldValueTooLong, + // but the error indicates quantity instead of length. + ErrorTypeTooFew ErrorType = "FieldValueTooFew" // ErrorTypeInternal is used to report other errors that are not related // to user input. See InternalError(). ErrorTypeInternal ErrorType = "InternalError" // ErrorTypeTypeInvalid is for the value did not match the schema type for that field ErrorTypeTypeInvalid ErrorType = "FieldValueTypeInvalid" + // ErrorTypeTooShort is used to report that the given value is too short. + // This is similar to ErrorTypeInvalid. See TooShort(). + ErrorTypeTooShort ErrorType = "FieldValueTooShort" ) // String converts a ErrorType into its corresponding canonical error message. @@ -190,10 +234,14 @@ func (t ErrorType) String() string { return "Too long" case ErrorTypeTooMany: return "Too many" + case ErrorTypeTooFew: + return "Too few" case ErrorTypeInternal: return "Internal error" case ErrorTypeTypeInvalid: return "Invalid value" + case ErrorTypeTooShort: + return "Too short" default: return fmt.Sprintf("", string(t)) } @@ -201,32 +249,56 @@ func (t ErrorType) String() string { // TypeInvalid returns a *Error indicating "type is invalid" func TypeInvalid(field *Path, value interface{}, detail string) *Error { - return &Error{ErrorTypeTypeInvalid, field.String(), value, detail, "", false} + return &Error{ + Type: ErrorTypeTypeInvalid, + Field: field.String(), + BadValue: value, + Detail: detail, + } } // NotFound returns a *Error indicating "value not found". This is // used to report failure to find a requested value (e.g. looking up an ID). func NotFound(field *Path, value interface{}) *Error { - return &Error{ErrorTypeNotFound, field.String(), value, "", "", false} + return &Error{ + Type: ErrorTypeNotFound, + Field: field.String(), + BadValue: value, + } } // Required returns a *Error indicating "value required". This is used // to report required values that are not provided (e.g. empty strings, null // values, or empty arrays). func Required(field *Path, detail string) *Error { - return &Error{ErrorTypeRequired, field.String(), "", detail, "", false} + return &Error{ + Type: ErrorTypeRequired, + Field: field.String(), + Detail: detail, + BadValue: "", + } } // Duplicate returns a *Error indicating "duplicate value". This is // used to report collisions of values that must be unique (e.g. names or IDs). func Duplicate(field *Path, value interface{}) *Error { - return &Error{ErrorTypeDuplicate, field.String(), value, "", "", false} + return &Error{ + Type: ErrorTypeDuplicate, + Field: field.String(), + BadValue: value, + } } // Invalid returns a *Error indicating "invalid value". This is used // to report malformed values (e.g. failed regex match, too long, out of bounds). func Invalid(field *Path, value interface{}, detail string) *Error { - return &Error{ErrorTypeInvalid, field.String(), value, detail, "", false} + return &Error{ + Type: ErrorTypeInvalid, + Field: field.String(), + BadValue: value, + Detail: detail, + } + } // NotSupported returns a *Error indicating "unsupported value". @@ -241,7 +313,12 @@ func NotSupported[T ~string](field *Path, value interface{}, validValues []T) *E } detail = "supported values: " + strings.Join(quotedValues, ", ") } - return &Error{ErrorTypeNotSupported, field.String(), value, detail, "", false} + return &Error{ + Type: ErrorTypeNotSupported, + Field: field.String(), + BadValue: value, + Detail: detail, + } } // Forbidden returns a *Error indicating "forbidden". This is used to @@ -249,7 +326,12 @@ func NotSupported[T ~string](field *Path, value interface{}, validValues []T) *E // some conditions, but which are not permitted by current conditions (e.g. // security policy). func Forbidden(field *Path, detail string) *Error { - return &Error{ErrorTypeForbidden, field.String(), "", detail, "", false} + return &Error{ + Type: ErrorTypeForbidden, + Field: field.String(), + Detail: detail, + BadValue: "", + } } // TooLong returns a *Error indicating "too long". This is used to report that @@ -267,7 +349,35 @@ func TooLong(field *Path, _ interface{}, maxLength int) *Error { } else { msg = "value is too long" } - return &Error{ErrorTypeTooLong, field.String(), "", msg, "", false} + return &Error{ + Type: ErrorTypeTooLong, + Field: field.String(), + BadValue: "", + Detail: msg, + } +} + +// TooLongCharacters returns a *Error indicating "too long". This is used to report that +// the given value is too long in characters (including multi-byte characters). +// This is similar to Invalid, but the returned error will not include the too-long value. +// If maxLength is negative, it will be included in the message. The value argument is not used. +func TooLongCharacters[T ~string](field *Path, _ T, maxLength int) *Error { + var msg string + if maxLength >= 0 { + bs := "characters" + if maxLength == 1 { + bs = "character" + } + msg = fmt.Sprintf("may not be more than %d %s", maxLength, bs) + } else { + msg = "value is too long" + } + return &Error{ + Type: ErrorTypeTooLong, + Field: field.String(), + BadValue: "", + Detail: msg, + } } // TooLongMaxLength returns a *Error indicating "too long". @@ -299,14 +409,46 @@ func TooMany(field *Path, actualQuantity, maxQuantity int) *Error { actual = omitValue } - return &Error{ErrorTypeTooMany, field.String(), actual, msg, "", false} + return &Error{ + Type: ErrorTypeTooMany, + Field: field.String(), + BadValue: actual, + Detail: msg, + } } // InternalError returns a *Error indicating "internal error". This is used // to signal that an error was found that was not directly related to user // input. The err argument must be non-nil. func InternalError(field *Path, err error) *Error { - return &Error{ErrorTypeInternal, field.String(), nil, err.Error(), "", false} + return &Error{ + Type: ErrorTypeInternal, + Field: field.String(), + BadValue: err, + Detail: err.Error(), + } +} + +// TooShort returns a *Error indicating "too short". This is used to report that +// the given value is too short in characters. This is similar to Invalid. +// If minLength is non-negative, it will be included in the message. +func TooShort[T ~string](field *Path, value T, minLength int) *Error { + var msg string + if minLength >= 0 { + bs := "characters" + if minLength == 1 { + bs = "character" + } + msg = fmt.Sprintf("must be at least %d %s", minLength, bs) + } else { + msg = "value is too short" + } + return &Error{ + Type: ErrorTypeTooShort, + Field: field.String(), + BadValue: value, + Detail: msg, + } } // ErrorList holds a set of Errors. It is plausible that we might one day have @@ -397,6 +539,46 @@ func (list ErrorList) ExtractCoveredByDeclarative() ErrorList { return newList } +// MarkAlpha marks the error as an alpha validation error. +func (e *Error) MarkAlpha() *Error { + e.ValidationStabilityLevel = stabilityLevelAlpha + return e +} + +// MarkAlpha marks the errors as alpha validation errors. +func (list ErrorList) MarkAlpha() ErrorList { + for _, err := range list { + err.ValidationStabilityLevel = stabilityLevelAlpha + } + return list +} + +// MarkBeta marks the error as a beta validation error. +func (e *Error) MarkBeta() *Error { + e.ValidationStabilityLevel = stabilityLevelBeta + return e +} + +// MarkBeta marks the errors as beta validation errors. +func (list ErrorList) MarkBeta() ErrorList { + for _, err := range list { + err.ValidationStabilityLevel = stabilityLevelBeta + } + return list +} + +func (e *Error) MarkFromImperative() *Error { + e.FromImperative = true + return e +} + +func (list ErrorList) MarkFromImperative() ErrorList { + for _, err := range list { + err.FromImperative = true + } + return list +} + // RemoveCoveredByDeclarative returns a new ErrorList containing only the errors that should not be covered by declarative validation. func (list ErrorList) RemoveCoveredByDeclarative() ErrorList { newList := ErrorList{} @@ -407,3 +589,27 @@ func (list ErrorList) RemoveCoveredByDeclarative() ErrorList { } return newList } + +// TooFew returns a *Error indicating "too few". This is used to +// report that a given list has too few items. This is similar to TooLong, +// but the returned error indicates quantity instead of length. +func TooFew(field *Path, actualQuantity, minQuantity int) *Error { + var msg string + + if minQuantity >= 0 { + is := "items" + if minQuantity == 1 { + is = "item" + } + msg = fmt.Sprintf("must have at least %d %s", minQuantity, is) + } else { + msg = "has too few items" + } + + return &Error{ + Type: ErrorTypeTooFew, + Field: field.String(), + BadValue: actualQuantity, + Detail: msg, + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go b/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go index 6e947c74c9..869fb0aad0 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go @@ -115,7 +115,7 @@ func GetWarningsForIP(fldPath *field.Path, value string) []string { // ParseAddr() doesn't) or IPv4-mapped IPv6 (.Is4In6()). Either way, // re-stringifying the net.IP value will give the preferred form. return []string{ - fmt.Sprintf("%s: non-standard IP address %q will be considered invalid in a future Kubernetes release: use %q", fldPath, value, ip.String()), + fmt.Sprintf("%s: non-standard IP address %q is invalid: use %q", fldPath, value, ip.String()), } } @@ -233,7 +233,7 @@ func GetWarningsForCIDR(fldPath *field.Path, value string) []string { // ParsePrefix() doesn't) or IPv4-mapped IPv6 (.Is4In6()). Either way, // re-stringifying the net.IPNet value will give the preferred form. warnings = append(warnings, - fmt.Sprintf("%s: non-standard CIDR value %q will be considered invalid in a future Kubernetes release: use %q", fldPath, value, ipnet.String()), + fmt.Sprintf("%s: non-standard CIDR value %q is invalid: use %q", fldPath, value, ipnet.String()), ) } diff --git a/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go b/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go index 511e625b63..bb0fa55f21 100644 --- a/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go +++ b/vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go @@ -178,7 +178,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, } // Two lists that are both empty and both non nil are equal - if v1.Len() == 0 || v2.Len() == 0 { + if v1.Len() == 0 && v2.Len() == 0 { return true } } @@ -229,7 +229,7 @@ func (e Equalities) deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, } // Two maps that are both empty and both non nil are equal - if v1.Len() == 0 || v2.Len() == 0 { + if v1.Len() == 0 && v2.Len() == 0 { return true } } diff --git a/vendor/k8s.io/apiserver/pkg/admission/config.go b/vendor/k8s.io/apiserver/pkg/admission/config.go index 4bb5f27bfb..1e64af4474 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/config.go +++ b/vendor/k8s.io/apiserver/pkg/admission/config.go @@ -108,7 +108,7 @@ func ReadAdmissionConfiguration(pluginNames []string, configFilePath string, con // in order to preserve backwards compatibility, we set plugins that // previously read input from a non-versioned file configuration to the // current input file. - legacyPluginsWithUnversionedConfig := sets.NewString("ImagePolicyWebhook", "PodNodeSelector") + legacyPluginsWithUnversionedConfig := sets.New[string]("ImagePolicyWebhook", "PodNodeSelector") externalConfig := &apiserverv1.AdmissionConfiguration{} for _, pluginName := range pluginNames { if legacyPluginsWithUnversionedConfig.Has(pluginName) { diff --git a/vendor/k8s.io/apiserver/pkg/admission/handler.go b/vendor/k8s.io/apiserver/pkg/admission/handler.go index d2a9e7d4cf..e498b78f6b 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/handler.go +++ b/vendor/k8s.io/apiserver/pkg/admission/handler.go @@ -34,7 +34,7 @@ type ReadyFunc func() bool // Handler is a base for admission control handlers that // support a predefined set of operations type Handler struct { - operations sets.String + operations sets.Set[string] readyFunc ReadyFunc } @@ -46,7 +46,7 @@ func (h *Handler) Handles(operation Operation) bool { // NewHandler creates a new base handler that handles the passed // in operations func NewHandler(ops ...Operation) *Handler { - operations := sets.NewString() + operations := sets.New[string]() for _, op := range ops { operations.Insert(string(op)) } diff --git a/vendor/k8s.io/apiserver/pkg/admission/initializer/apiserver_id.go b/vendor/k8s.io/apiserver/pkg/admission/initializer/apiserver_id.go new file mode 100644 index 0000000000..b708d03ad8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/initializer/apiserver_id.go @@ -0,0 +1,43 @@ +/* +Copyright 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 initializer + +import "k8s.io/apiserver/pkg/admission" + +// apiServerIDInitializer injects the API server identity into admission plugins +// that implement WantsAPIServerID. This is used for metrics labeling in HA setups +// where multiple API servers may be running with different manifest configurations. +type apiServerIDInitializer struct { + apiServerID string +} + +var _ admission.PluginInitializer = &apiServerIDInitializer{} + +// NewAPIServerIDInitializer returns a PluginInitializer that injects the given +// API server ID into admission plugins that implement WantsAPIServerID. +// This initializer must be placed before the generic initializer in the chain +// so that the API server ID is available when SetExternalKubeInformerFactory is called. +func NewAPIServerIDInitializer(apiServerID string) admission.PluginInitializer { + return &apiServerIDInitializer{apiServerID: apiServerID} +} + +// Initialize checks whether the plugin implements WantsAPIServerID and injects the ID. +func (i *apiServerIDInitializer) Initialize(plugin admission.Interface) { + if wants, ok := plugin.(WantsAPIServerID); ok { + wants.SetAPIServerID(i.apiServerID) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go index a66d62dff0..cd3da1a619 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go +++ b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go @@ -17,6 +17,7 @@ limitations under the License. package initializer import ( + admissionregistrationv1api "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" @@ -104,3 +105,41 @@ type WantsExcludedAdmissionResources interface { SetExcludedAdmissionResources(excludedAdmissionResources []schema.GroupResource) admission.InitializationValidator } + +// WantsAPIServerID defines a function which sets the API server ID for admission plugins +// that need it (e.g., for metrics labeling in HA setups). +type WantsAPIServerID interface { + SetAPIServerID(apiServerID string) + admission.InitializationValidator +} + +// ValidatingWebhookManifestLoadFunc loads ValidatingWebhookConfiguration manifests from a directory. +type ValidatingWebhookManifestLoadFunc func(dir string) ([]*admissionregistrationv1api.ValidatingWebhookConfiguration, string, error) + +// MutatingWebhookManifestLoadFunc loads MutatingWebhookConfiguration manifests from a directory. +type MutatingWebhookManifestLoadFunc func(dir string) ([]*admissionregistrationv1api.MutatingWebhookConfiguration, string, error) + +// ValidatingPolicyManifestLoadFunc loads ValidatingAdmissionPolicy manifests from a directory. +type ValidatingPolicyManifestLoadFunc func(dir string) ([]*admissionregistrationv1api.ValidatingAdmissionPolicy, []*admissionregistrationv1api.ValidatingAdmissionPolicyBinding, string, error) + +// MutatingPolicyManifestLoadFunc loads MutatingAdmissionPolicy manifests from a directory. +type MutatingPolicyManifestLoadFunc func(dir string) ([]*admissionregistrationv1api.MutatingAdmissionPolicy, []*admissionregistrationv1api.MutatingAdmissionPolicyBinding, string, error) + +// ManifestLoaders provides functions to load admission configurations from static manifest files +// with scheme-based defaulting and validation. +type ManifestLoaders struct { + // LoadValidatingWebhookManifests loads ValidatingWebhookConfiguration manifests. + LoadValidatingWebhookManifests ValidatingWebhookManifestLoadFunc + // LoadMutatingWebhookManifests loads MutatingWebhookConfiguration manifests. + LoadMutatingWebhookManifests MutatingWebhookManifestLoadFunc + // LoadValidatingPolicyManifests loads ValidatingAdmissionPolicy manifests. + LoadValidatingPolicyManifests ValidatingPolicyManifestLoadFunc + // LoadMutatingPolicyManifests loads MutatingAdmissionPolicy manifests. + LoadMutatingPolicyManifests MutatingPolicyManifestLoadFunc +} + +// WantsManifestLoaders is implemented by admission plugins that load configurations +// from static manifest files and need scheme-based defaulting and validation. +type WantsManifestLoaders interface { + SetManifestLoaders(loaders *ManifestLoaders) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/composition.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/composition.go index bf8715a144..d7456d090b 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/composition.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/composition.go @@ -34,7 +34,7 @@ import ( "k8s.io/apiserver/pkg/cel/lazy" ) -const VariablesTypeName = "kubernetes.variables" +const variablesTypeName = "kubernetes.variables" // CompositedCompiler compiles expressions with variable composition. type CompositedCompiler struct { @@ -42,7 +42,7 @@ type CompositedCompiler struct { ConditionCompiler MutatingCompiler - CompositionEnv *CompositionEnv + state *compositionState } // CompositedConditionEvaluator provides evaluation of a condition expression with variable composition. @@ -50,7 +50,7 @@ type CompositedCompiler struct { type CompositedConditionEvaluator struct { ConditionEvaluator - compositionEnv *CompositionEnv + state *compositionState } // CompositedEvaluator provides evaluation of a single expression with variable composition. @@ -58,32 +58,78 @@ type CompositedConditionEvaluator struct { type CompositedEvaluator struct { MutatingEvaluator - compositionEnv *CompositionEnv + state *compositionState } func NewCompositedCompiler(envSet *environment.EnvSet) (*CompositedCompiler, error) { - compositionContext, err := NewCompositionEnv(VariablesTypeName, envSet) + newMapType := apiservercel.NewObjectType(variablesTypeName, map[string]*apiservercel.DeclField{}) + + newEnvSet, err := envSet.Extend(environment.VersionedOptions{ + IntroducedVersion: version.MajorMinor(1, 0), + EnvOptions: []cel.EnvOption{ + cel.Variable("variables", newMapType.CelType()), + }, + DeclTypes: []*apiservercel.DeclType{ + newMapType, + }, + }) if err != nil { return nil, err } - return NewCompositedCompilerFromTemplate(compositionContext), nil -} -func NewCompositedCompilerFromTemplate(context *CompositionEnv) *CompositedCompiler { - context = &CompositionEnv{ - MapType: context.MapType, - EnvSet: context.EnvSet, - CompiledVariables: map[string]CompilationResult{}, + state := &compositionState{ + mapType: newMapType, + EnvSet: newEnvSet, + compiledVariables: map[string]CompilationResult{}, } - compiler := NewCompiler(context.EnvSet) + + compiler := NewCompiler(state.EnvSet) conditionCompiler := &conditionCompiler{compiler} mutation := &mutatingCompiler{compiler} return &CompositedCompiler{ Compiler: compiler, ConditionCompiler: conditionCompiler, MutatingCompiler: mutation, - CompositionEnv: context, + state: state, + }, nil +} + +// NewCompositedCompilerForTypeChecking creates a CompositedCompiler for type checking. +// It initializes the composition state but leaves the Compilers nil, as they are expected +// to be replaced by the caller (who is doing type checking). +func NewCompositedCompilerForTypeChecking(envSet *environment.EnvSet) (*CompositedCompiler, error) { + newMapType := apiservercel.NewObjectType(variablesTypeName, map[string]*apiservercel.DeclField{}) + + newEnvSet, err := envSet.Extend(environment.VersionedOptions{ + IntroducedVersion: version.MajorMinor(1, 0), + EnvOptions: []cel.EnvOption{ + cel.Variable("variables", newMapType.CelType()), + }, + DeclTypes: []*apiservercel.DeclType{ + newMapType, + }, + }) + if err != nil { + return nil, err } + + state := &compositionState{ + mapType: newMapType, + EnvSet: newEnvSet, + compiledVariables: map[string]CompilationResult{}, + } + return &CompositedCompiler{ + state: state, + }, nil +} + +// Env returns the CEL environment for the given mode. +func (c *CompositedCompiler) Env(mode environment.Type) (*cel.Env, error) { + return c.state.Env(mode) +} + +func (c *CompositedCompiler) CreateContext(parent context.Context) CompositionContext { + return c.state.CreateContext(parent) } func (c *CompositedCompiler) CompileAndStoreVariables(variables []NamedExpressionAccessor, options OptionalVariableDeclarations, mode environment.Type) { @@ -94,8 +140,8 @@ func (c *CompositedCompiler) CompileAndStoreVariables(variables []NamedExpressio func (c *CompositedCompiler) CompileAndStoreVariable(variable NamedExpressionAccessor, options OptionalVariableDeclarations, mode environment.Type) CompilationResult { result := c.Compiler.CompileCELExpression(variable, options, mode) - c.CompositionEnv.AddField(variable.GetName(), result.OutputType) - c.CompositionEnv.CompiledVariables[variable.GetName()] = result + c.state.AddField(variable.GetName(), result.OutputType) + c.state.compiledVariables[variable.GetName()] = result return result } @@ -103,7 +149,7 @@ func (c *CompositedCompiler) CompileCondition(expressions []ExpressionAccessor, condition := c.ConditionCompiler.CompileCondition(expressions, optionalDecls, envType) return &CompositedConditionEvaluator{ ConditionEvaluator: condition, - compositionEnv: c.CompositionEnv, + state: c.state, } } @@ -112,47 +158,25 @@ func (c *CompositedCompiler) CompileMutatingEvaluator(expression ExpressionAcces mutation := c.MutatingCompiler.CompileMutatingEvaluator(expression, optionalDecls, envType) return &CompositedEvaluator{ MutatingEvaluator: mutation, - compositionEnv: c.CompositionEnv, + state: c.state, } } -type CompositionEnv struct { +type compositionState struct { *environment.EnvSet - MapType *apiservercel.DeclType - CompiledVariables map[string]CompilationResult -} - -func (c *CompositionEnv) AddField(name string, celType *cel.Type) { - c.MapType.Fields[name] = apiservercel.NewDeclField(name, convertCelTypeToDeclType(celType), true, nil, nil) + mapType *apiservercel.DeclType + compiledVariables map[string]CompilationResult } -func NewCompositionEnv(typeName string, baseEnvSet *environment.EnvSet) (*CompositionEnv, error) { - declType := apiservercel.NewObjectType(typeName, map[string]*apiservercel.DeclField{}) - envSet, err := baseEnvSet.Extend(environment.VersionedOptions{ - // set to 1.0 because composition is one of the fundamental components - IntroducedVersion: version.MajorMinor(1, 0), - EnvOptions: []cel.EnvOption{ - cel.Variable("variables", declType.CelType()), - }, - DeclTypes: []*apiservercel.DeclType{ - declType, - }, - }) - if err != nil { - return nil, err - } - return &CompositionEnv{ - MapType: declType, - EnvSet: envSet, - CompiledVariables: map[string]CompilationResult{}, - }, nil +func (c *compositionState) AddField(name string, celType *cel.Type) { + c.mapType.Fields[name] = apiservercel.NewDeclField(name, convertCelTypeToDeclType(celType), true, nil, nil) } -func (c *CompositionEnv) CreateContext(parent context.Context) CompositionContext { +func (c *compositionState) CreateContext(parent context.Context) CompositionContext { return &compositionContext{ - Context: parent, - compositionEnv: c, + Context: parent, + state: c, } } @@ -165,13 +189,13 @@ type CompositionContext interface { type compositionContext struct { context.Context - compositionEnv *CompositionEnv + state *compositionState accumulatedCost int64 } func (c *compositionContext) Variables(activation any) ref.Val { - lazyMap := lazy.NewMapValue(c.compositionEnv.MapType) - for name, result := range c.compositionEnv.CompiledVariables { + lazyMap := lazy.NewMapValue(c.state.mapType) + for name, result := range c.state.compiledVariables { accessor := &variableAccessor{ name: name, result: result, @@ -184,7 +208,7 @@ func (c *compositionContext) Variables(activation any) ref.Val { } func (f *CompositedConditionEvaluator) ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *v1.AdmissionRequest, optionalVars OptionalVariableBindings, namespace *corev1.Namespace, runtimeCELCostBudget int64) ([]EvaluationResult, int64, error) { - ctx = f.compositionEnv.CreateContext(ctx) + ctx = f.state.CreateContext(ctx) return f.ConditionEvaluator.ForInput(ctx, versionedAttr, request, optionalVars, namespace, runtimeCELCostBudget) } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/loader.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/loader.go new file mode 100644 index 0000000000..bb160fc10b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/loader.go @@ -0,0 +1,120 @@ +/* +Copyright 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 manifest provides shared utilities for loading admission configurations +// from static manifest files. +package manifest + +import ( + "bufio" + "bytes" + "crypto/sha256" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + utilyaml "k8s.io/apimachinery/pkg/util/yaml" +) + +// splitYAMLDocuments splits a multi-document YAML byte slice into individual documents. +// Empty documents are skipped. +func splitYAMLDocuments(data []byte) ([][]byte, error) { + reader := utilyaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(data))) + var docs [][]byte + for { + doc, err := reader.Read() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + return nil, err + } + doc = bytes.TrimSpace(doc) + if len(doc) == 0 { + continue + } + docs = append(docs, doc) + } + return docs, nil +} + +// FileDoc holds a decoded YAML document and the file it came from. +type FileDoc struct { + FilePath string + Doc []byte +} + +// LoadFiles reads all YAML/JSON files from dir, splits multi-document YAML, +// and returns individual documents with their source file paths plus a +// sha256-prefixed hash of the file contents for change detection. +// Files are processed in alphabetical order for deterministic behavior. +func LoadFiles(dir string) ([]FileDoc, string, error) { + if len(dir) == 0 { + return nil, "", fmt.Errorf("manifest directory path is empty") + } + + // os.ReadDir returns entries sorted by filename. + entries, err := os.ReadDir(dir) + if err != nil { + return nil, "", fmt.Errorf("failed to read manifest directory %q: %w", dir, err) + } + + var fileDocs []FileDoc + h := sha256.New() + hasData := false + + for _, entry := range entries { + if entry.IsDir() { + continue + } + name := entry.Name() + ext := strings.ToLower(filepath.Ext(name)) + if ext != ".yaml" && ext != ".yml" && ext != ".json" { + continue + } + + filePath := filepath.Join(dir, name) + data, err := os.ReadFile(filePath) + if err != nil { + return nil, "", fmt.Errorf("failed to read file %q: %w", filePath, err) + } + if len(data) == 0 { + continue + } + + h.Write(data) + h.Write([]byte{0}) + hasData = true + + docs, err := splitYAMLDocuments(data) + if err != nil { + return nil, "", fmt.Errorf("failed to split YAML documents in file %q: %w", filePath, err) + } + for _, doc := range docs { + fileDocs = append(fileDocs, FileDoc{FilePath: filePath, Doc: doc}) + } + } + + var hash string + if hasData { + hash = fmt.Sprintf("sha256:%x", h.Sum(nil)) + } + + return fileDocs, hash, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/metrics/metrics.go new file mode 100644 index 0000000000..efdf2fe21e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/metrics/metrics.go @@ -0,0 +1,161 @@ +/* +Copyright 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 metrics provides metrics for manifest-based admission configuration. +package metrics + +import ( + "crypto/sha256" + "fmt" + "sync" + + "k8s.io/apiserver/pkg/util/configmetrics" + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + namespace = "apiserver" + subsystem = "manifest_admission_config_controller" +) + +var ( + admissionManifestAutomaticReloadsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "automatic_reloads_total", + Help: "Total number of automatic reloads of admission manifest configuration split by status, plugin, and apiserver identity.", + StabilityLevel: metrics.ALPHA, + }, + []string{"status", "plugin", "apiserver_id_hash"}, + ) + + admissionManifestAutomaticReloadLastTimestampSeconds = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "automatic_reload_last_timestamp_seconds", + Help: "Timestamp of the last automatic reload of admission manifest configuration split by status, plugin, and apiserver identity.", + StabilityLevel: metrics.ALPHA, + }, + []string{"status", "plugin", "apiserver_id_hash"}, + ) + + admissionManifestLastConfigInfo = metrics.NewDesc( + metrics.BuildFQName(namespace, subsystem, "last_config_info"), + "Information about the last applied admission manifest configuration with hash as label, split by plugin and apiserver identity.", + []string{"plugin", "apiserver_id_hash", "hash"}, + nil, + metrics.ALPHA, + "", + ) +) + +// ManifestType represents the admission plugin name for which manifests are being tracked. +type ManifestType string + +const ( + // ValidatingWebhookManifestType represents validating webhook configurations. + ValidatingWebhookManifestType ManifestType = "ValidatingAdmissionWebhook" + // MutatingWebhookManifestType represents mutating webhook configurations. + MutatingWebhookManifestType ManifestType = "MutatingAdmissionWebhook" + // VAPManifestType represents validating admission policy configurations. + VAPManifestType ManifestType = "ValidatingAdmissionPolicy" + // MAPManifestType represents mutating admission policy configurations. + MAPManifestType ManifestType = "MutatingAdmissionPolicy" +) + +var registerMetrics sync.Once + +// configHashProviders stores providers per plugin for config info metrics. +// Each plugin has its own provider that stores [apiserver_id_hash, config_hash]. +var configHashProviders = map[ManifestType]*configmetrics.AtomicHashProvider{ + ValidatingWebhookManifestType: configmetrics.NewAtomicHashProvider(), + MutatingWebhookManifestType: configmetrics.NewAtomicHashProvider(), + VAPManifestType: configmetrics.NewAtomicHashProvider(), + MAPManifestType: configmetrics.NewAtomicHashProvider(), +} + +// multiTypeConfigInfoCollector emits config info metrics for multiple manifest types. +type multiTypeConfigInfoCollector struct { + metrics.BaseStableCollector + desc *metrics.Desc +} + +var _ metrics.StableCollector = &multiTypeConfigInfoCollector{} + +func (c *multiTypeConfigInfoCollector) DescribeWithStability(ch chan<- *metrics.Desc) { + ch <- c.desc +} + +func (c *multiTypeConfigInfoCollector) CollectWithStability(ch chan<- metrics.Metric) { + // Emit a metric for each plugin that has data + for manifestType, provider := range configHashProviders { + hashes := provider.GetCurrentHashes() + if len(hashes) >= 2 && len(hashes[0]) > 0 { + // hashes contains [apiserver_id_hash, config_hash] + // Prepend the plugin to match label order: ["plugin", "apiserver_id_hash", "hash"] + labelValues := append([]string{string(manifestType)}, hashes...) + ch <- metrics.NewLazyConstMetric(c.desc, metrics.GaugeValue, 1, labelValues...) + } + } +} + +func RegisterMetrics() { + registerMetrics.Do(func() { + legacyregistry.MustRegister(admissionManifestAutomaticReloadsTotal) + legacyregistry.MustRegister(admissionManifestAutomaticReloadLastTimestampSeconds) + // Use a custom collector that emits metrics for all manifest types + legacyregistry.CustomMustRegister(&multiTypeConfigInfoCollector{desc: admissionManifestLastConfigInfo}) + }) +} + +func ResetMetricsForTest() { + admissionManifestAutomaticReloadsTotal.Reset() + admissionManifestAutomaticReloadLastTimestampSeconds.Reset() +} + +// RecordAutomaticReloadFailure records a failed reload attempt for the given manifest type. +func RecordAutomaticReloadFailure(manifestType ManifestType, apiServerID string) { + apiServerIDHash := getHash(apiServerID) + admissionManifestAutomaticReloadsTotal.WithLabelValues("failure", string(manifestType), apiServerIDHash).Inc() + admissionManifestAutomaticReloadLastTimestampSeconds.WithLabelValues("failure", string(manifestType), apiServerIDHash).SetToCurrentTime() +} + +// RecordAutomaticReloadSuccess records a successful reload for the given manifest type. +func RecordAutomaticReloadSuccess(manifestType ManifestType, apiServerID, configHash string) { + apiServerIDHash := getHash(apiServerID) + admissionManifestAutomaticReloadsTotal.WithLabelValues("success", string(manifestType), apiServerIDHash).Inc() + admissionManifestAutomaticReloadLastTimestampSeconds.WithLabelValues("success", string(manifestType), apiServerIDHash).SetToCurrentTime() + + RecordLastConfigInfo(manifestType, apiServerID, configHash) +} + +// RecordLastConfigInfo records the hash of the last successfully loaded configuration. +func RecordLastConfigInfo(manifestType ManifestType, apiServerID, configHash string) { + if provider, ok := configHashProviders[manifestType]; ok { + // Store [apiserver_id_hash, config_hash] - the multiTypeConfigInfoCollector prepends the type + provider.SetHashes(getHash(apiServerID), configHash) + } +} + +func getHash(data string) string { + if len(data) == 0 { + return "" + } + return fmt.Sprintf("sha256:%x", sha256.Sum256([]byte(data))) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/validation.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/validation.go new file mode 100644 index 0000000000..9effc544f1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/manifest/validation.go @@ -0,0 +1,74 @@ +/* +Copyright 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 manifest provides shared utilities for loading admission configurations +// from static manifest files. +package manifest + +import ( + "fmt" + "os" + "path" + "strings" + + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" +) + +// StaticConfigSuffix is the reserved suffix for manifest-based admission configurations. +// Resources with names ending in this suffix can only be created via static manifest +// files loaded at API server startup, not through the REST API. +// NOTE: This constant is duplicated in pkg/apis/admissionregistration/validation/static_suffix.go +// because that package cannot import from staging. Keep both in sync. +const StaticConfigSuffix = ".static.k8s.io" + +// ValidateStaticManifestsDir validates the staticManifestsDir config field. +// It checks the feature gate is enabled, the path is absolute, exists, and is a directory. +func ValidateStaticManifestsDir(staticManifestsDir string) error { + if len(staticManifestsDir) > 0 { + if !utilfeature.DefaultFeatureGate.Enabled(features.ManifestBasedAdmissionControlConfig) { + return field.Forbidden(field.NewPath("staticManifestsDir"), "staticManifestsDir requires the ManifestBasedAdmissionControlConfig feature gate to be enabled") + } + if !path.IsAbs(staticManifestsDir) { + return field.Invalid(field.NewPath("staticManifestsDir"), staticManifestsDir, "must be an absolute file path") + } + info, err := os.Stat(staticManifestsDir) + if err != nil { + return field.Invalid(field.NewPath("staticManifestsDir"), staticManifestsDir, fmt.Sprintf("unable to read: %v", err)) + } + if !info.IsDir() { + return field.Invalid(field.NewPath("staticManifestsDir"), staticManifestsDir, "must be a directory") + } + } + return nil +} + +// ValidateManifestName checks that the object name is non-empty, has the required +// .static.k8s.io suffix, and is unique within the manifest set. +func ValidateManifestName(name, filePath string, seenNames map[string]string) error { + if len(name) == 0 { + return fmt.Errorf("resource in file %q must have a name", filePath) + } + if !strings.HasSuffix(name, StaticConfigSuffix) { + return fmt.Errorf("%q in file %q must have a name ending with %q", name, filePath, StaticConfigSuffix) + } + if prevFile, ok := seenNames[name]; ok { + return fmt.Errorf("duplicate name %q found in file %q (previously seen in %q)", name, filePath, prevFile) + } + seenNames[name] = filePath + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission.go index cec6769c65..19958c1137 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission.go @@ -54,7 +54,7 @@ const ( // Register registers a plugin func Register(plugins *admission.Plugins) { plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { - return NewLifecycle(sets.NewString(metav1.NamespaceDefault, metav1.NamespaceSystem, metav1.NamespacePublic, + return NewLifecycle(sets.New[string](metav1.NamespaceDefault, metav1.NamespaceSystem, metav1.NamespacePublic, // user specified configuration that cannot be rebuilt "openshift-config", // cluster generated configuration that cannot be rebuilt (etcd encryption keys) @@ -72,7 +72,7 @@ func Register(plugins *admission.Plugins) { type Lifecycle struct { *admission.Handler client kubernetes.Interface - immortalNamespaces sets.String + immortalNamespaces sets.Set[string] namespaceLister corelisters.NamespaceLister // forceLiveLookupCache holds a list of entries for namespaces that we have a strong reason to believe are stale in our local cache. // if a namespace is in this cache, then we will ignore our local state and always fetch latest from api server. @@ -195,11 +195,11 @@ func (l *Lifecycle) Admit(ctx context.Context, a admission.Attributes, o admissi } // NewLifecycle creates a new namespace Lifecycle admission control handler -func NewLifecycle(immortalNamespaces sets.String) (*Lifecycle, error) { +func NewLifecycle(immortalNamespaces sets.Set[string]) (*Lifecycle, error) { return newLifecycleWithClock(immortalNamespaces, clock.RealClock{}) } -func newLifecycleWithClock(immortalNamespaces sets.String, clock utilcache.Clock) (*Lifecycle, error) { +func newLifecycleWithClock(immortalNamespaces sets.Set[string], clock utilcache.Clock) (*Lifecycle, error) { forceLiveLookupCache := utilcache.NewLRUExpireCacheWithClock(100, clock) return &Lifecycle{ Handler: admission.NewHandler(admission.Create, admission.Update, admission.Delete), diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/doc.go new file mode 100644 index 0000000000..03728eda4e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// +k8s:deepcopy-gen=package + +// Package policyconfig defines the configuration for the validating and mutating admission policy plugins. +package policyconfig // import "k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig" diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/register.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/register.go similarity index 69% rename from vendor/k8s.io/api/autoscaling/v2beta2/register.go rename to vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/register.go index eb1265c168..11976152cd 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/register.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 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. @@ -14,37 +14,38 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v2beta2 +package policyconfig import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" ) +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + // GroupName is the group name use in this package -const GroupName = "autoscaling" +const GroupName = "apiserver.config.k8s.io" // SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2beta2"} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} // Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } -var ( - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme -) - -// Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &HorizontalPodAutoscaler{}, - &HorizontalPodAutoscalerList{}, + &ValidatingAdmissionPolicyConfiguration{}, + &MutatingAdmissionPolicyConfiguration{}, ) - metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/types.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/types.go new file mode 100644 index 0000000000..9af5101222 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/types.go @@ -0,0 +1,63 @@ +/* +Copyright 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 policyconfig + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ValidatingAdmissionPolicyConfiguration provides configuration for the validating admission policy controller. +type ValidatingAdmissionPolicyConfiguration struct { + metav1.TypeMeta + + // StaticManifestsDir is the path to a directory containing static + // ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding + // resources to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string +} + +// GetStaticManifestsDir returns the static manifests directory path. +func (c *ValidatingAdmissionPolicyConfiguration) GetStaticManifestsDir() string { + return c.StaticManifestsDir +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MutatingAdmissionPolicyConfiguration provides configuration for the mutating admission policy controller. +type MutatingAdmissionPolicyConfiguration struct { + metav1.TypeMeta + + // StaticManifestsDir is the path to a directory containing static + // MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding + // resources to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string +} + +// GetStaticManifestsDir returns the static manifests directory path. +func (c *MutatingAdmissionPolicyConfiguration) GetStaticManifestsDir() string { + return c.StaticManifestsDir +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/doc.go new file mode 100644 index 0000000000..52837293d5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig + +// Package v1 is the v1 version of the API. +package v1 // import "k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1" diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/register.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/register.go similarity index 91% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/register.go rename to vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/register.go index 56489f7804..f9b3d1176b 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/register.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/register.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +Copyright 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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1 import ( "k8s.io/apimachinery/pkg/runtime" @@ -25,7 +25,7 @@ import ( const GroupName = "apiserver.config.k8s.io" // SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. @@ -44,7 +44,8 @@ func init() { func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &WebhookAdmission{}, + &ValidatingAdmissionPolicyConfiguration{}, + &MutatingAdmissionPolicyConfiguration{}, ) return nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/types.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/types.go new file mode 100644 index 0000000000..967b6ca3f9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/types.go @@ -0,0 +1,53 @@ +/* +Copyright 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 v1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ValidatingAdmissionPolicyConfiguration provides configuration for the validating admission policy controller. +type ValidatingAdmissionPolicyConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // StaticManifestsDir is the path to a directory containing static + // ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding + // resources to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string `json:"staticManifestsDir,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MutatingAdmissionPolicyConfiguration provides configuration for the mutating admission policy controller. +type MutatingAdmissionPolicyConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // StaticManifestsDir is the path to a directory containing static + // MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding + // resources to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string `json:"staticManifestsDir,omitempty"` +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.conversion.go new file mode 100644 index 0000000000..e65c4e52f1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.conversion.go @@ -0,0 +1,98 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + policyconfig "k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*MutatingAdmissionPolicyConfiguration)(nil), (*policyconfig.MutatingAdmissionPolicyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_MutatingAdmissionPolicyConfiguration_To_policyconfig_MutatingAdmissionPolicyConfiguration(a.(*MutatingAdmissionPolicyConfiguration), b.(*policyconfig.MutatingAdmissionPolicyConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*policyconfig.MutatingAdmissionPolicyConfiguration)(nil), (*MutatingAdmissionPolicyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_policyconfig_MutatingAdmissionPolicyConfiguration_To_v1_MutatingAdmissionPolicyConfiguration(a.(*policyconfig.MutatingAdmissionPolicyConfiguration), b.(*MutatingAdmissionPolicyConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ValidatingAdmissionPolicyConfiguration)(nil), (*policyconfig.ValidatingAdmissionPolicyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ValidatingAdmissionPolicyConfiguration_To_policyconfig_ValidatingAdmissionPolicyConfiguration(a.(*ValidatingAdmissionPolicyConfiguration), b.(*policyconfig.ValidatingAdmissionPolicyConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*policyconfig.ValidatingAdmissionPolicyConfiguration)(nil), (*ValidatingAdmissionPolicyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_policyconfig_ValidatingAdmissionPolicyConfiguration_To_v1_ValidatingAdmissionPolicyConfiguration(a.(*policyconfig.ValidatingAdmissionPolicyConfiguration), b.(*ValidatingAdmissionPolicyConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1_MutatingAdmissionPolicyConfiguration_To_policyconfig_MutatingAdmissionPolicyConfiguration(in *MutatingAdmissionPolicyConfiguration, out *policyconfig.MutatingAdmissionPolicyConfiguration, s conversion.Scope) error { + out.StaticManifestsDir = in.StaticManifestsDir + return nil +} + +// Convert_v1_MutatingAdmissionPolicyConfiguration_To_policyconfig_MutatingAdmissionPolicyConfiguration is an autogenerated conversion function. +func Convert_v1_MutatingAdmissionPolicyConfiguration_To_policyconfig_MutatingAdmissionPolicyConfiguration(in *MutatingAdmissionPolicyConfiguration, out *policyconfig.MutatingAdmissionPolicyConfiguration, s conversion.Scope) error { + return autoConvert_v1_MutatingAdmissionPolicyConfiguration_To_policyconfig_MutatingAdmissionPolicyConfiguration(in, out, s) +} + +func autoConvert_policyconfig_MutatingAdmissionPolicyConfiguration_To_v1_MutatingAdmissionPolicyConfiguration(in *policyconfig.MutatingAdmissionPolicyConfiguration, out *MutatingAdmissionPolicyConfiguration, s conversion.Scope) error { + out.StaticManifestsDir = in.StaticManifestsDir + return nil +} + +// Convert_policyconfig_MutatingAdmissionPolicyConfiguration_To_v1_MutatingAdmissionPolicyConfiguration is an autogenerated conversion function. +func Convert_policyconfig_MutatingAdmissionPolicyConfiguration_To_v1_MutatingAdmissionPolicyConfiguration(in *policyconfig.MutatingAdmissionPolicyConfiguration, out *MutatingAdmissionPolicyConfiguration, s conversion.Scope) error { + return autoConvert_policyconfig_MutatingAdmissionPolicyConfiguration_To_v1_MutatingAdmissionPolicyConfiguration(in, out, s) +} + +func autoConvert_v1_ValidatingAdmissionPolicyConfiguration_To_policyconfig_ValidatingAdmissionPolicyConfiguration(in *ValidatingAdmissionPolicyConfiguration, out *policyconfig.ValidatingAdmissionPolicyConfiguration, s conversion.Scope) error { + out.StaticManifestsDir = in.StaticManifestsDir + return nil +} + +// Convert_v1_ValidatingAdmissionPolicyConfiguration_To_policyconfig_ValidatingAdmissionPolicyConfiguration is an autogenerated conversion function. +func Convert_v1_ValidatingAdmissionPolicyConfiguration_To_policyconfig_ValidatingAdmissionPolicyConfiguration(in *ValidatingAdmissionPolicyConfiguration, out *policyconfig.ValidatingAdmissionPolicyConfiguration, s conversion.Scope) error { + return autoConvert_v1_ValidatingAdmissionPolicyConfiguration_To_policyconfig_ValidatingAdmissionPolicyConfiguration(in, out, s) +} + +func autoConvert_policyconfig_ValidatingAdmissionPolicyConfiguration_To_v1_ValidatingAdmissionPolicyConfiguration(in *policyconfig.ValidatingAdmissionPolicyConfiguration, out *ValidatingAdmissionPolicyConfiguration, s conversion.Scope) error { + out.StaticManifestsDir = in.StaticManifestsDir + return nil +} + +// Convert_policyconfig_ValidatingAdmissionPolicyConfiguration_To_v1_ValidatingAdmissionPolicyConfiguration is an autogenerated conversion function. +func Convert_policyconfig_ValidatingAdmissionPolicyConfiguration_To_v1_ValidatingAdmissionPolicyConfiguration(in *policyconfig.ValidatingAdmissionPolicyConfiguration, out *ValidatingAdmissionPolicyConfiguration, s conversion.Scope) error { + return autoConvert_policyconfig_ValidatingAdmissionPolicyConfiguration_To_v1_ValidatingAdmissionPolicyConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..f4382cd852 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1/zz_generated.deepcopy.go @@ -0,0 +1,76 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopyInto(out *MutatingAdmissionPolicyConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyConfiguration. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopy() *MutatingAdmissionPolicyConfiguration { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopyInto(out *ValidatingAdmissionPolicyConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyConfiguration. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopy() *ValidatingAdmissionPolicyConfiguration { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/zz_generated.deepcopy.go new file mode 100644 index 0000000000..cfc56a61ae --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/zz_generated.deepcopy.go @@ -0,0 +1,76 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package policyconfig + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopyInto(out *MutatingAdmissionPolicyConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyConfiguration. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopy() *MutatingAdmissionPolicyConfiguration { + if in == nil { + return nil + } + out := new(MutatingAdmissionPolicyConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MutatingAdmissionPolicyConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopyInto(out *ValidatingAdmissionPolicyConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidatingAdmissionPolicyConfiguration. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopy() *ValidatingAdmissionPolicyConfiguration { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidatingAdmissionPolicyConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/config.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/config.go new file mode 100644 index 0000000000..125b9d8b0b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/config/config.go @@ -0,0 +1,97 @@ +/* +Copyright 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 config + +import ( + "fmt" + "io" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/admission/plugin/manifest" + "k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig" + v1 "k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1" +) + +var ( + scheme = runtime.NewScheme() + codecs = serializer.NewCodecFactory(scheme, serializer.EnableStrict) +) + +func init() { + utilruntime.Must(policyconfig.AddToScheme(scheme)) + utilruntime.Must(v1.AddToScheme(scheme)) +} + +// PolicyConfig holds the configuration loaded from the config file. +type PolicyConfig struct { + // StaticManifestsDir is the path to the directory containing static policy manifests. + StaticManifestsDir string +} + +// staticManifestsDirAccessor is implemented by config types that have a StaticManifestsDir field. +type staticManifestsDirAccessor interface { + runtime.Object + GetStaticManifestsDir() string +} + +// LoadValidatingConfig extracts the validating admission policy configuration from configFile. +func LoadValidatingConfig(configFile io.Reader) (PolicyConfig, error) { + return loadConfig(configFile, func(obj runtime.Object) bool { + _, ok := obj.(*policyconfig.ValidatingAdmissionPolicyConfiguration) + return ok + }) +} + +// LoadMutatingConfig extracts the mutating admission policy configuration from configFile. +func LoadMutatingConfig(configFile io.Reader) (PolicyConfig, error) { + return loadConfig(configFile, func(obj runtime.Object) bool { + _, ok := obj.(*policyconfig.MutatingAdmissionPolicyConfiguration) + return ok + }) +} + +func loadConfig(configFile io.Reader, isExpectedType func(runtime.Object) bool) (PolicyConfig, error) { + var cfg PolicyConfig + if configFile == nil { + return cfg, nil + } + + data, err := io.ReadAll(configFile) + if err != nil { + return cfg, err + } + decoder := codecs.UniversalDecoder() + decodedObj, err := runtime.Decode(decoder, data) + if err != nil { + return cfg, err + } + if !isExpectedType(decodedObj) { + return cfg, fmt.Errorf("unexpected type: %T", decodedObj) + } + config, ok := decodedObj.(staticManifestsDirAccessor) + if !ok { + return cfg, fmt.Errorf("type %T does not implement staticManifestsDirAccessor", decodedObj) + } + + if err := manifest.ValidateStaticManifestsDir(config.GetStaticManifestsDir()); err != nil { + return cfg, err + } + cfg.StaticManifestsDir = config.GetStaticManifestsDir() + return cfg, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/composite_policy_source.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/composite_policy_source.go new file mode 100644 index 0000000000..f991674e53 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/composite_policy_source.go @@ -0,0 +1,119 @@ +/* +Copyright 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 generic + +import ( + "context" + "sync" +) + +// HookSource provides hooks and sync status. This is the minimal interface +// needed for static sources that don't have their own Run lifecycle. +type HookSource[H Hook] interface { + Hooks() []H + HasSynced() bool +} + +// compositePolicySource combines multiple policy sources into a single source. +// Static (manifest-based) policies are returned before API-based policies. +type compositePolicySource[H Hook] struct { + staticSource HookSource[H] + apiSource Source[H] + + mu sync.RWMutex + lastStatic []H + lastAPI []H + lastCombined []H +} + +var _ Source[Hook] = &compositePolicySource[Hook]{} + +// NewCompositePolicySource creates a policy source that combines static and API-based sources. +// Static policies are evaluated first, followed by API-based policies. +// If staticSource is nil, only apiSource policies are returned. +func NewCompositePolicySource[H Hook](staticSource HookSource[H], apiSource Source[H]) Source[H] { + if staticSource == nil { + return apiSource + } + return &compositePolicySource[H]{ + staticSource: staticSource, + apiSource: apiSource, + } +} + +// Hooks returns all policy hooks from both sources. +// Static policies come first, followed by API-based policies. +// The combined slice is cached and reused when the underlying slices haven't changed. +func (c *compositePolicySource[H]) Hooks() []H { + var staticHooks, apiHooks []H + + // Static policies first (platform policies take precedence) + if c.staticSource != nil { + staticHooks = c.staticSource.Hooks() + } + + // Then API-based policies + if c.apiSource != nil { + apiHooks = c.apiSource.Hooks() + } + + c.mu.RLock() + if slicesAreEqual(staticHooks, c.lastStatic) && slicesAreEqual(apiHooks, c.lastAPI) { + combined := c.lastCombined + c.mu.RUnlock() + return combined + } + c.mu.RUnlock() + + c.mu.Lock() + defer c.mu.Unlock() + // Re-check under write lock. + if slicesAreEqual(staticHooks, c.lastStatic) && slicesAreEqual(apiHooks, c.lastAPI) { + return c.lastCombined + } + + combined := make([]H, 0, len(staticHooks)+len(apiHooks)) + combined = append(combined, staticHooks...) + combined = append(combined, apiHooks...) + + c.lastStatic = staticHooks + c.lastAPI = apiHooks + c.lastCombined = combined + return combined +} + +// slicesAreEqual reports whether two slices share the same backing array and length. +func slicesAreEqual[T any](a, b []T) bool { + return len(a) == len(b) && (len(a) == 0 || &a[0] == &b[0]) +} + +// Run starts the API-based source. The static source is started separately +// by the plugin via its own goroutine (file watcher), so this method only +// needs to handle the API source lifecycle. +func (c *compositePolicySource[H]) Run(ctx context.Context) error { + if c.apiSource != nil { + return c.apiSource.Run(ctx) + } + return nil +} + +// HasSynced returns true only when both sources have synced. +func (c *compositePolicySource[H]) HasSynced() bool { + staticSynced := c.staticSource == nil || c.staticSource.HasSynced() + apiSynced := c.apiSource == nil || c.apiSource.HasSynced() + return staticSynced && apiSynced +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/plugin.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/plugin.go index 03aebdd58a..20771583ce 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/plugin.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/plugin.go @@ -30,6 +30,8 @@ import ( "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/policy/matching" "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" @@ -37,9 +39,22 @@ import ( // H is the Hook type generated by the source and consumed by the dispatcher. // !TODO: Just pass in a Plugin[H] with accessors to all this information -type sourceFactory[H any] func(informers.SharedInformerFactory, kubernetes.Interface, dynamic.Interface, meta.RESTMapper) Source[H] +type apiSourceFactory[H any] func(informers.SharedInformerFactory, kubernetes.Interface, dynamic.Interface, meta.RESTMapper) Source[H] type dispatcherFactory[H any] func(authorizer.Authorizer, *matching.Matcher, kubernetes.Interface) Dispatcher[H] +// ReloadableSource extends HookSource with a method to run a reload loop +// that watches for configuration changes and blocks until the context is canceled. +type ReloadableSource[H any] interface { + HookSource[H] + // RunReloadLoop watches for configuration changes and reloads when detected. + // It blocks until ctx is canceled. + RunReloadLoop(ctx context.Context) +} + +// StaticSourceFactory creates a static policy source from a manifest directory. +// The returned Source should have LoadInitial() already called. +type StaticSourceFactory[H any] func(manifestsDir string) (ReloadableSource[H], error) + // admissionResources is the list of resources related to CEL-based admission // features. var admissionResources = []schema.GroupResource{ @@ -54,17 +69,37 @@ var admissionResources = []schema.GroupResource{ type Plugin[H any] struct { *admission.Handler - sourceFactory sourceFactory[H] - dispatcherFactory dispatcherFactory[H] + apiSourceFactory apiSourceFactory[H] + dispatcherFactory dispatcherFactory[H] + staticSourceFactory StaticSourceFactory[H] source Source[H] dispatcher Dispatcher[H] matcher *matching.Matcher - informerFactory informers.SharedInformerFactory - client kubernetes.Interface - restMapper meta.RESTMapper - dynamicClient dynamic.Interface + // staticSource holds a reference to only the static (manifest-based) policy source. + // This is used in Dispatch to run static hooks for admission config resources + // (e.g., VAP/MAP/VAPB/MAPB), allowing static policies to protect those resources + // without the circular dependency concern that applies to API-based policies. + staticSource HookSource[H] + + // staticManifestsDir is the path to a directory containing static policy manifests. + // When set and the feature gate is enabled, policies are also loaded from this directory. + staticManifestsDir string + + // apiServerID is the identity of this API server instance, used for metrics labeling. + apiServerID string + + informerFactory informers.SharedInformerFactory + client kubernetes.Interface + restMapper meta.RESTMapper + dynamicClient dynamic.Interface + // admissionConfigResources are admission configuration resources (VAP/MAP/VAPB/MAPB). + // API-based policies skip these to prevent circular dependencies, but static policies + // are safe to evaluate on them. + admissionConfigResources sets.Set[schema.GroupResource] + // excludedResources are non-persisted resources (auth/authz reviews) that must be + // excluded from ALL policy evaluation, including static policies. excludedResources sets.Set[schema.GroupResource] stopCh <-chan struct{} authorizer authorizer.Authorizer @@ -77,6 +112,7 @@ var ( _ initializer.WantsRESTMapper = &Plugin[any]{} _ initializer.WantsDynamicClient = &Plugin[any]{} _ initializer.WantsDrainedNotification = &Plugin[any]{} + _ initializer.WantsAPIServerID = &Plugin[any]{} _ initializer.WantsAuthorizer = &Plugin[any]{} _ initializer.WantsExcludedAdmissionResources = &Plugin[any]{} _ admission.InitializationValidator = &Plugin[any]{} @@ -84,16 +120,18 @@ var ( func NewPlugin[H any]( handler *admission.Handler, - sourceFactory sourceFactory[H], + apiSourceFactory apiSourceFactory[H], dispatcherFactory dispatcherFactory[H], ) *Plugin[H] { return &Plugin[H]{ Handler: handler, - sourceFactory: sourceFactory, + apiSourceFactory: apiSourceFactory, dispatcherFactory: dispatcherFactory, - // always exclude admission/mutating policies and bindings - excludedResources: sets.New(admissionResources...), + // admission config resources are skipped by API-based policies (circular dep) + // but evaluated by static policies + admissionConfigResources: sets.New(admissionResources...), + excludedResources: sets.New[schema.GroupResource](), } } @@ -133,6 +171,34 @@ func (c *Plugin[H]) SetExcludedAdmissionResources(excludedResources []schema.Gro c.excludedResources.Insert(excludedResources...) } +// SetStaticManifestsDir sets the directory containing static policy manifests. +func (c *Plugin[H]) SetStaticManifestsDir(dir string) { + c.staticManifestsDir = dir +} + +// GetStaticManifestsDir returns the directory containing static policy manifests. +func (c *Plugin[H]) GetStaticManifestsDir() string { + return c.staticManifestsDir +} + +// SetStaticSourceFactory sets the factory for creating static policy sources. +// This should be called before ValidateInitialization. +func (c *Plugin[H]) SetStaticSourceFactory(factory StaticSourceFactory[H]) { + c.staticSourceFactory = factory +} + +// SetAPIServerID implements the WantsAPIServerID interface. +// The API server ID is used for metrics labeling and must be set before +// ValidateInitialization is called. +func (c *Plugin[H]) SetAPIServerID(id string) { + c.apiServerID = id +} + +// GetAPIServerID returns the stored API server ID. +func (c *Plugin[H]) GetAPIServerID() string { + return c.apiServerID +} + // ValidateInitialization - once clientset and informer factory are provided, creates and starts the admission controller func (c *Plugin[H]) ValidateInitialization() error { // By default enabled is set to false. It is up to types which embed this @@ -162,38 +228,74 @@ func (c *Plugin[H]) ValidateInitialization() error { return errors.New("missing authorizer") } - // Use default matcher + // Guard: if static manifests dir is set but feature gate is off, return an error + if len(c.staticManifestsDir) > 0 && !utilfeature.DefaultFeatureGate.Enabled(features.ManifestBasedAdmissionControlConfig) { + return fmt.Errorf("static policy manifests dir %q configured but %s feature gate is not enabled", c.staticManifestsDir, features.ManifestBasedAdmissionControlConfig) + } + namespaceInformer := c.informerFactory.Core().V1().Namespaces() - c.matcher = matching.NewMatcher(namespaceInformer.Lister(), c.client) + // Construct matcher once, avoiding overwriting if already set. + if c.matcher == nil { + c.matcher = matching.NewMatcher(namespaceInformer.Lister(), c.client) + } if err := c.matcher.ValidateInitialization(); err != nil { return err } - c.source = c.sourceFactory(c.informerFactory, c.client, c.dynamicClient, c.restMapper) - c.dispatcher = c.dispatcherFactory(c.authorizer, c.matcher, c.client) - + // Create a shared context tied to server shutdown for all background goroutines. pluginContext, pluginContextCancel := context.WithCancel(context.Background()) go func() { defer pluginContextCancel() <-c.stopCh }() - go func() { - err := c.source.Run(pluginContext) - if err != nil && !errors.Is(err, context.Canceled) { - utilruntime.HandleError(fmt.Errorf("policy source context unexpectedly closed: %w", err)) + // Construct source once, avoiding overwriting if already set. + if c.source == nil { + apiSource := c.apiSourceFactory(c.informerFactory, c.client, c.dynamicClient, c.restMapper) + + if len(c.staticManifestsDir) > 0 { + if c.staticSourceFactory == nil { + return fmt.Errorf("static policy manifests configured in %q but no static source factory is set", c.staticManifestsDir) + } + staticSource, err := c.staticSourceFactory(c.staticManifestsDir) + if err != nil { + return fmt.Errorf("failed to load static policy manifests from %q: %w", c.staticManifestsDir, err) + } + // Use composite source that combines static + API sources + c.source = NewCompositePolicySource(staticSource, apiSource) + // Keep a reference to the static source so Dispatch can run static hooks + // for resources that are normally excluded from policy evaluation. + c.staticSource = staticSource + // Start the file watcher in a background goroutine + go staticSource.RunReloadLoop(pluginContext) + } else { + // Use only API-based source + c.source = apiSource } - }() - err := c.dispatcher.Start(pluginContext) - if err != nil && !errors.Is(err, context.Canceled) { - utilruntime.HandleError(fmt.Errorf("policy dispatcher context unexpectedly closed: %w", err)) + go func() { + err := c.source.Run(pluginContext) + if err != nil && !errors.Is(err, context.Canceled) { + utilruntime.HandleError(fmt.Errorf("policy source context unexpectedly closed: %w", err)) + } + }() + + c.SetReadyFunc(func() bool { + return namespaceInformer.Informer().HasSynced() && c.source.HasSynced() + }) + } + + // Construct dispatcher once, avoiding overwriting if already set. + if c.dispatcher == nil { + c.dispatcher = c.dispatcherFactory(c.authorizer, c.matcher, c.client) + + err := c.dispatcher.Start(pluginContext) + if err != nil && !errors.Is(err, context.Canceled) { + utilruntime.HandleError(fmt.Errorf("policy dispatcher context unexpectedly closed: %w", err)) + } } - c.SetReadyFunc(func() bool { - return namespaceInformer.Informer().HasSynced() && c.source.HasSynced() - }) return nil } @@ -204,18 +306,42 @@ func (c *Plugin[H]) Dispatch( ) (err error) { if !c.enabled { return nil - } else if c.shouldIgnoreResource(a) { + } + + gr := a.GetResource().GroupResource() + + if c.isExcludedFromAllHooks(gr) { + // Non-persisted resources (auth/authz reviews) are excluded from all policy + // evaluation to avoid breaking the cluster. + return nil + } else if c.isExcludedFromAPIHooks(gr) { + // Admission config resources (VAP/MAP/VAPB/MAPB) are excluded from API-based + // policies to prevent circular dependencies. However, static (manifest-based) + // policies are safe to evaluate since they don't have self-referential concerns. + if c.staticSource != nil { + if !c.staticSource.HasSynced() { + return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request")) + } + return c.dispatcher.Dispatch(ctx, a, o, c.staticSource.Hooks()) + } return nil - } else if !c.WaitForReady() { + } + + if !c.WaitForReady() { return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request")) } return c.dispatcher.Dispatch(ctx, a, o, c.source.Hooks()) } -func (c *Plugin[H]) shouldIgnoreResource(attr admission.Attributes) bool { - gvr := attr.GetResource() - // exclusion decision ignores the version. - gr := gvr.GroupResource() +// isExcludedFromAllHooks returns true for non-persisted resources (auth/authz reviews) +// that must not be intercepted by any policy hook. +func (c *Plugin[H]) isExcludedFromAllHooks(gr schema.GroupResource) bool { return c.excludedResources.Has(gr) } + +// isExcludedFromAPIHooks returns true for admission config resources (VAP/MAP/VAPB/MAPB) +// that are excluded from API-based hooks but may be evaluated by static hooks. +func (c *Plugin[H]) isExcludedFromAPIHooks(gr schema.GroupResource) bool { + return c.admissionConfigResources.Has(gr) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/policy_test_context.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/policy_test_context.go index b98c10e705..5a98902864 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/policy_test_context.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/generic/policy_test_context.go @@ -164,7 +164,7 @@ func NewPolicyTestContext[P, B runtime.Object, E Evaluator]( return policiesAndBindingsTracker.List(fakePolicyGVR, fakePolicyGVK, "") }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { - return policiesAndBindingsTracker.Watch(fakePolicyGVR, "") + return policiesAndBindingsTracker.Watch(fakePolicyGVR, "", options) }, }, policiesAndBindingsTracker), Pexample, @@ -177,7 +177,7 @@ func NewPolicyTestContext[P, B runtime.Object, E Evaluator]( return policiesAndBindingsTracker.List(fakeBindingGVR, fakeBindingGVK, "") }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { - return policiesAndBindingsTracker.Watch(fakeBindingGVR, "") + return policiesAndBindingsTracker.Watch(fakeBindingGVR, "", options) }, }, policiesAndBindingsTracker), Bexample, diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/internal/generic/controller.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/internal/generic/controller.go index a94004c272..65ffee4e2f 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/internal/generic/controller.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/internal/generic/controller.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "sync" - "sync/atomic" "time" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -48,10 +47,7 @@ type controller[T runtime.Object] struct { options ControllerOptions - // must hold a func() bool or nil - notificationsDelivered atomic.Value - - hasProcessed synctrack.AsyncTracker[string] + hasProcessed *synctrack.AsyncTracker[string] } type ControllerOptions struct { @@ -77,17 +73,11 @@ func NewController[T runtime.Object]( } c := &controller[T]{ - options: options, - informer: informer, - reconciler: reconciler, - queue: nil, - } - c.hasProcessed.UpstreamHasSynced = func() bool { - f := c.notificationsDelivered.Load() - if f == nil { - return false - } - return f.(func() bool)() + options: options, + informer: informer, + reconciler: reconciler, + queue: nil, + hasProcessed: synctrack.NewAsyncTracker[string](options.Name), } return c } @@ -159,12 +149,9 @@ func (c *controller[T]) Run(ctx context.Context) error { return err } - c.notificationsDelivered.Store(registration.HasSynced) - // Make sure event handler is removed from informer in case return early from // an error defer func() { - c.notificationsDelivered.Store(func() bool { return false }) // Remove event handler and Handle Error here. Error should only be raised // for improper usage of event handler API. if err := c.informer.RemoveEventHandler(registration); err != nil { @@ -174,7 +161,12 @@ func (c *controller[T]) Run(ctx context.Context) error { // Wait for initial cache list to complete before beginning to reconcile // objects. - if !cache.WaitForNamedCacheSyncWithContext(ctx, c.informer.HasSynced) { + if !cache.WaitFor(ctx, "caches", c.informer.HasSyncedChecker(), registration.HasSyncedChecker()) { + // TODO: should cache.WaitFor return an error? + // ctx.Err() or context.Cause(ctx)? + // Either of them would make dead code like the "if err == nil" + // below more obvious. + // ctx cancelled during cache sync. return early err := ctx.Err() if err == nil { @@ -184,6 +176,10 @@ func (c *controller[T]) Run(ctx context.Context) error { return err } + // c.informer *and* our handler have synced, which implies that our AddFunc(= enqueue) + // and thus c.hasProcessed.Start have been called for the initial list => upstream is done. + c.hasProcessed.UpstreamHasSynced() + waitGroup := sync.WaitGroup{} for i := uint(0); i < c.options.Workers; i++ { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source/source.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source/source.go new file mode 100644 index 0000000000..0e37d78645 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source/source.go @@ -0,0 +1,192 @@ +/* +Copyright 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 source provides a Source implementation that loads policy configurations from manifest files. +package source + +import ( + "context" + "fmt" + "sync/atomic" + "time" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission/plugin/manifest/metrics" + "k8s.io/apiserver/pkg/admission/plugin/policy/generic" + "k8s.io/apiserver/pkg/util/filesystem" + "k8s.io/klog/v2" +) + +// defaultReloadInterval is the default interval at which the manifest directory is checked for changes. +var defaultReloadInterval = 1 * time.Minute + +// SetReloadIntervalForTests sets the reload interval for testing and returns a function to restore the original value. +func SetReloadIntervalForTests(interval time.Duration) func() { + original := defaultReloadInterval + defaultReloadInterval = interval + return func() { + defaultReloadInterval = original + } +} + +// PolicyLoadFunc loads policy and binding manifests from a directory. +type PolicyLoadFunc[P, B runtime.Object] func(dir string) ([]P, []B, string, error) + +// PolicyCompiler compiles a policy into an Evaluator. +type PolicyCompiler[P runtime.Object, E generic.Evaluator] func(P) (E, error) + +// BindingPolicyName extracts the policy name referenced by a binding. +type BindingPolicyName[B runtime.Object] func(B) string + +// StaticPolicySource provides policy configurations loaded from manifest files. +type StaticPolicySource[P, B runtime.Object, E generic.Evaluator] struct { + manifestsDir string + apiServerID string + reloadInterval time.Duration + compiler PolicyCompiler[P, E] + loadFunc PolicyLoadFunc[P, B] + getBindingPolicyName BindingPolicyName[B] + manifestType metrics.ManifestType + + current atomic.Pointer[[]generic.PolicyHook[P, B, E]] + lastReadHash atomic.Pointer[string] // hash of last file content read (for short-circuiting) + hasSynced atomic.Bool +} + +// NewStaticPolicySource creates a new static policy source that loads configurations from the specified directory. +func NewStaticPolicySource[P, B runtime.Object, E generic.Evaluator]( + manifestsDir, apiServerID string, + compiler PolicyCompiler[P, E], + loadFunc PolicyLoadFunc[P, B], + getBindingPolicyName BindingPolicyName[B], + manifestType metrics.ManifestType, +) *StaticPolicySource[P, B, E] { + metrics.RegisterMetrics() + return &StaticPolicySource[P, B, E]{ + manifestsDir: manifestsDir, + apiServerID: apiServerID, + reloadInterval: defaultReloadInterval, + compiler: compiler, + loadFunc: loadFunc, + getBindingPolicyName: getBindingPolicyName, + manifestType: manifestType, + } +} + +// LoadInitial performs the initial load of manifests. +// This should be called during API server startup and will fail if the manifests cannot be loaded. +func (s *StaticPolicySource[P, B, E]) LoadInitial() error { + policies, bindings, hash, err := s.loadFunc(s.manifestsDir) + if err != nil { + return err + } + + hooks, err := s.compile(policies, bindings) + if err != nil { + return err + } + s.current.Store(&hooks) + s.lastReadHash.Store(&hash) + s.hasSynced.Store(true) + + klog.InfoS("Loaded manifest-based admission policy configurations", "plugin", string(s.manifestType), "count", len(hooks)) + metrics.RecordAutomaticReloadSuccess(s.manifestType, s.apiServerID, hash) + return nil +} + +// RunReloadLoop watches for configuration changes and reloads when detected. +// It blocks until ctx is canceled. +func (s *StaticPolicySource[P, B, E]) RunReloadLoop(ctx context.Context) { + filesystem.WatchUntil( + ctx, + s.reloadInterval, + s.manifestsDir, + func() { + s.checkAndReload() + }, + func(err error) { + klog.ErrorS(err, "watching manifest directory", "plugin", string(s.manifestType), "dir", s.manifestsDir) + }, + ) +} + +func (s *StaticPolicySource[P, B, E]) compile(policies []P, bindings []B) ([]generic.PolicyHook[P, B, E], error) { + bindingsByPolicy := make(map[string][]B) + for _, binding := range bindings { + policyName := s.getBindingPolicyName(binding) + bindingsByPolicy[policyName] = append(bindingsByPolicy[policyName], binding) + } + + var hooks []generic.PolicyHook[P, B, E] + for _, policy := range policies { + nameGetter, ok := any(policy).(interface{ GetName() string }) + if !ok { + return nil, fmt.Errorf("policy type %T does not implement GetName()", policy) + } + evaluator, err := s.compiler(policy) + if err != nil { + return nil, fmt.Errorf("failed to compile policy %q: %w", nameGetter.GetName(), err) + } + hook := generic.PolicyHook[P, B, E]{ + Policy: policy, + Bindings: bindingsByPolicy[nameGetter.GetName()], + Evaluator: evaluator, + } + hooks = append(hooks, hook) + } + + return hooks, nil +} + +func (s *StaticPolicySource[P, B, E]) checkAndReload() { + policies, bindings, hash, err := s.loadFunc(s.manifestsDir) + if err != nil { + klog.ErrorS(err, "reloading manifest config", "plugin", string(s.manifestType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadFailure(s.manifestType, s.apiServerID) + return + } + + // Short-circuit if file content hasn't changed since last read. + if last := s.lastReadHash.Load(); last != nil && hash == *last { + return + } + s.lastReadHash.Store(&hash) + + hooks, err := s.compile(policies, bindings) + if err != nil { + klog.ErrorS(err, "compiling manifest config", "plugin", string(s.manifestType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadFailure(s.manifestType, s.apiServerID) + return + } + s.current.Store(&hooks) + + klog.InfoS("reloaded manifest config", "plugin", string(s.manifestType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadSuccess(s.manifestType, s.apiServerID, hash) +} + +// HasSynced returns true if the initial load has completed. +func (s *StaticPolicySource[P, B, E]) HasSynced() bool { + return s.hasSynced.Load() +} + +// Hooks returns the list of policy hooks. +func (s *StaticPolicySource[P, B, E]) Hooks() []generic.PolicyHook[P, B, E] { + current := s.current.Load() + if current == nil { + return nil + } + return *current +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/accessor.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/accessor.go index ff342623a9..b20103c574 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/accessor.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/accessor.go @@ -18,7 +18,6 @@ package mutating import ( v1 "k8s.io/api/admissionregistration/v1" - "k8s.io/api/admissionregistration/v1beta1" "k8s.io/apimachinery/pkg/types" "k8s.io/apiserver/pkg/admission/plugin/policy/generic" ) @@ -59,19 +58,11 @@ func (v *mutatingAdmissionPolicyAccessor) GetParamKind() *v1.ParamKind { } func (v *mutatingAdmissionPolicyAccessor) GetMatchConstraints() *v1.MatchResources { - return convertV1alpha1ResourceRulesToV1(v.Spec.MatchConstraints) + return v.Spec.MatchConstraints } func (v *mutatingAdmissionPolicyAccessor) GetFailurePolicy() *v1.FailurePolicyType { - return toV1FailurePolicy(v.Spec.FailurePolicy) -} - -func toV1FailurePolicy(failurePolicy *v1beta1.FailurePolicyType) *v1.FailurePolicyType { - if failurePolicy == nil { - return nil - } - fp := v1.FailurePolicyType(*failurePolicy) - return &fp + return v.Spec.FailurePolicy } type mutatingAdmissionPolicyBindingAccessor struct { @@ -94,7 +85,7 @@ func (v *mutatingAdmissionPolicyBindingAccessor) GetPolicyName() types.Namespace } func (v *mutatingAdmissionPolicyBindingAccessor) GetMatchResources() *v1.MatchResources { - return convertV1alpha1ResourceRulesToV1(v.Spec.MatchResources) + return v.Spec.MatchResources } func (v *mutatingAdmissionPolicyBindingAccessor) GetParamRef() *v1.ParamRef { @@ -115,30 +106,3 @@ func (v *mutatingAdmissionPolicyBindingAccessor) GetParamRef() *v1.ParamRef { ParameterNotFoundAction: nfa, } } - -func convertV1alpha1ResourceRulesToV1(mc *v1beta1.MatchResources) *v1.MatchResources { - if mc == nil { - return nil - } - - var res v1.MatchResources - res.NamespaceSelector = mc.NamespaceSelector - res.ObjectSelector = mc.ObjectSelector - for _, ex := range mc.ExcludeResourceRules { - res.ExcludeResourceRules = append(res.ExcludeResourceRules, v1.NamedRuleWithOperations{ - ResourceNames: ex.ResourceNames, - RuleWithOperations: ex.RuleWithOperations, - }) - } - for _, ex := range mc.ResourceRules { - res.ResourceRules = append(res.ResourceRules, v1.NamedRuleWithOperations{ - ResourceNames: ex.ResourceNames, - RuleWithOperations: ex.RuleWithOperations, - }) - } - if mc.MatchPolicy != nil { - mp := v1.MatchPolicyType(*mc.MatchPolicy) - res.MatchPolicy = &mp - } - return &res -} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/compilation.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/compilation.go index 121c3b4004..a0772aab44 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/compilation.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/compilation.go @@ -19,9 +19,10 @@ package mutating import ( "fmt" - "k8s.io/api/admissionregistration/v1beta1" + "k8s.io/api/admissionregistration/v1" plugincel "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/policy/mutating/patch" + "k8s.io/apiserver/pkg/admission/plugin/policy/validating" "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" apiservercel "k8s.io/apiserver/pkg/cel" "k8s.io/apiserver/pkg/cel/environment" @@ -32,7 +33,7 @@ import ( // // Each individual mutation is compiled into MutationEvaluationFunc and // returned is a PolicyEvaluator in the same order as the mutations appeared in the policy. -func compilePolicy(policy *Policy) PolicyEvaluator { +func compilePolicy(policy *v1.MutatingAdmissionPolicy) PolicyEvaluator { opts := plugincel.OptionalVariableDeclarations{HasParams: policy.Spec.ParamKind != nil, HasAuthorizer: true} compiler, err := plugincel.NewCompositedCompiler(environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion())) if err != nil { @@ -43,7 +44,7 @@ func compilePolicy(policy *Policy) PolicyEvaluator { } // Compile and store variables - compiler.CompileAndStoreVariables(convertv1alpha1Variables(policy.Spec.Variables), opts, environment.StoredExpressions) + compiler.CompileAndStoreVariables(convertV1Variables(policy.Spec.Variables), opts, environment.StoredExpressions) // Compile matchers var matcher matchconditions.Matcher = nil @@ -53,7 +54,7 @@ func compilePolicy(policy *Policy) PolicyEvaluator { for i := range matchConditions { matchExpressionAccessors[i] = (*matchconditions.MatchCondition)(&matchConditions[i]) } - matcher = matchconditions.NewMatcher(compiler.CompileCondition(matchExpressionAccessors, opts, environment.StoredExpressions), toV1FailurePolicy(policy.Spec.FailurePolicy), "policy", "validate", policy.Name) + matcher = matchconditions.NewMatcher(compiler.CompileCondition(matchExpressionAccessors, opts, environment.StoredExpressions), policy.Spec.FailurePolicy, "policy", "validate", policy.Name) } // Compiler patchers @@ -62,13 +63,13 @@ func compilePolicy(policy *Policy) PolicyEvaluator { patchOptions.HasPatchTypes = true for _, m := range policy.Spec.Mutations { switch m.PatchType { - case v1beta1.PatchTypeJSONPatch: + case v1.PatchTypeJSONPatch: if m.JSONPatch != nil { accessor := &patch.JSONPatchCondition{Expression: m.JSONPatch.Expression} compileResult := compiler.CompileMutatingEvaluator(accessor, patchOptions, environment.StoredExpressions) patchers = append(patchers, patch.NewJSONPatcher(compileResult)) } - case v1beta1.PatchTypeApplyConfiguration: + case v1.PatchTypeApplyConfiguration: if m.ApplyConfiguration != nil { accessor := &patch.ApplyConfigurationCondition{Expression: m.ApplyConfiguration.Expression} compileResult := compiler.CompileMutatingEvaluator(accessor, patchOptions, environment.StoredExpressions) @@ -77,5 +78,19 @@ func compilePolicy(policy *Policy) PolicyEvaluator { } } - return PolicyEvaluator{Matcher: matcher, Mutators: patchers, CompositionEnv: compiler.CompositionEnv} + return PolicyEvaluator{Matcher: matcher, Mutators: patchers, CompositedCompiler: compiler} +} + +func convertV1Variables(variables []v1.Variable) []plugincel.NamedExpressionAccessor { + if variables == nil { + return nil + } + res := make([]plugincel.NamedExpressionAccessor, len(variables)) + for i, v := range variables { + res[i] = &validating.Variable{ + Name: v.Name, + Expression: v.Expression, + } + } + return res } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/dispatcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/dispatcher.go index 53dbd6486f..e5b10c7f6d 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/dispatcher.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/dispatcher.go @@ -22,7 +22,7 @@ import ( "fmt" "time" - "k8s.io/api/admissionregistration/v1beta1" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -137,8 +137,8 @@ func (d *dispatcher) dispatchInvocations( // Should loop through invocations, handling possible error and invoking // evaluator to apply patch, also should handle re-invocations for _, invocation := range invocations { - if invocation.Evaluator.CompositionEnv != nil { - ctx = invocation.Evaluator.CompositionEnv.CreateContext(ctx) + if invocation.Evaluator.CompositedCompiler != nil { + ctx = invocation.Evaluator.CompositedCompiler.CreateContext(ctx) } if len(invocation.Evaluator.Mutators) != len(invocation.Policy.Spec.Mutations) { // This would be a bug. The compiler should always return exactly as @@ -210,7 +210,7 @@ func (d *dispatcher) dispatchInvocations( policyReinvokeCtx.RequireReinvokingPreviouslyInvokedPlugins() reinvokeCtx.SetShouldReinvoke() } - if invocation.Policy.Spec.ReinvocationPolicy == v1beta1.IfNeededReinvocationPolicy { + if invocation.Policy.Spec.ReinvocationPolicy == admissionregistrationv1.IfNeededReinvocationPolicy { policyReinvokeCtx.AddReinvocablePolicyToPreviouslyInvoked(invocationKey) } } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/plugin.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/plugin.go index 20e4d2d0c4..01dd230dea 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/plugin.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/plugin.go @@ -18,18 +18,23 @@ package mutating import ( "context" - celgo "github.com/google/cel-go/cel" "io" - "k8s.io/api/admissionregistration/v1beta1" + celgo "github.com/google/cel-go/cel" + + v1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/manifest/metrics" + "k8s.io/apiserver/pkg/admission/plugin/policy/config" "k8s.io/apiserver/pkg/admission/plugin/policy/generic" + "k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source" "k8s.io/apiserver/pkg/admission/plugin/policy/matching" "k8s.io/apiserver/pkg/admission/plugin/policy/mutating/patch" "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" @@ -49,13 +54,13 @@ const ( // Register registers a plugin func Register(plugins *admission.Plugins) { plugins.Register(PluginName, func(configFile io.Reader) (admission.Interface, error) { - return NewPlugin(configFile), nil + return NewPlugin(configFile) }) } -type Policy = v1beta1.MutatingAdmissionPolicy -type PolicyBinding = v1beta1.MutatingAdmissionPolicyBinding -type PolicyMutation = v1beta1.Mutation +type Policy = v1.MutatingAdmissionPolicy +type PolicyBinding = v1.MutatingAdmissionPolicyBinding + type PolicyHook = generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator] type Mutator struct { @@ -73,10 +78,10 @@ type MutationEvaluationFunc func( ) (runtime.Object, error) type PolicyEvaluator struct { - Matcher matchconditions.Matcher - Mutators []patch.Patcher - CompositionEnv *cel.CompositionEnv - Error error + Matcher matchconditions.Matcher + Mutators []patch.Patcher + CompositedCompiler *cel.CompositedCompiler + Error error } // Plugin is an implementation of admission.Interface. @@ -86,9 +91,43 @@ type Plugin struct { var _ admission.Interface = &Plugin{} var _ admission.MutationInterface = &Plugin{} +var _ initializer.WantsManifestLoaders = &Plugin{} + +// SetManifestLoaders provides the manifest load functions for scheme-based defaulting and validation. +func (a *Plugin) SetManifestLoaders(loaders *initializer.ManifestLoaders) { + if loaders == nil || loaders.LoadMutatingPolicyManifests == nil { + return + } + loadFunc := loaders.LoadMutatingPolicyManifests + a.SetStaticSourceFactory(func(manifestsDir string) (generic.ReloadableSource[PolicyHook], error) { + staticSource := source.NewStaticPolicySource(manifestsDir, a.GetAPIServerID(), + func(p *v1.MutatingAdmissionPolicy) (PolicyEvaluator, error) { + e := compilePolicy(p) + if e.Error != nil { + return PolicyEvaluator{}, e.Error + } + return e, nil + }, + func(dir string) ([]*v1.MutatingAdmissionPolicy, []*v1.MutatingAdmissionPolicyBinding, string, error) { + return loadFunc(dir) + }, + func(b *v1.MutatingAdmissionPolicyBinding) string { return b.Spec.PolicyName }, + metrics.MAPManifestType, + ) + if err := staticSource.LoadInitial(); err != nil { + return nil, err + } + return staticSource, nil + }) +} // NewPlugin returns a generic admission webhook plugin. -func NewPlugin(_ io.Reader) *Plugin { +func NewPlugin(configFile io.Reader) (*Plugin, error) { + cfg, err := config.LoadMutatingConfig(configFile) + if err != nil { + return nil, err + } + // There is no request body to mutate for DELETE, so this plugin never handles that operation. handler := admission.NewHandler(admission.Create, admission.Update, admission.Connect) res := &Plugin{} @@ -96,8 +135,8 @@ func NewPlugin(_ io.Reader) *Plugin { handler, func(f informers.SharedInformerFactory, client kubernetes.Interface, dynamicClient dynamic.Interface, restMapper meta.RESTMapper) generic.Source[PolicyHook] { return generic.NewPolicySource( - f.Admissionregistration().V1beta1().MutatingAdmissionPolicies().Informer(), - f.Admissionregistration().V1beta1().MutatingAdmissionPolicyBindings().Informer(), + f.Admissionregistration().V1().MutatingAdmissionPolicies().Informer(), + f.Admissionregistration().V1().MutatingAdmissionPolicyBindings().Informer(), NewMutatingAdmissionPolicyAccessor, NewMutatingAdmissionPolicyBindingAccessor, compilePolicy, @@ -112,7 +151,8 @@ func NewPlugin(_ io.Reader) *Plugin { return NewDispatcher(a, m, patch.NewTypeConverterManager(nil, client.Discovery().OpenAPIV3())) }, ) - return res + res.SetStaticManifestsDir(cfg.StaticManifestsDir) + return res, nil } // Admit makes an admission decision based on the request attributes. @@ -141,11 +181,3 @@ func (v *Variable) ReturnTypes() []*celgo.Type { func (v *Variable) GetName() string { return v.Name } - -func convertv1alpha1Variables(variables []v1beta1.Variable) []cel.NamedExpressionAccessor { - namedExpressions := make([]cel.NamedExpressionAccessor, len(variables)) - for i, variable := range variables { - namedExpressions[i] = &Variable{Name: variable.Name, Expression: variable.Expression} - } - return namedExpressions -} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/interface.go index 97eeb95504..fd8015e7ce 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/interface.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/interface.go @@ -92,4 +92,6 @@ type Validator interface { // Validate is used to take cel evaluations and convert into decisions // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. Validate(ctx context.Context, matchedResource schema.GroupVersionResource, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, namespace *corev1.Namespace, runtimeCELCostBudget int64, authz authorizer.Authorizer) ValidateResult + // CompileError returns any error from CEL compilation, or nil if compilation succeeded. + CompileError() error } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/plugin.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/plugin.go index bdca01e691..348ecde2d0 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/plugin.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/plugin.go @@ -26,7 +26,10 @@ import ( "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/manifest/metrics" + "k8s.io/apiserver/pkg/admission/plugin/policy/config" "k8s.io/apiserver/pkg/admission/plugin/policy/generic" + "k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source" "k8s.io/apiserver/pkg/admission/plugin/policy/matching" "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" "k8s.io/apiserver/pkg/authorization/authorizer" @@ -43,16 +46,12 @@ const ( var ( lazyCompositionEnvTemplateWithStrictCostInit sync.Once - lazyCompositionEnvTemplateWithStrictCost *cel.CompositionEnv + lazyCompositionEnvTemplateWithStrictCost *environment.EnvSet ) -func getCompositionEnvTemplateWithStrictCost() *cel.CompositionEnv { +func getCompositionEnvTemplateWithStrictCost() *environment.EnvSet { lazyCompositionEnvTemplateWithStrictCostInit.Do(func() { - env, err := cel.NewCompositionEnv(cel.VariablesTypeName, environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion())) - if err != nil { - panic(err) - } - lazyCompositionEnvTemplateWithStrictCost = env + lazyCompositionEnvTemplateWithStrictCost = environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion()) }) return lazyCompositionEnvTemplateWithStrictCost } @@ -60,7 +59,7 @@ func getCompositionEnvTemplateWithStrictCost() *cel.CompositionEnv { // Register registers a plugin func Register(plugins *admission.Plugins) { plugins.Register(PluginName, func(configFile io.Reader) (admission.Interface, error) { - return NewPlugin(configFile), nil + return NewPlugin(configFile) }) } @@ -77,8 +76,42 @@ type Plugin struct { var _ admission.Interface = &Plugin{} var _ admission.ValidationInterface = &Plugin{} var _ initializer.WantsExcludedAdmissionResources = &Plugin{} +var _ initializer.WantsManifestLoaders = &Plugin{} + +// SetManifestLoaders provides the manifest load functions for scheme-based defaulting and validation. +func (a *Plugin) SetManifestLoaders(loaders *initializer.ManifestLoaders) { + if loaders == nil || loaders.LoadValidatingPolicyManifests == nil { + return + } + loadFunc := loaders.LoadValidatingPolicyManifests + a.SetStaticSourceFactory(func(manifestsDir string) (generic.ReloadableSource[PolicyHook], error) { + staticSource := source.NewStaticPolicySource(manifestsDir, a.GetAPIServerID(), + func(p *v1.ValidatingAdmissionPolicy) (Validator, error) { + v := compilePolicy(p) + if err := v.CompileError(); err != nil { + return nil, err + } + return v, nil + }, + func(dir string) ([]*v1.ValidatingAdmissionPolicy, []*v1.ValidatingAdmissionPolicyBinding, string, error) { + return loadFunc(dir) + }, + func(b *v1.ValidatingAdmissionPolicyBinding) string { return b.Spec.PolicyName }, + metrics.VAPManifestType, + ) + if err := staticSource.LoadInitial(); err != nil { + return nil, err + } + return staticSource, nil + }) +} + +func NewPlugin(configFile io.Reader) (*Plugin, error) { + cfg, err := config.LoadValidatingConfig(configFile) + if err != nil { + return nil, err + } -func NewPlugin(_ io.Reader) *Plugin { handler := admission.NewHandler(admission.Connect, admission.Create, admission.Delete, admission.Update) p := &Plugin{ @@ -102,7 +135,8 @@ func NewPlugin(_ io.Reader) *Plugin { ), } p.SetEnabled(true) - return p + p.SetStaticManifestsDir(cfg.StaticManifestsDir) + return p, nil } // Validate makes an admission decision based on the request attributes. @@ -120,9 +154,11 @@ func compilePolicy(policy *Policy) Validator { failurePolicy := policy.Spec.FailurePolicy var matcher matchconditions.Matcher = nil matchConditions := policy.Spec.MatchConditions - var compositionEnvTemplate *cel.CompositionEnv - compositionEnvTemplate = getCompositionEnvTemplateWithStrictCost() - filterCompiler := cel.NewCompositedCompilerFromTemplate(compositionEnvTemplate) + compositionEnvTemplate := getCompositionEnvTemplateWithStrictCost() + filterCompiler, err := cel.NewCompositedCompiler(compositionEnvTemplate) + if err != nil { + return NewValidator(nil, nil, nil, nil, failurePolicy, err) + } filterCompiler.CompileAndStoreVariables(convertv1beta1Variables(policy.Spec.Variables), optionalVars, environment.StoredExpressions) if len(matchConditions) > 0 { @@ -138,6 +174,7 @@ func compilePolicy(policy *Policy) Validator { filterCompiler.CompileCondition(convertv1AuditAnnotations(policy.Spec.AuditAnnotations), optionalVars, environment.StoredExpressions), filterCompiler.CompileCondition(convertv1MessageExpressions(policy.Spec.Validations), expressionOptionalVars, environment.StoredExpressions), failurePolicy, + nil, ) return res diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/typechecking.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/typechecking.go index 6a284e6de9..c8b258f163 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/typechecking.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/typechecking.go @@ -177,20 +177,17 @@ func (c *TypeChecker) CreateContext(policy *v1.ValidatingAdmissionPolicy) *TypeC func (c *TypeChecker) compiler(ctx *TypeCheckingContext, typeOverwrite typeOverwrite) (*plugincel.CompositedCompiler, error) { envSet, err := buildEnvSet( - /* hasParams */ ctx.paramDeclType != nil, + /* hasParams */ !ctx.paramGVK.Empty(), /* hasAuthorizer */ true, typeOverwrite) if err != nil { return nil, err } - env, err := plugincel.NewCompositionEnv(plugincel.VariablesTypeName, envSet) + compiler, err := plugincel.NewCompositedCompilerForTypeChecking(envSet) if err != nil { return nil, err } - compiler := &plugincel.CompositedCompiler{ - Compiler: &typeCheckingCompiler{typeOverwrite: typeOverwrite, compositionEnv: env}, - CompositionEnv: env, - } + compiler.Compiler = &typeCheckingCompiler{typeOverwrite: typeOverwrite, compiler: compiler} return compiler, nil } @@ -208,7 +205,7 @@ func (c *TypeChecker) CheckExpression(ctx *TypeCheckingContext, expression strin continue } options := plugincel.OptionalVariableDeclarations{ - HasParams: ctx.paramDeclType != nil, + HasParams: !ctx.paramGVK.Empty(), HasAuthorizer: true, } compiler.CompileAndStoreVariables(convertv1beta1Variables(ctx.variables), options, environment.StoredExpressions) @@ -247,7 +244,11 @@ func (c *TypeChecker) declType(gvk schema.GroupVersionKind) (*apiservercel.DeclT if err != nil { return nil, err } - return common.SchemaDeclType(&openapi.Schema{Schema: s}, true).MaybeAssignTypeName(generateUniqueTypeName(gvk.Kind)), nil + declType := common.SchemaDeclType(&openapi.Schema{Schema: s}, true) + if declType == nil { + return nil, nil + } + return declType.MaybeAssignTypeName(generateUniqueTypeName(gvk.Kind)), nil } func (c *TypeChecker) paramsGVK(policy *v1.ValidatingAdmissionPolicy) schema.GroupVersionKind { @@ -407,12 +408,16 @@ func buildEnvSet(hasParams bool, hasAuthorizer bool, types typeOverwrite) (*envi varOpts = append(varOpts, createVariableOpts(requestType, plugincel.RequestVarName)...) // object and oldObject, same type, type(s) resolved from constraints - declTypes = append(declTypes, types.object) + if types.object != nil { + declTypes = append(declTypes, types.object) + } varOpts = append(varOpts, createVariableOpts(types.object, plugincel.ObjectVarName, plugincel.OldObjectVarName)...) // params, defined by ParamKind - if hasParams && types.params != nil { - declTypes = append(declTypes, types.params) + if hasParams { + if types.params != nil { + declTypes = append(declTypes, types.params) + } varOpts = append(varOpts, createVariableOpts(types.params, plugincel.ParamsVarName)...) } @@ -449,8 +454,8 @@ func createVariableOpts(declType *apiservercel.DeclType, variables ...string) [] } type typeCheckingCompiler struct { - compositionEnv *plugincel.CompositionEnv - typeOverwrite typeOverwrite + compiler *plugincel.CompositedCompiler + typeOverwrite typeOverwrite } // CompileCELExpression compiles the given expression. @@ -469,7 +474,7 @@ func (c *typeCheckingCompiler) CompileCELExpression(expressionAccessor plugincel ExpressionAccessor: expressionAccessor, } } - env, err := c.compositionEnv.Env(mode) + env, err := c.compiler.Env(mode) if err != nil { return resultError(fmt.Sprintf("fail to build env: %v", err), apiservercel.ErrorTypeInternal) } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/validator.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/validator.go index 4057e515ee..2144795fd8 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/validator.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/policy/validating/validator.go @@ -45,15 +45,19 @@ type validator struct { auditAnnotationFilter cel.ConditionEvaluator messageFilter cel.ConditionEvaluator failPolicy *v1.FailurePolicyType + // compileError holds any compilation error from the CEL expressions. + // If non-nil, the validator will return an error result based on the failPolicy. + compileError error } -func NewValidator(validationFilter cel.ConditionEvaluator, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.ConditionEvaluator, failPolicy *v1.FailurePolicyType) Validator { +func NewValidator(validationFilter cel.ConditionEvaluator, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.ConditionEvaluator, failPolicy *v1.FailurePolicyType, err error) Validator { return &validator{ celMatcher: celMatcher, validationFilter: validationFilter, auditAnnotationFilter: auditAnnotationFilter, messageFilter: messageFilter, failPolicy: failPolicy, + compileError: err, } } @@ -71,6 +75,10 @@ func auditAnnotationEvaluationForError(f v1.FailurePolicyType) PolicyAuditAnnota return AuditAnnotationActionError } +func (v *validator) CompileError() error { + return v.compileError +} + // Validate takes a list of Evaluation and a failure policy and converts them into actionable PolicyDecisions // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. @@ -81,6 +89,17 @@ func (v *validator) Validate(ctx context.Context, matchedResource schema.GroupVe } else { f = *v.failPolicy } + if v.compileError != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: v.compileError.Error(), + }, + }, + } + } if v.celMatcher != nil { matchResults := v.celMatcher.Match(ctx, versionedAttr, versionedParams, authz) if matchResults.Error != nil { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/types.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/types.go index 71ce47b1f4..f6ba94e7cd 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/types.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/types.go @@ -26,4 +26,14 @@ type WebhookAdmission struct { // KubeConfigFile is the path to the kubeconfig file. KubeConfigFile string + + // StaticManifestsDir is the path to a directory containing static webhook + // configurations to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // ValidatingWebhookConfiguration and MutatingWebhookConfiguration + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/types.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/types.go index 632427d7df..be09205348 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/types.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/types.go @@ -26,4 +26,14 @@ type WebhookAdmission struct { // KubeConfigFile is the path to the kubeconfig file. KubeConfigFile string `json:"kubeConfigFile"` + + // StaticManifestsDir is the path to a directory containing static webhook + // configurations to be loaded at startup. Files with extensions .yaml, + // .yml, and .json are read. Only admissionregistration.k8s.io/v1 + // ValidatingWebhookConfiguration and MutatingWebhookConfiguration + // resources are supported. + // Using this field requires the ManifestBasedAdmissionControlConfig + // feature gate to be enabled. + // +optional + StaticManifestsDir string `json:"staticManifestsDir,omitempty"` } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/zz_generated.conversion.go index 4cf69291b3..90235e1e9d 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1/zz_generated.conversion.go @@ -49,6 +49,7 @@ func RegisterConversions(s *runtime.Scheme) error { func autoConvert_v1_WebhookAdmission_To_webhookadmission_WebhookAdmission(in *WebhookAdmission, out *webhookadmission.WebhookAdmission, s conversion.Scope) error { out.KubeConfigFile = in.KubeConfigFile + out.StaticManifestsDir = in.StaticManifestsDir return nil } @@ -59,6 +60,7 @@ func Convert_v1_WebhookAdmission_To_webhookadmission_WebhookAdmission(in *Webhoo func autoConvert_webhookadmission_WebhookAdmission_To_v1_WebhookAdmission(in *webhookadmission.WebhookAdmission, out *WebhookAdmission, s conversion.Scope) error { out.KubeConfigFile = in.KubeConfigFile + out.StaticManifestsDir = in.StaticManifestsDir return nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/doc.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/doc.go deleted file mode 100644 index 703f467f9f..0000000000 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2017 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. -*/ - -// +k8s:deepcopy-gen=package -// +k8s:conversion-gen=k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission -// +k8s:defaulter-gen=TypeMeta -// +groupName=apiserver.config.k8s.io - -// Package v1alpha1 is the v1alpha1 version of the API. -package v1alpha1 diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.conversion.go deleted file mode 100644 index 66aaecbd86..0000000000 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.conversion.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by conversion-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - conversion "k8s.io/apimachinery/pkg/conversion" - runtime "k8s.io/apimachinery/pkg/runtime" - webhookadmission "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission" -) - -func init() { - localSchemeBuilder.Register(RegisterConversions) -} - -// RegisterConversions adds conversion functions to the given scheme. -// Public to allow building arbitrary schemes. -func RegisterConversions(s *runtime.Scheme) error { - if err := s.AddGeneratedConversionFunc((*WebhookAdmission)(nil), (*webhookadmission.WebhookAdmission)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_WebhookAdmission_To_webhookadmission_WebhookAdmission(a.(*WebhookAdmission), b.(*webhookadmission.WebhookAdmission), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*webhookadmission.WebhookAdmission)(nil), (*WebhookAdmission)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_webhookadmission_WebhookAdmission_To_v1alpha1_WebhookAdmission(a.(*webhookadmission.WebhookAdmission), b.(*WebhookAdmission), scope) - }); err != nil { - return err - } - return nil -} - -func autoConvert_v1alpha1_WebhookAdmission_To_webhookadmission_WebhookAdmission(in *WebhookAdmission, out *webhookadmission.WebhookAdmission, s conversion.Scope) error { - out.KubeConfigFile = in.KubeConfigFile - return nil -} - -// Convert_v1alpha1_WebhookAdmission_To_webhookadmission_WebhookAdmission is an autogenerated conversion function. -func Convert_v1alpha1_WebhookAdmission_To_webhookadmission_WebhookAdmission(in *WebhookAdmission, out *webhookadmission.WebhookAdmission, s conversion.Scope) error { - return autoConvert_v1alpha1_WebhookAdmission_To_webhookadmission_WebhookAdmission(in, out, s) -} - -func autoConvert_webhookadmission_WebhookAdmission_To_v1alpha1_WebhookAdmission(in *webhookadmission.WebhookAdmission, out *WebhookAdmission, s conversion.Scope) error { - out.KubeConfigFile = in.KubeConfigFile - return nil -} - -// Convert_webhookadmission_WebhookAdmission_To_v1alpha1_WebhookAdmission is an autogenerated conversion function. -func Convert_webhookadmission_WebhookAdmission_To_v1alpha1_WebhookAdmission(in *webhookadmission.WebhookAdmission, out *WebhookAdmission, s conversion.Scope) error { - return autoConvert_webhookadmission_WebhookAdmission_To_v1alpha1_WebhookAdmission(in, out, s) -} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/kubeconfig.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/kubeconfig.go index 7b845f1d19..1b751effa0 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/kubeconfig.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/kubeconfig.go @@ -25,46 +25,49 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/admission/plugin/manifest" "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission" - "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1" - "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1" + v1 "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1" ) var ( scheme = runtime.NewScheme() - codecs = serializer.NewCodecFactory(scheme) + codecs = serializer.NewCodecFactory(scheme, serializer.EnableStrict) ) func init() { utilruntime.Must(webhookadmission.AddToScheme(scheme)) utilruntime.Must(v1.AddToScheme(scheme)) - utilruntime.Must(v1alpha1.AddToScheme(scheme)) } -// LoadConfig extract the KubeConfigFile from configFile -func LoadConfig(configFile io.Reader) (string, error) { - var kubeconfigFile string - if configFile != nil { - // we have a config so parse it. - data, err := io.ReadAll(configFile) - if err != nil { - return "", err - } - decoder := codecs.UniversalDecoder() - decodedObj, err := runtime.Decode(decoder, data) - if err != nil { - return "", err - } - config, ok := decodedObj.(*webhookadmission.WebhookAdmission) - if !ok { - return "", fmt.Errorf("unexpected type: %T", decodedObj) - } +// LoadConfig extracts the webhook admission configuration from configFile. +func LoadConfig(configFile io.Reader) (*webhookadmission.WebhookAdmission, error) { + if configFile == nil { + return &webhookadmission.WebhookAdmission{}, nil + } + // we have a config so parse it. + data, err := io.ReadAll(configFile) + if err != nil { + return nil, err + } + decoder := codecs.UniversalDecoder() + decodedObj, err := runtime.Decode(decoder, data) + if err != nil { + return nil, err + } + config, ok := decodedObj.(*webhookadmission.WebhookAdmission) + if !ok { + return nil, fmt.Errorf("unexpected type: %T", decodedObj) + } - if !path.IsAbs(config.KubeConfigFile) { - return "", field.Invalid(field.NewPath("kubeConfigFile"), config.KubeConfigFile, "must be an absolute file path") - } + // KubeConfigFile may be empty when only staticManifestsDir is configured. + if len(config.KubeConfigFile) > 0 && !path.IsAbs(config.KubeConfigFile) { + return nil, field.Invalid(field.NewPath("kubeConfigFile"), config.KubeConfigFile, "must be an absolute file path") + } - kubeconfigFile = config.KubeConfigFile + if err := manifest.ValidateStaticManifestsDir(config.StaticManifestsDir); err != nil { + return nil, err } - return kubeconfigFile, nil + + return config, nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/composite_webhook_source.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/composite_webhook_source.go new file mode 100644 index 0000000000..3b38c9fade --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/composite_webhook_source.go @@ -0,0 +1,99 @@ +/* +Copyright 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 generic + +import ( + "sync" + + "k8s.io/apiserver/pkg/admission/plugin/webhook" +) + +// compositeWebhookSource combines multiple webhook sources into a single source. +// Static (manifest-based) webhooks are returned before API-based webhooks. +type compositeWebhookSource struct { + staticSource Source + apiSource Source + + mu sync.RWMutex + lastStaticSlice []webhook.WebhookAccessor + lastAPISlice []webhook.WebhookAccessor + lastCombined []webhook.WebhookAccessor +} + +var _ Source = &compositeWebhookSource{} + +// NewCompositeWebhookSource creates a webhook source that combines static and API-based sources. +// Static webhooks are evaluated first, followed by API-based webhooks. +// If staticSource is nil, only apiSource webhooks are returned. +func NewCompositeWebhookSource(staticSource, apiSource Source) Source { + if staticSource == nil { + return apiSource + } + return &compositeWebhookSource{ + staticSource: staticSource, + apiSource: apiSource, + } +} + +// Webhooks returns all webhook accessors from both sources. +// Static webhooks come first, followed by API-based webhooks. +// The combined slice is cached and reused when the underlying slices haven't changed. +func (c *compositeWebhookSource) Webhooks() []webhook.WebhookAccessor { + var staticSlice, apiSlice []webhook.WebhookAccessor + if c.staticSource != nil { + staticSlice = c.staticSource.Webhooks() + } + if c.apiSource != nil { + apiSlice = c.apiSource.Webhooks() + } + + c.mu.RLock() + if slicesAreEqual(c.lastStaticSlice, staticSlice) && slicesAreEqual(c.lastAPISlice, apiSlice) { + combined := c.lastCombined + c.mu.RUnlock() + return combined + } + c.mu.RUnlock() + + c.mu.Lock() + defer c.mu.Unlock() + // Re-check under write lock. + if slicesAreEqual(c.lastStaticSlice, staticSlice) && slicesAreEqual(c.lastAPISlice, apiSlice) { + return c.lastCombined + } + + combined := make([]webhook.WebhookAccessor, 0, len(staticSlice)+len(apiSlice)) + combined = append(combined, staticSlice...) + combined = append(combined, apiSlice...) + + c.lastStaticSlice = staticSlice + c.lastAPISlice = apiSlice + c.lastCombined = combined + return combined +} + +// slicesAreEqual reports whether two slices share the same backing array and length. +func slicesAreEqual[T any](a, b []T) bool { + return len(a) == len(b) && (len(a) == 0 || &a[0] == &b[0]) +} + +// HasSynced returns true only when both sources have synced. +func (c *compositeWebhookSource) HasSynced() bool { + staticSynced := c.staticSource == nil || c.staticSource.HasSynced() + apiSynced := c.apiSource == nil || c.apiSource.HasSynced() + return staticSynced && apiSynced +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go index bf646d0080..cef27b2330 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go @@ -22,6 +22,7 @@ import ( "io" "k8s.io/apiserver/pkg/cel/environment" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" admissionv1 "k8s.io/api/admission/v1" @@ -39,8 +40,10 @@ import ( "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules" "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/features" webhookutil "k8s.io/apiserver/pkg/util/webhook" "k8s.io/client-go/informers" + coreinformers "k8s.io/client-go/informers/core/v1" clientset "k8s.io/client-go/kubernetes" ) @@ -48,28 +51,63 @@ import ( type Webhook struct { *admission.Handler - sourceFactory sourceFactory + // Factories for creating webhook sources. + apiSourceFactory sourceFactory + staticSourceFactory StaticSourceFactory - hookSource Source - clientManager *webhookutil.ClientManager - namespaceMatcher *namespace.Matcher - objectMatcher *object.Matcher - dispatcher Dispatcher - filterCompiler cel.ConditionCompiler - authorizer authorizer.Authorizer + // Configuration provided via admission config file and initializers. + staticManifestsDir string // path to static webhook manifest directory (optional) + apiServerID string // identity of this API server instance, used for metrics + + // hookSource is the webhook source used at admission time. When staticManifestsDir + // is configured, this is a composite source combining staticSource (loaded from disk) + // with apiSource (from the API). Otherwise, it points directly to apiSource. + hookSource Source + // apiSource provides webhook configurations from the Kubernetes API (informer-based). + apiSource Source + // staticSource holds a reference to only the static (manifest-based) webhook source. + // This can be used to route requests for excluded resources to static hooks only. + staticSource ReloadableSource + + // Admission-time dependencies. + namespaceInformer coreinformers.NamespaceInformer + clientManager *webhookutil.ClientManager + namespaceMatcher *namespace.Matcher + objectMatcher *object.Matcher + dispatcher Dispatcher + filterCompiler cel.ConditionCompiler + authorizer authorizer.Authorizer + + // Lifecycle. + stopCh <-chan struct{} } var ( _ genericadmissioninit.WantsExternalKubeClientSet = &Webhook{} + _ genericadmissioninit.WantsDrainedNotification = &Webhook{} + _ genericadmissioninit.WantsAPIServerID = &Webhook{} _ admission.Interface = &Webhook{} ) type sourceFactory func(f informers.SharedInformerFactory) Source type dispatcherFactory func(cm *webhookutil.ClientManager) Dispatcher +// ReloadableSource extends Source with a method to run a reload loop +// that watches for configuration changes and blocks until the context is canceled. +type ReloadableSource interface { + Source + // RunReloadLoop watches for configuration changes and reloads when detected. + // It blocks until ctx is canceled. + RunReloadLoop(ctx context.Context) +} + +// StaticSourceFactory creates a static webhook source from a manifest directory. +// The returned Source should have LoadInitial() already called. +type StaticSourceFactory func(manifestsDir string) (ReloadableSource, error) + // NewWebhook creates a new generic admission webhook. func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory sourceFactory, dispatcherFactory dispatcherFactory) (*Webhook, error) { - kubeconfigFile, err := config.LoadConfig(configFile) + cfg, err := config.LoadConfig(configFile) if err != nil { return nil, err } @@ -85,7 +123,7 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory if err != nil { return nil, err } - authInfoResolver, err := webhookutil.NewDefaultAuthenticationInfoResolver(kubeconfigFile) + authInfoResolver, err := webhookutil.NewDefaultAuthenticationInfoResolver(cfg.KubeConfigFile) if err != nil { return nil, err } @@ -94,13 +132,14 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory cm.SetServiceResolver(webhookutil.NewDefaultServiceResolver()) return &Webhook{ - Handler: handler, - sourceFactory: sourceFactory, - clientManager: &cm, - namespaceMatcher: &namespace.Matcher{}, - objectMatcher: &object.Matcher{}, - dispatcher: dispatcherFactory(&cm), - filterCompiler: cel.NewConditionCompiler(environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion())), + Handler: handler, + apiSourceFactory: sourceFactory, + staticManifestsDir: cfg.StaticManifestsDir, + clientManager: &cm, + namespaceMatcher: &namespace.Matcher{}, + objectMatcher: &object.Matcher{}, + dispatcher: dispatcherFactory(&cm), + filterCompiler: cel.NewConditionCompiler(environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion())), }, nil } @@ -117,6 +156,29 @@ func (a *Webhook) SetServiceResolver(sr webhookutil.ServiceResolver) { a.clientManager.SetServiceResolver(sr) } +// SetStaticSourceFactory sets the factory for creating static webhook sources. +// This should be called before SetExternalKubeInformerFactory. +func (a *Webhook) SetStaticSourceFactory(factory StaticSourceFactory) { + a.staticSourceFactory = factory +} + +// SetAPIServerID implements the WantsAPIServerID interface. +// The API server ID is used for metrics labeling and must be set before +// SetExternalKubeInformerFactory is called. +func (a *Webhook) SetAPIServerID(id string) { + a.apiServerID = id +} + +// GetAPIServerID returns the stored API server ID. +func (a *Webhook) GetAPIServerID() string { + return a.apiServerID +} + +// SetDrainedNotification implements the WantsDrainedNotification interface. +func (a *Webhook) SetDrainedNotification(stopCh <-chan struct{}) { + a.stopCh = stopCh +} + // SetExternalKubeClientSet implements the WantsExternalKubeInformerFactory interface. // It sets external ClientSet for admission plugins that need it func (a *Webhook) SetExternalKubeClientSet(client clientset.Interface) { @@ -127,10 +189,10 @@ func (a *Webhook) SetExternalKubeClientSet(client clientset.Interface) { func (a *Webhook) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { namespaceInformer := f.Core().V1().Namespaces() a.namespaceMatcher.NamespaceLister = namespaceInformer.Lister() - a.hookSource = a.sourceFactory(f) - a.SetReadyFunc(func() bool { - return namespaceInformer.Informer().HasSynced() && a.hookSource.HasSynced() - }) + a.namespaceInformer = namespaceInformer + + // Create the API-based source (stored for later use in ValidateInitialization) + a.apiSource = a.apiSourceFactory(f) } func (a *Webhook) SetAuthorizer(authorizer authorizer.Authorizer) { @@ -138,8 +200,10 @@ func (a *Webhook) SetAuthorizer(authorizer authorizer.Authorizer) { } // ValidateInitialization implements the InitializationValidator interface. +// Static source creation happens here (after all initializers have run) because +// SetManifestLoaders may be called after SetExternalKubeInformerFactory. func (a *Webhook) ValidateInitialization() error { - if a.hookSource == nil { + if a.apiSource == nil { return fmt.Errorf("kubernetes client is not properly setup") } if err := a.namespaceMatcher.Validate(); err != nil { @@ -148,6 +212,46 @@ func (a *Webhook) ValidateInitialization() error { if err := a.clientManager.Validate(); err != nil { return fmt.Errorf("clientManager is not properly setup: %v", err) } + + // Guard: if static manifests dir is set but feature gate is off, return an error + if len(a.staticManifestsDir) > 0 && !utilfeature.DefaultFeatureGate.Enabled(features.ManifestBasedAdmissionControlConfig) { + return fmt.Errorf("static webhook manifests dir %q configured but %s feature gate is not enabled", a.staticManifestsDir, features.ManifestBasedAdmissionControlConfig) + } + + // Construct hookSource. The static source path (which starts goroutines) + // is guarded to avoid duplicate construction. The API-only path is a cheap + // pointer assignment that must reflect the latest apiSource. + if len(a.staticManifestsDir) > 0 { + if a.hookSource == nil { + if a.staticSourceFactory == nil { + return fmt.Errorf("static webhook manifests configured in %q but no static source factory is set", a.staticManifestsDir) + } + if a.stopCh == nil { + return fmt.Errorf("stopCh not set: WantsDrainedNotification must be called before ValidateInitialization") + } + staticSource, err := a.staticSourceFactory(a.staticManifestsDir) + if err != nil { + return fmt.Errorf("failed to load static webhook manifests from %q: %w", a.staticManifestsDir, err) + } + a.staticSource = staticSource + // Start the file watcher in a background goroutine, tied to server shutdown + staticCtx, staticCancel := context.WithCancel(context.Background()) + go func() { + defer staticCancel() + <-a.stopCh + }() + go staticSource.RunReloadLoop(staticCtx) + // Use composite source that combines static + API sources + a.hookSource = NewCompositeWebhookSource(staticSource, a.apiSource) + } + } else { + a.hookSource = a.apiSource + } + + a.SetReadyFunc(func() bool { + return a.namespaceInformer.Informer().HasSynced() && a.hookSource.HasSynced() + }) + return nil } @@ -252,6 +356,16 @@ func (a *attrWithResourceOverride) GetResource() schema.GroupVersionResource { r // Dispatch is called by the downstream Validate or Admit methods. func (a *Webhook) Dispatch(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces) error { if rules.IsExemptAdmissionConfigurationResource(attr) { + // Admission config resources are excluded from API-based webhooks to + // prevent circular dependencies. However, static (manifest-based) webhooks + // are safe to evaluate since they don't have self-referential concerns. + if a.staticSource != nil { + if !a.staticSource.HasSynced() { + return admission.NewForbidden(attr, fmt.Errorf("not yet ready to handle request")) + } + hooks := a.staticSource.Webhooks() + return a.dispatcher.Dispatch(ctx, attr, o, hooks) + } return nil } if !a.WaitForReady() { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader/loader.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader/loader.go new file mode 100644 index 0000000000..258e5b47d7 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader/loader.go @@ -0,0 +1,220 @@ +/* +Copyright 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 loader provides generic functionality to load webhook configurations +// from manifest files. It handles file reading, YAML/JSON decoding, and generic +// manifest validation. Type-specific defaulting and validation (e.g., scheme-based +// defaulting via internal types) are injected by callers through the AcceptObjectFunc +// callback. +package loader + +import ( + "fmt" + "sort" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission/plugin/manifest" + "k8s.io/apiserver/pkg/admission/plugin/webhook" +) + +// AcceptObjectFunc extracts typed items from a decoded runtime.Object, applying +// defaulting and validation. Returns the extracted items, or an error if the +// object type is not recognized or processing fails. +type AcceptObjectFunc[T metav1.Object] func(obj runtime.Object) ([]T, error) + +// LoadManifests loads webhook configurations from manifest files in dir using +// the provided decoder and acceptObject callback. It handles file I/O, YAML +// splitting, decoding, v1.List unwrapping, manifest name validation, webhook +// client config validation, and deterministic sorting by name. +func LoadManifests[T metav1.Object]( + dir string, + decoder runtime.Decoder, + acceptObject AcceptObjectFunc[T], +) ([]T, string, error) { + fileDocs, hash, err := manifest.LoadFiles(dir) + if err != nil { + return nil, "", err + } + + configs := make([]T, 0) + seenNames := map[string]string{} + + for _, fd := range fileDocs { + obj, _, err := decoder.Decode(fd.Doc, nil, nil) + if err != nil { + return nil, "", fmt.Errorf("error loading %s: %w", fd.FilePath, err) + } + + items, err := acceptFileObject(obj, fd.FilePath, seenNames, decoder, acceptObject) + if err != nil { + return nil, "", fmt.Errorf("error loading %s: %w", fd.FilePath, err) + } + configs = append(configs, items...) + } + + sort.Slice(configs, func(i, j int) bool { + return configs[i].GetName() < configs[j].GetName() + }) + + return configs, hash, nil +} + +// acceptFileObject handles type dispatch for a decoded object, including +// generic v1.List unwrapping, manifest name validation, item validation, +// and the default unsupported-type error. +func acceptFileObject[T metav1.Object]( + obj runtime.Object, + filePath string, + seenNames map[string]string, + decoder runtime.Decoder, + acceptObject AcceptObjectFunc[T], +) ([]T, error) { + // Handle generic v1.List by recursing into each item + if list, ok := obj.(*metav1.List); ok { + var allItems []T + for _, rawItem := range list.Items { + itemObj, _, err := decoder.Decode(rawItem.Raw, nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to decode list item: %w", err) + } + items, err := acceptFileObject(itemObj, filePath, seenNames, decoder, acceptObject) + if err != nil { + return nil, err + } + allItems = append(allItems, items...) + } + return allItems, nil + } + + items, err := acceptObject(obj) + if err != nil { + return nil, err + } + for _, item := range items { + if err := validateAcceptedItem(item, filePath, seenNames); err != nil { + return nil, err + } + } + return items, nil +} + +// validateAcceptedItem runs manifest name validation and webhook client config validation. +func validateAcceptedItem[T metav1.Object](item T, filePath string, seenNames map[string]string) error { + name := item.GetName() + if err := manifest.ValidateManifestName(name, filePath, seenNames); err != nil { + return err + } + // Validate webhook client configs for webhook configuration types. + obj, ok := any(item).(runtime.Object) + if !ok { + return fmt.Errorf("type %T does not implement runtime.Object", item) + } + return validateWebhookClientConfigs(obj, name, filePath) +} + +// validateWebhookClientConfigs validates that all webhooks in a configuration +// use URL-based client config (service references are not supported for manifests). +func validateWebhookClientConfigs(obj runtime.Object, configName, filePath string) error { + switch c := obj.(type) { + case *admissionregistrationv1.ValidatingWebhookConfiguration: + for _, wh := range c.Webhooks { + if err := ValidateWebhookClientConfig(wh.Name, configName, filePath, wh.ClientConfig); err != nil { + return err + } + } + case *admissionregistrationv1.MutatingWebhookConfiguration: + for _, wh := range c.Webhooks { + if err := ValidateWebhookClientConfig(wh.Name, configName, filePath, wh.ClientConfig); err != nil { + return err + } + } + default: + return fmt.Errorf("unsupported webhook configuration type %T in file %q", obj, filePath) + } + return nil +} + +// ValidateWebhookClientConfig checks that a webhook uses URL-based client config +// (service references are not supported for static manifests). +func ValidateWebhookClientConfig(webhookName, configName, filePath string, cc admissionregistrationv1.WebhookClientConfig) error { + if cc.Service != nil { + return fmt.Errorf("webhook %q in %q (file %q): clientConfig.service is not supported for static manifests; use clientConfig.url instead", webhookName, configName, filePath) + } + if cc.URL == nil || len(*cc.URL) == 0 { + return fmt.Errorf("webhook %q in %q (file %q): clientConfig.url is required for static manifests", webhookName, configName, filePath) + } + return nil +} + +// ValidatingLoadResult holds the validating webhook configurations loaded from manifest files. +type ValidatingLoadResult struct { + // Configurations is the list of loaded validating webhook configurations. + Configurations []*admissionregistrationv1.ValidatingWebhookConfiguration + // Hash is the sha256 hash of all loaded files, used for change detection. + Hash string +} + +// MutatingLoadResult holds the mutating webhook configurations loaded from manifest files. +type MutatingLoadResult struct { + // Configurations is the list of loaded mutating webhook configurations. + Configurations []*admissionregistrationv1.MutatingWebhookConfiguration + // Hash is the sha256 hash of all loaded files, used for change detection. + Hash string +} + +// BuildValidatingAccessors builds webhook accessors from validating webhook configurations. +func BuildValidatingAccessors(configs []*admissionregistrationv1.ValidatingWebhookConfiguration) []webhook.WebhookAccessor { + var accessors []webhook.WebhookAccessor + for _, config := range configs { + names := map[string]int{} + for i := range config.Webhooks { + w := &config.Webhooks[i] + n := w.Name + uid := fmt.Sprintf("manifest/%s/%s/%d", config.Name, n, names[n]) + names[n]++ + accessors = append(accessors, webhook.NewValidatingWebhookAccessor(uid, config.Name, w)) + } + } + return accessors +} + +// BuildMutatingAccessors builds webhook accessors from mutating webhook configurations. +func BuildMutatingAccessors(configs []*admissionregistrationv1.MutatingWebhookConfiguration) []webhook.WebhookAccessor { + var accessors []webhook.WebhookAccessor + for _, config := range configs { + names := map[string]int{} + for i := range config.Webhooks { + w := &config.Webhooks[i] + n := w.Name + uid := fmt.Sprintf("manifest/%s/%s/%d", config.Name, n, names[n]) + names[n]++ + accessors = append(accessors, webhook.NewMutatingWebhookAccessor(uid, config.Name, w)) + } + } + return accessors +} + +// GetWebhookAccessors returns webhook accessors for all validating webhooks. +func (r *ValidatingLoadResult) GetWebhookAccessors() []webhook.WebhookAccessor { + return BuildValidatingAccessors(r.Configurations) +} + +// GetWebhookAccessors returns webhook accessors for all mutating webhooks. +func (r *MutatingLoadResult) GetWebhookAccessors() []webhook.WebhookAccessor { + return BuildMutatingAccessors(r.Configurations) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source/source.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source/source.go new file mode 100644 index 0000000000..7ebd2bd5c8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source/source.go @@ -0,0 +1,218 @@ +/* +Copyright 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 source provides a Source implementation that loads webhook configurations from manifest files. +package source + +import ( + "context" + "errors" + "fmt" + "sync/atomic" + "time" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission/plugin/manifest/metrics" + "k8s.io/apiserver/pkg/admission/plugin/webhook" + stagingloader "k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader" + "k8s.io/apiserver/pkg/util/filesystem" + "k8s.io/klog/v2" +) + +// defaultReloadInterval is the default interval at which the manifest directory is checked for changes. +var defaultReloadInterval = 1 * time.Minute + +// SetReloadIntervalForTests sets the reload interval for testing and returns a function to restore the original value. +func SetReloadIntervalForTests(interval time.Duration) func() { + original := defaultReloadInterval + defaultReloadInterval = interval + return func() { + defaultReloadInterval = original + } +} + +// ValidatingWebhookLoadFunc loads validating webhook configurations from a directory. +// Returns the configurations, a hash string for change detection, and any error. +type ValidatingWebhookLoadFunc func(dir string) ([]*admissionregistrationv1.ValidatingWebhookConfiguration, string, error) + +// MutatingWebhookLoadFunc loads mutating webhook configurations from a directory. +// Returns the configurations, a hash string for change detection, and any error. +type MutatingWebhookLoadFunc func(dir string) ([]*admissionregistrationv1.MutatingWebhookConfiguration, string, error) + +// accessorBuilder builds webhook accessors from configurations. +type accessorBuilder[T runtime.Object] func(configs []T) []webhook.WebhookAccessor + +// webhookData holds the currently loaded webhook configurations and pre-built accessors. +type webhookData[T runtime.Object] struct { + configurations []T + accessors []webhook.WebhookAccessor +} + +// staticWebhookSource provides webhook configurations loaded from manifest files. +type staticWebhookSource[T runtime.Object] struct { + manifestsDir string + apiServerID string + reloadInterval time.Duration + webhookType metrics.ManifestType + loadFunc func(dir string) ([]T, string, error) + buildAccessors accessorBuilder[T] + + current atomic.Pointer[webhookData[T]] + lastReadHash atomic.Pointer[string] // hash of last file content read (for short-circuiting) + hasSynced atomic.Bool +} + +// ValidatingSource provides validating webhook configurations loaded from manifest files. +type ValidatingSource struct { + *staticWebhookSource[*admissionregistrationv1.ValidatingWebhookConfiguration] +} + +// MutatingSource provides mutating webhook configurations loaded from manifest files. +type MutatingSource struct { + *staticWebhookSource[*admissionregistrationv1.MutatingWebhookConfiguration] +} + +// NewValidatingSource creates a new validating webhook source that loads configurations from the specified directory. +func NewValidatingSource(manifestsDir, apiServerID string, loadFunc ValidatingWebhookLoadFunc) *ValidatingSource { + metrics.RegisterMetrics() + return &ValidatingSource{ + staticWebhookSource: &staticWebhookSource[*admissionregistrationv1.ValidatingWebhookConfiguration]{ + manifestsDir: manifestsDir, + apiServerID: apiServerID, + reloadInterval: defaultReloadInterval, + webhookType: metrics.ValidatingWebhookManifestType, + loadFunc: loadFunc, + buildAccessors: stagingloader.BuildValidatingAccessors, + }, + } +} + +// NewMutatingSource creates a new mutating webhook source that loads configurations from the specified directory. +func NewMutatingSource(manifestsDir, apiServerID string, loadFunc MutatingWebhookLoadFunc) *MutatingSource { + metrics.RegisterMetrics() + return &MutatingSource{ + staticWebhookSource: &staticWebhookSource[*admissionregistrationv1.MutatingWebhookConfiguration]{ + manifestsDir: manifestsDir, + apiServerID: apiServerID, + reloadInterval: defaultReloadInterval, + webhookType: metrics.MutatingWebhookManifestType, + loadFunc: loadFunc, + buildAccessors: stagingloader.BuildMutatingAccessors, + }, + } +} + +// LoadInitial performs the initial load of webhook manifests. +func (s *staticWebhookSource[T]) LoadInitial() error { + configs, hash, err := s.loadFunc(s.manifestsDir) + if err != nil { + return err + } + + accessors := s.buildAccessors(configs) + + // Validate accessors eagerly to catch selector parse errors at startup. + if err := validateAccessors(accessors); err != nil { + return err + } + + s.current.Store(&webhookData[T]{configurations: configs, accessors: accessors}) + s.lastReadHash.Store(&hash) + s.hasSynced.Store(true) + + klog.InfoS("Loaded manifest-based webhook configurations", "plugin", string(s.webhookType), + "configurations", len(configs)) + metrics.RecordAutomaticReloadSuccess(s.webhookType, s.apiServerID, hash) + return nil +} + +// RunReloadLoop watches for configuration changes and reloads when detected. +// It blocks until ctx is canceled. +func (s *staticWebhookSource[T]) RunReloadLoop(ctx context.Context) { + filesystem.WatchUntil( + ctx, + s.reloadInterval, + s.manifestsDir, + func() { + s.checkAndReload() + }, + func(err error) { + klog.ErrorS(err, "watching manifest directory", "plugin", string(s.webhookType), "dir", s.manifestsDir) + }, + ) +} + +func (s *staticWebhookSource[T]) checkAndReload() { + configs, hash, err := s.loadFunc(s.manifestsDir) + if err != nil { + klog.ErrorS(err, "reloading admission manifest config", "plugin", string(s.webhookType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadFailure(s.webhookType, s.apiServerID) + return + } + + // Short-circuit if file content hasn't changed since last read. + if last := s.lastReadHash.Load(); last != nil && hash == *last { + return + } + s.lastReadHash.Store(&hash) + + // Build and validate accessors (configs may be empty if files deleted) + accessors := s.buildAccessors(configs) + if err := validateAccessors(accessors); err != nil { + klog.ErrorS(err, "manifest webhook accessor validation failed after reload", "plugin", string(s.webhookType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadFailure(s.webhookType, s.apiServerID) + return + } + + s.current.Store(&webhookData[T]{configurations: configs, accessors: accessors}) + klog.InfoS("reloaded admission manifest config", "plugin", string(s.webhookType), "dir", s.manifestsDir) + metrics.RecordAutomaticReloadSuccess(s.webhookType, s.apiServerID, hash) +} + +// HasSynced returns true if the initial load has completed. +func (s *staticWebhookSource[T]) HasSynced() bool { + return s.hasSynced.Load() +} + +// Webhooks returns the list of webhook accessors. +func (s *staticWebhookSource[T]) Webhooks() []webhook.WebhookAccessor { + current := s.current.Load() + if current == nil { + return nil + } + return current.accessors +} + +// validateAccessors exercises lazy getters on each accessor to surface latent +// errors (e.g. invalid label selectors) early. +// Note: We intentionally skip GetRESTClient validation here because it requires +// a ClientManager. API validation (applied during defaulting) already ensures +// CA bundles parse and URLs are present and valid, and the manifest loader +// rejects service references, which covers the inputs needed to construct a +// REST client at admission time. +func validateAccessors(accessors []webhook.WebhookAccessor) error { + var errs []error + for _, a := range accessors { + if _, err := a.GetParsedNamespaceSelector(); err != nil { + errs = append(errs, fmt.Errorf("webhook %q: invalid namespaceSelector: %w", a.GetName(), err)) + } + if _, err := a.GetParsedObjectSelector(); err != nil { + errs = append(errs, fmt.Errorf("webhook %q: invalid objectSelector: %w", a.GetName(), err)) + } + } + return errors.Join(errs...) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/plugin.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/plugin.go index fb07a61c1b..4ffd4c97d6 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/plugin.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/plugin.go @@ -22,7 +22,9 @@ import ( "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/configuration" + "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" + "k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source" ) const ( @@ -48,6 +50,22 @@ type Plugin struct { } var _ admission.MutationInterface = &Plugin{} +var _ initializer.WantsManifestLoaders = &Plugin{} + +// SetManifestLoaders provides the manifest load functions for scheme-based defaulting and validation. +func (a *Plugin) SetManifestLoaders(loaders *initializer.ManifestLoaders) { + if loaders == nil || loaders.LoadMutatingWebhookManifests == nil { + return + } + loadFunc := loaders.LoadMutatingWebhookManifests + a.Webhook.SetStaticSourceFactory(func(manifestsDir string) (generic.ReloadableSource, error) { + src := source.NewMutatingSource(manifestsDir, a.Webhook.GetAPIServerID(), source.MutatingWebhookLoadFunc(loadFunc)) + if err := src.LoadInitial(); err != nil { + return nil, err + } + return src, nil + }) +} // NewMutatingWebhook returns a generic admission webhook plugin. func NewMutatingWebhook(configFile io.Reader) (*Plugin, error) { @@ -58,7 +76,6 @@ func NewMutatingWebhook(configFile io.Reader) (*Plugin, error) { if err != nil { return nil, err } - return p, nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/reinvocationcontext.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/reinvocationcontext.go index de0af221e1..d7237d0518 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/reinvocationcontext.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/reinvocationcontext.go @@ -27,9 +27,9 @@ type webhookReinvokeContext struct { lastWebhookOutput runtime.Object // previouslyInvokedReinvocableWebhooks holds the set of webhooks that have been invoked and // should be reinvoked if a later mutation occurs - previouslyInvokedReinvocableWebhooks sets.String + previouslyInvokedReinvocableWebhooks sets.Set[string] // reinvokeWebhooks holds the set of webhooks that should be reinvoked - reinvokeWebhooks sets.String + reinvokeWebhooks sets.Set[string] } func (rc *webhookReinvokeContext) ShouldReinvokeWebhook(webhook string) bool { @@ -50,7 +50,7 @@ func (rc *webhookReinvokeContext) SetLastWebhookInvocationOutput(object runtime. func (rc *webhookReinvokeContext) AddReinvocableWebhookToPreviouslyInvoked(webhook string) { if rc.previouslyInvokedReinvocableWebhooks == nil { - rc.previouslyInvokedReinvocableWebhooks = sets.NewString() + rc.previouslyInvokedReinvocableWebhooks = sets.New[string]() } rc.previouslyInvokedReinvocableWebhooks.Insert(webhook) } @@ -58,11 +58,11 @@ func (rc *webhookReinvokeContext) AddReinvocableWebhookToPreviouslyInvoked(webho func (rc *webhookReinvokeContext) RequireReinvokingPreviouslyInvokedPlugins() { if len(rc.previouslyInvokedReinvocableWebhooks) > 0 { if rc.reinvokeWebhooks == nil { - rc.reinvokeWebhooks = sets.NewString() + rc.reinvokeWebhooks = sets.New[string]() } for s := range rc.previouslyInvokedReinvocableWebhooks { rc.reinvokeWebhooks.Insert(s) } - rc.previouslyInvokedReinvocableWebhooks = sets.NewString() + rc.previouslyInvokedReinvocableWebhooks = sets.New[string]() } } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/plugin.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/plugin.go index 6972877b18..da20960210 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/plugin.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/plugin.go @@ -22,7 +22,9 @@ import ( "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/configuration" + "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" + "k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source" ) const ( @@ -48,6 +50,22 @@ type Plugin struct { } var _ admission.ValidationInterface = &Plugin{} +var _ initializer.WantsManifestLoaders = &Plugin{} + +// SetManifestLoaders provides the manifest load functions for scheme-based defaulting and validation. +func (a *Plugin) SetManifestLoaders(loaders *initializer.ManifestLoaders) { + if loaders == nil || loaders.LoadValidatingWebhookManifests == nil { + return + } + loadFunc := loaders.LoadValidatingWebhookManifests + a.Webhook.SetStaticSourceFactory(func(manifestsDir string) (generic.ReloadableSource, error) { + src := source.NewValidatingSource(manifestsDir, a.Webhook.GetAPIServerID(), source.ValidatingWebhookLoadFunc(loadFunc)) + if err := src.LoadInitial(); err != nil { + return nil, err + } + return src, nil + }) +} // NewValidatingAdmissionWebhook returns a generic admission webhook plugin. func NewValidatingAdmissionWebhook(configFile io.Reader) (*Plugin, error) { diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go index 596b1f140a..0c5e6b5485 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -146,6 +146,10 @@ type TLSConfig struct { // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientCert string + + // tlsServerName is used to check server certificate. If tlsServerName is empty, the hostname used to contact the server is used. + // +optional + TLSServerName string } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index 6e0f86da86..1e20c697b5 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -147,6 +147,10 @@ type TLSConfig struct { // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientCert string `json:"clientCert,omitempty"` + + // tlsServerName is used to check server certificate. If tlsServerName is empty, the hostname used to contact the server is used. + // +optional + TLSServerName string `json:"tlsServerName,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go index 9d7a8ce627..4ea0297895 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go @@ -817,6 +817,7 @@ func autoConvert_v1alpha1_TLSConfig_To_apiserver_TLSConfig(in *TLSConfig, out *a out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert + out.TLSServerName = in.TLSServerName return nil } @@ -829,6 +830,7 @@ func autoConvert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in *apiserver.TLSConf out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert + out.TLSServerName = in.TLSServerName return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go index 16260efb66..44bfbbd3c1 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go @@ -118,6 +118,10 @@ type TLSConfig struct { // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientCert string `json:"clientCert,omitempty"` + + // tlsServerName is used to check server certificate. If tlsServerName is empty, the hostname used to contact the server is used. + // +optional + TLSServerName string `json:"tlsServerName,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go index 4f25bd60c2..04323e2082 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go @@ -753,6 +753,7 @@ func autoConvert_v1beta1_TLSConfig_To_apiserver_TLSConfig(in *TLSConfig, out *ap out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert + out.TLSServerName = in.TLSServerName return nil } @@ -765,6 +766,7 @@ func autoConvert_apiserver_TLSConfig_To_v1beta1_TLSConfig(in *apiserver.TLSConfi out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert + out.TLSServerName = in.TLSServerName return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation.go index be85d4f3d7..a5eeaef60f 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation.go @@ -763,7 +763,7 @@ func ValidateWebhookConfiguration(compiler authorizationcel.Compiler, fldPath *f allErrs = append(allErrs, field.NotSupported(fldPath.Child("connectionInfo", "type"), c.ConnectionInfo, []string{api.AuthorizationWebhookConnectionInfoTypeInCluster, api.AuthorizationWebhookConnectionInfoTypeKubeConfigFile})) } - _, errs := compileMatchConditions(compiler, c.MatchConditions, fldPath, utilfeature.DefaultFeatureGate.Enabled(features.StructuredAuthorizationConfiguration)) + _, errs := compileMatchConditions(compiler, c.MatchConditions, fldPath) allErrs = append(allErrs, errs...) return allErrs @@ -772,15 +772,11 @@ func ValidateWebhookConfiguration(compiler authorizationcel.Compiler, fldPath *f // ValidateAndCompileMatchConditions validates a given webhook's matchConditions. // This is exported for use in authz package. func ValidateAndCompileMatchConditions(compiler authorizationcel.Compiler, matchConditions []api.WebhookMatchCondition) (*authorizationcel.CELMatcher, field.ErrorList) { - return compileMatchConditions(compiler, matchConditions, nil, utilfeature.DefaultFeatureGate.Enabled(features.StructuredAuthorizationConfiguration)) + return compileMatchConditions(compiler, matchConditions, nil) } -func compileMatchConditions(compiler authorizationcel.Compiler, matchConditions []api.WebhookMatchCondition, fldPath *field.Path, structuredAuthzFeatureEnabled bool) (*authorizationcel.CELMatcher, field.ErrorList) { +func compileMatchConditions(compiler authorizationcel.Compiler, matchConditions []api.WebhookMatchCondition, fldPath *field.Path) (*authorizationcel.CELMatcher, field.ErrorList) { var allErrs field.ErrorList - // should fail when match conditions are used without feature enabled - if len(matchConditions) > 0 && !structuredAuthzFeatureEnabled { - allErrs = append(allErrs, field.Invalid(fldPath.Child("matchConditions"), "", "not supported when StructuredAuthorizationConfiguration feature gate is disabled")) - } if len(matchConditions) > 64 { allErrs = append(allErrs, field.TooMany(fldPath.Child("matchConditions"), len(matchConditions), 64)) return nil, allErrs diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_patch.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_patch.go new file mode 100644 index 0000000000..e1a79d2066 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/validation/validation_patch.go @@ -0,0 +1,39 @@ +/* +Copyright 2026 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 validation + +import ( + celgo "github.com/google/cel-go/cel" + authenticationcel "k8s.io/apiserver/pkg/authentication/cel" +) + +// UPSTREAM: : Export email claim validation functions for use in OpenShift authentication validation + +// UsesEmailClaim checks if the given CEL AST references claims.email +func UsesEmailClaim(ast *celgo.Ast) bool { + return usesEmailClaim(ast) +} + +// UsesEmailVerifiedClaim checks if the given CEL AST references claims.email_verified +func UsesEmailVerifiedClaim(ast *celgo.Ast) bool { + return usesEmailVerifiedClaim(ast) +} + +// AnyUsesEmailVerifiedClaim checks if any of the given compilation results reference claims.email_verified +func AnyUsesEmailVerifiedClaim(results []authenticationcel.CompilationResult) bool { + return anyUsesEmailVerifiedClaim(results) +} diff --git a/vendor/k8s.io/apiserver/pkg/apis/audit/types.go b/vendor/k8s.io/apiserver/pkg/apis/audit/types.go index dfc9c4fd23..6218ae315c 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/audit/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/audit/types.go @@ -275,6 +275,7 @@ type PolicyRule struct { type GroupResources struct { // Group is the name of the API group that contains the resources. // The empty string represents the core API group. + // `*` matches all groups // +optional Group string // Resources is a list of resources this rule applies to. diff --git a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto b/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto index 632db99862..db0afa5e42 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto +++ b/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.proto @@ -135,6 +135,7 @@ message EventList { message GroupResources { // Group is the name of the API group that contains the resources. // The empty string represents the core API group. + // `*` matches all groups // +optional optional string group = 1; diff --git a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.protomessage.pb.go b/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.protomessage.pb.go deleted file mode 100644 index 93920227e1..0000000000 --- a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*AuthenticationMetadata) ProtoMessage() {} - -func (*Event) ProtoMessage() {} - -func (*EventList) ProtoMessage() {} - -func (*GroupResources) ProtoMessage() {} - -func (*ObjectReference) ProtoMessage() {} - -func (*Policy) ProtoMessage() {} - -func (*PolicyList) ProtoMessage() {} - -func (*PolicyRule) ProtoMessage() {} diff --git a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/types.go b/vendor/k8s.io/apiserver/pkg/apis/audit/v1/types.go index 28d3f2ace3..8c6dc676af 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/audit/v1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/audit/v1/types.go @@ -278,6 +278,7 @@ type PolicyRule struct { type GroupResources struct { // Group is the name of the API group that contains the resources. // The empty string represents the core API group. + // `*` matches all groups // +optional Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` // Resources is a list of resources this rule applies to. diff --git a/vendor/k8s.io/apiserver/pkg/apis/audit/validation/validation.go b/vendor/k8s.io/apiserver/pkg/apis/audit/validation/validation.go index 0611c1ae5f..3b0d077fd4 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/audit/validation/validation.go +++ b/vendor/k8s.io/apiserver/pkg/apis/audit/validation/validation.go @@ -98,7 +98,7 @@ func validateResources(groupResources []audit.GroupResources, fldPath *field.Pat var allErrs field.ErrorList for _, groupResource := range groupResources { // The empty string represents the core API group. - if len(groupResource.Group) != 0 { + if len(groupResource.Group) != 0 && groupResource.Group != "*" { // Group names must be lower case and be valid DNS subdomains. // reference: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md // an error is returned for group name like rbac.authorization.k8s.io/v1beta1 diff --git a/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go b/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go index cd6ec92bc8..9c21e2348a 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go +++ b/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go @@ -191,7 +191,7 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool name := attrs.GetName() for _, gr := range r.Resources { - if gr.Group == apiGroup { + if gr.Group == apiGroup || gr.Group == "*" { if len(gr.Resources) == 0 { return true } diff --git a/vendor/k8s.io/apiserver/pkg/audit/union.go b/vendor/k8s.io/apiserver/pkg/audit/union.go index 0766a9207b..39dd74f740 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/union.go +++ b/vendor/k8s.io/apiserver/pkg/audit/union.go @@ -48,7 +48,6 @@ func (u union) ProcessEvents(events ...*auditinternal.Event) bool { func (u union) Run(stopCh <-chan struct{}) error { var funcs []func() error for _, backend := range u.backends { - backend := backend funcs = append(funcs, func() error { return backend.Run(stopCh) }) diff --git a/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader_controller.go b/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader_controller.go index a9e76fe011..e5419d0cec 100644 --- a/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader_controller.go +++ b/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader_controller.go @@ -174,7 +174,7 @@ func (c *RequestHeaderAuthRequestController) AllowedClientNames() []string { // Run starts RequestHeaderAuthRequestController controller and blocks until stopCh is closed. func (c *RequestHeaderAuthRequestController) Run(ctx context.Context, workers int) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer c.queue.ShutDown() klog.Infof("Starting %s", c.name) diff --git a/vendor/k8s.io/apiserver/pkg/authentication/request/websocket/protocol.go b/vendor/k8s.io/apiserver/pkg/authentication/request/websocket/protocol.go index ee8c89f5ce..a3a7833156 100644 --- a/vendor/k8s.io/apiserver/pkg/authentication/request/websocket/protocol.go +++ b/vendor/k8s.io/apiserver/pkg/authentication/request/websocket/protocol.go @@ -24,8 +24,8 @@ import ( "strings" "unicode/utf8" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/streaming/pkg/httpstream/wsstream" ) const bearerProtocolPrefix = "base64url.bearer.authorization.k8s.io." diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/cidr.go b/vendor/k8s.io/apiserver/pkg/cel/library/cidr.go index a638fd4ac1..befc05d706 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/cidr.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/cidr.go @@ -82,24 +82,24 @@ import ( // // Examples: // -// cidr('192.168.0.0/24').containsIP(ip('192.168.0.1')) // returns true -// cidr('192.168.0.0/24').containsIP(ip('192.168.1.1')) // returns false -// cidr('192.168.0.0/24').containsIP('192.168.0.1') // returns true -// cidr('192.168.0.0/24').containsIP('192.168.1.1') // returns false -// cidr('192.168.0.0/16').containsCIDR(cidr('192.168.10.0/24')) // returns true -// cidr('192.168.1.0/24').containsCIDR(cidr('192.168.2.0/24')) // returns false -// cidr('192.168.0.0/16').containsCIDR('192.168.10.0/24') // returns true -// cidr('192.168.1.0/24').containsCIDR('192.168.2.0/24') // returns false -// cidr('192.168.0.1/24').ip() // returns ipAddr('192.168.0.1') -// cidr('192.168.0.1/24').ip().family() // returns '4' -// cidr('::1/128').ip() // returns ipAddr('::1') -// cidr('::1/128').ip().family() // returns '6' -// cidr('192.168.0.0/24').masked() // returns cidr('192.168.0.0/24') -// cidr('192.168.0.1/24').masked() // returns cidr('192.168.0.0/24') -// cidr('192.168.0.0/24') == cidr('192.168.0.0/24').masked() // returns true, CIDR was already in canonical format -// cidr('192.168.0.1/24') == cidr('192.168.0.1/24').masked() // returns false, CIDR was not in canonical format -// cidr('192.168.0.0/16').prefixLength() // returns 16 -// cidr('::1/128').prefixLength() // returns 128 +// cidr('192.168.0.0/24').containsIP(ip('192.168.0.1')) // returns true +// cidr('192.168.0.0/24').containsIP(ip('192.168.1.1')) // returns false +// cidr('192.168.0.0/24').containsIP('192.168.0.1') // returns true +// cidr('192.168.0.0/24').containsIP('192.168.1.1') // returns false +// cidr('192.168.0.0/16').containsCIDR(cidr('192.168.10.0/24')) // returns true +// cidr('192.168.1.0/24').containsCIDR(cidr('192.168.2.0/24')) // returns false +// cidr('192.168.0.0/16').containsCIDR('192.168.10.0/24') // returns true +// cidr('192.168.1.0/24').containsCIDR('192.168.2.0/24') // returns false +// cidr('192.168.0.1/24').ip() // returns ipAddr('192.168.0.1') +// cidr('192.168.0.1/24').ip().family() // returns '4' +// cidr('::1/128').ip() // returns ipAddr('::1') +// cidr('::1/128').ip().family() // returns '6' +// cidr('192.168.0.0/24').masked() // returns cidr('192.168.0.0/24') +// cidr('192.168.0.1/24').masked() // returns cidr('192.168.0.0/24') +// cidr('192.168.0.0/24') == cidr('192.168.0.0/24').masked() // returns true, CIDR was already in canonical format +// cidr('192.168.0.1/24') == cidr('192.168.0.1/24').masked() // returns false, CIDR was not in canonical format +// cidr('192.168.0.0/16').prefixLength() // returns 16 +// cidr('::1/128').prefixLength() // returns 128 func CIDR() cel.EnvOption { return cel.Lib(cidrsLib) } diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/format.go b/vendor/k8s.io/apiserver/pkg/cel/library/format.go index 2adc35c905..e8b2d07b55 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/format.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/format.go @@ -41,53 +41,53 @@ var ( // Format provides a CEL library exposing common named Kubernetes string // validations. Can be used in CRD ValidationRules messageExpression. // -// Example: +// Example: // -// rule: format.dns1123label.validate(object.metadata.name).hasValue() -// messageExpression: format.dns1123label.validate(object.metadata.name).value().join("\n") +// rule: format.dns1123label.validate(object.metadata.name).hasValue() +// messageExpression: format.dns1123label.validate(object.metadata.name).value().join("\n") // // format.named(name: string) -> ?Format // -// Returns the Format with the given name, if it exists. Otherwise, optional.none -// Allowed names are: -// - `dns1123Label` -// - `dns1123Subdomain` -// - `dns1035Label` -// - `qualifiedName` -// - `dns1123LabelPrefix` -// - `dns1123SubdomainPrefix` -// - `dns1035LabelPrefix` -// - `labelValue` -// - `uri` -// - `uuid` -// - `byte` -// - `date` -// - `datetime` +// Returns the Format with the given name, if it exists. Otherwise, optional.none +// Allowed names are: +// - `dns1123Label` +// - `dns1123Subdomain` +// - `dns1035Label` +// - `qualifiedName` +// - `dns1123LabelPrefix` +// - `dns1123SubdomainPrefix` +// - `dns1035LabelPrefix` +// - `labelValue` +// - `uri` +// - `uuid` +// - `byte` +// - `date` +// - `datetime` // // format.() -> Format // -// Convenience functions for all the named formats are also available +// Convenience functions for all the named formats are also available. // -// Examples: -// format.dns1123Label().validate("my-label-name") -// format.dns1123Subdomain().validate("apiextensions.k8s.io") -// format.dns1035Label().validate("my-label-name") -// format.qualifiedName().validate("apiextensions.k8s.io/v1beta1") -// format.dns1123LabelPrefix().validate("my-label-prefix-") -// format.dns1123SubdomainPrefix().validate("mysubdomain.prefix.-") -// format.dns1035LabelPrefix().validate("my-label-prefix-") -// format.uri().validate("http://example.com") -// Uses same pattern as isURL, but returns an error -// format.uuid().validate("123e4567-e89b-12d3-a456-426614174000") -// format.byte().validate("aGVsbG8=") -// format.date().validate("2021-01-01") -// format.datetime().validate("2021-01-01T00:00:00Z") +// Examples: +// +// format.dns1123Label().validate("my-label-name") +// format.dns1123Subdomain().validate("apiextensions.k8s.io") +// format.dns1035Label().validate("my-label-name") +// format.qualifiedName().validate("apiextensions.k8s.io/v1beta1") +// format.dns1123LabelPrefix().validate("my-label-prefix-") +// format.dns1123SubdomainPrefix().validate("mysubdomain.prefix.-") +// format.dns1035LabelPrefix().validate("my-label-prefix-") +// format.uri().validate("http://example.com") +// Uses same pattern as isURL, but returns an error +// format.uuid().validate("123e4567-e89b-12d3-a456-426614174000") +// format.byte().validate("aGVsbG8=") +// format.date().validate("2021-01-01") +// format.datetime().validate("2021-01-01T00:00:00Z") // - // .validate(str: string) -> ?list // -// Validates the given string against the given format. Returns optional.none -// if the string is valid, otherwise a list of validation error strings. +// Validates the given string against the given format. Returns optional.none +// if the string is valid, otherwise a list of validation error strings. func Format() cel.EnvOption { return cel.Lib(formatLib) } diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/ip.go b/vendor/k8s.io/apiserver/pkg/cel/library/ip.go index 5a089ae1cd..fa5e9f001d 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/ip.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/ip.go @@ -99,30 +99,30 @@ import ( // // Examples: // -// ip('127.0.0.1').family() // returns '4” -// ip('::1').family() // returns '6' -// ip('127.0.0.1').family() == 4 // returns true -// ip('::1').family() == 6 // returns true -// ip('0.0.0.0').isUnspecified() // returns true -// ip('127.0.0.1').isUnspecified() // returns false -// ip('::').isUnspecified() // returns true -// ip('::1').isUnspecified() // returns false -// ip('127.0.0.1').isLoopback() // returns true -// ip('192.168.0.1').isLoopback() // returns false -// ip('::1').isLoopback() // returns true -// ip('2001:db8::abcd').isLoopback() // returns false -// ip('224.0.0.1').isLinkLocalMulticast() // returns true -// ip('224.0.1.1').isLinkLocalMulticast() // returns false -// ip('ff02::1').isLinkLocalMulticast() // returns true -// ip('fd00::1').isLinkLocalMulticast() // returns false -// ip('169.254.169.254').isLinkLocalUnicast() // returns true -// ip('192.168.0.1').isLinkLocalUnicast() // returns false -// ip('fe80::1').isLinkLocalUnicast() // returns true -// ip('fd80::1').isLinkLocalUnicast() // returns false -// ip('192.168.0.1').isGlobalUnicast() // returns true -// ip('255.255.255.255').isGlobalUnicast() // returns false -// ip('2001:db8::abcd').isGlobalUnicast() // returns true -// ip('ff00::1').isGlobalUnicast() // returns false +// ip('127.0.0.1').family() // returns '4” +// ip('::1').family() // returns '6' +// ip('127.0.0.1').family() == 4 // returns true +// ip('::1').family() == 6 // returns true +// ip('0.0.0.0').isUnspecified() // returns true +// ip('127.0.0.1').isUnspecified() // returns false +// ip('::').isUnspecified() // returns true +// ip('::1').isUnspecified() // returns false +// ip('127.0.0.1').isLoopback() // returns true +// ip('192.168.0.1').isLoopback() // returns false +// ip('::1').isLoopback() // returns true +// ip('2001:db8::abcd').isLoopback() // returns false +// ip('224.0.0.1').isLinkLocalMulticast() // returns true +// ip('224.0.1.1').isLinkLocalMulticast() // returns false +// ip('ff02::1').isLinkLocalMulticast() // returns true +// ip('fd00::1').isLinkLocalMulticast() // returns false +// ip('169.254.169.254').isLinkLocalUnicast() // returns true +// ip('192.168.0.1').isLinkLocalUnicast() // returns false +// ip('fe80::1').isLinkLocalUnicast() // returns true +// ip('fd80::1').isLinkLocalUnicast() // returns false +// ip('192.168.0.1').isGlobalUnicast() // returns true +// ip('255.255.255.255').isGlobalUnicast() // returns false +// ip('2001:db8::abcd').isGlobalUnicast() // returns true +// ip('ff00::1').isGlobalUnicast() // returns false func IP() cel.EnvOption { return cel.Lib(ipLib) } diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/quantity.go b/vendor/k8s.io/apiserver/pkg/cel/library/quantity.go index f9036a47c7..f3fd8b1c50 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/quantity.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/quantity.go @@ -82,12 +82,12 @@ import ( // // Examples: // -// quantity("50000000G").isInteger() // returns true -// quantity("50k").isInteger() // returns true -// quantity("9999999999999999999999999999999999999G").asInteger() // error: cannot convert value to integer -// quantity("9999999999999999999999999999999999999G").isInteger() // returns false -// quantity("50k").asInteger() == 50000 // returns true -// quantity("50k").sub(20000).asApproximateFloat() == 30000 // returns true +// quantity("50000000G").isInteger() // returns true +// quantity("50k").isInteger() // returns true +// quantity("9999999999999999999999999999999999999G").asInteger() // error: cannot convert value to integer +// quantity("9999999999999999999999999999999999999G").isInteger() // returns false +// quantity("50k").asInteger() == 50000 // returns true +// quantity("50k").sub(20000).asApproximateFloat() == 30000 // returns true // // Arithmetic // @@ -105,11 +105,11 @@ import ( // // Examples: // -// quantity("50k").add("20k") == quantity("70k") // returns true -// quantity("50k").add(20) == quantity("50020") // returns true -// quantity("50k").sub("20k") == quantity("30k") // returns true -// quantity("50k").sub(20000) == quantity("30k") // returns true -// quantity("50k").add(20).sub(quantity("100k")).sub(-50000) == quantity("20") // returns true +// quantity("50k").add("20k") == quantity("70k") // returns true +// quantity("50k").add(20) == quantity("50020") // returns true +// quantity("50k").sub("20k") == quantity("30k") // returns true +// quantity("50k").sub(20000) == quantity("30k") // returns true +// quantity("50k").add(20).sub(quantity("100k")).sub(-50000) == quantity("20") // returns true // // Comparisons // @@ -125,13 +125,13 @@ import ( // // Examples: // -// quantity("200M").compareTo(quantity("0.2G")) // returns 0 -// quantity("50M").compareTo(quantity("50Mi")) // returns -1 -// quantity("50Mi").compareTo(quantity("50M")) // returns 1 -// quantity("150Mi").isGreaterThan(quantity("100Mi")) // returns true -// quantity("50Mi").isGreaterThan(quantity("100Mi")) // returns false -// quantity("50M").isLessThan(quantity("100M")) // returns true -// quantity("100M").isLessThan(quantity("50M")) // returns false +// quantity("200M").compareTo(quantity("0.2G")) // returns 0 +// quantity("50M").compareTo(quantity("50Mi")) // returns -1 +// quantity("50Mi").compareTo(quantity("50M")) // returns 1 +// quantity("150Mi").isGreaterThan(quantity("100Mi")) // returns true +// quantity("50Mi").isGreaterThan(quantity("100Mi")) // returns false +// quantity("50M").isLessThan(quantity("100M")) // returns true +// quantity("100M").isLessThan(quantity("50M")) // returns false func Quantity() cel.EnvOption { return cel.Lib(quantityLib) } diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go index f95ec2a372..a5bfac2620 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go @@ -156,7 +156,6 @@ func (s *Schema) Nullable() bool { func (s *Schema) AllOf() []common.Schema { var res []common.Schema for _, nestedSchema := range s.Schema.AllOf { - nestedSchema := nestedSchema res = append(res, &Schema{&nestedSchema}) } return res @@ -165,7 +164,6 @@ func (s *Schema) AllOf() []common.Schema { func (s *Schema) AnyOf() []common.Schema { var res []common.Schema for _, nestedSchema := range s.Schema.AnyOf { - nestedSchema := nestedSchema res = append(res, &Schema{&nestedSchema}) } return res @@ -174,7 +172,6 @@ func (s *Schema) AnyOf() []common.Schema { func (s *Schema) OneOf() []common.Schema { var res []common.Schema for _, nestedSchema := range s.Schema.OneOf { - nestedSchema := nestedSchema res = append(res, &Schema{&nestedSchema}) } return res diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go index 56e2a4bbd3..808d643415 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go @@ -86,7 +86,9 @@ func populateRefs(schemaOf func(ref string) (*spec.Schema, bool), visited sets.S } if populated != result.AdditionalProperties.Schema { changed = true - result.AdditionalProperties.Schema = populated + newProps := *result.AdditionalProperties + newProps.Schema = populated + result.AdditionalProperties = &newProps } } // schema is a list, populate its items @@ -97,7 +99,9 @@ func populateRefs(schemaOf func(ref string) (*spec.Schema, bool), visited sets.S } if populated != result.Items.Schema { changed = true - result.Items.Schema = populated + newItems := *result.Items + newItems.Schema = populated + result.Items = &newItems } } if changed { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go index 5e325ba447..1b8e8c72e0 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go @@ -559,9 +559,13 @@ func writeDiscoveryResponse( return } var targetGV schema.GroupVersion - if mediaType.Convert == nil || - (mediaType.Convert.GroupVersion() != apidiscoveryv2.SchemeGroupVersion && - mediaType.Convert.GroupVersion() != apidiscoveryv2beta1.SchemeGroupVersion) { + if mediaType.Convert == nil { + utilruntime.HandleError(fmt.Errorf("expected aggregated discovery group version, got unknown group and version")) + w.WriteHeader(http.StatusInternalServerError) + return + } + if mediaType.Convert.GroupVersion() != apidiscoveryv2.SchemeGroupVersion && + mediaType.Convert.GroupVersion() != apidiscoveryv2beta1.SchemeGroupVersion { utilruntime.HandleError(fmt.Errorf("expected aggregated discovery group version, got group: %s, version %s", mediaType.Convert.Group, mediaType.Convert.Version)) w.WriteHeader(http.StatusInternalServerError) return diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go index d25bf35ae3..83537bd215 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go @@ -149,7 +149,6 @@ func evaluatePolicyAndCreateAuditEvent(req *http.Request, policy audit.PolicyRul // writeLatencyToAnnotation writes the latency incurred in different // layers of the apiserver to the annotations of the audit object. -// it should be invoked after ev.StageTimestamp has been set appropriately. func writeLatencyToAnnotation(ctx context.Context) { ac := audit.AuditContextFrom(ctx) // we will track latency in annotation only when the total latency @@ -157,7 +156,7 @@ func writeLatencyToAnnotation(ctx context.Context) { // traces in rest/handlers for create, delete, update, // get, list, and deletecollection. const threshold = 500 * time.Millisecond - latency := ac.GetEventStageTimestamp().Sub(ac.GetEventRequestReceivedTimestamp().Time) + latency := time.Since(ac.GetEventRequestReceivedTimestamp().Time) if latency <= threshold { return } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/cache.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/cache.go index cf73107896..c0ef42c583 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/cache.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/cache.go @@ -18,11 +18,12 @@ package impersonation import ( "crypto/sha256" + "encoding/binary" + "encoding/hex" "fmt" "hash/fnv" "time" - - "golang.org/x/crypto/cryptobyte" + "unsafe" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" @@ -60,21 +61,19 @@ func modeIndexCacheKey(attributes authorizer.Attributes) string { key := attributes.GetUser().GetName() // hash the name so our cache size is predicable regardless of the size of usernames // collisions do not matter for this logic as it simply changes the ordering of the modes used - hash := fnvSum128a([]byte(key)) - return fmt.Sprintf("%x", hash) -} - -func fnvSum128a(data []byte) []byte { h := fnv.New128a() - h.Write(data) + h.Write([]byte(key)) var sum [16]byte - return h.Sum(sum[:0]) + h.Sum(sum[:0]) + buf := make([]byte, 32) // 16 bytes of hash -> 32 hex chars + hex.Encode(buf, sum[:]) + return toString(buf) // only safe because buf is heap allocated via make } func newModeIndexCache() *modeIndexCache { return &modeIndexCache{ - // each entry is roughly ~24 bytes (16 bytes for the hashed key, 8 bytes for value) - // thus at even 10k entries, we should use less than 1 MB memory + // each entry is roughly ~100 bytes (hashed string key + int value + LRU list/map overhead) + // thus at even 10k entries, we should use about 1 MB memory // this hardcoded size allows us to remember many users without leaking memory cache: lru.New(10_000), } @@ -246,7 +245,7 @@ func buildKey(wantedUser *user.DefaultInfo, attributes authorizer.Attributes) (s } }) - return b.build() + return b.build(), nil } func addUser(b *cacheKeyBuilder, u user.Info) { @@ -265,20 +264,21 @@ func addUser(b *cacheKeyBuilder, u user.Info) { }) } -// cacheKeyBuilder adds syntactic sugar on top of cryptobyte.Builder to make it easier to use for complex inputs. +// cacheKeyBuilder builds a binary key from structured inputs using uint32 length-prefixed encoding, then hashes +// it with SHA-256. All methods operate on a single shared buffer to avoid closure and child-builder allocations. type cacheKeyBuilder struct { namespace string // in the programming sense, not the Kubernetes concept - builder *cryptobyte.Builder + builder []byte } func newCacheKeyBuilder(namespace string) *cacheKeyBuilder { // start with a reasonable size to avoid too many allocations - return &cacheKeyBuilder{namespace: namespace, builder: cryptobyte.NewBuilder(make([]byte, 0, 384))} + return &cacheKeyBuilder{namespace: namespace, builder: make([]byte, 0, 384)} } func (c *cacheKeyBuilder) addString(value string) *cacheKeyBuilder { c.addLengthPrefixed(func(c *cacheKeyBuilder) { - c.builder.AddBytes([]byte(value)) + c.builder = append(c.builder, value...) }) return c } @@ -297,24 +297,36 @@ func (c *cacheKeyBuilder) addBool(value bool) *cacheKeyBuilder { if value { b = 1 } - c.builder.AddUint8(b) + c.builder = append(c.builder, b) return c } type builderContinuation func(child *cacheKeyBuilder) func (c *cacheKeyBuilder) addLengthPrefixed(f builderContinuation) { - c.builder.AddUint32LengthPrefixed(func(b *cryptobyte.Builder) { - c := &cacheKeyBuilder{namespace: c.namespace, builder: b} - f(c) - }) + offset := len(c.builder) + c.builder = append(c.builder, 0, 0, 0, 0) // placeholder for uint32 length + f(c) + binary.BigEndian.PutUint32(c.builder[offset:], uint32(len(c.builder)-offset-4)) } -func (c *cacheKeyBuilder) build() (string, error) { - key, err := c.builder.Bytes() - if err != nil { - return "", err +func (c *cacheKeyBuilder) build() string { + hashed := sha256.Sum256(c.builder) // reduce the size of the cache key to keep the overall cache size small + // sha256 = 32 bytes -> 64 hex chars + "/" + namespace + buf := make([]byte, 0, 64+1+len(c.namespace)) + buf = hex.AppendEncode(buf, hashed[:]) + buf = append(buf, '/') + buf = append(buf, c.namespace...) + return toString(buf) // only safe because buf is heap allocated via make +} + +// toString performs unholy acts to avoid allocations +func toString(b []byte) string { + // unsafe.SliceData relies on cap whereas we want to rely on len + if len(b) == 0 { + return "" } - hash := sha256.Sum256(key) // reduce the size of the cache key to keep the overall cache size small - return fmt.Sprintf("%x/%s", hash[:], c.namespace), nil + // Copied from go 1.20.1 strings.Builder.String + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/strings/builder.go#L48 + return unsafe.String(unsafe.SliceData(b), len(b)) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/constrained_impersonation.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/constrained_impersonation.go index 861e6d6990..e2a6e953d5 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/constrained_impersonation.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/constrained_impersonation.go @@ -22,6 +22,7 @@ import ( "fmt" "net/http" "strings" + "time" authenticationv1 "k8s.io/api/authentication/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -30,6 +31,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/endpoints/filters" + "k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/server/httplog" @@ -42,10 +44,25 @@ import ( // expression of impersonation access. For example, a service account may be authorized to impersonate the // node that it is associated with but only when listing pods. See the linked KEP for further details. func WithConstrainedImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime.NegotiatedSerializer) http.Handler { + metrics.RegisterMetrics() + + ma := &metricsAuthorizer{ + delegate: a, + recordAuthorizationCall: metrics.RecordImpersonationAuthorizationCall, + } + + recordAttempt := func(ctx context.Context, mode, decision string, duration time.Duration) { + metrics.RecordImpersonationAttempt(mode, decision, duration) + request.TrackImpersonationLatency(ctx, duration) + } + return &constrainedImpersonationHandler{ handler: handler, - tracker: newImpersonationModesTracker(a), + tracker: newImpersonationModesTracker(ma), s: s, + + recordAttempt: recordAttempt, + metricsAuthorizer: ma, } } @@ -53,6 +70,10 @@ type constrainedImpersonationHandler struct { handler http.Handler tracker *impersonationModesTracker s runtime.NegotiatedSerializer + + // to allow unit tests to override metrics recording + recordAttempt func(ctx context.Context, mode, decision string, duration time.Duration) + metricsAuthorizer *metricsAuthorizer } func (c *constrainedImpersonationHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { @@ -78,12 +99,16 @@ func (c *constrainedImpersonationHandler) ServeHTTP(w http.ResponseWriter, req * return } + start := time.Now() impersonatedUser, err := c.tracker.getImpersonatedUser(ctx, wantedUser, attributes) + duration := time.Since(start) if err != nil { + c.recordAttempt(ctx, "", "denied", duration) klog.V(4).InfoS("Forbidden", "URI", req.RequestURI, "err", err) responsewriters.RespondWithError(w, req, err, c.s) return } + c.recordAttempt(ctx, modeFromConstraint(impersonatedUser.constraint), "allowed", duration) req = req.WithContext(request.WithUser(ctx, impersonatedUser.user)) httplog.LogOf(req, w).Addf("%v is impersonating %v", userString(requestor), userString(impersonatedUser.user)) @@ -249,3 +274,49 @@ func (t *impersonationModesTracker) getImpersonatedUser(ctx context.Context, wan // this should not happen, but make sure we fail closed when no impersonation mode succeeded return nil, errors.New("all impersonation modes failed") } + +type metricsAuthorizer struct { + delegate authorizer.Authorizer + recordAuthorizationCall func(mode, decision string, duration time.Duration) +} + +func (m *metricsAuthorizer) Authorize(ctx context.Context, attributes authorizer.Attributes) (authorizer.Decision, string, error) { + start := time.Now() + decision, reason, err := m.delegate.Authorize(ctx, attributes) + duration := time.Since(start) + + m.recordAuthorizationCall(modeFromVerb(attributes.GetVerb()), decisionToLabel(decision), duration) + + return decision, reason, err +} + +func modeFromConstraint(constraint string) string { + if len(constraint) == 0 { + return "legacy" + } + return modeFromVerb(constraint) +} + +func modeFromVerb(verb string) string { + switch { + case verb == "impersonate": + return "legacy" + case verb == "impersonate:associated-node" || strings.HasPrefix(verb, "impersonate-on:associated-node:"): + return "associated-node" + case verb == "impersonate:arbitrary-node" || strings.HasPrefix(verb, "impersonate-on:arbitrary-node:"): + return "arbitrary-node" + case verb == "impersonate:serviceaccount" || strings.HasPrefix(verb, "impersonate-on:serviceaccount:"): + return "serviceaccount" + case verb == "impersonate:user-info" || strings.HasPrefix(verb, "impersonate-on:user-info:"): + return "user-info" + default: + return "unknown" + } +} + +func decisionToLabel(decision authorizer.Decision) string { + if decision == authorizer.DecisionAllow { + return "allowed" + } + return "denied" +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics/metrics.go new file mode 100644 index 0000000000..ac47de82a0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics/metrics.go @@ -0,0 +1,99 @@ +/* +Copyright 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 metrics + +import ( + "sync" + "time" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + namespace = "apiserver" + subsystem = "impersonation" +) + +var ( + impersonationAttemptsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "attempts_total", + Help: "Total number of impersonation attempts split by mode and decision.", + StabilityLevel: metrics.ALPHA, + }, + []string{"mode", "decision"}, + ) + + impersonationAttemptsDurationSeconds = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "attempts_duration_seconds", + Help: "Latency of impersonation attempts in seconds split by mode and decision.", + StabilityLevel: metrics.ALPHA, + Buckets: metrics.ExponentialBuckets(0.001, 2, 15), + }, + []string{"mode", "decision"}, + ) + + impersonationAuthorizationAttemptsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "authorization_attempts_total", + Help: "Total number of authorization checks made by the impersonation handler split by mode and decision.", + StabilityLevel: metrics.ALPHA, + }, + []string{"mode", "decision"}, + ) + + impersonationAuthorizationAttemptsDurationSeconds = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "authorization_attempts_duration_seconds", + Help: "Latency of authorization checks made by the impersonation handler in seconds split by mode and decision.", + StabilityLevel: metrics.ALPHA, + Buckets: metrics.ExponentialBuckets(0.001, 2, 15), + }, + []string{"mode", "decision"}, + ) +) + +var registerMetrics sync.Once + +func RegisterMetrics() { + registerMetrics.Do(func() { + legacyregistry.MustRegister(impersonationAttemptsTotal) + legacyregistry.MustRegister(impersonationAttemptsDurationSeconds) + legacyregistry.MustRegister(impersonationAuthorizationAttemptsTotal) + legacyregistry.MustRegister(impersonationAuthorizationAttemptsDurationSeconds) + }) +} + +func RecordImpersonationAttempt(mode, decision string, duration time.Duration) { + impersonationAttemptsTotal.WithLabelValues(mode, decision).Inc() + impersonationAttemptsDurationSeconds.WithLabelValues(mode, decision).Observe(duration.Seconds()) +} + +func RecordImpersonationAuthorizationCall(mode, decision string, duration time.Duration) { + impersonationAuthorizationAttemptsTotal.WithLabelValues(mode, decision).Inc() + impersonationAuthorizationAttemptsDurationSeconds.WithLabelValues(mode, decision).Observe(duration.Seconds()) +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index 2efd08d25a..3d0800747a 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -415,7 +415,7 @@ func authorizeUnsafeDelete(ctx context.Context, attr admission.Attributes, authz decision, reason, err := authz.Authorize(ctx, record) if err != nil { err = fmt.Errorf("error while checking permission for %q, %w", record.Verb, err) - klog.FromContext(ctx).V(1).Error(err, "failed to authorize") + klog.FromContext(ctx).V(1).Info("failed to authorize", "err", err) return admission.NewForbidden(attr, err) } if decision == authorizer.DecisionAllow { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go index eb52baf194..134e163eeb 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go @@ -25,10 +25,7 @@ import ( "strings" "time" - "go.opentelemetry.io/otel/attribute" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metainternalversionscheme "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme" metainternalversionvalidation "k8s.io/apimachinery/pkg/apis/meta/internalversion/validation" @@ -36,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/endpoints/request" @@ -170,142 +168,163 @@ func getRequestOptions(req *http.Request, scope *RequestScope, into runtime.Obje func ListResource(r rest.Lister, rw rest.Watcher, scope *RequestScope, forceWatch bool, minRequestTimeout time.Duration) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { ctx := req.Context() - // For performance tracking purposes. - ctx, span := tracing.Start(ctx, "List", traceFields(req)...) - req = req.WithContext(ctx) - namespace, err := scope.Namer.Namespace(req) if err != nil { scope.err(err, w, req) return } - - // Watches for single objects are routed to this function. - // Treat a name parameter the same as a field selector entry. - hasName := true - _, name, err := scope.Namer.Name(req) - if err != nil { - hasName = false - } ctx = request.WithNamespace(ctx, namespace) - opts := metainternalversion.ListOptions{} - if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, &opts); err != nil { - err = errors.NewBadRequest(err.Error()) + outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) + if err != nil { scope.err(err, w, req) return } - - metainternalversion.SetListOptionsDefaults(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)) - if errs := metainternalversionvalidation.ValidateListOptions(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)); len(errs) > 0 { - err := errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "ListOptions"}, "", errs) + opts, err := listOpts(req, scope) + if err != nil { scope.err(err, w, req) return } - outputMediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope) + switch { + case opts.Watch || forceWatch: + err = handleWatch(ctx, rw, scope, req, w, opts, outputMediaType, minRequestTimeout) + default: + err = handleList(ctx, r, scope, req, w, opts, outputMediaType) + } if err != nil { scope.err(err, w, req) return } + } +} - // transform fields - // TODO: DecodeParametersInto should do this. - if opts.FieldSelector != nil { - fn := func(label, value string) (newLabel, newValue string, err error) { - return scope.Convertor.ConvertFieldLabel(scope.Kind, label, value) - } - if opts.FieldSelector, err = opts.FieldSelector.Transform(fn); err != nil { - // TODO: allow bad request to set field causes based on query parameters - err = errors.NewBadRequest(err.Error()) - scope.err(err, w, req) - return - } +func listOpts(req *http.Request, scope *RequestScope) (metainternalversion.ListOptions, error) { + // Watches for single objects are routed to this function. + // Treat a name parameter the same as a field selector entry. + hasName := true + _, name, err := scope.Namer.Name(req) + if err != nil { + hasName = false + } + + opts := metainternalversion.ListOptions{} + if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, &opts); err != nil { + return opts, errors.NewBadRequest(err.Error()) + } + + metainternalversion.SetListOptionsDefaults(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)) + if errs := metainternalversionvalidation.ValidateListOptions(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)); len(errs) > 0 { + err := errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "ListOptions"}, "", errs) + return opts, err + } + + // transform fields + // TODO: DecodeParametersInto should do this. + if opts.FieldSelector != nil { + fn := func(label, value string) (newLabel, newValue string, err error) { + return scope.Convertor.ConvertFieldLabel(scope.Kind, label, value) } + if opts.FieldSelector, err = opts.FieldSelector.Transform(fn); err != nil { + // TODO: allow bad request to set field causes based on query parameters + return opts, errors.NewBadRequest(err.Error()) + } + } - if hasName { - // metadata.name is the canonical internal name. - // SelectionPredicate will notice that this is a request for - // a single object and optimize the storage query accordingly. - nameSelector := fields.OneTermEqualSelector("metadata.name", name) - - // Note that fieldSelector setting explicitly the "metadata.name" - // will result in reaching this branch (as the value of that field - // is propagated to requestInfo as the name parameter. - // That said, the allowed field selectors in this branch are: - // nil, fields.Everything and field selector matching metadata.name - // for our name. - if opts.FieldSelector != nil && !opts.FieldSelector.Empty() { - selectedName, ok := opts.FieldSelector.RequiresExactMatch("metadata.name") - if !ok || name != selectedName { - scope.err(errors.NewBadRequest("fieldSelector metadata.name doesn't match requested name"), w, req) - return - } - } else { - opts.FieldSelector = nameSelector + if hasName { + // metadata.name is the canonical internal name. + // SelectionPredicate will notice that this is a request for + // a single object and optimize the storage query accordingly. + nameSelector := fields.OneTermEqualSelector("metadata.name", name) + + // Note that fieldSelector setting explicitly the "metadata.name" + // will result in reaching this branch (as the value of that field + // is propagated to requestInfo as the name parameter. + // That said, the allowed field selectors in this branch are: + // nil, fields.Everything and field selector matching metadata.name + // for our name. + if opts.FieldSelector != nil && !opts.FieldSelector.Empty() { + selectedName, ok := opts.FieldSelector.RequiresExactMatch("metadata.name") + if !ok || name != selectedName { + return opts, errors.NewBadRequest("fieldSelector metadata.name doesn't match requested name") } + } else { + opts.FieldSelector = nameSelector } + } + return opts, nil +} - if opts.Watch || forceWatch { - if rw == nil { - scope.err(errors.NewMethodNotSupported(scope.Resource.GroupResource(), "watch"), w, req) - return - } - // TODO: Currently we explicitly ignore ?timeout= and use only ?timeoutSeconds=. - timeout := time.Duration(0) - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - if timeout == 0 && minRequestTimeout > 0 { - timeout = time.Duration(float64(minRequestTimeout) * (rand.Float64() + 1.0)) - } +func handleWatch(ctx context.Context, rw rest.Watcher, scope *RequestScope, req *http.Request, w http.ResponseWriter, opts metainternalversion.ListOptions, outputMediaType negotiation.MediaTypeOptions, minRequestTimeout time.Duration) error { + var span *tracing.Span + var onWatchListComplete WatchListCompleteHook + if isListWatchRequest(opts) { + ctx, span = tracing.Start(ctx, "WatchList", traceFields(req)...) + onWatchListComplete = func() { span.End(500 * time.Millisecond) } + req = req.WithContext(ctx) + } - klog.V(3).InfoS("Starting watch", "path", req.URL.Path, "resourceVersion", opts.ResourceVersion, "labels", opts.LabelSelector, "fields", opts.FieldSelector, "timeout", timeout) - ctx, cancel := context.WithTimeout(ctx, timeout) - defer func() { cancel() }() - watcher, err := rw.Watch(ctx, &opts) - if err != nil { - scope.err(err, w, req) - return - } - handler, err := serveWatchHandler(watcher, scope, outputMediaType, req, w, timeout, metrics.CleanListScope(ctx, &opts)) - if err != nil { - scope.err(err, w, req) - return - } - // Invalidate cancel() to defer until serve() is complete. - deferredCancel := cancel - cancel = func() {} - - serve := func() { - defer deferredCancel() - requestInfo, _ := request.RequestInfoFrom(ctx) - metrics.RecordLongRunning(req, requestInfo, metrics.APIServerComponent, func() { - defer watcher.Stop() - handler.ServeHTTP(w, req) - }) - } + if rw == nil { + return errors.NewMethodNotSupported(scope.Resource.GroupResource(), "watch") + } + // TODO: Currently we explicitly ignore ?timeout= and use only ?timeoutSeconds=. + timeout := time.Duration(0) + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + if timeout == 0 && minRequestTimeout > 0 { + timeout = time.Duration(float64(minRequestTimeout) * (rand.Float64() + 1.0)) + } - // Run watch serving in a separate goroutine to allow freeing current stack memory - t := routine.TaskFrom(req.Context()) - if t != nil { - t.Func = serve - } else { - serve() - } - return - } + klog.V(3).InfoS("Starting watch", "path", req.URL.Path, "resourceVersion", opts.ResourceVersion, "labels", opts.LabelSelector, "fields", opts.FieldSelector, "sendInitialEvents", opts.SendInitialEvents, "timeout", timeout, "audit-ID", audit.GetAuditIDTruncated(ctx)) + ctx, cancel := context.WithTimeout(ctx, timeout) + defer func() { cancel() }() + watcher, err := rw.Watch(ctx, &opts) + if err != nil { + return err + } + handler, err := serveWatchHandler(watcher, scope, outputMediaType, req, w, timeout, metrics.CleanListScope(ctx, &opts), onWatchListComplete) + if err != nil { + return err + } + // Invalidate cancel() to defer until serve() is complete. + deferredCancel := cancel + cancel = func() {} - // Log only long List requests (ignore Watch). - defer span.End(500 * time.Millisecond) - span.AddEvent("About to List from storage") - result, err := r.List(ctx, &opts) - if err != nil { - scope.err(err, w, req) - return - } - span.AddEvent("Listing from storage done") - defer span.AddEvent("Writing http response done", attribute.Int("count", meta.LenList(result))) - transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result) + serve := func() { + defer deferredCancel() + requestInfo, _ := request.RequestInfoFrom(ctx) + metrics.RecordLongRunning(req, requestInfo, metrics.APIServerComponent, func() { + defer watcher.Stop() + handler.ServeHTTP(w, req) + }) } + + // Run watch serving in a separate goroutine to allow freeing current stack memory + t := routine.TaskFrom(req.Context()) + if t != nil { + t.Func = serve + } else { + serve() + } + return nil +} + +func handleList(ctx context.Context, r rest.Lister, scope *RequestScope, req *http.Request, w http.ResponseWriter, opts metainternalversion.ListOptions, outputMediaType negotiation.MediaTypeOptions) error { + // For performance tracking purposes. + ctx, span := tracing.Start(ctx, "List", traceFields(req)...) + defer span.End(500 * time.Millisecond) + req = req.WithContext(ctx) + + result, err := r.List(ctx, &opts) + if err != nil { + return err + } + transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result) + return nil +} + +// isListWatchRequest is mirrored in staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go +func isListWatchRequest(opts metainternalversion.ListOptions) bool { + return opts.SendInitialEvents != nil && *opts.SendInitialEvents && opts.AllowWatchBookmarks } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/metrics/OWNERS b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/metrics/OWNERS index 433e84aa3e..04bd3fa653 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/metrics/OWNERS +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/metrics/OWNERS @@ -1,4 +1,5 @@ # See the OWNERS docs at https://go.k8s.io/owners -approvers: +approvers: [] +emeritus_approvers: - logicalhan diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go index 55f8b657a3..cb782f76a3 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go @@ -34,7 +34,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" @@ -44,6 +43,7 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/util/flushwriter" "k8s.io/component-base/tracing" + "k8s.io/streaming/pkg/httpstream/wsstream" ) // StreamObject performs input stream negotiation from a ResourceStreamer and writes that to the response. diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go index 822e562889..9121ec3fad 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go @@ -24,21 +24,26 @@ import ( "sync/atomic" "time" + "go.opentelemetry.io/otel/attribute" "golang.org/x/net/websocket" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/metrics" apirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/server/httplog" "k8s.io/apiserver/pkg/storage" utilfeature "k8s.io/apiserver/pkg/util/feature" compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/tracing" + "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream/wsstream" ) // timeoutFactory abstracts watch timeout logic for testing @@ -64,7 +69,7 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) { // serveWatchHandler returns a handle to serve a watch response. // TODO: the functionality in this method and in WatchServer.Serve is not cleanly decoupled. -func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOptions negotiation.MediaTypeOptions, req *http.Request, w http.ResponseWriter, timeout time.Duration, metricsScope string) (http.Handler, error) { +func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOptions negotiation.MediaTypeOptions, req *http.Request, w http.ResponseWriter, timeout time.Duration, metricsScope string, completeHook WatchListCompleteHook) (http.Handler, error) { options, err := optionsForTransform(mediaTypeOptions, req) if err != nil { return nil, err @@ -171,7 +176,8 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp TimeoutFactory: &realTimeoutFactory{timeout}, ServerShuttingDownCh: serverShuttingDownCh, - metricsScope: metricsScope, + metricsScope: metricsScope, + watchListCompleteHook: completeHook, } if wsstream.IsWebSocketRequest(req) { @@ -201,9 +207,12 @@ type WatchServer struct { TimeoutFactory TimeoutFactory ServerShuttingDownCh <-chan struct{} - metricsScope string + metricsScope string + watchListCompleteHook WatchListCompleteHook } +type WatchListCompleteHook func() + // watchEventMetricsRecorder allows the caller to count bytes written and report the size of the event. // It is thread-safe, as long as underlying io.Writer is thread-safe. // Once all Write calls for a given watch event have finished, RecordEvent must be called. @@ -230,6 +239,15 @@ func (c *watchEventMetricsRecorder) RecordEvent() { // HandleHTTP serves a series of encoded events via HTTP with Transfer-Encoding: chunked. // or over a websocket connection. func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { + ctx := req.Context() + ctx, span := tracing.Start(ctx, "WatchServer.HandleHTTP", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("method", req.Method), + attribute.String("url", req.URL.Path), + attribute.String("protocol", req.Proto), + attribute.String("mediaType", s.MediaType), + attribute.String("encoder", string(s.Encoder.Identifier()))) + req = req.WithContext(ctx) defer func() { if s.MemoryAllocator != nil { runtime.AllocatorPool.Put(s.MemoryAllocator) @@ -239,7 +257,7 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { flusher, ok := w.(http.Flusher) if !ok { err := fmt.Errorf("unable to start watch - can't get http.Flusher: %#v", w) - utilruntime.HandleError(err) + utilruntime.HandleErrorWithContext(req.Context(), err, "Unable to start watch") s.Scope.err(errors.NewInternalError(err), w, req) return } @@ -248,7 +266,7 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { if framer == nil { // programmer error err := fmt.Errorf("no stream framing support is available for media type %q", s.MediaType) - utilruntime.HandleError(err) + utilruntime.HandleErrorWithContext(req.Context(), err, "No stream framing support available") s.Scope.err(errors.NewBadRequest(err.Error()), w, req) return } @@ -275,6 +293,7 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { ch := s.Watching.ResultChan() done := req.Context().Done() + span.AddEvent("About to start writing response") for { select { case <-s.ServerShuttingDownCh: @@ -295,10 +314,10 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { // End of results. return } - isWatchListLatencyRecordingRequired := shouldRecordWatchListLatency(event) + isWatchListLatencyRecordingRequired := shouldRecordWatchListLatency(req.Context(), event) if err := watchEncoder.Encode(event); err != nil { - utilruntime.HandleError(err) + utilruntime.HandleErrorWithContext(req.Context(), err, "Failed to encode watch event") // client disconnect. return } @@ -308,7 +327,20 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { flusher.Flush() } if isWatchListLatencyRecordingRequired { - metrics.RecordWatchListLatency(req.Context(), s.Scope.Resource, s.metricsScope) + // Record completion of initial listing phase for WatchList + receivedTimestamp, ok := apirequest.ReceivedTimestampFrom(req.Context()) + if !ok { + utilruntime.HandleErrorWithContext(req.Context(), nil, "Unable to measure watchlist latency, no received timestamp found in the context", "gvr", s.Scope.Resource) + } else { + initLatency := time.Since(receivedTimestamp) + metrics.RecordWatchListLatency(req.Context(), s.Scope.Resource, s.metricsScope, initLatency) + auditID := audit.GetAuditIDTruncated(req.Context()) + klog.V(3).InfoS("WatchList initial events sent", "path", req.URL.Path, "auditID", auditID, "initLatency", initLatency) + httplog.AddKeyValue(req.Context(), "watchlist_init_latency", initLatency) + span.AddEvent("Writing initial events done") + span.End(5 * time.Second) + s.watchListCompleteHook() + } } } } @@ -316,6 +348,9 @@ func (s *WatchServer) HandleHTTP(w http.ResponseWriter, req *http.Request) { // HandleWS serves a series of encoded events over a websocket connection. func (s *WatchServer) HandleWS(ws *websocket.Conn) { + ctx := ws.Request().Context() + logger := klog.FromContext(ctx) + defer func() { if s.MemoryAllocator != nil { runtime.AllocatorPool.Put(s.MemoryAllocator) @@ -329,10 +364,10 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) { defer cleanup() go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithLogger(logger) // This blocks until the connection is closed. // Client should not send anything. - wsstream.IgnoreReceives(ws, 0) + wsstream.IgnoreReceivesWithLogger(logger, ws, 0) // Once the client closes, we should also close close(done) }() @@ -340,7 +375,7 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) { framer := newWebsocketFramer(ws, s.UseTextFraming) gvr := s.Scope.Resource - watchEncoder := newWatchEncoder(context.TODO(), gvr, s.EmbeddedEncoder, s.Encoder, framer) + watchEncoder := newWatchEncoder(ctx, gvr, s.EmbeddedEncoder, s.Encoder, framer) ch := s.Watching.ResultChan() for { @@ -356,7 +391,7 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) { } if err := watchEncoder.Encode(event); err != nil { - utilruntime.HandleError(err) + utilruntime.HandleErrorWithLogger(logger, err, "Failed to encode watch event") // client disconnect. return } @@ -393,7 +428,7 @@ func (w *websocketFramer) Write(p []byte) (int, error) { var _ io.Writer = &websocketFramer{} -func shouldRecordWatchListLatency(event watch.Event) bool { +func shouldRecordWatchListLatency(ctx context.Context, event watch.Event) bool { if event.Type != watch.Bookmark || !utilfeature.DefaultFeatureGate.Enabled(features.WatchList) { return false } @@ -403,7 +438,7 @@ func shouldRecordWatchListLatency(event watch.Event) bool { // for more please read https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list hasAnnotation, err := storage.HasInitialEventsEndBookmarkAnnotation(event.Object) if err != nil { - utilruntime.HandleError(fmt.Errorf("unable to determine if the obj has the required annotation for measuring watchlist latency, obj %T: %v", event.Object, err)) + utilruntime.HandleErrorWithContext(ctx, err, "Unable to determine if the object has the required annotation for measuring watchlist latency", "object", fmt.Sprintf("%T", event.Object)) return false } return hasAnnotation diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/OWNERS b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/OWNERS index 43fbd53336..50b8726a7d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/OWNERS +++ b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/OWNERS @@ -2,5 +2,6 @@ reviewers: - wojtek-t -approvers: +approvers: [] +emeritus_approvers: - logicalhan diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go index c0fe2bd411..3773c07f2b 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go @@ -18,7 +18,6 @@ package metrics import ( "context" - "fmt" "net/http" "net/url" "strconv" @@ -32,7 +31,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilsets "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/endpoints/request" @@ -290,7 +288,7 @@ var ( Name: "watch_list_duration_seconds", Help: "Response latency distribution in seconds for watch list requests broken by group, version, resource and scope.", Buckets: []float64{0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 2, 4, 6, 8, 10, 15, 20, 30, 45, 60}, - StabilityLevel: compbasemetrics.ALPHA, + StabilityLevel: compbasemetrics.BETA, }, []string{"group", "version", "resource", "scope"}, ) @@ -573,15 +571,8 @@ func RecordLongRunning(req *http.Request, requestInfo *request.RequestInfo, comp } // RecordWatchListLatency simply records response latency for watch list requests. -func RecordWatchListLatency(ctx context.Context, gvr schema.GroupVersionResource, metricsScope string) { - requestReceivedTimestamp, ok := request.ReceivedTimestampFrom(ctx) - if !ok { - utilruntime.HandleError(fmt.Errorf("unable to measure watchlist latency because no received ts found in the ctx, gvr: %s", gvr)) - return - } - elapsedSeconds := time.Since(requestReceivedTimestamp).Seconds() - - watchListLatencies.WithContext(ctx).WithLabelValues(gvr.Group, gvr.Version, gvr.Resource, metricsScope).Observe(elapsedSeconds) +func RecordWatchListLatency(ctx context.Context, gvr schema.GroupVersionResource, metricsScope string, elapsed time.Duration) { + watchListLatencies.WithContext(ctx).WithLabelValues(gvr.Group, gvr.Version, gvr.Resource, metricsScope).Observe(elapsed.Seconds()) } // MonitorRequest handles standard transformations for client and the reported verb and then invokes Monitor to record diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go index d6bf062a19..1cf14d892f 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go @@ -22,7 +22,7 @@ import ( "net/http" "strings" - "k8s.io/apimachinery/pkg/api/validation/path" + "k8s.io/apimachinery/pkg/api/validate/content" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metainternalversionscheme "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -246,7 +246,7 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er if opts.FieldSelector != nil { if name, ok := opts.FieldSelector.RequiresExactMatch("metadata.name"); ok { - if len(path.IsValidPathSegmentName(name)) == 0 { + if len(content.IsPathSegmentName(name)) == 0 { requestInfo.Name = name } } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go index bda43b617b..df0ff77d89 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go @@ -165,6 +165,10 @@ type LatencyTrackers struct { // When called multiple times, the latency incurred inside to // decode func each time will be summed up. DecodeTracker DurationTracker + + // ImpersonationTracker tracks the latency incurred in resolving impersonation. + // This includes mode selection, authorization checks, and cache lookups. + ImpersonationTracker DurationTracker } type latencyTrackersKeyType int @@ -193,6 +197,7 @@ func WithLatencyTrackersAndCustomClock(parent context.Context, c clock.Clock) co SerializationTracker: newSumLatencyTracker(c), ResponseWriteTracker: newSumLatencyTracker(c), DecodeTracker: newSumLatencyTracker(c), + ImpersonationTracker: newSumLatencyTracker(c), }) } @@ -286,6 +291,14 @@ func TrackDecodeLatency(ctx context.Context, d time.Duration) { } } +// TrackImpersonationLatency is used to track latency incurred +// in resolving impersonation for the request. +func TrackImpersonationLatency(ctx context.Context, d time.Duration) { + if tracker, ok := LatencyTrackersFrom(ctx); ok { + tracker.ImpersonationTracker.TrackDuration(d) + } +} + // AuditAnnotationsFromLatencyTrackers will inspect each latency tracker // associated with the request context and return a set of audit // annotations that can be added to the API audit entry. @@ -301,6 +314,7 @@ func AuditAnnotationsFromLatencyTrackers(ctx context.Context) map[string]string apfQueueWaitLatencyKey = "apiserver.latency.k8s.io/apf-queue-wait" authenticationLatencyKey = "apiserver.latency.k8s.io/authentication" authorizationLatencyKey = "apiserver.latency.k8s.io/authorization" + impersonationLatencyKey = "apiserver.latency.k8s.io/impersonation" ) tracker, ok := LatencyTrackersFrom(ctx) @@ -339,5 +353,8 @@ func AuditAnnotationsFromLatencyTrackers(ctx context.Context) map[string]string if latency := tracker.AuthorizationTracker.GetLatency(); latency != 0 { annotations[authorizationLatencyKey] = latency.String() } + if latency := tracker.ImpersonationTracker.GetLatency(); latency != 0 { + annotations[impersonationLatencyKey] = latency.String() + } return annotations } diff --git a/vendor/k8s.io/apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiserver/pkg/features/kube_features.go index 3c9a799a58..dbe776e8af 100644 --- a/vendor/k8s.io/apiserver/pkg/features/kube_features.go +++ b/vendor/k8s.io/apiserver/pkg/features/kube_features.go @@ -128,13 +128,32 @@ const ( // Enables running declarative validation of APIs, where declared. When enabled, APIs with // declarative validation rules will validate objects using the generated // declarative validation code and compare the results to the regular imperative validation. - // See DeclarativeValidationTakeover for more. + // See DeclarativeValidationBeta for more. DeclarativeValidation featuregate.Feature = "DeclarativeValidation" + // owner: @jpbetz @aaron-prindle @yongruilin + // kep: http://kep.k8s.io/5073 + // beta: v1.36 + // + // This feature gate acts as the Global Safety Switch for Beta-stage validation rules (+k8s:beta). + // It allows cluster admins to disable enforcement for validations in the Beta stage if + // regressions are found, forcing them back to Shadow mode. + // In Shadow mode, declarative validation is executed and mismatches against handwritten + // validation are logged as metrics, but failures do not reject requests. + // Handwritten validation remains authoritative and enforced. + // Enforcement logic for resources using WithDeclarativeEnforcement(): + // - Standard tags (no prefix): Always Enforced (Bypasses this gate). + // - Beta tags (+k8s:beta): Enforced when this gate is enabled (default), otherwise Shadowed. + // - Alpha tags (+k8s:alpha): Always Shadowed. + // This gate has no effect if the master DeclarativeValidation feature gate is disabled. + DeclarativeValidationBeta featuregate.Feature = "DeclarativeValidationBeta" + // owner: @jpbetz @aaron-prindle @yongruilin // kep: http://kep.k8s.io/5073 // beta: v1.33 // + // Deprecated: in favor of DeclarativeValidationBeta. + // // When enabled, declarative validation errors are returned directly to the caller, // replacing hand-written validation errors for rules that have declarative implementations. // When disabled, hand-written validation errors are always returned, effectively putting @@ -162,6 +181,15 @@ const ( // Enables generating snapshots of watch cache store and using them to serve LIST requests. ListFromCacheSnapshot featuregate.Feature = "ListFromCacheSnapshot" + // owner: @aramase @BenTheElder + // kep: https://kep.k8s.io/5793 + // + // Enables manifest-based admission control configuration for webhooks and policies. + // When enabled, admission webhooks and policies can be loaded from + // manifest files on disk at API server startup, providing bootstrap-time enforcement + // and protection against API-based modification. + ManifestBasedAdmissionControlConfig featuregate.Feature = "ManifestBasedAdmissionControlConfig" + // owner: @alexzielenski, @cici37, @jiahuif, @jpbetz // kep: https://kep.k8s.io/3962 // @@ -199,6 +227,14 @@ const ( // This prevents watch cache from being starved by other watches. SeparateCacheWatchRPC featuregate.Feature = "SeparateCacheWatchRPC" + // owner: @jefftree + // kep: https://kep.k8s.io/5866 + // + // Enables the shard selector parameter on List/Watch requests, + // allowing clients to receive a filtered subset of objects based + // on hash ranges of metadata fields (e.g. UID). + ShardedListAndWatch featuregate.Feature = "ShardedListAndWatch" + // owner: @serathius // // Enables APF to use size of objects for estimating request cost. @@ -241,12 +277,6 @@ const ( // Enables JWKs metrics for Structured Authentication Configuration StructuredAuthenticationConfigurationJWKSMetrics featuregate.Feature = "StructuredAuthenticationConfigurationJWKSMetrics" - // owner: @palnabarun - // kep: https://kep.k8s.io/3221 - // - // Enables Structured Authorization Configuration - StructuredAuthorizationConfiguration featuregate.Feature = "StructuredAuthorizationConfiguration" - // owner: @aramase // // Enables validation of service account UID in TokenRequest API. @@ -284,11 +314,6 @@ const ( // Enables post-start-hook for storage readiness WatchCacheInitializationPostStartHook featuregate.Feature = "WatchCacheInitializationPostStartHook" - // owner: @serathius - // Enables watches without resourceVersion to be served from storage. - // Used to prevent https://github.com/kubernetes/kubernetes/issues/123072 until etcd fixes the issue. - WatchFromStorageWithoutResourceVersion featuregate.Feature = "WatchFromStorageWithoutResourceVersion" - // owner: @p0lyn0mial // // Allow the API server to stream individual items instead of chunking @@ -374,6 +399,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate ConstrainedImpersonation: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, CoordinatedLeaderElection: { @@ -383,10 +409,16 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate DeclarativeValidation: { {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.36, remove in 1.39 + }, + + DeclarativeValidationBeta: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, DeclarativeValidationTakeover: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Deprecated}, }, DetectCacheInconsistency: { @@ -404,9 +436,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, }, + ManifestBasedAdmissionControlConfig: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + MutatingAdmissionPolicy: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA}, }, OpenAPIEnums: { @@ -433,6 +470,11 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate SeparateCacheWatchRPC: { {Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, + {Version: version.MustParse("1.36"), Default: false, LockToDefault: true, PreRelease: featuregate.Deprecated}, + }, + + ShardedListAndWatch: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, SizeBasedListCostEstimate: { @@ -472,12 +514,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, }, - StructuredAuthorizationConfiguration: { - {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - }, - TokenRequestServiceAccountUIDValidation: { {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, }, @@ -489,15 +525,12 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate UnknownVersionInteroperabilityProxy: { {Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, WatchCacheInitializationPostStartHook: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta}, - }, - - WatchFromStorageWithoutResourceVersion: { - {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, WatchList: { diff --git a/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go b/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go index b664719209..6fa01fc613 100644 --- a/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go +++ b/vendor/k8s.io/apiserver/pkg/quota/v1/resources.go @@ -17,7 +17,7 @@ limitations under the License. package v1 import ( - "sort" + "slices" "strings" corev1 "k8s.io/api/core/v1" @@ -198,7 +198,7 @@ func Intersection(a []corev1.ResourceName, b []corev1.ResourceName) []corev1.Res } result = append(result, item) } - sort.Slice(result, func(i, j int) bool { return result[i] < result[j] }) + slices.Sort(result) return result } @@ -211,7 +211,7 @@ func Difference(a []corev1.ResourceName, b []corev1.ResourceName) []corev1.Resou } result = append(result, item) } - sort.Slice(result, func(i, j int) bool { return result[i] < result[j] }) + slices.Sort(result) return result } diff --git a/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go index 722a312270..4fef3be397 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -27,8 +27,8 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validate/content" "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/api/validation/path" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" @@ -45,6 +45,7 @@ import ( "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/apiserver/pkg/sharding" "k8s.io/apiserver/pkg/storage" storeerr "k8s.io/apiserver/pkg/storage/errors" "k8s.io/apiserver/pkg/storage/etcd3/metrics" @@ -286,7 +287,7 @@ func NamespaceKeyFunc(ctx context.Context, prefix string, name string) (string, if len(name) == 0 { return "", apierrors.NewBadRequest("Name parameter required.") } - if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + if msgs := content.IsPathSegmentName(name); len(msgs) != 0 { return "", apierrors.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";"))) } key = key + "/" + name @@ -299,7 +300,7 @@ func NoNamespaceKeyFunc(ctx context.Context, prefix string, name string) (string if len(name) == 0 { return "", apierrors.NewBadRequest("Name parameter required.") } - if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + if msgs := content.IsPathSegmentName(name); len(msgs) != 0 { return "", apierrors.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";"))) } key := prefix + "/" + name @@ -393,6 +394,13 @@ func (e *Store) ListPredicate(ctx context.Context, p storage.SelectionPredicate, } p.Limit = options.Limit p.Continue = options.Continue + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) && options.ShardSelector != "" { + sel, err := sharding.Parse(options.ShardSelector) + if err != nil { + return nil, fmt.Errorf("invalid shard selector: %w", err) + } + p.ShardSelector = sel + } list := e.NewListFunc() qualifiedResource := e.qualifiedResourceFromContext(ctx) storageOpts := storage.ListOptions{ @@ -1263,7 +1271,7 @@ func (e *Store) DeleteCollection(ctx context.Context, deleteValidation rest.Vali for i := 0; i < workersNumber; i++ { go func() { // panics don't cross goroutine boundaries - defer utilruntime.HandleCrash(func(panicReason interface{}) { + defer utilruntime.HandleCrashWithContext(ctx, func(_ context.Context, panicReason interface{}) { errs <- fmt.Errorf("DeleteCollection goroutine panicked: %v", panicReason) }) defer wg.Done() @@ -1288,7 +1296,7 @@ func (e *Store) DeleteCollection(ctx context.Context, deleteValidation rest.Vali } // In case of all workers exit, notify distributor. go func() { - defer utilruntime.HandleCrash(func(panicReason interface{}) { + defer utilruntime.HandleCrashWithContext(ctx, func(_ context.Context, panicReason interface{}) { errs <- fmt.Errorf("DeleteCollection workers closer panicked: %v", panicReason) }) wg.Wait() @@ -1429,13 +1437,25 @@ func (e *Store) Watch(ctx context.Context, options *metainternalversion.ListOpti if options != nil { resourceVersion = options.ResourceVersion predicate.AllowWatchBookmarks = options.AllowWatchBookmarks + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) && options.ShardSelector != "" { + sel, err := sharding.Parse(options.ShardSelector) + if err != nil { + return nil, fmt.Errorf("invalid shard selector: %w", err) + } + predicate.ShardSelector = sel + } } return e.WatchPredicate(ctx, predicate, resourceVersion, options.SendInitialEvents) } // WatchPredicate starts a watch for the items that matches. func (e *Store) WatchPredicate(ctx context.Context, p storage.SelectionPredicate, resourceVersion string, sendInitialEvents *bool) (watch.Interface, error) { - storageOpts := storage.ListOptions{ResourceVersion: resourceVersion, Predicate: p, Recursive: true, SendInitialEvents: sendInitialEvents} + storageOpts := storage.ListOptions{ + ResourceVersion: resourceVersion, + Predicate: p, + Recursive: true, + SendInitialEvents: sendInitialEvents, + } // if we're not already namespace-scoped, see if the field selector narrows the scope of the watch if requestNamespace, _ := genericapirequest.NamespaceFrom(ctx); len(requestNamespace) == 0 { diff --git a/vendor/k8s.io/apiserver/pkg/registry/rest/create.go b/vendor/k8s.io/apiserver/pkg/registry/rest/create.go index b3e57d0a45..87b2c9d81b 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/rest/create.go +++ b/vendor/k8s.io/apiserver/pkg/registry/rest/create.go @@ -22,8 +22,8 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validate/content" genericvalidation "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/api/validation/path" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -89,6 +89,13 @@ type RESTCreateStrategy interface { Canonicalize(obj runtime.Object) } +func validatePathSegment(name string, prefix bool) []string { + if prefix { + return content.IsPathSegmentPrefix(name) + } + return content.IsPathSegmentName(name) +} + // BeforeCreate ensures that common operations for all resources are performed on creation. It only returns // errors that can be converted to api.Status. It invokes PrepareForCreate, then Validate. // It returns nil if the object should be created. @@ -126,7 +133,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx context.Context, obj runtime. // Custom validation (including name validation) passed // Now run common validation on object meta // Do this *after* custom validation so that specific error messages are shown whenever possible - if errs := genericvalidation.ValidateObjectMetaAccessor(objectMeta, strategy.NamespaceScoped(), path.ValidatePathSegmentName, field.NewPath("metadata")); len(errs) > 0 { + if errs := genericvalidation.ValidateObjectMetaAccessor(objectMeta, strategy.NamespaceScoped(), validatePathSegment, field.NewPath("metadata")); len(errs) > 0 { return errors.NewInvalid(kind.GroupKind(), objectMeta.GetName(), errs) } diff --git a/vendor/k8s.io/apiserver/pkg/registry/rest/update.go b/vendor/k8s.io/apiserver/pkg/registry/rest/update.go index 00f42cfe7c..32de351aa7 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/rest/update.go +++ b/vendor/k8s.io/apiserver/pkg/registry/rest/update.go @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" genericvalidation "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/api/validation/path" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" @@ -94,7 +93,7 @@ func validateCommonFields(obj, old runtime.Object, strategy RESTUpdateStrategy) if err != nil { return nil, fmt.Errorf("failed to get old object metadata: %v", err) } - allErrs = append(allErrs, genericvalidation.ValidateObjectMetaAccessor(objectMeta, strategy.NamespaceScoped(), path.ValidatePathSegmentName, field.NewPath("metadata"))...) + allErrs = append(allErrs, genericvalidation.ValidateObjectMetaAccessor(objectMeta, strategy.NamespaceScoped(), validatePathSegment, field.NewPath("metadata"))...) allErrs = append(allErrs, genericvalidation.ValidateObjectMetaAccessorUpdate(objectMeta, oldObjectMeta, field.NewPath("metadata"))...) return allErrs, nil diff --git a/vendor/k8s.io/apiserver/pkg/registry/rest/validate.go b/vendor/k8s.io/apiserver/pkg/registry/rest/validate.go index 65ffdd4f16..f0e355e54f 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/rest/validate.go +++ b/vendor/k8s.io/apiserver/pkg/registry/rest/validate.go @@ -76,13 +76,37 @@ func WithNormalizationRules(rules []field.NormalizationRule) ValidationConfig { } } +// WithDeclarativeEnforcement marks the validation configuration to indicate that it includes +// declarative validations that should follow the fine-grained Validation Lifecycle. +// When set, declarative validation is always executed regardless of feature gates. +// Authority is determined by individual tag prefixes (+k8s:alpha, +k8s:beta) and the +// DeclarativeValidationBeta safety switch. +func WithDeclarativeEnforcement() ValidationConfig { + return func(config *validationConfigOption) { + config.declarativeEnforcement = true + } +} + +type allDeclarativeEnforcedKeyType struct{} + +var allDeclarativeEnforcedKey = allDeclarativeEnforcedKeyType{} + +// WithAllDeclarativeEnforcedForTest returns a copy of parent context with allDeclarativeEnforcedKey set to true. +// This is used for testing to expose all declarative validation errors and filter all handwritten validation errors +// that are covered by declarative validation, regardless of the feature gate or maturity level. +// +// NOTE: This function is intended for testing purposes only and should not be used in production code. +func WithAllDeclarativeEnforcedForTest(ctx context.Context) context.Context { + return context.WithValue(ctx, allDeclarativeEnforcedKey, true) +} + type validationConfigOption struct { - opType operation.Type - options []string - takeover bool - subresourceGVKMapper GroupVersionKindProvider - validationIdentifier string - normalizationRules []field.NormalizationRule + opType operation.Type + options []string + subresourceGVKMapper GroupVersionKindProvider + validationIdentifier string + normalizationRules []field.NormalizationRule + declarativeEnforcement bool } // validateDeclaratively validates obj and oldObj against declarative @@ -155,9 +179,9 @@ func parseSubresourcePath(subresourcePath string) ([]string, error) { // compareDeclarativeErrorsAndEmitMismatches checks for mismatches between imperative and declarative validation // and logs + emits metrics when inconsistencies are found -func compareDeclarativeErrorsAndEmitMismatches(ctx context.Context, imperativeErrs, declarativeErrs field.ErrorList, takeover bool, validationIdentifier string, normalizationRules []field.NormalizationRule) { +func compareDeclarativeErrorsAndEmitMismatches(ctx context.Context, imperativeErrs, declarativeErrs field.ErrorList, enforced bool, validationIdentifier string, normalizationRules []field.NormalizationRule) { logger := klog.FromContext(ctx) - mismatchDetails := gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs, takeover, normalizationRules) + mismatchDetails := gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs, enforced, normalizationRules) for _, detail := range mismatchDetails { // Log information about the mismatch using contextual logger logger.Error(nil, detail) @@ -169,29 +193,34 @@ func compareDeclarativeErrorsAndEmitMismatches(ctx context.Context, imperativeEr // gatherDeclarativeValidationMismatches compares imperative and declarative validation errors // and returns detailed information about any mismatches found. Errors are compared via type, field, and origin -func gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs field.ErrorList, takeover bool, normalizationRules []field.NormalizationRule) []string { +func gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs field.ErrorList, enforced bool, normalizationRules []field.NormalizationRule) []string { var mismatchDetails []string // short circuit here to minimize allocs for usual case of 0 validation errors if len(imperativeErrs) == 0 && len(declarativeErrs) == 0 { return mismatchDetails } - // recommendation based on takeover status - recommendation := "This difference should not affect system operation since hand written validation is authoritative." - if takeover { - recommendation = "Consider disabling the DeclarativeValidationTakeover feature gate to keep data persisted in etcd consistent with prior versions of Kubernetes." + // default recommendation based on enforcement status + const ( + authoritativeMsg = "This difference should not affect system operation since hand written validation is authoritative." + disableBetaMsg = "Consider disabling the DeclarativeValidationBeta feature gate to keep data persisted in etcd consistent with prior versions of Kubernetes." + ) + + defaultRecommendation := authoritativeMsg + if enforced { + defaultRecommendation = disableBetaMsg } + fuzzyMatcher := field.ErrorMatcher{}.ByType().ByOrigin().RequireOriginWhenInvalid().ByFieldNormalized(normalizationRules) - exactMatcher := field.ErrorMatcher{}.Exactly() - // Dedupe imperative errors of exact error matches as they are - // not intended and come from (buggy) duplicate validation calls + // Dedupe imperative errors using the fuzzy matcher (type, field, and origin) as they are + // not intended and come from (buggy) duplicate validation calls. // This is necessary as without deduping we could get unmatched - // imperative errors for cases that are correct (matching) + // imperative errors for cases that are correct (matching). dedupedImperativeErrs := field.ErrorList{} for _, err := range imperativeErrs { found := false for _, existingErr := range dedupedImperativeErrs { - if exactMatcher.Matches(existingErr, err) { + if fuzzyMatcher.Matches(existingErr, err) { found = true break } @@ -233,12 +262,18 @@ func gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs field } if matchCount == 0 { + rec := defaultRecommendation + // If the imperative error is explicitly Alpha, it is never enforced, so HV is authoritative. + if iErr.IsAlpha() { + rec = authoritativeMsg + } + mismatchDetails = append(mismatchDetails, fmt.Sprintf( "Unexpected difference between hand written validation and declarative validation error results, unmatched error(s) found %s. "+ "This indicates an issue with declarative validation. %s", fuzzyMatcher.Render(iErr), - recommendation, + rec, ), ) } @@ -248,12 +283,18 @@ func gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs field // Any remaining unmatched declarative errors are considered "extra" for _, dErr := range remaining { + rec := defaultRecommendation + // If the declarative error is Alpha, it is never enforced (shadowed), so HV is authoritative. + if dErr.IsAlpha() { + rec = authoritativeMsg + } + mismatchDetails = append(mismatchDetails, fmt.Sprintf( "Unexpected difference between hand written validation and declarative validation error results, extra error(s) found %s. "+ "This indicates an issue with declarative validation. %s", fuzzyMatcher.Render(dErr), - recommendation, + rec, ), ) } @@ -262,8 +303,8 @@ func gatherDeclarativeValidationMismatches(imperativeErrs, declarativeErrs field } // createDeclarativeValidationPanicHandler returns a function with panic recovery logic -// that will increment the panic metric and either log or append errors based on the takeover parameter. -func createDeclarativeValidationPanicHandler(ctx context.Context, errs *field.ErrorList, takeover bool, validationIdentifier string) func() { +// that will increment the panic metric and either log or append errors based on the shouldFail parameter. +func createDeclarativeValidationPanicHandler(ctx context.Context, errs *field.ErrorList, shouldFail bool, validationIdentifier string) func() { logger := klog.FromContext(ctx) return func() { if r := recover(); r != nil { @@ -271,11 +312,11 @@ func createDeclarativeValidationPanicHandler(ctx context.Context, errs *field.Er validationmetrics.Metrics.IncDeclarativeValidationPanicMetric(validationIdentifier) const errorFmt = "panic during declarative validation: %v" - if takeover { - // If takeover is enabled, output as a validation error as authoritative validator panicked and validation should error + if shouldFail { + // If shouldFail is enabled, output as a validation error as authoritative validator panicked and validation should error *errs = append(*errs, field.InternalError(nil, fmt.Errorf(errorFmt, r))) } else { - // if takeover not enabled, log the panic as an error message + // if shouldFail not enabled, log the panic as an error message logger.Error(nil, fmt.Sprintf(errorFmt, r)) } } @@ -285,15 +326,15 @@ func createDeclarativeValidationPanicHandler(ctx context.Context, errs *field.Er // panicSafeValidateFunc wraps an validation function with panic recovery logic. // The returned function will execute the wrapped function and handle any panics by // incrementing the panic metric, and logging an error message -// if takeover=false, and adding a validation error if takeover=true. +// if shouldFail=false, and adding a validation error if shouldFail=true. func panicSafeValidateFunc( - validateUpdateFunc func(ctx context.Context, scheme *runtime.Scheme, obj, oldObj runtime.Object, o *validationConfigOption) field.ErrorList, - takeover bool, validationIdentifier string, + validateFunc func(ctx context.Context, scheme *runtime.Scheme, obj, oldObj runtime.Object, o *validationConfigOption) field.ErrorList, + shouldFail bool, validationIdentifier string, ) func(ctx context.Context, scheme *runtime.Scheme, obj, oldObj runtime.Object, o *validationConfigOption) field.ErrorList { return func(ctx context.Context, scheme *runtime.Scheme, obj, oldObj runtime.Object, o *validationConfigOption) (errs field.ErrorList) { - defer createDeclarativeValidationPanicHandler(ctx, &errs, takeover, validationIdentifier)() + defer createDeclarativeValidationPanicHandler(ctx, &errs, shouldFail, validationIdentifier)() - return validateUpdateFunc(ctx, scheme, obj, oldObj, o) + return validateFunc(ctx, scheme, obj, oldObj, o) } } @@ -334,16 +375,25 @@ func metricIdentifier(ctx context.Context, scheme *runtime.Scheme, obj runtime.O return identifier, errs } -// ValidateDeclarativelyWithMigrationChecks is a helper function that encapsulates the logic for running declarative validation. -// It checks if the DeclarativeValidation feature gate is enabled, generates a validation identifier, -// runs declarative validation, compares the results with imperative validation, and merges the errors if takeover is enabled. +// ValidateDeclarativelyWithMigrationChecks executes declarative validation and implements the Validation Lifecycle strategy. +// It manages the transition from handwritten (HV) to declarative (DV) validation by controlling enforcement: +// - Standard: Enforced if declarativeEnforcement is set. HV counterparts are expected to be deleted from source. +// - Beta: Enforced if declarativeEnforcement is set AND DeclarativeValidationBeta feature gate is enabled. +// When enforced, corresponding HV errors are filtered out. Otherwise, DV is shadowed. +// - Alpha: Always shadowed; HV remains authoritative. +// +// Mismatches between HV and DV are logged if the DeclarativeValidation gate is enabled. +// Mismatch checking is limited to Alpha and Beta stages when explicit enforcement is active. +// +// For testing purposes, WithAllDeclarativeEnforcedForTest can be used to enforce all declarative validations +// regardless of feature gates and filter all covered handwritten validations. func ValidateDeclarativelyWithMigrationChecks(ctx context.Context, scheme *runtime.Scheme, obj, oldObj runtime.Object, errs field.ErrorList, opType operation.Type, configOpts ...ValidationConfig) field.ErrorList { - if !utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidation) { - return errs - } - - takeover := utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidationTakeover) - + declarativeValidationEnabled := utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidation) + betaEnabled := utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidationBeta) + // allDeclarativeEnforced indicates that we should check all declarative errors for testing purposes. + allDeclarativeEnforced := ctx.Value(allDeclarativeEnforcedKey) == true + // These errors must be errors returned by the handwritten validation. + errs = errs.MarkFromImperative() validationIdentifier, err := metricIdentifier(ctx, scheme, obj, opType) if err != nil { // Log the error, but continue with the best-effort identifier. @@ -353,24 +403,92 @@ func ValidateDeclarativelyWithMigrationChecks(ctx context.Context, scheme *runti // Directly create the config and call the core validation logic. cfg := &validationConfigOption{ opType: opType, - takeover: takeover, validationIdentifier: validationIdentifier, } for _, opt := range configOpts { opt(cfg) } + // Short-circuit if neither DeclarativeValidation is enabled nor the object is explicitly configured for declarative enforcement. + if !declarativeValidationEnabled && !cfg.declarativeEnforcement && !allDeclarativeEnforced { + return errs + } + // Call the panic-safe wrapper with the real validation function. - declarativeErrs := panicSafeValidateFunc(validateDeclaratively, cfg.takeover, cfg.validationIdentifier)(ctx, scheme, obj, oldObj, cfg) + // We should fail if validation is enforced. + declarativeErrs := panicSafeValidateFunc(validateDeclaratively, cfg.declarativeEnforcement, cfg.validationIdentifier)(ctx, scheme, obj, oldObj, cfg) + + if declarativeValidationEnabled { + // Log mismatches. + // When explicit strategy is used (declarativeEnforcement), Standard errors are authoritative + // and may not have handwritten counterparts (e.g., in new APIs). + // We only mismatch check Alpha and Beta errors in this mode. + mismatchCandidateErrs := declarativeErrs + if cfg.declarativeEnforcement { + mismatchCandidateErrs = nil + for _, err := range declarativeErrs { + if err.IsAlpha() || err.IsBeta() { + mismatchCandidateErrs = append(mismatchCandidateErrs, err) + } + } + } - compareDeclarativeErrorsAndEmitMismatches(ctx, errs, declarativeErrs, takeover, validationIdentifier, cfg.normalizationRules) - if takeover { - errs = append(errs.RemoveCoveredByDeclarative(), declarativeErrs...) + // We pass betaEnabled (and enforcement) as the takeover flag to avoid changing logic elsewhere for now. + compareDeclarativeErrorsAndEmitMismatches(ctx, errs, mismatchCandidateErrs, cfg.declarativeEnforcement && betaEnabled, validationIdentifier, cfg.normalizationRules) + } + + if !cfg.declarativeEnforcement && !allDeclarativeEnforced { + // If enforcement is not enabled, we shadow declarative errors with hand-written ones, so we return early here. + return errs + } + + // Filter HV errors + errs = filterHandwrittenErrors(errs, allDeclarativeEnforced, betaEnabled) + + // Append Enforced DV errors + for _, dvErr := range declarativeErrs { + if allDeclarativeEnforced { + errs = append(errs, dvErr) + continue + } + switch { + case dvErr.Type == field.ErrorTypeInternal: + errs = append(errs, dvErr) + case dvErr.IsBeta(): + if betaEnabled { + errs = append(errs, dvErr) + } + case !dvErr.IsAlpha(): + errs = append(errs, dvErr) // Standard + } } return errs } +func filterHandwrittenErrors(errs field.ErrorList, allDeclarativeEnforced, betaEnabled bool) field.ErrorList { + // We remove HV errors that are covered by declarative validation AND are enforced. + return errs.Filter(func(e error) bool { + var fe *field.Error + if !errors.As(e, &fe) || !fe.CoveredByDeclarative { + return false + } + + if allDeclarativeEnforced { + return true + } + + // Explicit Strategy + if fe.IsBeta() { + // Beta validations are enforced only if the Beta feature gate is enabled. + return betaEnabled + } + // For Standard validations, we keep the handwritten error for now to avoid losing coverage + // before it is deleted from source. Alpha validations are always shadowed (kept). + return false + }) +} + // RecordDuplicateValidationErrors increments a metric and log the error when duplicate validation errors are found. func RecordDuplicateValidationErrors(ctx context.Context, qualifiedKind schema.GroupKind, errs field.ErrorList) { logger := klog.FromContext(ctx) diff --git a/vendor/k8s.io/apiserver/pkg/server/config.go b/vendor/k8s.io/apiserver/pkg/server/config.go index efe10e81a6..c09051a1bb 100644 --- a/vendor/k8s.io/apiserver/pkg/server/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/config.go @@ -19,6 +19,7 @@ package server import ( "context" "crypto/sha256" + "crypto/tls" "encoding/base32" "fmt" "net" @@ -382,6 +383,13 @@ type SecureServingInfo struct { // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). CipherSuites []uint16 + // CurvePreferences optionally specifies the set of allowed key exchange mechanisms for the server. + // The order of the list is ignored, and key exchange mechanisms + // are chosen by Go from this list using an internal preference order. + // If empty, the default Go curves will be used. + // Values are from the Go crypto/tls CurveID constants (https://golang.org/pkg/crypto/tls/#CurveID). + CurvePreferences []tls.CurveID + // HTTP2MaxStreamsPerConnection is the limit that the api server imposes on each client. // A value of zero means to use the default provided by golang's HTTP/2 support. HTTP2MaxStreamsPerConnection int @@ -590,6 +598,18 @@ func (c *Config) AddHealthChecks(healthChecks ...healthz.HealthChecker) { c.AddReadyzChecks(healthChecks...) } +// AddHealthzChecks adds the provided health checks to our config to be exposed by the +// healthz endpoint of our configured apiserver. +func (c *Config) AddHealthzChecks(healthChecks ...healthz.HealthChecker) { + c.HealthzChecks = append(c.HealthzChecks, healthChecks...) +} + +// AddLivezChecks adds the provided health checks to our config to be exposed by the +// livez endpoint of our configured apiserver. +func (c *Config) AddLivezChecks(healthChecks ...healthz.HealthChecker) { + c.LivezChecks = append(c.LivezChecks, healthChecks...) +} + // AddReadyzChecks adds a health check to our config to be exposed by the readyz endpoint // of our configured apiserver. func (c *Config) AddReadyzChecks(healthChecks ...healthz.HealthChecker) { @@ -874,6 +894,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G UnprotectedDebugSocket: debugSocket, listedPathProvider: apiServerHandler, + Flagz: c.Flagz, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, ShutdownTimeout: c.RequestTimeout, diff --git a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/configmap_cafile_content.go b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/configmap_cafile_content.go index dbe9e375f2..5af3dbe866 100644 --- a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/configmap_cafile_content.go +++ b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/configmap_cafile_content.go @@ -199,7 +199,7 @@ func (c *ConfigMapCAController) RunOnce(ctx context.Context) error { // Run starts the kube-apiserver and blocks until stopCh is closed. func (c *ConfigMapCAController) Run(ctx context.Context, workers int) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer c.queue.ShutDown() klog.InfoS("Starting controller", "name", c.name) diff --git a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_cafile_content.go b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_cafile_content.go index 0fcf82bd0d..2f21951349 100644 --- a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_cafile_content.go +++ b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_cafile_content.go @@ -155,7 +155,7 @@ func (c *DynamicFileCAContent) RunOnce(ctx context.Context) error { // Run starts the controller and blocks until stopCh is closed. func (c *DynamicFileCAContent) Run(ctx context.Context, workers int) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer c.queue.ShutDown() klog.InfoS("Starting controller", "name", c.name) diff --git a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_serving_content.go b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_serving_content.go index e0dd0474b1..268fe70b0d 100644 --- a/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_serving_content.go +++ b/vendor/k8s.io/apiserver/pkg/server/dynamiccertificates/dynamic_serving_content.go @@ -129,7 +129,7 @@ func (c *DynamicCertKeyPairContent) RunOnce(ctx context.Context) error { // Run starts the controller and blocks until context is killed. func (c *DynamicCertKeyPairContent) Run(ctx context.Context, workers int) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer c.queue.ShutDown() klog.InfoS("Starting controller", "name", c.name) diff --git a/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index 27408fe158..b898ff3270 100644 --- a/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/vendor/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -300,6 +300,7 @@ func getTLSConfig(t *apiserver.TLSConfig) (*tls.Config, error) { return &tls.Config{ Certificates: []tls.Certificate{clientCerts}, RootCAs: certPool, + ServerName: t.TLSServerName, }, nil } diff --git a/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1alpha1/doc.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1alpha1/doc.go index ab7a48c210..42d5fcef53 100644 --- a/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1alpha1/doc.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1alpha1/doc.go @@ -18,5 +18,5 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:openapi-model-package=io.k8s.apiserver.pkg.server.flagz.api.v1alpha1 -// Package v1alpha1 contains API Schema definitions for the zpages v1alpha1 API group +// Package v1alpha1 contains API Schema definitions for the flagz v1alpha1 API group package v1alpha1 diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/doc.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/doc.go similarity index 73% rename from vendor/k8s.io/api/autoscaling/v2beta2/doc.go rename to vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/doc.go index 5ea9edb68a..bc8cffc0a0 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/doc.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 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. @@ -15,9 +15,8 @@ limitations under the License. */ // +k8s:deepcopy-gen=package -// +k8s:protobuf-gen=package // +k8s:openapi-gen=true -// +k8s:prerelease-lifecycle-gen=true -// +k8s:openapi-model-package=io.k8s.api.autoscaling.v2beta2 +// +k8s:openapi-model-package=io.k8s.apiserver.pkg.server.flagz.api.v1beta1 -package v2beta2 +// Package v1beta1 contains API Schema definitions for the flagz v1beta1 API group +package v1beta1 diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/register.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/register.go similarity index 53% rename from vendor/k8s.io/api/autoscaling/v2beta1/register.go rename to vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/register.go index 12d697f013..f66acc7dd6 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/register.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/register.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 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. @@ -14,38 +14,33 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v2beta1 +package v1beta1 import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" ) -// GroupName is the group name use in this package -const GroupName = "autoscaling" +const ( + GroupName = "config.k8s.io" + Version = "v1beta1" +) // SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2beta1"} - -// Resource takes an unqualified resource and returns a Group qualified GroupResource -func Resource(resource string) schema.GroupResource { - return SchemeGroupVersion.WithResource(resource).GroupResource() -} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} var ( - // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. - // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + // SchemeBuilder initializes a scheme builder + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that adds this group's types to a scheme + AddToScheme = SchemeBuilder.AddToScheme ) -// Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &HorizontalPodAutoscaler{}, - &HorizontalPodAutoscalerList{}, + &Flagz{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/types.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/types.go similarity index 52% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/types.go rename to vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/types.go index a49a6a813e..403436fdcf 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/types.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/types.go @@ -1,5 +1,5 @@ /* -Copyright 2017 The Kubernetes Authors. +Copyright 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. @@ -14,16 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1beta1 -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// WebhookAdmission provides configuration for the webhook admission controller. -type WebhookAdmission struct { +// Flagz is the structured response for the /flagz endpoint. +type Flagz struct { + // TypeMeta is the type metadata for the object. metav1.TypeMeta `json:",inline"` - - // KubeConfigFile is the path to the kubeconfig file. - KubeConfigFile string `json:"kubeConfigFile"` + // Standard object's metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Flags contains the command-line flags and their values. + // The keys are the flag names and the values are the flag values, + // possibly with confidential values redacted. + // +optional + Flags map[string]string `json:"flags,omitempty"` } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.deepcopy.go similarity index 75% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.deepcopy.go rename to vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.deepcopy.go index f997f4abaf..1d5e52605c 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.deepcopy.go @@ -19,31 +19,39 @@ limitations under the License. // Code generated by deepcopy-gen. DO NOT EDIT. -package v1alpha1 +package v1beta1 import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WebhookAdmission) DeepCopyInto(out *WebhookAdmission) { +func (in *Flagz) DeepCopyInto(out *Flagz) { *out = *in out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Flags != nil { + in, out := &in.Flags, &out.Flags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookAdmission. -func (in *WebhookAdmission) DeepCopy() *WebhookAdmission { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Flagz. +func (in *Flagz) DeepCopy() *Flagz { if in == nil { return nil } - out := new(WebhookAdmission) + out := new(Flagz) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WebhookAdmission) DeepCopyObject() runtime.Object { +func (in *Flagz) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } diff --git a/vendor/k8s.io/api/events/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.model_name.go similarity index 67% rename from vendor/k8s.io/api/events/v1beta1/generated.protomessage.pb.go rename to vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.model_name.go index a70924a20d..d475a0aa64 100644 --- a/vendor/k8s.io/api/events/v1beta1/generated.protomessage.pb.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/api/v1beta1/zz_generated.model_name.go @@ -1,5 +1,5 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release +//go:build !ignore_autogenerated +// +build !ignore_autogenerated /* Copyright The Kubernetes Authors. @@ -17,12 +17,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. +// Code generated by openapi-gen. DO NOT EDIT. package v1beta1 -func (*Event) ProtoMessage() {} - -func (*EventList) ProtoMessage() {} - -func (*EventSeries) ProtoMessage() {} +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in Flagz) OpenAPIModelName() string { + return "io.k8s.apiserver.pkg.server.flagz.api.v1beta1.Flagz" +} diff --git a/vendor/k8s.io/apiserver/pkg/server/flagz/flagz.go b/vendor/k8s.io/apiserver/pkg/server/flagz/flagz.go index de5dfe79fe..cb6df7b5d6 100644 --- a/vendor/k8s.io/apiserver/pkg/server/flagz/flagz.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/flagz.go @@ -20,25 +20,44 @@ import ( "fmt" "net/http" "strings" + "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/runtime/serializer/cbor" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" - v1alpha1 "k8s.io/apiserver/pkg/server/flagz/api/v1alpha1" + "k8s.io/apiserver/pkg/endpoints/metrics" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/endpoints/responsewriter" + "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/server/flagz/api/v1alpha1" + "k8s.io/apiserver/pkg/server/flagz/api/v1beta1" "k8s.io/apiserver/pkg/server/flagz/negotiate" + utilfeature "k8s.io/apiserver/pkg/util/feature" ) -const ( - DefaultFlagzPath = "/flagz" - Kind = "Flagz" - GroupName = "config.k8s.io" - Version = "v1alpha1" +var ( + v1alpha1FlagzKind = v1alpha1.SchemeGroupVersion.WithKind("Flagz") + v1beta1FlagzKind = v1beta1.SchemeGroupVersion.WithKind("Flagz") + recognizedStructuredKinds = map[schema.GroupVersionKind]bool{ + v1alpha1FlagzKind: true, + v1beta1FlagzKind: true, + } ) +const DefaultFlagzPath = "/flagz" + +// flagzCodecFactory wraps a CodecFactory to filter out unsupported media types (like protobuf) +// from the supported media types list, so error messages only show actually supported types. +type flagzCodecFactory struct { + serializer.CodecFactory + supportedMediaTypes []runtime.SerializerInfo +} + type mux interface { Handle(path string, handler http.Handler) } @@ -47,7 +66,7 @@ type mux interface { func Install(m mux, componentName string, flagReader Reader, opts ...Option) { reg := ®istry{ reader: flagReader, - deprecatedVersionsMap: map[string]bool{}, + deprecatedVersionsMap: map[string]bool{"v1alpha1": true}, } for _, opt := range opts { opt(reg) @@ -55,10 +74,23 @@ func Install(m mux, componentName string, flagReader Reader, opts ...Option) { scheme := runtime.NewScheme() utilruntime.Must(v1alpha1.AddToScheme(scheme)) - codecFactory := serializer.NewCodecFactory( - scheme, + utilruntime.Must(v1beta1.AddToScheme(scheme)) + filteredCodecFactory, err := newFlagzCodecFactory(scheme, componentName, reg.reader) + if err != nil { + utilruntime.HandleError(err) + } + restrictions := negotiate.FlagzEndpointRestrictions{ + RecognizedStructuredKinds: recognizedStructuredKinds, + } + m.Handle(DefaultFlagzPath, handleFlagz(componentName, reg, filteredCodecFactory, restrictions)) +} + +// newFlagzCodecFactory creates a codec factory with the standard serializers for flagz, +// filtering out unsupported media types (e.g., protobuf). +func newFlagzCodecFactory(scheme *runtime.Scheme, componentName string, flagReader Reader) (*flagzCodecFactory, error) { + codecFactoryOpts := []serializer.CodecFactoryOptionsMutator{ serializer.WithSerializer(func(_ runtime.ObjectCreater, _ runtime.ObjectTyper) runtime.SerializerInfo { - textSerializer := flagzTextSerializer{componentName, reg.reader} + textSerializer := flagzTextSerializer{componentName, flagReader} return runtime.SerializerInfo{ MediaType: "text/plain", MediaTypeType: "text", @@ -68,16 +100,75 @@ func Install(m mux, componentName string, flagReader Reader, opts ...Option) { PrettySerializer: textSerializer, } }), - ) - m.Handle(DefaultFlagzPath, handleFlagz(componentName, reg, codecFactory, negotiate.FlagzEndpointRestrictions{})) + } + // TODO: remove this explicit check when https://github.com/kubernetes/enhancements/pull/5740 is implemented. + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { + codecFactoryOpts = append(codecFactoryOpts, serializer.WithSerializer(cbor.NewSerializerInfo)) + } + + codecFactory := serializer.NewCodecFactory(scheme, codecFactoryOpts...) + allTypes := codecFactory.SupportedMediaTypes() + filtered := make([]runtime.SerializerInfo, 0, len(allTypes)) + + var unknownTypes []string + for _, info := range allTypes { + switch info.MediaType { + // Supported media types + case "text/plain", runtime.ContentTypeJSON, runtime.ContentTypeYAML, runtime.ContentTypeCBOR: + filtered = append(filtered, info) + // Unsupported media types + case runtime.ContentTypeProtobuf: + continue + default: + unknownTypes = append(unknownTypes, info.MediaType) + } + } + + var err error + if len(unknownTypes) > 0 { + err = fmt.Errorf("flagz: unknown media type(s) %v, excluding from supported types", unknownTypes) + } + + return &flagzCodecFactory{ + CodecFactory: codecFactory, + supportedMediaTypes: filtered, + }, err +} + +func (f *flagzCodecFactory) SupportedMediaTypes() []runtime.SerializerInfo { + return f.supportedMediaTypes } func handleFlagz(componentName string, reg *registry, serializer runtime.NegotiatedSerializer, restrictions negotiate.FlagzEndpointRestrictions) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - obj := flagz(componentName, reg.reader) + requestReceivedTimestamp, ok := request.ReceivedTimestampFrom(r.Context()) + if !ok { + requestReceivedTimestamp = time.Now() + } + delegate := &metrics.ResponseWriterDelegator{ResponseWriter: w} + w = responsewriter.WrapForHTTP1Or2(delegate) + + // Use MonitorRequest instead of InstrumentHandlerFunc because the group, + // version, and deprecated status depend on per-request content negotiation. + // For text/plain requests, group and version remain empty. For structured + // responses (JSON/YAML/CBOR), they are set to the negotiated API group and + // version (e.g., config.k8s.io/v1alpha1). + var group, version string + var deprecated bool + defer func() { + metrics.MonitorRequest(r, "GET", group, version, + "flagz", // resource + "", // subresource + "", // scope + componentName, // component + deprecated, + "", // removedRelease + delegate.Status(), delegate.ContentLength(), time.Since(requestReceivedTimestamp)) + }() + acceptHeader := r.Header.Get("Accept") if strings.TrimSpace(acceptHeader) == "" { - writePlainTextResponse(obj, serializer, w, reg) + writePlainTextResponse(v1beta1Flagz(componentName, reg.reader), serializer, w, reg) return } @@ -94,11 +185,10 @@ func handleFlagz(componentName string, reg *registry, serializer runtime.Negotia return } - var targetGV schema.GroupVersion switch serializerInfo.MediaType { - case "application/json": + case "application/json", "application/yaml", "application/cbor": if mediaType.Convert == nil { - err := fmt.Errorf("content negotiation failed: mediaType.Convert is nil for application/json") + err := fmt.Errorf("content negotiation failed: mediaType.Convert is nil for %s", serializerInfo.MediaType) utilruntime.HandleError(err) responsewriters.ErrorNegotiated( err, @@ -109,15 +199,17 @@ func handleFlagz(componentName string, reg *registry, serializer runtime.Negotia ) return } - targetGV = mediaType.Convert.GroupVersion() - if reg.deprecatedVersions()[targetGV.Version] { + group = mediaType.Convert.Group + version = mediaType.Convert.Version + deprecated = reg.deprecatedVersions()[version] + if deprecated { w.Header().Set("Warning", `299 - "This version of the flagz endpoint is deprecated. Please use a newer version."`) } + handleStructuredResponse(w, r, componentName, reg, serializer, restrictions, mediaType) case "text/plain": - writePlainTextResponse(obj, serializer, w, reg) - return + writePlainTextResponse(v1beta1Flagz(componentName, reg.reader), serializer, w, reg) default: - err = fmt.Errorf("content negotiation failed: unsupported media type '%s'", serializerInfo.MediaType) + err := fmt.Errorf("unsupported media type: %s/%s", serializerInfo.MediaType, serializerInfo.MediaTypeSubType) utilruntime.HandleError(err) responsewriters.ErrorNegotiated( err, @@ -126,10 +218,7 @@ func handleFlagz(componentName string, reg *registry, serializer runtime.Negotia w, r, ) - return } - - writeResponse(obj, serializer, targetGV, restrictions, w, r) } } @@ -170,7 +259,7 @@ func writePlainTextResponse(obj runtime.Object, serializer runtime.NegotiatedSer } } -func writeResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, targetGV schema.GroupVersion, restrictions negotiate.FlagzEndpointRestrictions, w http.ResponseWriter, r *http.Request) { +func writeStructuredResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, targetGV schema.GroupVersion, restrictions negotiate.FlagzEndpointRestrictions, w http.ResponseWriter, r *http.Request) { responsewriters.WriteObjectNegotiated( serializer, restrictions, @@ -183,12 +272,45 @@ func writeResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, ) } -func flagz(componentName string, flagReader Reader) *v1alpha1.Flagz { +func handleStructuredResponse(w http.ResponseWriter, r *http.Request, componentName string, reg *registry, serializer runtime.NegotiatedSerializer, restrictions negotiate.FlagzEndpointRestrictions, mediaType negotiation.MediaTypeOptions) { + switch *mediaType.Convert { + case v1alpha1FlagzKind: + writeStructuredResponse(v1alpha1Flagz(componentName, reg.reader), serializer, v1alpha1FlagzKind.GroupVersion(), restrictions, w, r) + case v1beta1FlagzKind: + writeStructuredResponse(v1beta1Flagz(componentName, reg.reader), serializer, v1beta1FlagzKind.GroupVersion(), restrictions, w, r) + default: + err := fmt.Errorf("unsupported media type: %s", mediaType.Convert.String()) + utilruntime.HandleError(err) + responsewriters.ErrorNegotiated( + err, + serializer, + schema.GroupVersion{}, + w, + r, + ) + } +} + +func v1alpha1Flagz(componentName string, flagReader Reader) *v1alpha1.Flagz { flags := flagReader.GetFlagz() return &v1alpha1.Flagz{ TypeMeta: metav1.TypeMeta{ - Kind: Kind, - APIVersion: fmt.Sprintf("%s/%s", GroupName, Version), + Kind: v1alpha1FlagzKind.Kind, + APIVersion: v1alpha1FlagzKind.GroupVersion().String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: componentName, + }, + Flags: flags, + } +} + +func v1beta1Flagz(componentName string, flagReader Reader) *v1beta1.Flagz { + flags := flagReader.GetFlagz() + return &v1beta1.Flagz{ + TypeMeta: metav1.TypeMeta{ + Kind: v1beta1FlagzKind.Kind, + APIVersion: v1beta1FlagzKind.GroupVersion().String(), }, ObjectMeta: metav1.ObjectMeta{ Name: componentName, diff --git a/vendor/k8s.io/apiserver/pkg/server/flagz/negotiate/negotiation.go b/vendor/k8s.io/apiserver/pkg/server/flagz/negotiate/negotiation.go index f3edc8f3c1..ec2d28e67c 100644 --- a/vendor/k8s.io/apiserver/pkg/server/flagz/negotiate/negotiation.go +++ b/vendor/k8s.io/apiserver/pkg/server/flagz/negotiate/negotiation.go @@ -20,16 +20,21 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -// FlagzEndpointRestrictions implements content negotiation restrictions for the z-pages. +// FlagzEndpointRestrictions implements content negotiation restrictions for the flagz endpoint. // It is used to validate and restrict which GroupVersionKinds are allowed for structured responses. -type FlagzEndpointRestrictions struct{} +type FlagzEndpointRestrictions struct { + RecognizedStructuredKinds map[schema.GroupVersionKind]bool +} -// AllowsMediaTypeTransform checks if the provided GVK is supported for structured z-page responses. -func (FlagzEndpointRestrictions) AllowsMediaTypeTransform(mimeType string, mimeSubType string, gvk *schema.GroupVersionKind) bool { +// AllowsMediaTypeTransform checks if the provided GVK is supported for structured flagz responses. +func (f FlagzEndpointRestrictions) AllowsMediaTypeTransform(mimeType string, mimeSubType string, gvk *schema.GroupVersionKind) bool { if mimeType == "text" && mimeSubType == "plain" { return gvk == nil } - return isStructured(gvk) + if gvk != nil { + return f.RecognizedStructuredKinds[*gvk] + } + return false } func (FlagzEndpointRestrictions) AllowsServerVersion(string) bool { @@ -39,15 +44,3 @@ func (FlagzEndpointRestrictions) AllowsServerVersion(string) bool { func (FlagzEndpointRestrictions) AllowsStreamSchema(s string) bool { return false } - -func isStructured(gvk *schema.GroupVersionKind) bool { - if gvk != nil { - if gvk.Group == "config.k8s.io" && gvk.Version == "v1alpha1" { - if gvk.Kind == "Flagz" { - return true - } - } - } - - return false -} diff --git a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go index 0cb1007495..c821dbfa52 100644 --- a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -50,6 +50,7 @@ import ( discoveryendpoint "k8s.io/apiserver/pkg/endpoints/discovery/aggregated" "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/apiserver/pkg/server/flagz" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/routes" "k8s.io/apiserver/pkg/server/statusz" @@ -114,6 +115,9 @@ type GenericAPIServer struct { // LoopbackClientConfig is a config for a privileged loopback connection to the API server LoopbackClientConfig *restclient.Config + // Flagz is used to set up flagz endpoint. + Flagz flagz.Reader + // minRequestTimeout is how short the request timeout can be. This is used to build the RESTHandler minRequestTimeout time.Duration @@ -467,8 +471,15 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer { } s.installReadyz() + componentName := "apiserver" + if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { + if s.Flagz != nil { + flagz.Install(s.Handler.NonGoRestfulMux, componentName, s.Flagz) + } + } + // statusz is installed last so that it can list all the paths that have been registered if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentStatusz) { - statusz.Install(s.Handler.NonGoRestfulMux, "apiserver", statusz.NewRegistry(s.EffectiveVersion, statusz.WithListedPaths(s.ListedPaths()))) + statusz.Install(s.Handler.NonGoRestfulMux, componentName, statusz.NewRegistry(s.EffectiveVersion, statusz.WithListedPaths(s.ListedPaths()))) } return preparedGenericAPIServer{s} @@ -537,7 +548,7 @@ func (s preparedGenericAPIServer) RunWithContext(ctx context.Context) error { // If UDS profiling is enabled, start a local http server listening on that socket if s.UnprotectedDebugSocket != nil { go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) klog.Error(s.UnprotectedDebugSocket.RunWithContext(ctx)) }() } @@ -593,7 +604,7 @@ func (s preparedGenericAPIServer) RunWithContext(ctx context.Context) error { Listener: s.SecureServingInfo.Listener, lateStopCh: lateStopCh, } - unexpectedRequestsEventf.Store(s.Eventf) + unexpectedRequestsEventf.Store(eventfFunc(s.Eventf)) // close socket after delayed stopCh shutdownTimeout := s.ShutdownTimeout @@ -763,6 +774,11 @@ func (s preparedGenericAPIServer) RunWithContext(ctx context.Context) error { klog.V(1).Info("[graceful-termination] apiserver is exiting") s.Eventf(corev1.EventTypeNormal, "TerminationGracefulTerminationFinished", "All pending requests processed") + // Release the global reference to s.Eventf so the server object graph can + // be garbage collected. The TLS transport cache relies on GC to cancel cert + // rotation goroutines via runtime.AddCleanup (ClientsAllowTLSCacheGC). + unexpectedRequestsEventf.Store(eventfFunc(nil)) + return nil } diff --git a/vendor/k8s.io/apiserver/pkg/server/hooks.go b/vendor/k8s.io/apiserver/pkg/server/hooks.go index 150b40b475..3a828061e8 100644 --- a/vendor/k8s.io/apiserver/pkg/server/hooks.go +++ b/vendor/k8s.io/apiserver/pkg/server/hooks.go @@ -195,8 +195,7 @@ func (s *GenericAPIServer) isPostStartHookRegistered(name string) bool { func runPostStartHook(name string, entry postStartHookEntry, context PostStartHookContext) { var err error func() { - // don't let the hook *accidentally* panic and kill the server - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(context) err = entry.hook(context) }() // if the hook intentionally wants to kill server, let it. diff --git a/vendor/k8s.io/apiserver/pkg/server/options/admission.go b/vendor/k8s.io/apiserver/pkg/server/options/admission.go index b41f97ec96..ec09f0d564 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/admission.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/admission.go @@ -157,7 +157,7 @@ func (a *AdmissionOptions) ApplyTo( discoveryRESTMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient) genericInitializer := initializer.New(kubeClient, dynamicClient, informers, c.Authorization.Authorizer, features, effectiveVersion, c.DrainedNotify(), NewAdmissionRESTMapper(discoveryRESTMapper)) - initializersChain := admission.PluginInitializers{genericInitializer} + initializersChain := admission.PluginInitializers{initializer.NewAPIServerIDInitializer(c.APIServerID), genericInitializer} initializersChain = append(initializersChain, pluginInitializers...) admissionPostStartHook := func(hookContext server.PostStartHookContext) error { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/api_enablement.go b/vendor/k8s.io/apiserver/pkg/server/options/api_enablement.go index 81e4899f08..6698c73a2d 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/api_enablement.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/api_enablement.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server/resourceconfig" serverstore "k8s.io/apiserver/pkg/server/storage" @@ -70,20 +71,22 @@ func (s *APIEnablementOptions) Validate(registries ...GroupRegistry) []error { errors := []error{} if s.RuntimeConfig[resourceconfig.APIAll] == "false" && len(s.RuntimeConfig) == 1 { // Do not allow only set api/all=false, in such case apiserver startup has no meaning. - return append(errors, fmt.Errorf("invalid key with only %v=false", resourceconfig.APIAll)) + return append(errors, fmt.Errorf("invalid runtime-config with only %v=false", resourceconfig.APIAll)) } - groups, err := resourceconfig.ParseGroups(s.RuntimeConfig) + groupVersions, err := resourceconfig.ParseGroupVersions(s.RuntimeConfig) if err != nil { return append(errors, err) } - for _, registry := range registries { - // filter out known groups - groups = unknownGroups(groups, registry) + unknownGroupVersions := sets.New[string]() + for _, groupVersion := range groupVersions { + if !isGroupRegistered(groupVersion.Group, registries) { + unknownGroupVersions.Insert(groupVersion.String()) + } } - if len(groups) != 0 { - errors = append(errors, fmt.Errorf("unknown api groups %s", strings.Join(groups, ","))) + if len(unknownGroupVersions) != 0 { + errors = append(errors, fmt.Errorf("unknown api groups %s", strings.Join(sets.List(unknownGroupVersions), ","))) } return errors @@ -129,18 +132,17 @@ func (s *APIEnablementOptions) ApplyTo(c *server.Config, defaultResourceConfig * return err } -func unknownGroups(groups []string, registry GroupRegistry) []string { - unknownGroups := []string{} - for _, group := range groups { - if !registry.IsGroupRegistered(group) { - unknownGroups = append(unknownGroups, group) - } - } - return unknownGroups -} - // GroupRegistry provides a method to check whether given group is registered. type GroupRegistry interface { - // IsRegistered returns true if given group is registered. + // IsGroupRegistered returns true if given group is registered. IsGroupRegistered(group string) bool } + +func isGroupRegistered(group string, registries []GroupRegistry) bool { + for _, registry := range registries { + if registry.IsGroupRegistered(group) { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/server/options/audit.go b/vendor/k8s.io/apiserver/pkg/server/options/audit.go index af5b06a5bd..74e2e71971 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/audit.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/audit.go @@ -154,6 +154,10 @@ func NewAuditOptions() *AuditOptions { GroupVersionString: "audit.k8s.io/v1", }, LogOptions: AuditLogOptions{ + MaxSize: 100, + MaxAge: 366, + MaxBackups: 100, + Format: pluginlog.FormatJson, BatchOptions: AuditBatchOptions{ Mode: ModeBlocking, @@ -436,11 +440,11 @@ func (o *AuditLogOptions) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&o.Path, "audit-log-path", o.Path, "If set, all requests coming to the apiserver will be logged to this file. '-' means standard out.") fs.IntVar(&o.MaxAge, "audit-log-maxage", o.MaxAge, - "The maximum number of days to retain old audit log files based on the timestamp encoded in their filename.") + "The maximum number of days to retain old audit log files based on the timestamp encoded in their filename. Setting a value of 0 means old audit log files are not removed based on age.") fs.IntVar(&o.MaxBackups, "audit-log-maxbackup", o.MaxBackups, "The maximum number of old audit log files to retain. Setting a value of 0 will mean there's no restriction on the number of files.") fs.IntVar(&o.MaxSize, "audit-log-maxsize", o.MaxSize, - "The maximum size in megabytes of the audit log file before it gets rotated.") + "The maximum size in megabytes of the audit log file before it gets rotated. Setting to 0 disables rotation (not recommended).") fs.StringVar(&o.Format, "audit-log-format", o.Format, "Format of saved audits. \"legacy\" indicates 1-line text format for each event."+ " \"json\" indicates structured json format. Known formats are "+ @@ -506,6 +510,10 @@ func (o *AuditLogOptions) getWriter() (io.Writer, error) { return nil, fmt.Errorf("ensureLogFile: %w", err) } + if o.MaxSize == 0 { + return os.OpenFile(o.Path, os.O_APPEND|os.O_WRONLY, 0644) + } + return &lumberjack.Logger{ Filename: o.Path, MaxAge: o.MaxAge, diff --git a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go index e340c9d2ce..2d481bc6f7 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go @@ -282,8 +282,6 @@ func getTransformerOverridesAndKMSPluginProbes(ctx context.Context, config *apis // For each entry in the configuration for _, resourceConfig := range config.Resources { - resourceConfig := resourceConfig - transformers, p, used, err := prefixTransformersAndProbes(ctx, resourceConfig, apiServerID) if err != nil { return nil, nil, nil, err @@ -292,7 +290,6 @@ func getTransformerOverridesAndKMSPluginProbes(ctx context.Context, config *apis // For each resource, create a list of providers to use for _, resource := range resourceConfig.Resources { - resource := resource gr := schema.ParseGroupResource(resource) // check if resource is masked by *.group rule @@ -317,8 +314,6 @@ func getTransformerOverridesAndKMSPluginProbes(ctx context.Context, config *apis transformers := make(map[schema.GroupResource]storagevalue.Transformer, len(resourceToPrefixTransformer)) for gr, transList := range resourceToPrefixTransformer { - gr := gr - transList := transList transformers[gr] = storagevalue.NewPrefixTransformers(fmt.Errorf("no matching prefix found"), transList...) } @@ -567,7 +562,6 @@ func prefixTransformersAndProbes(ctx context.Context, config apiserver.ResourceC var kmsUsed kmsState for _, provider := range config.Providers { - provider := provider var ( transformer storagevalue.PrefixTransformer transformerErr error @@ -624,7 +618,6 @@ func aesPrefixTransformer(config *apiserver.AESConfiguration, fn blockTransforme return result, fmt.Errorf("aes provider has no valid keys") } for _, key := range config.Keys { - key := key if key.Name == "" { return result, fmt.Errorf("key with invalid name provided") } @@ -636,7 +629,6 @@ func aesPrefixTransformer(config *apiserver.AESConfiguration, fn blockTransforme keyTransformers := []storagevalue.PrefixTransformer{} for _, keyData := range config.Keys { - keyData := keyData key, err := base64.StdEncoding.DecodeString(keyData.Secret) if err != nil { return result, fmt.Errorf("could not obtain secret for named key %s: %w", keyData.Name, err) @@ -677,7 +669,6 @@ func secretboxPrefixTransformer(config *apiserver.SecretboxConfiguration) (stora return result, fmt.Errorf("secretbox provider has no valid keys") } for _, key := range config.Keys { - key := key if key.Name == "" { return result, fmt.Errorf("key with invalid name provided") } @@ -689,7 +680,6 @@ func secretboxPrefixTransformer(config *apiserver.SecretboxConfiguration) (stora keyTransformers := []storagevalue.PrefixTransformer{} for _, keyData := range config.Keys { - keyData := keyData key, err := base64.StdEncoding.DecodeString(keyData.Secret) if err != nil { return result, fmt.Errorf("could not obtain secret for named key %s: %s", keyData.Name, err) diff --git a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go index 5c249bcc08..9314d6d125 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go @@ -92,7 +92,7 @@ func NewDynamicEncryptionConfiguration( // Run starts the controller and blocks until ctx is canceled. func (d *DynamicEncryptionConfigContent) Run(ctx context.Context) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) klog.InfoS("Starting controller", "name", d.name) defer klog.InfoS("Shutting down controller", "name", d.name) @@ -101,7 +101,7 @@ func (d *DynamicEncryptionConfigContent) Run(ctx context.Context) { wg.Add(1) go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer wg.Done() defer d.queue.ShutDown() <-ctx.Done() @@ -109,7 +109,7 @@ func (d *DynamicEncryptionConfigContent) Run(ctx context.Context) { wg.Add(1) go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer wg.Done() d.runWorker(ctx) }() diff --git a/vendor/k8s.io/apiserver/pkg/server/options/etcd.go b/vendor/k8s.io/apiserver/pkg/server/options/etcd.go index c0574c8bfe..3cad57cc5b 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/etcd.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/etcd.go @@ -23,6 +23,7 @@ import ( "sort" "strconv" "strings" + "sync" "time" "github.com/spf13/pflag" @@ -240,32 +241,98 @@ func (s *EtcdOptions) ApplyWithStorageFactoryTo(factory serverstorage.StorageFac return err } - metrics.SetStorageMonitorGetter(monitorGetter(factory)) + monitorCache, err := newMonitorCache(factory, c.DrainedNotify()) + if err != nil { + return err + } + metrics.SetStorageMonitorGetter(monitorCache.get) c.RESTOptionsGetter = s.CreateRESTOptionsGetter(factory, c.ResourceTransformers) return nil } -func monitorGetter(factory serverstorage.StorageFactory) func() (monitors []metrics.Monitor, err error) { - return func() (monitors []metrics.Monitor, err error) { - defer func() { - if err != nil { - for _, m := range monitors { - m.Close() - } - } - }() +type monitorCache struct { + mu sync.RWMutex + closed bool + monitors []metrics.Monitor + factory serverstorage.StorageFactory + stopCh <-chan struct{} +} - var m metrics.Monitor - for _, cfg := range factory.Configs() { - m, err = storagefactory.CreateMonitor(cfg) - if err != nil { - return nil, err +var createMonitor = storagefactory.CreateMonitor + +func newMonitorCache(factory serverstorage.StorageFactory, stopCh <-chan struct{}) (*monitorCache, error) { + if stopCh == nil { + return nil, fmt.Errorf("stopCh is required for monitor cache cleanup") + } + cache := &monitorCache{ + factory: factory, + stopCh: stopCh, + } + return cache, nil +} + +func (c *monitorCache) get() ([]metrics.Monitor, error) { + // Fast path: check if already initialized with read lock + c.mu.RLock() + if c.closed { + c.mu.RUnlock() + return nil, fmt.Errorf("monitor cache is closed") + } + if c.monitors != nil { + result := c.monitors + c.mu.RUnlock() + return result, nil + } + c.mu.RUnlock() + + // Slow path: initialize with write lock + return c.initialize() +} + +func (c *monitorCache) initialize() ([]metrics.Monitor, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.closed { + return nil, fmt.Errorf("monitor cache is closed") + } + if c.monitors != nil { + return c.monitors, nil + } + + var monitors []metrics.Monitor + for _, cfg := range c.factory.Configs() { + m, err := createMonitor(cfg) + if err != nil { + for _, already := range monitors { + already.Close() //nolint:errcheck } - monitors = append(monitors, m) + return nil, err } - return monitors, nil + monitors = append(monitors, m) + } + c.monitors = monitors + + go func() { + <-c.stopCh + c.close() + }() + + return c.monitors, nil +} + +func (c *monitorCache) close() { + c.mu.Lock() + defer c.mu.Unlock() + if c.closed { + return + } + c.closed = true + for _, m := range c.monitors { + m.Close() //nolint:errcheck } + c.monitors = nil } func (s *EtcdOptions) CreateRESTOptionsGetter(factory serverstorage.StorageFactory, resourceTransformers storagevalue.ResourceTransformers) generic.RESTOptionsGetter { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/recommended.go b/vendor/k8s.io/apiserver/pkg/server/options/recommended.go index a80c3f9ed4..9721797787 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/recommended.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/recommended.go @@ -105,7 +105,7 @@ func (o *RecommendedOptions) ApplyTo(config *server.RecommendedConfig) error { if err := o.Traces.ApplyTo(config.Config.EgressSelector, &config.Config); err != nil { return err } - if err := o.SecureServing.ApplyTo(&config.Config.SecureServing, &config.Config.LoopbackClientConfig); err != nil { + if err := o.SecureServing.ApplyToConfig(&config.Config); err != nil { return err } if err := o.Authentication.ApplyTo(&config.Config.Authentication, config.SecureServing, config.OpenAPIConfig); err != nil { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/serving.go b/vendor/k8s.io/apiserver/pkg/server/options/serving.go index 21a2736e10..fbcb072470 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/serving.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/serving.go @@ -64,6 +64,14 @@ type SecureServingOptions struct { // CipherSuites is the list of allowed cipher suites for the server. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). CipherSuites []string + // CurvePreferences is the set of allowed key exchange mechanisms for the server, + // specified as numeric Go crypto/tls CurveID values. + // The supported values depend on the Go version used. + // See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. + // The order of the list is ignored, and key exchange mechanisms are + // chosen by Go from this list using an internal preference order. + // If empty, the default Go curves will be used. + CurvePreferences []int32 // MinTLSVersion is the minimum TLS version supported. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). MinTLSVersion string @@ -189,6 +197,15 @@ func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) { "Preferred values: "+strings.Join(tlsCipherPreferredValues, ", ")+". \n"+ "Insecure values: "+strings.Join(tlsCipherInsecureValues, ", ")+".") + fs.Int32SliceVar(&s.CurvePreferences, "tls-curve-preferences", s.CurvePreferences, + "Comma-separated list of numeric Go crypto/tls CurveID values, "+ + "as the allowed key exchange mechanisms for the server. "+ + "The supported values depend on the Go version used. "+ + "See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. "+ + "The order of the list is ignored, and key exchange mechanisms are chosen "+ + "by Go from this list using an internal preference order. "+ + "If omitted, the default Go curves will be used.") + tlsPossibleVersions := cliflag.TLSPossibleVersions() fs.StringVar(&s.MinTLSVersion, "tls-min-version", s.MinTLSVersion, "Minimum TLS version supported. "+ @@ -317,6 +334,14 @@ func (s *SecureServingOptions) ApplyTo(config **server.SecureServingInfo) error c.CipherSuites = cipherSuites } + if len(s.CurvePreferences) != 0 { + curvePreferences, err := cliflag.TLSCurvePreferences(s.CurvePreferences) + if err != nil { + return err + } + c.CurvePreferences = curvePreferences + } + var err error c.MinTLSVersion, err = cliflag.TLSVersion(s.MinTLSVersion) if err != nil { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/serving_unix.go b/vendor/k8s.io/apiserver/pkg/server/options/serving_unix.go index 483eac79b2..6f484ac376 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/serving_unix.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/serving_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/apiserver/pkg/server/options/serving_windows.go b/vendor/k8s.io/apiserver/pkg/server/options/serving_windows.go index 844de61883..f8fb141098 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/serving_windows.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/serving_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go b/vendor/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go index 980ddc61a4..2dea7d2db1 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go @@ -18,26 +18,48 @@ package options import ( "fmt" + "net/http" "time" "github.com/google/uuid" "k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server/dynamiccertificates" + "k8s.io/apiserver/pkg/server/healthz" "k8s.io/client-go/rest" certutil "k8s.io/client-go/util/cert" + "k8s.io/utils/clock" ) type SecureServingOptionsWithLoopback struct { *SecureServingOptions + clock clock.PassiveClock } func (o *SecureServingOptions) WithLoopback() *SecureServingOptionsWithLoopback { - return &SecureServingOptionsWithLoopback{o} + return &SecureServingOptionsWithLoopback{ + SecureServingOptions: o, + clock: clock.RealClock{}, + } } +// Set a validity period of approximately 3 years for the loopback certificate +// to avoid kube-apiserver disruptions due to certificate expiration. +// When this certificate expires, restarting kube-apiserver will automatically +// regenerate a new certificate with fresh validity dates. +const maxAge = (3*365 + 1) * 24 * time.Hour + // ApplyTo fills up serving information in the server configuration. func (s *SecureServingOptionsWithLoopback) ApplyTo(secureServingInfo **server.SecureServingInfo, loopbackClientConfig **rest.Config) error { + return s.applyTo(secureServingInfo, loopbackClientConfig, nil) +} + +type HealthzLivezHealthChecksAdder interface { + AddHealthzChecks(checks ...healthz.HealthChecker) + AddLivezChecks(checks ...healthz.HealthChecker) +} + +func (s *SecureServingOptionsWithLoopback) applyTo(secureServingInfo **server.SecureServingInfo, loopbackClientConfig **rest.Config, healthCheckAdder HealthzLivezHealthChecksAdder) error { if s == nil || s.SecureServingOptions == nil || secureServingInfo == nil { return nil } @@ -50,12 +72,6 @@ func (s *SecureServingOptionsWithLoopback) ApplyTo(secureServingInfo **server.Se return nil } - // Set a validity period of approximately 3 years for the loopback certificate - // to avoid kube-apiserver disruptions due to certificate expiration. - // When this certificate expires, restarting kube-apiserver will automatically - // regenerate a new certificate with fresh validity dates. - maxAge := (3*365 + 1) * 24 * time.Hour - // create self-signed cert+key with the fake server.LoopbackClientServerNameOverride and // let the server return it when the loopback client connects. certPem, keyPem, err := certutil.GenerateSelfSignedCertKeyWithOptions(certutil.SelfSignedCertKeyOptions{ @@ -85,7 +101,37 @@ func (s *SecureServingOptionsWithLoopback) ApplyTo(secureServingInfo **server.Se default: *loopbackClientConfig = secureLoopbackClientConfig + if healthCheckAdder != nil { + s.addLoopbackServingCertificateHealthCheck(healthCheckAdder) + } } return nil } + +func (s *SecureServingOptionsWithLoopback) ApplyToConfig(cfg *server.Config) error { + return s.applyTo(&cfg.SecureServing, &cfg.LoopbackClientConfig, cfg) +} + +// addLoopbackServingCertificateHealthCheck adds a health check called `loopback-certificate-expiry` to the +// server that fails when the loopback client certificate has expired, enabling +// liveness probes to be used to automatically restart the apiserver. +func (s *SecureServingOptionsWithLoopback) addLoopbackServingCertificateHealthCheck(healthCheckAdder HealthzLivezHealthChecksAdder) { + expirationDate := s.clock.Now().Add(maxAge) + check := healthz.NamedCheck("loopback-serving-certificate", func(r *http.Request) error { + if s.clock.Now().After(expirationDate) { + return LoopbackCertificateExpiredError{} + } + + return nil + }) + + healthCheckAdder.AddHealthzChecks(check) + healthCheckAdder.AddLivezChecks(check) +} + +type LoopbackCertificateExpiredError struct{} + +func (lcee LoopbackCertificateExpiredError) Error() string { + return "loopback serving certificate is expired" +} diff --git a/vendor/k8s.io/apiserver/pkg/server/resourceconfig/helpers.go b/vendor/k8s.io/apiserver/pkg/server/resourceconfig/helpers.go index c546112ec9..d99d8b8b2a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/resourceconfig/helpers.go +++ b/vendor/k8s.io/apiserver/pkg/server/resourceconfig/helpers.go @@ -221,24 +221,37 @@ func getRuntimeConfigValue(overrides cliflag.ConfigurationMap, apiKey string, de // ParseGroups takes in resourceConfig and returns parsed groups. func ParseGroups(resourceConfig cliflag.ConfigurationMap) ([]string, error) { + groupVersions, err := ParseGroupVersions(resourceConfig) + if err != nil { + return nil, err + } groups := []string{} + for _, gv := range groupVersions { + groups = append(groups, gv.Group) + } + return groups, nil +} + +// ParseGroupVersions takes in resourceConfig and returns parsed group versions. +func ParseGroupVersions(resourceConfig cliflag.ConfigurationMap) ([]schema.GroupVersion, error) { + groupVersions := []schema.GroupVersion{} for key := range resourceConfig { if _, ok := groupVersionMatchers[key]; ok { continue } tokens := strings.Split(key, "/") if len(tokens) != 2 && len(tokens) != 3 { - return groups, fmt.Errorf("runtime-config invalid key %s", key) + return nil, fmt.Errorf("runtime-config invalid key %s", key) } groupVersionString := tokens[0] + "/" + tokens[1] groupVersion, err := schema.ParseGroupVersion(groupVersionString) if err != nil { return nil, fmt.Errorf("runtime-config invalid key %s", key) } - groups = append(groups, groupVersion.Group) + groupVersions = append(groupVersions, groupVersion) } - return groups, nil + return groupVersions, nil } // EmulationForwardCompatibleResourceConfig creates a new ResourceConfig that besides all the enabled resources in resourceConfig, diff --git a/vendor/k8s.io/apiserver/pkg/server/routes/metrics.go b/vendor/k8s.io/apiserver/pkg/server/routes/metrics.go index 8fd4d55999..644020049a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/routes/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/server/routes/metrics.go @@ -24,6 +24,7 @@ import ( etcd3metrics "k8s.io/apiserver/pkg/storage/etcd3/metrics" flowcontrolmetrics "k8s.io/apiserver/pkg/util/flowcontrol/metrics" peerproxymetrics "k8s.io/apiserver/pkg/util/peerproxy/metrics" + proxymetrics "k8s.io/apiserver/pkg/util/proxy/metrics" "k8s.io/component-base/metrics/legacyregistry" ) @@ -54,4 +55,5 @@ func register() { flowcontrolmetrics.Register() peerproxymetrics.Register() handlersmetrics.Register() + proxymetrics.Register() } diff --git a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go index 13982b7b4c..459d737776 100644 --- a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go +++ b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go @@ -29,6 +29,7 @@ import ( "k8s.io/kube-openapi/pkg/common/restfuladapter" "k8s.io/kube-openapi/pkg/handler" "k8s.io/kube-openapi/pkg/handler3" + "k8s.io/kube-openapi/pkg/spec3" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -76,7 +77,9 @@ func (oa OpenAPI) InstallV2(c *restful.Container, mux *mux.PathRecorderMux) (*ha return openAPIVersionedService, spec } -// InstallV3 adds the static group/versions defined in the RegisteredWebServices to the OpenAPI v3 spec +// InstallV3 adds the static group/versions defined in the RegisteredWebServices to the OpenAPI v3 spec. +// This only covers built-in resources served via go-restful; CRDs and aggregated APIs publish +// their OpenAPI v3 specs through separate code paths. func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *handler3.OpenAPIService { openAPIVersionedService := handler3.NewOpenAPIService() err := openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux) @@ -96,9 +99,111 @@ func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *han spec, err := builder3.BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(ws), oa.V3Config) if err != nil { klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err) - + continue + } + if group, version, ok := groupVersionFromPath(gv); ok { + filterScopedGVKs(spec, group, version) } openAPIVersionedService.UpdateGroupVersion(gv, spec) } return openAPIVersionedService } + +// groupVersionFromPath extracts the API group and version from a root path like "apis/apps/v1" or "api/v1". +func groupVersionFromPath(path string) (group, version string, ok bool) { + // "api/v1" → ("", "v1", true) + // "apis/apps/v1" → ("apps", "v1", true) + // "apis/networking.k8s.io/v1" → ("networking.k8s.io", "v1", true) + parts := strings.SplitN(path, "/", 4) + switch { + case len(parts) < 2: + return "", "", false + case parts[0] == "api" && len(parts) == 2: + return "", parts[1], true + case parts[0] == "apis" && len(parts) == 3: + return parts[1], parts[2], true + default: + return "", "", false + } +} + +// crossRegisteredKinds lists the kinds that AddToGroupVersion (in +// k8s.io/apimachinery/pkg/apis/meta/v1) registers into every API group. +// Only these types get their x-kubernetes-group-version-kind list filtered +// in per-GV v3 specs. +var crossRegisteredKinds = map[string]bool{ + "WatchEvent": true, + "DeleteOptions": true, +} + +// filterScopedGVKs narrows x-kubernetes-group-version-kind on the meta types +// that AddToGroupVersion cross-registers into every API group (WatchEvent and +// DeleteOptions). Without filtering, each per-GV v3 spec carries ~60 GVKs for +// these types. This filter keeps only the entry matching this spec's group/version +// plus the canonical core/v1 entry. +// +// Only the meta types listed in crossRegisteredKinds are filtered. Other types +// that are intentionally registered into specific groups (like autoscaling/v1 +// Scale into apps/v1 and core/v1) are left unchanged. +// +// This only affects built-in resource specs generated by InstallV3 above. +// CRDs and aggregated APIs are not affected as they publish specs through separate paths. +func filterScopedGVKs(s *spec3.OpenAPI, group, version string) { + if s == nil || s.Components == nil { + return + } + for _, schema := range s.Components.Schemas { + if schema == nil { + continue + } + ext, ok := schema.Extensions["x-kubernetes-group-version-kind"] + if !ok { + continue + } + gvks, ok := ext.([]interface{}) + if !ok || len(gvks) <= 1 { + continue + } + if !isCrossRegisteredKind(gvks) { + continue + } + var filtered []interface{} + for _, item := range gvks { + m, ok := item.(map[string]interface{}) + if !ok { + continue + } + g, ok := m["group"].(string) + if !ok { + continue + } + v, ok := m["version"].(string) + if !ok { + continue + } + if (g == group && v == version) || (g == "" && v == "v1") { + filtered = append(filtered, item) + } + } + if len(filtered) > 0 { + schema.Extensions["x-kubernetes-group-version-kind"] = filtered + } else { + klog.Warningf("Unexpected: filtering x-kubernetes-group-version-kind for %s/%s produced no matches", group, version) + delete(schema.Extensions, "x-kubernetes-group-version-kind") + } + } +} + +// isCrossRegisteredKind checks whether a GVK list represents one of the +// meta types from crossRegisteredKinds by inspecting the first entry's kind. +func isCrossRegisteredKind(gvks []interface{}) bool { + if len(gvks) == 0 { + return false + } + m, ok := gvks[0].(map[string]interface{}) + if !ok { + return false + } + kind, _ := m["kind"].(string) + return crossRegisteredKinds[kind] +} diff --git a/vendor/k8s.io/apiserver/pkg/server/secure_serving.go b/vendor/k8s.io/apiserver/pkg/server/secure_serving.go index 867c7efac2..0c14893a74 100644 --- a/vendor/k8s.io/apiserver/pkg/server/secure_serving.go +++ b/vendor/k8s.io/apiserver/pkg/server/secure_serving.go @@ -71,6 +71,9 @@ func (s *SecureServingInfo) tlsConfig(stopCh <-chan struct{}) (*tls.Config, erro } } } + if len(s.CurvePreferences) > 0 { + tlsConfig.CurvePreferences = s.CurvePreferences + } if s.ClientCA != nil { // Populate PeerCertificates in requests, but don't reject connections without certificates diff --git a/vendor/k8s.io/apiserver/pkg/server/signal_posix.go b/vendor/k8s.io/apiserver/pkg/server/signal_posix.go index 7acb2038a1..fc0ab2d671 100644 --- a/vendor/k8s.io/apiserver/pkg/server/signal_posix.go +++ b/vendor/k8s.io/apiserver/pkg/server/signal_posix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1alpha1/doc.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1alpha1/doc.go index aa0fdaed0b..9a542b0970 100644 --- a/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1alpha1/doc.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1alpha1/doc.go @@ -18,5 +18,5 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:openapi-model-package=io.k8s.apiserver.pkg.server.statusz.api.v1alpha1 -// Package v1alpha1 contains API Schema definitions for the zpages v1alpha1 API group +// Package v1alpha1 contains API Schema definitions for the statusz v1alpha1 API group package v1alpha1 diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/doc.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/doc.go similarity index 73% rename from vendor/k8s.io/api/autoscaling/v2beta1/doc.go rename to vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/doc.go index 58cc1f89dc..8237e4776f 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/doc.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 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. @@ -15,9 +15,8 @@ limitations under the License. */ // +k8s:deepcopy-gen=package -// +k8s:protobuf-gen=package // +k8s:openapi-gen=true -// +k8s:prerelease-lifecycle-gen=true -// +k8s:openapi-model-package=io.k8s.api.autoscaling.v2beta1 +// +k8s:openapi-model-package=io.k8s.apiserver.pkg.server.statusz.api.v1beta1 -package v2beta1 +// Package v1beta1 contains API Schema definitions for the statusz v1beta1 API group +package v1beta1 diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/register.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/register.go new file mode 100644 index 0000000000..c41806b69d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/register.go @@ -0,0 +1,47 @@ +/* +Copyright 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 v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +const ( + GroupName = "config.k8s.io" + Version = "v1beta1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +var ( + // SchemeBuilder initializes a scheme builder + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that adds this group's types to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Statusz{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/types.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/types.go new file mode 100644 index 0000000000..a8898826bb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/types.go @@ -0,0 +1,50 @@ +/* +Copyright 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// Statusz is a struct used for versioned statusz endpoint. +type Statusz struct { + // TypeMeta is the type metadata for the object. + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + // StartTime is the time the component process was initiated. + StartTime metav1.Time `json:"startTime"` + // UptimeSeconds is the duration in seconds for which the component has been running continuously. + UptimeSeconds int64 `json:"uptimeSeconds"` + // GoVersion is the version of the Go programming language used to build the binary. + // The format is not guaranteed to be consistent across different Go builds. + // +optional + GoVersion string `json:"goVersion"` + // BinaryVersion is the version of the component's binary. + // The format is not guaranteed to be semantic versioning and may be an arbitrary string. + BinaryVersion string `json:"binaryVersion"` + // EmulationVersion is the Kubernetes API version which this component is emulating. + // if present, formatted as "." + // +optional + EmulationVersion string `json:"emulationVersion,omitempty"` + // Paths contains relative URLs to other essential read-only endpoints for debugging and troubleshooting. + // +optional + // +listType=set + Paths []string `json:"paths"` +} diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..e879af624c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Statusz) DeepCopyInto(out *Statusz) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.StartTime.DeepCopyInto(&out.StartTime) + if in.Paths != nil { + in, out := &in.Paths, &out.Paths + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Statusz. +func (in *Statusz) DeepCopy() *Statusz { + if in == nil { + return nil + } + out := new(Statusz) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Statusz) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.model_name.go similarity index 66% rename from vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.protomessage.pb.go rename to vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.model_name.go index a782b1d8f0..8a4134750b 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.protomessage.pb.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/api/v1beta1/zz_generated.model_name.go @@ -1,5 +1,5 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release +//go:build !ignore_autogenerated +// +build !ignore_autogenerated /* Copyright The Kubernetes Authors. @@ -17,8 +17,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. +// Code generated by openapi-gen. DO NOT EDIT. package v1beta1 -func (*PartialObjectMetadataList) ProtoMessage() {} +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in Statusz) OpenAPIModelName() string { + return "io.k8s.apiserver.pkg.server.statusz.api.v1beta1.Statusz" +} diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/negotiate/negotiation.go b/vendor/k8s.io/apiserver/pkg/server/statusz/negotiate/negotiation.go index 04c6943774..cd314e4aea 100644 --- a/vendor/k8s.io/apiserver/pkg/server/statusz/negotiate/negotiation.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/negotiate/negotiation.go @@ -20,34 +20,29 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -// StatuszEndpointRestrictions implements content negotiation restrictions for the z-pages. +// StatuszEndpointRestrictions implements content negotiation restrictions for statusz. // It is used to validate and restrict which GroupVersionKinds are allowed for structured responses. -type StatuszEndpointRestrictions struct{} +type StatuszEndpointRestrictions struct { + RecognizedStructuredKinds map[schema.GroupVersionKind]bool +} -// AllowsMediaTypeTransform checks if the provided GVK is supported for structured z-page responses. -func (StatuszEndpointRestrictions) AllowsMediaTypeTransform(mimeType string, mimeSubType string, gvk *schema.GroupVersionKind) bool { +// AllowsMediaTypeTransform checks if the provided GVK is supported for structured statusz responses. +func (s StatuszEndpointRestrictions) AllowsMediaTypeTransform(mimeType string, mimeSubType string, gvk *schema.GroupVersionKind) bool { if mimeType == "text" && mimeSubType == "plain" { return gvk == nil } - return isStructured(gvk) -} -func (StatuszEndpointRestrictions) AllowsServerVersion(string) bool { + if gvk != nil { + return s.RecognizedStructuredKinds[*gvk] + } + return false } -func (StatuszEndpointRestrictions) AllowsStreamSchema(s string) bool { +func (StatuszEndpointRestrictions) AllowsServerVersion(s string) bool { return false } -func isStructured(gvk *schema.GroupVersionKind) bool { - if gvk != nil { - if gvk.Group == "config.k8s.io" && gvk.Version == "v1alpha1" { - if gvk.Kind == "Statusz" { - return true - } - } - } - +func (StatuszEndpointRestrictions) AllowsStreamSchema(s string) bool { return false } diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/statusz.go b/vendor/k8s.io/apiserver/pkg/server/statusz/statusz.go index f9f24dfbd7..1b334b1699 100644 --- a/vendor/k8s.io/apiserver/pkg/server/statusz/statusz.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/statusz.go @@ -26,15 +26,22 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/runtime/serializer/cbor" "k8s.io/component-base/compatibility" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" + "k8s.io/apiserver/pkg/endpoints/metrics" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/endpoints/responsewriter" + "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/server/statusz/api/v1alpha1" + "k8s.io/apiserver/pkg/server/statusz/api/v1beta1" "k8s.io/apiserver/pkg/server/statusz/negotiate" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - v1alpha1 "k8s.io/apiserver/pkg/server/statusz/api/v1alpha1" + utilfeature "k8s.io/apiserver/pkg/util/feature" ) var ( @@ -46,21 +53,27 @@ var ( "/openapi": true, "/.well-known": true, } + v1alpha1StatuszKind = v1alpha1.SchemeGroupVersion.WithKind("Statusz") + v1beta1StatuszKind = v1beta1.SchemeGroupVersion.WithKind("Statusz") + recognizedStructuredKinds = map[schema.GroupVersionKind]bool{ + v1alpha1StatuszKind: true, + v1beta1StatuszKind: true, + } ) -const ( - DefaultStatuszPath = "/statusz" - Kind = "Statusz" - GroupName = "config.k8s.io" - Version = "v1alpha1" -) +const DefaultStatuszPath = "/statusz" const headerFmt = ` %s statusz Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only. ` -var schemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} +// statuszCodecFactory wraps a CodecFactory to filter out unsupported media types (like protobuf) +// from the supported media types list, so error messages only show actually supported types. +type statuszCodecFactory struct { + serializer.CodecFactory + supportedMediaTypes []runtime.SerializerInfo +} type mux interface { Handle(path string, handler http.Handler) @@ -70,7 +83,8 @@ type ListedPathsOption []string func NewRegistry(effectiveVersion compatibility.EffectiveVersion, opts ...Option) statuszRegistry { r := ®istry{ - effectiveVersion: effectiveVersion, + effectiveVersion: effectiveVersion, + deprecatedVersionsMap: map[string]bool{"v1alpha1": true}, } for _, opt := range opts { opt(r) @@ -82,8 +96,21 @@ func NewRegistry(effectiveVersion compatibility.EffectiveVersion, opts ...Option func Install(m mux, componentName string, reg statuszRegistry) { scheme := runtime.NewScheme() utilruntime.Must(v1alpha1.AddToScheme(scheme)) - codecFactory := serializer.NewCodecFactory( - scheme, + utilruntime.Must(v1beta1.AddToScheme(scheme)) + filteredCodecFactory, err := newStatuszCodecFactory(scheme, componentName, reg) + if err != nil { + utilruntime.HandleError(err) + } + restrictions := negotiate.StatuszEndpointRestrictions{ + RecognizedStructuredKinds: recognizedStructuredKinds, + } + m.Handle(DefaultStatuszPath, handleStatusz(componentName, reg, filteredCodecFactory, restrictions)) +} + +// newStatuszCodecFactory creates a codec factory with the standard serializers for statusz, +// filtering out unsupported media types (e.g., protobuf). +func newStatuszCodecFactory(scheme *runtime.Scheme, componentName string, reg statuszRegistry) (*statuszCodecFactory, error) { + codecFactoryOpts := []serializer.CodecFactoryOptionsMutator{ serializer.WithSerializer(func(_ runtime.ObjectCreater, _ runtime.ObjectTyper) runtime.SerializerInfo { textSerializer := statuszTextSerializer{componentName, reg} return runtime.SerializerInfo{ @@ -95,16 +122,75 @@ func Install(m mux, componentName string, reg statuszRegistry) { PrettySerializer: textSerializer, } }), - ) - m.Handle(DefaultStatuszPath, handleStatusz(componentName, reg, codecFactory, negotiate.StatuszEndpointRestrictions{})) + } + // TODO: remove this explicit check when https://github.com/kubernetes/enhancements/pull/5740 is implemented. + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { + codecFactoryOpts = append(codecFactoryOpts, serializer.WithSerializer(cbor.NewSerializerInfo)) + } + + codecFactory := serializer.NewCodecFactory(scheme, codecFactoryOpts...) + allTypes := codecFactory.SupportedMediaTypes() + filtered := make([]runtime.SerializerInfo, 0, len(allTypes)) + + var unknownTypes []string + for _, info := range allTypes { + switch info.MediaType { + // Supported media types + case "text/plain", runtime.ContentTypeJSON, runtime.ContentTypeYAML, runtime.ContentTypeCBOR: + filtered = append(filtered, info) + // Unsupported media types + case runtime.ContentTypeProtobuf: + continue + default: + unknownTypes = append(unknownTypes, info.MediaType) + } + } + + var err error + if len(unknownTypes) > 0 { + err = fmt.Errorf("statusz: unknown media type(s) %v, excluding from supported types", unknownTypes) + } + + return &statuszCodecFactory{ + CodecFactory: codecFactory, + supportedMediaTypes: filtered, + }, err +} + +func (f *statuszCodecFactory) SupportedMediaTypes() []runtime.SerializerInfo { + return f.supportedMediaTypes } func handleStatusz(componentName string, reg statuszRegistry, serializer runtime.NegotiatedSerializer, restrictions negotiate.StatuszEndpointRestrictions) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - obj := statusz(componentName, reg) + requestReceivedTimestamp, ok := request.ReceivedTimestampFrom(r.Context()) + if !ok { + requestReceivedTimestamp = time.Now() + } + delegate := &metrics.ResponseWriterDelegator{ResponseWriter: w} + w = responsewriter.WrapForHTTP1Or2(delegate) + + // Use MonitorRequest instead of InstrumentHandlerFunc because the group, + // version, and deprecated status depend on per-request content negotiation. + // For text/plain requests, group and version remain empty. For structured + // responses (JSON/YAML/CBOR), they are set to the negotiated API group and + // version (e.g., config.k8s.io/v1alpha1). + var group, version string + var deprecated bool + defer func() { + metrics.MonitorRequest(r, "GET", group, version, + "statusz", // resource + "", // subresource + "", // scope + componentName, // component + deprecated, + "", // removedRelease + delegate.Status(), delegate.ContentLength(), time.Since(requestReceivedTimestamp)) + }() + acceptHeader := r.Header.Get("Accept") if strings.TrimSpace(acceptHeader) == "" { - writePlainTextResponse(obj, serializer, w) + writePlainTextResponse(v1beta1Statusz(componentName, reg), serializer, w) return } @@ -121,11 +207,10 @@ func handleStatusz(componentName string, reg statuszRegistry, serializer runtime return } - var targetGV schema.GroupVersion switch serializerInfo.MediaType { - case "application/json": + case "application/json", "application/yaml", "application/cbor": if mediaType.Convert == nil { - err := fmt.Errorf("content negotiation failed: mediaType.Convert is nil for application/json") + err := fmt.Errorf("content negotiation failed: mediaType.Convert is nil for %s", serializerInfo.MediaType) utilruntime.HandleError(err) responsewriters.ErrorNegotiated( err, @@ -136,18 +221,19 @@ func handleStatusz(componentName string, reg statuszRegistry, serializer runtime ) return } - targetGV = mediaType.Convert.GroupVersion() - deprecated := reg.deprecatedVersions()[targetGV.Version] + // Set group, version, and deprecated from the negotiated target so + // the deferred MonitorRequest records the actual requested API version. + group = mediaType.Convert.Group + version = mediaType.Convert.Version + deprecated = reg.deprecatedVersions()[version] if deprecated { w.Header().Set("Warning", `299 - "This version of the statusz endpoint is deprecated. Please use a newer version."`) } + handleStructuredResponse(w, r, componentName, reg, serializer, restrictions, mediaType) case "text/plain": - // Even though text/plain serialization does not use the group/version, - // the serialization machinery expects a non-zero schema.GroupVersion to be passed. - // Passing the zero value can cause errors or unexpected behavior in the negotiation logic. - targetGV = schemeGroupVersion + writePlainTextResponse(v1beta1Statusz(componentName, reg), serializer, w) default: - err = fmt.Errorf("content negotiation failed: unsupported media type '%s'", serializerInfo.MediaType) + err := fmt.Errorf("unsupported media type: %s/%s", serializerInfo.MediaType, serializerInfo.MediaTypeSubType) utilruntime.HandleError(err) responsewriters.ErrorNegotiated( err, @@ -156,14 +242,29 @@ func handleStatusz(componentName string, reg statuszRegistry, serializer runtime w, r, ) - return } + } +} - writeResponse(obj, serializer, targetGV, restrictions, w, r) +func handleStructuredResponse(w http.ResponseWriter, r *http.Request, componentName string, reg statuszRegistry, serializer runtime.NegotiatedSerializer, restrictions negotiate.StatuszEndpointRestrictions, mediaType negotiation.MediaTypeOptions) { + switch *mediaType.Convert { + case v1alpha1StatuszKind: + writeStructuredResponse(v1alpha1Statusz(componentName, reg), serializer, mediaType.Convert.GroupVersion(), restrictions, w, r) + case v1beta1StatuszKind: + writeStructuredResponse(v1beta1Statusz(componentName, reg), serializer, mediaType.Convert.GroupVersion(), restrictions, w, r) + default: + err := fmt.Errorf("unsupported media type: %s", mediaType.Convert.String()) + utilruntime.HandleError(err) + responsewriters.ErrorNegotiated( + err, + serializer, + schema.GroupVersion{}, + w, + r, + ) } } -// writePlainTextResponse writes the statusz response as text/plain using the registered serializer. func writePlainTextResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, w http.ResponseWriter) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") // Find the text/plain serializer @@ -185,7 +286,7 @@ func writePlainTextResponse(obj runtime.Object, serializer runtime.NegotiatedSer } } -func writeResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, targetGV schema.GroupVersion, restrictions negotiate.StatuszEndpointRestrictions, w http.ResponseWriter, r *http.Request) { +func writeStructuredResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, targetGV schema.GroupVersion, restrictions negotiate.StatuszEndpointRestrictions, w http.ResponseWriter, r *http.Request) { responsewriters.WriteObjectNegotiated( serializer, restrictions, @@ -198,7 +299,7 @@ func writeResponse(obj runtime.Object, serializer runtime.NegotiatedSerializer, ) } -func statusz(componentName string, reg statuszRegistry) *v1alpha1.Statusz { +func v1alpha1Statusz(componentName string, reg statuszRegistry) *v1alpha1.Statusz { startTime := reg.processStartTime() upTimeSeconds := max(0, int64(time.Since(startTime).Seconds())) goVersion := reg.goVersion() @@ -211,8 +312,38 @@ func statusz(componentName string, reg statuszRegistry) *v1alpha1.Statusz { paths := aggregatePaths(reg.paths()) data := &v1alpha1.Statusz{ TypeMeta: metav1.TypeMeta{ - Kind: Kind, - APIVersion: fmt.Sprintf("%s/%s", GroupName, Version), + Kind: v1alpha1StatuszKind.Kind, + APIVersion: v1alpha1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: componentName, + }, + StartTime: metav1.Time{Time: startTime}, + UptimeSeconds: upTimeSeconds, + GoVersion: goVersion, + BinaryVersion: binaryVersion, + EmulationVersion: emulationVersion, + Paths: paths, + } + + return data +} + +func v1beta1Statusz(componentName string, reg statuszRegistry) *v1beta1.Statusz { + startTime := reg.processStartTime() + upTimeSeconds := max(0, int64(time.Since(startTime).Seconds())) + goVersion := reg.goVersion() + binaryVersion := reg.binaryVersion().String() + var emulationVersion string + if reg.emulationVersion() != nil { + emulationVersion = reg.emulationVersion().String() + } + + paths := aggregatePaths(reg.paths()) + data := &v1beta1.Statusz{ + TypeMeta: metav1.TypeMeta{ + Kind: v1beta1StatuszKind.Kind, + APIVersion: v1beta1.SchemeGroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Name: componentName, diff --git a/vendor/k8s.io/apiserver/pkg/server/statusz/textserializer.go b/vendor/k8s.io/apiserver/pkg/server/statusz/textserializer.go index c8bdc2c72a..5c97923a0b 100644 --- a/vendor/k8s.io/apiserver/pkg/server/statusz/textserializer.go +++ b/vendor/k8s.io/apiserver/pkg/server/statusz/textserializer.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - v1alpha1 "k8s.io/apiserver/pkg/server/statusz/api/v1alpha1" + v1beta1 "k8s.io/apiserver/pkg/server/statusz/api/v1beta1" ) // statuszTextSerializer implements runtime.Serializer for text/plain output. @@ -45,9 +45,9 @@ func (s statuszTextSerializer) Encode(obj runtime.Object, w io.Writer) error { randomIndex := rand.Intn(len(delimiters)) delim := html.EscapeString(delimiters[randomIndex]) - statuszObj, ok := obj.(*v1alpha1.Statusz) + statuszObj, ok := obj.(*v1beta1.Statusz) if !ok { - return fmt.Errorf("expected *v1alpha1.Statusz, got %T", obj) + return fmt.Errorf("expected *v1beta1.Statusz, got %T", obj) } startTime := html.EscapeString(statuszObj.StartTime.Time.Format(time.UnixDate)) diff --git a/vendor/k8s.io/apiserver/pkg/sharding/parser.go b/vendor/k8s.io/apiserver/pkg/sharding/parser.go new file mode 100644 index 0000000000..fe08eac0c9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/sharding/parser.go @@ -0,0 +1,217 @@ +/* +Copyright 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 sharding + +import ( + "fmt" + "strings" + + celparser "github.com/google/cel-go/parser" + + "github.com/google/cel-go/common" + "github.com/google/cel-go/common/ast" + "github.com/google/cel-go/common/operators" + + apisharding "k8s.io/apimachinery/pkg/sharding" +) + +// Parse parses a CEL-based shard selector expression into a Selector. +// +// The expression format is: +// +// shardRange(object.metadata.uid, '0x0', '0x8000000000000000') +// shardRange(object.metadata.uid, '0x0', '0x8000000000000000') || shardRange(...) +// +// Only the shardRange() function and || operator are permitted. The CEL +// expression is parsed but never evaluated — the AST is walked to extract +// shard range requirements. +func Parse(expr string) (apisharding.Selector, error) { + expr = strings.TrimSpace(expr) + if expr == "" { + return nil, fmt.Errorf("empty shard selector is not allowed; omit the parameter for unfiltered lists") + } + + p, err := celparser.NewParser(celparser.Macros( /* no macros */ )) + if err != nil { + return nil, fmt.Errorf("failed to create CEL parser: %w", err) + } + + parsed, errs := p.Parse(common.NewTextSource(expr)) + if errs != nil && len(errs.GetErrors()) > 0 { + return nil, fmt.Errorf("CEL parse error: %s", errs.GetErrors()[0].Message) + } + + reqs, err := walkExpr(parsed.Expr()) + if err != nil { + return nil, err + } + + // Validate that all requirements use the same field key. + for i := 1; i < len(reqs); i++ { + if reqs[i].Key != reqs[0].Key { + return nil, fmt.Errorf("all shard ranges must use the same field, got %q and %q", reqs[0].Key, reqs[i].Key) + } + } + + return apisharding.NewSelector(reqs...), nil +} + +// walkExpr recursively walks the CEL AST and extracts ShardRangeRequirement values. +// The root expression must be either a shardRange() call or a chain of || operators +// combining shardRange() calls. +func walkExpr(e ast.Expr) ([]apisharding.ShardRangeRequirement, error) { + if e.Kind() == ast.CallKind { + call := e.AsCall() + fn := call.FunctionName() + + if fn == operators.LogicalOr { + // _||_ operator: recurse into both sides + args := call.Args() + if len(args) != 2 { + return nil, fmt.Errorf("|| operator requires exactly 2 arguments") + } + left, err := walkExpr(args[0]) + if err != nil { + return nil, err + } + right, err := walkExpr(args[1]) + if err != nil { + return nil, err + } + return append(left, right...), nil + } + + if fn == "shardRange" { + req, err := parseShardRangeCall(call) + if err != nil { + return nil, err + } + return []apisharding.ShardRangeRequirement{req}, nil + } + + return nil, fmt.Errorf("unsupported function %q; only shardRange() and || are allowed", fn) + } + + return nil, fmt.Errorf("unexpected expression kind %v; expected shardRange() call or || operator", e.Kind()) +} + +// parseShardRangeCall extracts a ShardRangeRequirement from a shardRange(field, start, end) call. +func parseShardRangeCall(call ast.CallExpr) (apisharding.ShardRangeRequirement, error) { + args := call.Args() + if len(args) != 3 { + return apisharding.ShardRangeRequirement{}, fmt.Errorf("shardRange() requires exactly 3 arguments, got %d", len(args)) + } + + // Arg 0: field path (select chain like object.metadata.uid) + fieldPath, err := extractFieldPath(args[0]) + if err != nil { + return apisharding.ShardRangeRequirement{}, fmt.Errorf("shardRange() first argument: %w", err) + } + + // Validate field path + switch fieldPath { + case "object.metadata.uid", "object.metadata.namespace": + // ok + default: + return apisharding.ShardRangeRequirement{}, fmt.Errorf("unsupported field path %q; supported: object.metadata.uid, object.metadata.namespace", fieldPath) + } + + // Arg 1: hex start (string literal) + hexStart, err := extractHexLiteral(args[1], "hexStart") + if err != nil { + return apisharding.ShardRangeRequirement{}, err + } + + // Arg 2: hex end (string literal) + hexEnd, err := extractHexLiteral(args[2], "hexEnd") + if err != nil { + return apisharding.ShardRangeRequirement{}, err + } + + // Validate start < end using the canonical hex comparison. + if !apisharding.HexLess(hexStart, hexEnd) { + return apisharding.ShardRangeRequirement{}, fmt.Errorf("shard range start %s must be less than end %s", hexStart, hexEnd) + } + + return apisharding.ShardRangeRequirement{ + Key: fieldPath, + Start: hexStart, + End: hexEnd, + }, nil +} + +// extractFieldPath walks a select chain (object.metadata.uid) and returns the dot-joined path. +func extractFieldPath(e ast.Expr) (string, error) { + switch e.Kind() { + case ast.IdentKind: + return e.AsIdent(), nil + case ast.SelectKind: + sel := e.AsSelect() + operand, err := extractFieldPath(sel.Operand()) + if err != nil { + return "", err + } + return operand + "." + sel.FieldName(), nil + default: + return "", fmt.Errorf("expected field path (e.g. object.metadata.uid), got expression kind %v", e.Kind()) + } +} + +// extractHexLiteral extracts a hex string from a CEL string literal. +// The literal must be a single-quoted string like '0xff' with a 0x prefix. +func extractHexLiteral(e ast.Expr, name string) (string, error) { + if e.Kind() != ast.LiteralKind { + return "", fmt.Errorf("%s must be a string literal (e.g. '0xff'), got expression kind %v", name, e.Kind()) + } + + val := e.AsLiteral() + s, ok := val.Value().(string) + if !ok { + return "", fmt.Errorf("%s must be a string literal, got %T", name, val.Value()) + } + + if !strings.HasPrefix(s, "0x") { + return "", fmt.Errorf("%s must have '0x' prefix, got %q", name, s) + } + + hex := s[2:] + if hex == "" { + return "", fmt.Errorf("%s: hex value is required after '0x'", name) + } + if len(hex) > 17 { + return "", fmt.Errorf("%s: hex value too long (%d chars, max 17): %q", name, len(hex), hex) + } + + for _, c := range hex { + if (c < '0' || c > '9') && (c < 'a' || c > 'f') { + return "", fmt.Errorf("%s: invalid hex character %q in %q", name, string(c), s) + } + } + + // Require exactly 16 hex digits, except for the special case + // "0x10000000000000000" (2^64) which is the exclusive upper bound. + if len(hex) == 17 { + if s != "0x10000000000000000" { + return "", fmt.Errorf("%s: 17-digit hex value must be '0x10000000000000000' (2^64), got %q", name, s) + } + } else if len(hex) != 16 { + padded := "0x" + strings.Repeat("0", 16-len(hex)) + hex + return "", fmt.Errorf("%s must be a 0x-prefixed 16-digit hex value, got %q (did you mean %q?)", name, s, padded) + } + + return s, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/OWNERS index b68cef1fe5..39822f47de 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/OWNERS +++ b/vendor/k8s.io/apiserver/pkg/storage/OWNERS @@ -3,6 +3,7 @@ approvers: - liggitt - wojtek-t + - serathius reviewers: - smarterclayton - wojtek-t @@ -14,6 +15,7 @@ reviewers: - enj - stevekuznetsov - MadhavJivrajani + - serathius emeritus_approvers: - xiang90 - timothysc diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go index a74cf8d4a3..8711596a3c 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go @@ -371,10 +371,10 @@ func (c *cacheWatcher) convertToWatchEvent(event *watchCacheEvent) *watch.Event return e } - curObjPasses := event.Type != watch.Deleted && c.filter(event.Key, event.ObjLabels, event.ObjFields) + curObjPasses := event.Type != watch.Deleted && c.filter(event.Key, event.ObjLabels, event.ObjFields, event.Object) oldObjPasses := false if event.PrevObject != nil { - oldObjPasses = c.filter(event.Key, event.PrevObjLabels, event.PrevObjFields) + oldObjPasses = c.filter(event.Key, event.PrevObjLabels, event.PrevObjFields, event.PrevObject) } if !curObjPasses && !oldObjPasses { // Watcher is not interested in that object. @@ -434,7 +434,7 @@ func (c *cacheWatcher) sendWatchCacheEvent(event *watchCacheEvent) { } func (c *cacheWatcher) processInterval(ctx context.Context, cacheInterval *watchCacheInterval, resourceVersion uint64) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer close(c.result) defer c.Stop() diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go index a5f7ab6d69..326ed27c80 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go @@ -36,6 +36,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/audit" @@ -45,6 +46,7 @@ import ( "k8s.io/apiserver/pkg/storage/cacher/delegator" "k8s.io/apiserver/pkg/storage/cacher/metrics" "k8s.io/apiserver/pkg/storage/cacher/progress" + "k8s.io/apiserver/pkg/storage/cacher/store" etcdfeature "k8s.io/apiserver/pkg/storage/feature" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/cache" @@ -246,7 +248,7 @@ func (t *watcherBookmarkTimeBuckets) popExpiredWatchersThreadUnsafe() [][]*cache return expiredWatchers } -type filterWithAttrsFunc func(key string, l labels.Set, f fields.Set) bool +type filterWithAttrsFunc func(key string, l labels.Set, f fields.Set, obj runtime.Object) bool type indexedTriggerFunc struct { indexName string @@ -505,6 +507,10 @@ type namespacedName struct { } func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + ctx, span := tracing.Start(ctx, "cacher.Watch", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.Stringer("type", c.groupResource)) + defer span.End(500 * time.Millisecond) key, err := c.prepareKey(key, opts.Recursive) if err != nil { return nil, err @@ -597,7 +603,7 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions // to compute watcher.forget function (which has to happen under lock). watcher := newCacheWatcher( chanSize, - filterWithAttrsAndPrefixFunction(key, pred), + filterWithAttrsAndPrefixFunction(key, pred, c.groupResource), emptyFunc, c.versioner, deadline, @@ -671,6 +677,15 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions return newImmediateCloseWatcher(), nil } + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) && pred.ShardSelector != nil && !pred.ShardSelector.Empty() { + metrics.RecordShardedWatchStarted(c.groupResource) + originalForget := watcher.forget + watcher.forget = func(drainWatcher bool) { + metrics.RecordShardedWatchStopped(c.groupResource) + originalForget(drainWatcher) + } + } + go watcher.processInterval(ctx, cacheInterval, requiredResourceVersion) return watcher, nil } @@ -696,9 +711,9 @@ func (c *Cacher) Get(ctx context.Context, key string, opts storage.GetOptions, o } if exists { - elem, ok := obj.(*storeElement) + elem, ok := obj.(*store.Element) if !ok { - return fmt.Errorf("non *storeElement returned from storage: %v", obj) + return fmt.Errorf("non *store.Element returned from storage: %v", obj) } objVal.Set(reflect.ValueOf(elem.Object).Elem()) } else { @@ -785,11 +800,19 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio var hasMoreListItems bool limit := computeListLimit(opts) for i, obj := range resp.Items { - elem, ok := obj.(*storeElement) + elem, ok := obj.(*store.Element) if !ok { - return fmt.Errorf("non *storeElement returned from storage: %v", obj) + return fmt.Errorf("non *store.Element returned from storage: %v", obj) } - if opts.Predicate.MatchesObjectAttributes(elem.Labels, elem.Fields) { + shardMatch := true + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + var err error + shardMatch, err = opts.Predicate.MatchesSharding(elem.Object) + if err != nil { + return fmt.Errorf("shard matching failed: %w", err) + } + } + if shardMatch && opts.Predicate.MatchesObjectAttributes(elem.Labels, elem.Fields) { selectedObjects = append(selectedObjects, elem.Object) lastSelectedObjectKey = elem.Key } @@ -820,6 +843,9 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio return err } } + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + opts.Predicate.SetShardInfoOnList(listObj) + } metrics.RecordListCacheMetrics(c.groupResource, indexUsed, len(resp.Items), listVal.Len()) return nil } @@ -1198,11 +1224,23 @@ func forgetWatcher(c *Cacher, w *cacheWatcher, index int, scope namespacedName, } } -func filterWithAttrsAndPrefixFunction(key string, p storage.SelectionPredicate) filterWithAttrsFunc { - filterFunc := func(objKey string, label labels.Set, field fields.Set) bool { +func filterWithAttrsAndPrefixFunction(key string, p storage.SelectionPredicate, groupResource schema.GroupResource) filterWithAttrsFunc { + isSharded := utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) && p.ShardSelector != nil && !p.ShardSelector.Empty() + filterFunc := func(objKey string, label labels.Set, field fields.Set, obj runtime.Object) bool { if !hasPathPrefix(objKey, key) { return false } + if isSharded { + matches, err := p.MatchesSharding(obj) + if err != nil { + utilruntime.HandleError(fmt.Errorf("shard matching failed for %v: %w", groupResource, err)) + return false + } + if !matches { + metrics.RecordWatchFilteredEvent(groupResource) + return false + } + } return p.MatchesObjectAttributes(label, field) } return filterFunc @@ -1238,6 +1276,7 @@ func (c *Cacher) getBookmarkAfterResourceVersionLockedFunc(parsedResourceVersion } } +// isListWatchRequest is mirrored in staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go func isListWatchRequest(opts storage.ListOptions) bool { return opts.SendInitialEvents != nil && *opts.SendInitialEvents && opts.Predicate.AllowWatchBookmarks } @@ -1258,7 +1297,7 @@ func (c *Cacher) getWatchCacheResourceVersion(ctx context.Context, parsedWatchRe return parsedWatchResourceVersion, nil } // legacy case - if !utilfeature.DefaultFeatureGate.Enabled(features.WatchFromStorageWithoutResourceVersion) && opts.SendInitialEvents == nil && opts.ResourceVersion == "" { + if opts.SendInitialEvents == nil && opts.ResourceVersion == "" { return 0, nil } rv, err := c.storage.GetCurrentResourceVersion(ctx) diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/delegator.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/delegator.go index b08c1fd5a4..4e1fabfaba 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/delegator.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/delegator.go @@ -39,6 +39,7 @@ import ( "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/cacher/delegator" "k8s.io/apiserver/pkg/storage/cacher/metrics" + "k8s.io/apiserver/pkg/storage/cacher/store" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/component-base/tracing" "k8s.io/klog/v2" @@ -111,7 +112,7 @@ func (c *CacheDelegator) Delete(ctx context.Context, key string, out runtime.Obj } else if exists { // DeepCopy the object since we modify resource version when serializing the // current object. - currObj := elem.(*storeElement).Object.DeepCopyObject() + currObj := elem.(*store.Element).Object.DeepCopyObject() return c.storage.Delete(ctx, key, out, preconditions, validateDeletion, currObj, opts) } // If we couldn't get the object, fallback to no-suggestion. @@ -129,10 +130,6 @@ func (c *CacheDelegator) Watch(ctx context.Context, key string, opts storage.Lis if !utilfeature.DefaultFeatureGate.Enabled(features.WatchList) && opts.SendInitialEvents != nil { opts.SendInitialEvents = nil } - // TODO: we should eventually get rid of this legacy case - if utilfeature.DefaultFeatureGate.Enabled(features.WatchFromStorageWithoutResourceVersion) && opts.SendInitialEvents == nil && opts.ResourceVersion == "" { - return c.storage.Watch(ctx, key, opts) - } return c.cacher.Watch(ctx, key, opts) } @@ -254,7 +251,7 @@ func (c *CacheDelegator) GuaranteedUpdate(ctx context.Context, key string, desti } else if exists { // DeepCopy the object since we modify resource version when serializing the // current object. - currObj := elem.(*storeElement).Object.DeepCopyObject() + currObj := elem.(*store.Element).Object.DeepCopyObject() return c.storage.GuaranteedUpdate(ctx, key, destination, ignoreNotFound, preconditions, tryUpdate, currObj) } // If we couldn't get the object, fallback to no-suggestion. @@ -344,10 +341,10 @@ func (c *consistencyChecker) check(ctx context.Context) { c.cacher.MarkConsistent(true) return } - klog.ErrorS(nil, "Cache consistency check failed", "group", c.groupResource.Group, "resource", c.groupResource.Resource, "resourceVersion", digests.ResourceVersion, "etcdDigest", digests.EtcdDigest, "cacheDigest", digests.CacheDigest) + klog.ErrorS(nil, "Cache consistency check failed", "group", c.groupResource.Group, "resource", c.groupResource.Resource, "resourceVersion", digests.ResourceVersion, "etcdDigest", digests.EtcdDigest, "cacheDigest", digests.CacheDigest, "diffDetail", digests.DiffDetail) metrics.StorageConsistencyCheckTotal.WithLabelValues(c.groupResource.Group, c.groupResource.Resource, "failure").Inc() if panicOnCacheInconsistency { - panic(fmt.Sprintf("Cache consistency check failed, group: %q, resource: %q, resourceVersion: %q, etcdDigest: %q, cacheDigest: %q", c.groupResource.Group, c.groupResource.Resource, digests.ResourceVersion, digests.EtcdDigest, digests.CacheDigest)) + panic(fmt.Sprintf("Cache consistency check failed, group: %q, resource: %q, resourceVersion: %q, etcdDigest: %q, cacheDigest: %q, diffDetail: %v", c.groupResource.Group, c.groupResource.Resource, digests.ResourceVersion, digests.EtcdDigest, digests.CacheDigest, digests.DiffDetail)) } c.cacher.MarkConsistent(false) } @@ -356,14 +353,43 @@ func (c *consistencyChecker) calculateDigests(ctx context.Context) (*storageDige if !c.cacher.Ready() { return nil, fmt.Errorf("cache is not ready") } - cacheDigest, cacheResourceVersion, err := c.calculateStoreDigest(ctx, c.cacher, "0", 0) + // variables for tracking the diff in consistency checker + cacheItems := []namespaceNameRV{} + var foundDiff *diffDetail + var etcdIndex int + + cacheDigest, cacheResourceVersion, err := c.calculateStoreDigest(ctx, c.cacher, "0", 0, func(obj metav1.Object) { + // collect items from cacher's list + cacheItems = append(cacheItems, namespaceNameRV{Namespace: obj.GetNamespace(), Name: obj.GetName(), RV: obj.GetResourceVersion()}) + }) if err != nil { return nil, fmt.Errorf("failed calculating cache digest: %w", err) } - etcdDigest, etcdResourceVersion, err := c.calculateStoreDigest(ctx, c.etcd, cacheResourceVersion, storageWatchListPageSize) + etcdDigest, etcdResourceVersion, err := c.calculateStoreDigest(ctx, c.etcd, cacheResourceVersion, storageWatchListPageSize, func(obj metav1.Object) { + // compare the item in etcd's list against cacheItems which is cacher's list + if foundDiff != nil { + return + } + etcdItem := namespaceNameRV{Namespace: obj.GetNamespace(), Name: obj.GetName(), RV: obj.GetResourceVersion()} + if len(cacheItems) <= etcdIndex { + foundDiff = &diffDetail{Index: etcdIndex, EtcdItem: &etcdItem} + cacheItems = nil // don't need it any more and nil it to allow GC to collect it + return + } + if cacheItem := cacheItems[etcdIndex]; cacheItem != etcdItem { + foundDiff = &diffDetail{Index: etcdIndex, EtcdItem: &etcdItem, CacheItem: &cacheItem} + cacheItems = nil // don't need it any more and nil it to allow GC to collect it + return + } + etcdIndex += 1 + }) if err != nil { return nil, fmt.Errorf("failed calculating etcd digest: %w", err) } + if len(cacheItems) > etcdIndex { + cacheItem := cacheItems[etcdIndex] + foundDiff = &diffDetail{Index: etcdIndex, CacheItem: &cacheItem} + } if cacheResourceVersion != etcdResourceVersion { return nil, fmt.Errorf("etcd returned different resource version then expected, cache: %q, etcd: %q", cacheResourceVersion, etcdResourceVersion) } @@ -371,16 +397,30 @@ func (c *consistencyChecker) calculateDigests(ctx context.Context) (*storageDige ResourceVersion: cacheResourceVersion, CacheDigest: cacheDigest, EtcdDigest: etcdDigest, + DiffDetail: foundDiff, }, nil } +type namespaceNameRV struct { + Namespace string + Name string + RV string +} + +type diffDetail struct { + Index int + CacheItem *namespaceNameRV + EtcdItem *namespaceNameRV +} + type storageDigest struct { ResourceVersion string CacheDigest string EtcdDigest string + DiffDetail *diffDetail } -func (c *consistencyChecker) calculateStoreDigest(ctx context.Context, store getLister, resourceVersion string, limit int64) (digest, rv string, err error) { +func (c *consistencyChecker) calculateStoreDigest(ctx context.Context, store getLister, resourceVersion string, limit int64, metaVisitor func(objectMeta metav1.Object)) (digest, rv string, err error) { opts := storage.ListOptions{ Recursive: true, Predicate: storage.Everything, @@ -399,7 +439,7 @@ func (c *consistencyChecker) calculateStoreDigest(ctx context.Context, store get if err != nil { return "", "", err } - err = addListToDigest(h, resp) + err = addListToDigest(h, resp, metaVisitor) if err != nil { return "", "", err } @@ -420,7 +460,7 @@ func (c *consistencyChecker) calculateStoreDigest(ctx context.Context, store get } } -func addListToDigest(h hash.Hash64, list runtime.Object) error { +func addListToDigest(h hash.Hash64, list runtime.Object, metaVisitor func(objectMeta metav1.Object)) error { return meta.EachListItem(list, func(obj runtime.Object) error { objectMeta, err := meta.Accessor(obj) if err != nil { @@ -430,6 +470,7 @@ func addListToDigest(h hash.Hash64, list runtime.Object) error { if err != nil { return err } + metaVisitor(objectMeta) return nil }) } diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go index 0f507cf121..0981d45739 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go @@ -20,6 +20,8 @@ import ( "sync" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" compbasemetrics "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/legacyregistry" ) @@ -112,7 +114,7 @@ var ( Namespace: namespace, Subsystem: subsystem, Name: "resource_version", - Help: "Current resource version of watch cache broken by resource type.", + Help: "Current resource version of watch cache broken by resource type. This is truncated to the 15 least significant digits.", StabilityLevel: compbasemetrics.ALPHA, }, []string{"group", "resource"}, @@ -185,6 +187,26 @@ var ( Help: "Counter for status of consistency checks between etcd and watch cache", StabilityLevel: compbasemetrics.ALPHA, }, []string{"group", "resource", "status"}) + + WatchShardsTotal = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Name: "watch_shards_total", + Help: "Number of active sharded watch connections broken by resource type.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"group", "resource"}, + ) + + WatchFilteredEventsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Name: "watch_filtered_events_total", + Help: "Counter of events filtered out by shard selector during watch dispatch, broken by resource type.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"group", "resource"}, + ) ) var registerMetrics sync.Once @@ -208,6 +230,10 @@ func Register() { legacyregistry.MustRegister(WatchCacheReadWait) legacyregistry.MustRegister(ConsistentReadTotal) legacyregistry.MustRegister(StorageConsistencyCheckTotal) + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + legacyregistry.MustRegister(WatchShardsTotal) + legacyregistry.MustRegister(WatchFilteredEventsTotal) + } }) } @@ -219,11 +245,28 @@ func RecordListCacheMetrics(groupResource schema.GroupResource, indexName string } // RecordResourceVersion sets the current resource version for a given resource type. +// The resource version is truncated to the 15 least significant digits to prevent +// the metric from growing indefinitely and losing precision when it exceeds 2^53-1. func RecordResourceVersion(groupResource schema.GroupResource, resourceVersion uint64) { - watchCacheResourceVersion.WithLabelValues(groupResource.Group, groupResource.Resource).Set(float64(resourceVersion)) + watchCacheResourceVersion.WithLabelValues(groupResource.Group, groupResource.Resource).Set(float64(resourceVersion % 1000000000000000)) +} + +// RecordShardedWatchStarted increments the active sharded watch gauge for the given resource. +func RecordShardedWatchStarted(groupResource schema.GroupResource) { + WatchShardsTotal.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() +} + +// RecordShardedWatchStopped decrements the active sharded watch gauge for the given resource. +func RecordShardedWatchStopped(groupResource schema.GroupResource) { + WatchShardsTotal.WithLabelValues(groupResource.Group, groupResource.Resource).Dec() +} + +// RecordWatchFilteredEvent increments the counter for events filtered by shard selector. +func RecordWatchFilteredEvent(groupResource schema.GroupResource) { + WatchFilteredEventsTotal.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() } -// RecordsWatchCacheCapacityChange record watchCache capacity resize(increase or decrease) operations. +// RecordsWatchCacheCapacityChange records watchCache capacity resize(increase or decrease) operations. func RecordsWatchCacheCapacityChange(groupResource schema.GroupResource, old, new int) { WatchCacheCapacity.WithLabelValues(groupResource.Group, groupResource.Resource).Set(float64(new)) if old < new { diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/progress/watch_progress.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/progress/watch_progress.go index 76fe73f136..9880fc6c36 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/progress/watch_progress.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/progress/watch_progress.go @@ -71,7 +71,7 @@ func (pr *ConditionalProgressRequester) Run(stopCh <-chan struct{}) { ctx = metadata.NewOutgoingContext(ctx, pr.contextMetadata) } go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) <-stopCh pr.mux.Lock() defer pr.mux.Unlock() diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/store.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/store/store.go similarity index 92% rename from vendor/k8s.io/apiserver/pkg/storage/cacher/store.go rename to vendor/k8s.io/apiserver/pkg/storage/cacher/store/store.go index 9ec654e7d1..00dbc21298 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/store.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/store/store.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cacher +package store import ( "fmt" @@ -60,7 +60,7 @@ const ( btreeDegree = 16 ) -type storeIndexer interface { +type Indexer interface { Add(obj interface{}) error Update(obj interface{}) error Delete(obj interface{}) error @@ -72,17 +72,17 @@ type storeIndexer interface { ByIndex(indexName, indexedValue string) ([]interface{}, error) } -type orderedLister interface { +type OrderedLister interface { ListPrefix(prefix, continueKey string) []interface{} Count(prefix, continueKey string) (count int) - Clone() orderedLister + Clone() OrderedLister } -func newStoreIndexer(indexers *cache.Indexers) storeIndexer { +func NewIndexer(indexers *cache.Indexers) Indexer { if utilfeature.DefaultFeatureGate.Enabled(features.BtreeWatchCache) { - return newThreadedBtreeStoreIndexer(storeElementIndexers(indexers), btreeDegree) + return newThreadedBtreeStoreIndexer(ElementIndexers(indexers), btreeDegree) } - return cache.NewIndexer(storeElementKey, storeElementIndexers(indexers)) + return cache.NewIndexer(ElementKey, ElementIndexers(indexers)) } // Computing a key of an object is generally non-trivial (it performs @@ -90,32 +90,32 @@ func newStoreIndexer(indexers *cache.Indexers) storeIndexer { // labels. To avoid computing them multiple times (to serve the event // in different List/Watch requests), in the underlying store we are // keeping structs (key, object, labels, fields). -type storeElement struct { +type Element struct { Key string Object runtime.Object Labels labels.Set Fields fields.Set } -func storeElementKey(obj interface{}) (string, error) { - elem, ok := obj.(*storeElement) +func ElementKey(obj interface{}) (string, error) { + elem, ok := obj.(*Element) if !ok { return "", fmt.Errorf("not a storeElement: %v", obj) } return elem.Key, nil } -func storeElementObject(obj interface{}) (runtime.Object, error) { - elem, ok := obj.(*storeElement) +func ElementObject(obj interface{}) (runtime.Object, error) { + elem, ok := obj.(*Element) if !ok { return nil, fmt.Errorf("not a storeElement: %v", obj) } return elem.Object, nil } -func storeElementIndexFunc(objIndexFunc cache.IndexFunc) cache.IndexFunc { +func ElementIndexFunc(objIndexFunc cache.IndexFunc) cache.IndexFunc { return func(obj interface{}) (strings []string, e error) { - seo, err := storeElementObject(obj) + seo, err := ElementObject(obj) if err != nil { return nil, err } @@ -123,13 +123,13 @@ func storeElementIndexFunc(objIndexFunc cache.IndexFunc) cache.IndexFunc { } } -func storeElementIndexers(indexers *cache.Indexers) cache.Indexers { +func ElementIndexers(indexers *cache.Indexers) cache.Indexers { if indexers == nil { return cache.Indexers{} } ret := cache.Indexers{} for indexName, indexFunc := range *indexers { - ret[indexName] = storeElementIndexFunc(indexFunc) + ret[indexName] = ElementIndexFunc(indexFunc) } return ret } diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/store_btree.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/store/store_btree.go similarity index 86% rename from vendor/k8s.io/apiserver/pkg/storage/cacher/store_btree.go rename to vendor/k8s.io/apiserver/pkg/storage/cacher/store/store_btree.go index 9908e2f64b..33e8e4f102 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/store_btree.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/store/store_btree.go @@ -14,15 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package cacher +package store import ( "fmt" "strings" "sync" - "github.com/google/btree" "k8s.io/client-go/tools/cache" + "k8s.io/utils/third_party/forked/golang/btree" ) // newThreadedBtreeStoreIndexer returns a storage for cacher by adding locking over the two 2 data structures: @@ -43,7 +43,7 @@ type threadedStoreIndexer struct { indexer indexer } -var _ orderedLister = (*threadedStoreIndexer)(nil) +var _ OrderedLister = (*threadedStoreIndexer)(nil) func (si *threadedStoreIndexer) Count(prefix, continueKey string) (count int) { si.lock.RLock() @@ -51,7 +51,7 @@ func (si *threadedStoreIndexer) Count(prefix, continueKey string) (count int) { return si.store.Count(prefix, continueKey) } -func (si *threadedStoreIndexer) Clone() orderedLister { +func (si *threadedStoreIndexer) Clone() OrderedLister { si.lock.RLock() defer si.lock.RUnlock() return si.store.Clone() @@ -69,7 +69,7 @@ func (si *threadedStoreIndexer) addOrUpdate(obj interface{}) error { if obj == nil { return fmt.Errorf("obj cannot be nil") } - newElem, ok := obj.(*storeElement) + newElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -80,7 +80,7 @@ func (si *threadedStoreIndexer) addOrUpdate(obj interface{}) error { } func (si *threadedStoreIndexer) Delete(obj interface{}) error { - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -141,17 +141,17 @@ func (si *threadedStoreIndexer) ByIndex(indexName, indexValue string) ([]interfa func newBtreeStore(degree int) btreeStore { return btreeStore{ - tree: btree.NewG(degree, func(a, b *storeElement) bool { + tree: btree.New(degree, func(a, b *Element) bool { return a.Key < b.Key }), } } type btreeStore struct { - tree *btree.BTreeG[*storeElement] + tree *btree.BTree[*Element] } -func (s *btreeStore) Clone() orderedLister { +func (s *btreeStore) Clone() OrderedLister { return &btreeStore{ tree: s.tree.Clone(), } @@ -161,7 +161,7 @@ func (s *btreeStore) Add(obj interface{}) error { if obj == nil { return fmt.Errorf("obj cannot be nil") } - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -173,7 +173,7 @@ func (s *btreeStore) Update(obj interface{}) error { if obj == nil { return fmt.Errorf("obj cannot be nil") } - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -185,7 +185,7 @@ func (s *btreeStore) Delete(obj interface{}) error { if obj == nil { return fmt.Errorf("obj cannot be nil") } - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -193,13 +193,13 @@ func (s *btreeStore) Delete(obj interface{}) error { return nil } -func (s *btreeStore) deleteElem(storeElem *storeElement) (*storeElement, bool) { +func (s *btreeStore) deleteElem(storeElem *Element) (*Element, bool) { return s.tree.Delete(storeElem) } func (s *btreeStore) List() []interface{} { items := make([]interface{}, 0, s.tree.Len()) - s.tree.Ascend(func(item *storeElement) bool { + s.tree.Ascend(func(item *Element) bool { items = append(items, item) return true }) @@ -208,7 +208,7 @@ func (s *btreeStore) List() []interface{} { func (s *btreeStore) ListKeys() []string { items := make([]string, 0, s.tree.Len()) - s.tree.Ascend(func(item *storeElement) bool { + s.tree.Ascend(func(item *Element) bool { items = append(items, item.Key) return true }) @@ -216,7 +216,7 @@ func (s *btreeStore) ListKeys() []string { } func (s *btreeStore) Get(obj interface{}) (item interface{}, exists bool, err error) { - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return nil, false, fmt.Errorf("obj is not a storeElement") } @@ -231,7 +231,7 @@ func (s *btreeStore) GetByKey(key string) (item interface{}, exists bool, err er func (s *btreeStore) Replace(objs []interface{}, _ string) error { s.tree.Clear(false) for _, obj := range objs { - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -242,13 +242,13 @@ func (s *btreeStore) Replace(objs []interface{}, _ string) error { // addOrUpdateLocked assumes a lock is held and is used for Add // and Update operations. -func (s *btreeStore) addOrUpdateElem(storeElem *storeElement) *storeElement { +func (s *btreeStore) addOrUpdateElem(storeElem *Element) *Element { oldObj, _ := s.tree.ReplaceOrInsert(storeElem) return oldObj } func (s *btreeStore) getByKey(key string) (item interface{}, exists bool, err error) { - keyElement := &storeElement{Key: key} + keyElement := &Element{Key: key} item, exists = s.tree.Get(keyElement) return item, exists, nil } @@ -258,7 +258,7 @@ func (s *btreeStore) ListPrefix(prefix, continueKey string) []interface{} { continueKey = prefix } var result []interface{} - s.tree.AscendGreaterOrEqual(&storeElement{Key: continueKey}, func(item *storeElement) bool { + s.tree.AscendGreaterOrEqual(&Element{Key: continueKey}, func(item *Element) bool { if !strings.HasPrefix(item.Key, prefix) { return false } @@ -272,7 +272,7 @@ func (s *btreeStore) Count(prefix, continueKey string) (count int) { if continueKey == "" { continueKey = prefix } - s.tree.AscendGreaterOrEqual(&storeElement{Key: continueKey}, func(item *storeElement) bool { + s.tree.AscendGreaterOrEqual(&Element{Key: continueKey}, func(item *Element) bool { if !strings.HasPrefix(item.Key, prefix) { return false } @@ -292,13 +292,13 @@ func (s *btreeStore) Count(prefix, continueKey string) (count int) { // Difference in mutability of stored values is used for optimizing some operations in client-go Indexer. func newIndexer(indexers cache.Indexers) indexer { return indexer{ - indices: map[string]map[string]map[string]*storeElement{}, + indices: map[string]map[string]map[string]*Element{}, indexers: indexers, } } type indexer struct { - indices map[string]map[string]map[string]*storeElement + indices map[string]map[string]map[string]*Element indexers cache.Indexers } @@ -317,9 +317,9 @@ func (i *indexer) ByIndex(indexName, indexValue string) ([]interface{}, error) { } func (i *indexer) Replace(objs []interface{}, resourceVersion string) error { - i.indices = map[string]map[string]map[string]*storeElement{} + i.indices = map[string]map[string]map[string]*Element{} for _, obj := range objs { - storeElem, ok := obj.(*storeElement) + storeElem, ok := obj.(*Element) if !ok { return fmt.Errorf("obj not a storeElement: %#v", obj) } @@ -331,7 +331,7 @@ func (i *indexer) Replace(objs []interface{}, resourceVersion string) error { return nil } -func (i *indexer) updateElem(key string, oldObj, newObj *storeElement) (err error) { +func (i *indexer) updateElem(key string, oldObj, newObj *Element) (err error) { var oldIndexValues, indexValues []string for name, indexFunc := range i.indexers { if oldObj != nil { @@ -352,7 +352,7 @@ func (i *indexer) updateElem(key string, oldObj, newObj *storeElement) (err erro } index := i.indices[name] if index == nil { - index = map[string]map[string]*storeElement{} + index = map[string]map[string]*Element{} i.indices[name] = index } if len(indexValues) == 1 && len(oldIndexValues) == 1 && indexValues[0] == oldIndexValues[0] { @@ -370,16 +370,16 @@ func (i *indexer) updateElem(key string, oldObj, newObj *storeElement) (err erro return nil } -func (i *indexer) add(key, value string, obj *storeElement, index map[string]map[string]*storeElement) { +func (i *indexer) add(key, value string, obj *Element, index map[string]map[string]*Element) { set := index[value] if set == nil { - set = map[string]*storeElement{} + set = map[string]*Element{} index[value] = set } set[key] = obj } -func (i *indexer) delete(key, value string, index map[string]map[string]*storeElement) { +func (i *indexer) delete(key, value string, index map[string]map[string]*Element) { set := index[value] if set == nil { return @@ -426,9 +426,9 @@ func (i *indexer) delete(key, value string, index map[string]map[string]*storeEl // However, this solution is more complex and is deferred for future implementation. // // TODO: Rewrite to use a cyclic buffer -func newStoreSnapshotter() *storeSnapshotter { +func NewSnapshotter() Snapshotter { s := &storeSnapshotter{ - snapshots: btree.NewG[rvSnapshot](btreeDegree, func(a, b rvSnapshot) bool { + snapshots: btree.New(btreeDegree, func(a, b rvSnapshot) bool { return a.resourceVersion < b.resourceVersion }), } @@ -439,20 +439,20 @@ var _ Snapshotter = (*storeSnapshotter)(nil) type Snapshotter interface { Reset() - GetLessOrEqual(rv uint64) (orderedLister, bool) - Add(rv uint64, indexer orderedLister) + GetLessOrEqual(rv uint64) (OrderedLister, bool) + Add(rv uint64, indexer OrderedLister) RemoveLess(rv uint64) Len() int } type storeSnapshotter struct { mux sync.RWMutex - snapshots *btree.BTreeG[rvSnapshot] + snapshots *btree.BTree[rvSnapshot] } type rvSnapshot struct { resourceVersion uint64 - snapshot orderedLister + snapshot OrderedLister } func (s *storeSnapshotter) Reset() { @@ -461,7 +461,7 @@ func (s *storeSnapshotter) Reset() { s.snapshots.Clear(false) } -func (s *storeSnapshotter) GetLessOrEqual(rv uint64) (orderedLister, bool) { +func (s *storeSnapshotter) GetLessOrEqual(rv uint64) (OrderedLister, bool) { s.mux.RLock() defer s.mux.RUnlock() @@ -476,7 +476,7 @@ func (s *storeSnapshotter) GetLessOrEqual(rv uint64) (orderedLister, bool) { return result.snapshot, true } -func (s *storeSnapshotter) Add(rv uint64, indexer orderedLister) { +func (s *storeSnapshotter) Add(rv uint64, indexer OrderedLister) { s.mux.Lock() defer s.mux.Unlock() s.snapshots.ReplaceOrInsert(rvSnapshot{resourceVersion: rv, snapshot: indexer.Clone()}) diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go index 620b0f36bd..fc73708a8c 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go @@ -37,6 +37,7 @@ import ( "k8s.io/apiserver/pkg/storage/cacher/delegator" "k8s.io/apiserver/pkg/storage/cacher/metrics" "k8s.io/apiserver/pkg/storage/cacher/progress" + "k8s.io/apiserver/pkg/storage/cacher/store" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/cache" "k8s.io/component-base/tracing" @@ -121,7 +122,7 @@ type watchCache struct { // history" i.e. from the moment just after the newest cached watched event. // It is necessary to effectively allow clients to start watching at now. // NOTE: We assume that is thread-safe. - store storeIndexer + store store.Indexer // ResourceVersion up to which the watchCache is propagated. resourceVersion uint64 @@ -156,7 +157,7 @@ type watchCache struct { waitingUntilFresh *progress.ConditionalProgressRequester // Stores previous snapshots of orderedLister to allow serving requests from previous revisions. - snapshots Snapshotter + snapshots store.Snapshotter snapshottingEnabled atomic.Bool getCurrentRV func(context.Context) (uint64, error) @@ -183,7 +184,7 @@ func newWatchCache( upperBoundCapacity: capacityUpperBound(eventFreshDuration), startIndex: 0, endIndex: 0, - store: newStoreIndexer(indexers), + store: store.NewIndexer(indexers), resourceVersion: 0, listResourceVersion: 0, eventHandler: eventHandler, @@ -196,7 +197,7 @@ func newWatchCache( } if utilfeature.DefaultFeatureGate.Enabled(features.ListFromCacheSnapshot) { wc.snapshottingEnabled.Store(true) - wc.snapshots = newStoreSnapshotter() + wc.snapshots = store.NewSnapshotter() } metrics.WatchCacheCapacity.WithLabelValues(groupResource.Group, groupResource.Resource).Set(float64(wc.capacity)) wc.cond = sync.NewCond(wc.RLocker()) @@ -237,7 +238,7 @@ func (w *watchCache) Add(obj interface{}) error { } event := watch.Event{Type: watch.Added, Object: object} - f := func(elem *storeElement) error { return w.store.Add(elem) } + f := func(elem *store.Element) error { return w.store.Add(elem) } return w.processEvent(event, resourceVersion, f) } @@ -249,7 +250,7 @@ func (w *watchCache) Update(obj interface{}) error { } event := watch.Event{Type: watch.Modified, Object: object} - f := func(elem *storeElement) error { return w.store.Update(elem) } + f := func(elem *store.Element) error { return w.store.Update(elem) } return w.processEvent(event, resourceVersion, f) } @@ -261,7 +262,7 @@ func (w *watchCache) Delete(obj interface{}) error { } event := watch.Event{Type: watch.Deleted, Object: object} - f := func(elem *storeElement) error { return w.store.Delete(elem) } + f := func(elem *store.Element) error { return w.store.Delete(elem) } return w.processEvent(event, resourceVersion, f) } @@ -279,14 +280,14 @@ func (w *watchCache) objectToVersionedRuntimeObject(obj interface{}) (runtime.Ob // processEvent is safe as long as there is at most one call to it in flight // at any point in time. -func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, updateFunc func(*storeElement) error) error { +func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, updateFunc func(*store.Element) error) error { metrics.EventsReceivedCounter.WithLabelValues(w.groupResource.Group, w.groupResource.Resource).Inc() key, err := w.keyFunc(event.Object) if err != nil { return fmt.Errorf("couldn't compute key: %v", err) } - elem := &storeElement{Key: key, Object: event.Object} + elem := &store.Element{Key: key, Object: event.Object} elem.Labels, elem.Fields, err = w.getAttrsFunc(event.Object) if err != nil { return err @@ -312,7 +313,7 @@ func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, upd return err } if exists { - previousElem := previous.(*storeElement) + previousElem := previous.(*store.Element) wcEvent.PrevObject = previousElem.Object wcEvent.PrevObjLabels = previousElem.Labels wcEvent.PrevObjFields = previousElem.Fields @@ -331,7 +332,7 @@ func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, upd return err } if w.snapshots != nil && w.snapshottingEnabled.Load() { - if orderedLister, ordered := w.store.(orderedLister); ordered { + if orderedLister, ordered := w.store.(store.OrderedLister); ordered { if w.isCacheFullLocked() { oldestRV := w.cache[w.startIndex%w.capacity].ResourceVersion w.snapshots.RemoveLess(oldestRV) @@ -437,7 +438,7 @@ func (w *watchCache) UpdateResourceVersion(resourceVersion string) { metrics.RecordResourceVersion(w.groupResource, rv) } -// List returns list of pointers to objects. +// List returns list of pointers to objects. func (w *watchCache) List() []interface{} { return w.store.List() } @@ -495,7 +496,7 @@ func (s sortableStoreElements) Len() int { } func (s sortableStoreElements) Less(i, j int) bool { - return s[i].(*storeElement).Key < s[j].(*storeElement).Key + return s[i].(*store.Element).Key < s[j].(*store.Element).Key } func (s sortableStoreElements) Swap(i, j int) { @@ -652,7 +653,7 @@ func (w *watchCache) listLatestRV(key, continueKey string, matchValues []storage }, matchValue.IndexName, err } } - if store, ok := w.store.(orderedLister); ok { + if store, ok := w.store.(store.OrderedLister); ok { result := store.ListPrefix(key, continueKey) return listResp{ Items: result, @@ -670,9 +671,9 @@ func (w *watchCache) listLatestRV(key, continueKey string, matchValues []storage func filterPrefixAndOrder(prefix string, items []interface{}) ([]interface{}, error) { var result []interface{} for _, item := range items { - elem, ok := item.(*storeElement) + elem, ok := item.(*store.Element) if !ok { - return nil, fmt.Errorf("non *storeElement returned from storage: %v", item) + return nil, fmt.Errorf("non *store.Element returned from storage: %v", item) } if !hasPathPrefix(elem.Key, prefix) { continue @@ -723,7 +724,7 @@ func (w *watchCache) Get(obj interface{}) (interface{}, bool, error) { return nil, false, fmt.Errorf("couldn't compute key: %v", err) } - return w.store.Get(&storeElement{Key: key, Object: object}) + return w.store.Get(&store.Element{Key: key, Object: object}) } // GetByKey returns pointer to . @@ -752,7 +753,7 @@ func (w *watchCache) Replace(objs []interface{}, resourceVersion string) error { if err != nil { return err } - toReplace = append(toReplace, &storeElement{ + toReplace = append(toReplace, &store.Element{ Key: key, Object: object, Labels: objLabels, @@ -777,7 +778,7 @@ func (w *watchCache) Replace(objs []interface{}, resourceVersion string) error { } if w.snapshots != nil { w.snapshots.Reset() - if orderedLister, ordered := w.store.(orderedLister); ordered && w.snapshottingEnabled.Load() { + if orderedLister, ordered := w.store.(store.OrderedLister); ordered && w.snapshottingEnabled.Load() { w.snapshots.Add(version, orderedLister) } } diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go index b74b3ca917..8cdcac370f 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go @@ -22,6 +22,7 @@ import ( "sync" "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/storage/cacher/store" ) // watchCacheInterval serves as an abstraction over a source @@ -136,11 +137,11 @@ func (s sortableWatchCacheEvents) Swap(i, j int) { // returned by Next() need to be events from a List() done on the underlying store of // the watch cache. // The items returned in the interval will be sorted by Key. -func newCacheIntervalFromStore(resourceVersion uint64, store storeIndexer, key string, matchesSingle bool) (*watchCacheInterval, error) { +func newCacheIntervalFromStore(resourceVersion uint64, indexer store.Indexer, key string, matchesSingle bool) (*watchCacheInterval, error) { buffer := &watchCacheIntervalBuffer{} var allItems []interface{} if matchesSingle { - item, exists, err := store.GetByKey(key) + item, exists, err := indexer.GetByKey(key) if err != nil { return nil, err } @@ -149,11 +150,11 @@ func newCacheIntervalFromStore(resourceVersion uint64, store storeIndexer, key s allItems = append(allItems, item) } } else { - allItems = store.List() + allItems = indexer.List() } buffer.buffer = make([]*watchCacheEvent, len(allItems)) for i, item := range allItems { - elem, ok := item.(*storeElement) + elem, ok := item.(*store.Element) if !ok { return nil, fmt.Errorf("not a storeElement: %v", elem) } diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go index 263c04ec02..b3a6378139 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go @@ -112,13 +112,22 @@ var ( Subsystem: "apiserver", Name: "storage_events_received_total", Help: "Number of etcd events received split by kind.", - StabilityLevel: compbasemetrics.ALPHA, + StabilityLevel: compbasemetrics.BETA, }, []string{"group", "resource"}, ) etcdBookmarkCounts = compbasemetrics.NewGaugeVec( &compbasemetrics.GaugeOpts{ - Name: "etcd_bookmark_counts", + Name: "etcd_bookmark_counts", + Help: "Number of etcd bookmarks (progress notify events) split by kind.", + StabilityLevel: compbasemetrics.ALPHA, + DeprecatedVersion: "1.36.0", + }, + []string{"group", "resource"}, + ) + etcdBookmarkTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "etcd_bookmark_total", Help: "Number of etcd bookmarks (progress notify events) split by kind.", StabilityLevel: compbasemetrics.ALPHA, }, @@ -200,6 +209,7 @@ func Register() { legacyregistry.CustomMustRegister(storageMonitor) legacyregistry.MustRegister(etcdEventsReceivedCounts) legacyregistry.MustRegister(etcdBookmarkCounts) + legacyregistry.MustRegister(etcdBookmarkTotal) legacyregistry.MustRegister(etcdLeaseObjectCounts) legacyregistry.MustRegister(listStorageCount) legacyregistry.MustRegister(listStorageNumFetched) @@ -255,9 +265,10 @@ func RecordEtcdEvent(groupResource schema.GroupResource) { etcdEventsReceivedCounts.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() } -// RecordEtcdBookmark updates the etcd_bookmark_counts metric. +// RecordEtcdBookmark updates the etcd_bookmark_total metric. func RecordEtcdBookmark(groupResource schema.GroupResource) { etcdBookmarkCounts.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() + etcdBookmarkTotal.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() } // RecordDecodeError sets the storage_decode_errors metrics. @@ -300,7 +311,7 @@ func UpdateEtcdRequestRetry(errorCode string) { etcdRequestRetry.WithLabelValues(errorCode).Inc() } -// RecordListEtcd3Metrics notes various metrics of the cost to serve a LIST request +// RecordStorageListMetrics notes various metrics of the cost to serve a LIST request func RecordStorageListMetrics(groupResource schema.GroupResource, numFetched, numEvald, numReturned int) { listStorageCount.WithLabelValues(groupResource.Group, groupResource.Resource).Inc() listStorageNumFetched.WithLabelValues(groupResource.Group, groupResource.Resource).Add(float64(numFetched)) @@ -355,7 +366,6 @@ func (c *monitorCollector) CollectWithStability(ch chan<- compbasemetrics.Metric ctx, cancel := context.WithTimeout(context.Background(), time.Second) metrics, err := m.Monitor(ctx) cancel() - m.Close() if err != nil { klog.InfoS("Failed to get storage metrics", "storage_cluster_id", storageClusterID, "err", err) continue diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go index 798567d1cd..8384832335 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -895,7 +895,13 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption if err != nil { return err } - return s.versioner.UpdateList(listObj, uint64(withRev), continueValue, remainingItemCount) + if err := s.versioner.UpdateList(listObj, uint64(withRev), continueValue, remainingItemCount); err != nil { + return err + } + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + opts.Predicate.SetShardInfoOnList(listObj) + } + return nil } func (s *store) getList(ctx context.Context, keyPrefix string, recursive bool, options kubernetes.ListOptions) (resp kubernetes.ListResponse, err error) { diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go index cf16606bc5..0559383f8d 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go @@ -24,6 +24,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" clientv3 "go.etcd.io/etcd/client/v3" @@ -55,17 +56,17 @@ const ( var defaultWatcherMaxLimit int64 = maxLimit // fatalOnDecodeError is used during testing to panic the server if watcher encounters a decoding error -var fatalOnDecodeError = false +var fatalOnDecodeError atomic.Bool func init() { // check to see if we are running in a test environment - TestOnlySetFatalOnDecodeError(true) - fatalOnDecodeError, _ = strconv.ParseBool(os.Getenv("KUBE_PANIC_WATCH_DECODE_ERROR")) + b, _ := strconv.ParseBool(os.Getenv("KUBE_PANIC_WATCH_DECODE_ERROR")) + TestOnlySetFatalOnDecodeError(b) } // TestOnlySetFatalOnDecodeError should only be used for cases where decode errors are expected and need to be tested. e.g. conversion webhooks. func TestOnlySetFatalOnDecodeError(b bool) { - fatalOnDecodeError = b + fatalOnDecodeError.Store(b) } type watcher struct { @@ -758,7 +759,7 @@ func (w *watcher) transformIfCorruptObjectError(e *event, err error) error { func decodeObj(codec runtime.Codec, versioner storage.Versioner, data []byte, rev int64) (_ runtime.Object, err error) { obj, err := runtime.Decode(codec, []byte(data)) if err != nil { - if fatalOnDecodeError { + if fatalOnDecodeError.Load() { // we are running in a test environment and thus an // error here is due to a coder mistake if the defer // does not catch it diff --git a/vendor/k8s.io/apiserver/pkg/storage/feature/feature_support_checker.go b/vendor/k8s.io/apiserver/pkg/storage/feature/feature_support_checker.go index 77f5ab05c9..e664d22a64 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/feature/feature_support_checker.go +++ b/vendor/k8s.io/apiserver/pkg/storage/feature/feature_support_checker.go @@ -109,7 +109,7 @@ func (f *defaultFeatureSupportChecker) checkClient(ctx context.Context, c client } f.checkingEndpoint[ep] = struct{}{} go func(ep string) { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithContext(ctx) err := delayFunc.Until(ctx, true, true, func(ctx context.Context) (done bool, err error) { internalErr := f.clientSupportsRequestWatchProgress(ctx, c, ep) return internalErr == nil, nil diff --git a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go index 480b5a8934..37d470b254 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go +++ b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go @@ -20,10 +20,14 @@ import ( "context" "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/sharding" "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" ) // AttrFunc returns label and field sets and the uninitialized flag for List or Watch to match. @@ -82,12 +86,19 @@ type SelectionPredicate struct { Limit int64 Continue string AllowWatchBookmarks bool + // ShardSelector is the parsed shard selector for filtering objects by hash range. + ShardSelector sharding.Selector } // Matches returns true if the given object's labels and fields (as // returned by s.GetAttrs) match s.Label and s.Field. An error is // returned if s.GetAttrs fails. func (s *SelectionPredicate) Matches(obj runtime.Object) (bool, error) { + if utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + if matched, err := s.MatchesSharding(obj); err != nil || !matched { + return matched, err + } + } if s.Empty() { return true, nil } @@ -168,6 +179,30 @@ func (s *SelectionPredicate) MatcherIndex(ctx context.Context) []MatchValue { return result } +// MatchesSharding returns true if the given object matches the sharding configuration. +// If ShardSelector is set and non-empty, it delegates to ShardSelector.Matches(). +func (s *SelectionPredicate) MatchesSharding(obj runtime.Object) (bool, error) { + if !utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + return true, nil + } + if s.ShardSelector != nil && !s.ShardSelector.Empty() { + return s.ShardSelector.Matches(obj) + } + return true, nil +} + +// SetShardInfoOnList sets shard metadata on the list response if sharding is active. +func (s *SelectionPredicate) SetShardInfoOnList(listObj runtime.Object) { + if !utilfeature.DefaultFeatureGate.Enabled(features.ShardedListAndWatch) { + return + } + if s.ShardSelector != nil && !s.ShardSelector.Empty() { + if setter, ok := listObj.(metav1.ShardedListInterface); ok { + setter.SetShardInfo(&metav1.ShardInfo{Selector: s.ShardSelector.String()}) + } + } +} + func isNamespaceScopedRequest(ctx context.Context) (string, bool) { re, _ := request.RequestInfoFrom(ctx) if re == nil || len(re.Namespace) == 0 { diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go index c6598d7cf2..49607fe936 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -29,7 +29,7 @@ import ( "sync" "time" - grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus" + grpcprom "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus" "go.etcd.io/etcd/client/pkg/v3/logutil" "go.etcd.io/etcd/client/pkg/v3/transport" clientv3 "go.etcd.io/etcd/client/v3" @@ -80,12 +80,15 @@ const ( // https://github.com/kubernetes/kubernetes/issues/111476 for more. var etcd3ClientLogger *zap.Logger +// grpcpromClientMetrics is a singleton instance of grpc client prometheus metrics. +var grpcpromClientMetrics = grpcprom.NewClientMetrics() + func init() { - // grpcprom auto-registers (via an init function) their client metrics, since we are opting out of - // using the global prometheus registry and using our own wrapped global registry, - // we need to explicitly register these metrics to our global registry here. + // Since we are opting out of using the global prometheus registry and using + // our own wrapped global registry, we need to explicitly register the client + // metrics to our global registry here. // For reference: https://github.com/kubernetes/kubernetes/pull/81387 - legacyregistry.RawMustRegister(grpcprom.DefaultClientMetrics) + legacyregistry.RawMustRegister(grpcpromClientMetrics) dbMetricsMonitors = make(map[string]struct{}) l, err := logutil.CreateDefaultZapLogger(etcdClientDebugLevel()) @@ -314,8 +317,8 @@ var newETCD3Client = func(c storagebackend.TransportConfig) (*kubernetes.Client, // // these optional interceptors will be placed after the default ones. // which seems to be what we want as the metrics will be collected on each attempt (retry) - grpc.WithChainUnaryInterceptor(grpcprom.UnaryClientInterceptor), - grpc.WithChainStreamInterceptor(grpcprom.StreamClientInterceptor), + grpc.WithChainUnaryInterceptor(grpcpromClientMetrics.UnaryClientInterceptor()), + grpc.WithChainStreamInterceptor(grpcpromClientMetrics.StreamClientInterceptor()), } if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) { tracingOpts := []otelgrpc.Option{ diff --git a/vendor/k8s.io/apiserver/pkg/storage/util.go b/vendor/k8s.io/apiserver/pkg/storage/util.go index 3ca9acf3bd..941422ef5e 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/util.go +++ b/vendor/k8s.io/apiserver/pkg/storage/util.go @@ -22,7 +22,7 @@ import ( "sync/atomic" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/api/validation/path" + "k8s.io/apimachinery/pkg/api/validate/content" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -46,7 +46,7 @@ func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { return "", err } name := meta.GetName() - if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + if msgs := content.IsPathSegmentName(name); len(msgs) != 0 { return "", fmt.Errorf("invalid name: %v", msgs) } return prefix + meta.GetNamespace() + "/" + name, nil @@ -61,7 +61,7 @@ func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { return "", err } name := meta.GetName() - if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + if msgs := content.IsPathSegmentName(name); len(msgs) != 0 { return "", fmt.Errorf("invalid name: %v", msgs) } return prefix + name, nil diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go index b2a5fd145c..a5987c7893 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go @@ -86,7 +86,7 @@ func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Durat s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) <-ctx.Done() _ = s.connection.Close() diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go index 4549257a03..01947eb053 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go @@ -523,7 +523,6 @@ func generateCacheKey(encryptedDEKSourceType kmstypes.EncryptedDEKSourceType, en // Sort the annotations by key. keys := make([]string, 0, len(annotations)) for k := range annotations { - k := k keys = append(keys, k) } sort.Strings(keys) diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go index 78cc02e57a..7cd7d1ce2b 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go @@ -83,7 +83,7 @@ func NewGRPCService(ctx context.Context, endpoint, providerName string, callTime s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) go func() { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) <-ctx.Done() _ = s.connection.Close() diff --git a/vendor/k8s.io/apiserver/pkg/util/filesystem/watchuntil.go b/vendor/k8s.io/apiserver/pkg/util/filesystem/watchuntil.go new file mode 100644 index 0000000000..fe594e4bfb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/filesystem/watchuntil.go @@ -0,0 +1,149 @@ +/* +Copyright 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 filesystem + +import ( + "context" + "fmt" + "time" + + "github.com/fsnotify/fsnotify" +) + +type watchAddRemover interface { + Add(path string) error + Remove(path string) error +} + +type noopWatcher struct{} + +func (noopWatcher) Add(path string) error { return nil } +func (noopWatcher) Remove(path string) error { return nil } + +// WatchUntil watches the specified path for changes and blocks until ctx is canceled. +// eventHandler() must be non-nil, and pollInterval must be greater than 0. +// eventHandler() is invoked whenever a change event is observed or pollInterval elapses. +// errorHandler() is invoked (if non-nil) whenever an error occurs initializing or watching the specified path. +// +// If path is a directory, only the directory and immediate children are watched. +// +// If path does not exist or cannot be watched, an error is passed to errorHandler() and eventHandler() is called at pollInterval. +// +// Multiple observed events may collapse to a single invocation of eventHandler(). +// +// eventHandler() is invoked immediately after successful initialization of the filesystem watch, +// in case the path changed concurrent with calling WatchUntil(). +func WatchUntil(ctx context.Context, pollInterval time.Duration, path string, eventHandler func(), errorHandler func(err error)) { + if pollInterval <= 0 { + panic(fmt.Errorf("pollInterval must be > 0")) + } + if eventHandler == nil { + panic(fmt.Errorf("eventHandler must be non-nil")) + } + if errorHandler == nil { + errorHandler = func(err error) {} + } + + // Initialize watcher, fall back to no-op + var ( + eventsCh chan fsnotify.Event + errorCh chan error + watcher watchAddRemover + ) + if w, err := fsnotify.NewWatcher(); err != nil { + errorHandler(fmt.Errorf("error creating file watcher, falling back to poll at interval %s: %w", pollInterval, err)) + watcher = noopWatcher{} + } else { + watcher = w + eventsCh = w.Events + errorCh = w.Errors + defer func() { + _ = w.Close() + }() + } + + // Initialize background poll + t := time.NewTicker(pollInterval) + defer t.Stop() + + attemptPeriodicRewatch := false + + // Start watching the path + if err := watcher.Add(path); err != nil { + errorHandler(err) + attemptPeriodicRewatch = true + } else { + // Invoke handle() at least once after successfully registering the listener, + // in case the file changed concurrent with calling WatchUntil. + eventHandler() + } + + for { + select { + case <-ctx.Done(): + return + + case <-t.C: + // Prioritize exiting if context is canceled + if ctx.Err() != nil { + return + } + + // Try to re-establish the watcher if we previously got a watch error + if attemptPeriodicRewatch { + _ = watcher.Remove(path) + if err := watcher.Add(path); err != nil { + errorHandler(err) + } else { + attemptPeriodicRewatch = false + } + } + + // Handle + eventHandler() + + case e := <-eventsCh: + // Prioritize exiting if context is canceled + if ctx.Err() != nil { + return + } + + // Try to re-establish the watcher for events which dropped the existing watch + if e.Name == path && (e.Has(fsnotify.Remove) || e.Has(fsnotify.Rename)) { + _ = watcher.Remove(path) + if err := watcher.Add(path); err != nil { + errorHandler(err) + attemptPeriodicRewatch = true + } + } + + // Handle + eventHandler() + + case err := <-errorCh: + // Prioritize exiting if context is canceled + if ctx.Err() != nil { + return + } + + // If the error occurs in response to calling watcher.Add, re-adding here could hot-loop. + // The periodic poll will attempt to re-establish the watch. + errorHandler(err) + attemptPeriodicRewatch = true + } + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/peerproxy/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/util/peerproxy/metrics/metrics.go index 9b7aee4eaa..9c7c5e0410 100644 --- a/vendor/k8s.io/apiserver/pkg/util/peerproxy/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/util/peerproxy/metrics/metrics.go @@ -27,6 +27,22 @@ import ( const ( subsystem = "apiserver" statuscode = "code" + group = "group" + version = "version" + resource = "resource" + errorType = "type" + + // ProxyErrorEndpointResolution indicates a failure to resolve the network address of a peer apiserver. + ProxyErrorEndpointResolution = "endpoint_resolution" + // ProxyErrorTransport indicates a failure to build the proxy transport for the request. + ProxyErrorTransport = "proxy_transport" + + // DiscoveryErrorLeaseList indicates a failure to list apiserver identity leases. + DiscoveryErrorLeaseList = "lease_list" + // DiscoveryErrorHostPortResolution indicates a failure to resolve host/port from an identity lease. + DiscoveryErrorHostPortResolution = "hostport_resolution" + // DiscoveryErrorFetch indicates a failure to fetch discovery document from a peer. + DiscoveryErrorFetch = "fetch_discovery" ) var registerMetricsOnce sync.Once @@ -37,16 +53,40 @@ var ( &metrics.CounterOpts{ Subsystem: subsystem, Name: "rerouted_request_total", - Help: "Total number of requests that were proxied to a peer kube apiserver because the local apiserver was not capable of serving it", + Help: `Total number of requests that were proxied to a peer kube-apiserver because the local apiserver was not capable of serving it, broken down by 'group', 'version', and 'resource' indicating the GVR of the request. If all three are empty (""), the request is a discovery request.`, + StabilityLevel: metrics.ALPHA, + }, + []string{statuscode, group, version, resource}, + ) + + // peerProxyErrorsTotal counts the number of errors encountered while proxying requests to a peer kube-apiserver. + peerProxyErrorsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: subsystem, + Name: "peer_proxy_errors_total", + Help: "Total number of errors encountered while proxying requests to a peer kube apiserver", + StabilityLevel: metrics.ALPHA, + }, + []string{errorType, group, version, resource}, + ) + + // peerDiscoverySyncErrorsTotal counts the number of errors encountered while syncing discovery information from a peer kube-apiserver. + peerDiscoverySyncErrorsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: subsystem, + Name: "peer_discovery_sync_errors_total", + Help: "Total number of errors encountered while syncing discovery information from a peer kube-apiserver", StabilityLevel: metrics.ALPHA, }, - []string{statuscode}, + []string{errorType}, ) ) func Register() { registerMetricsOnce.Do(func() { legacyregistry.MustRegister(peerProxiedRequestsTotal) + legacyregistry.MustRegister(peerProxyErrorsTotal) + legacyregistry.MustRegister(peerDiscoverySyncErrorsTotal) }) } @@ -56,6 +96,16 @@ func Reset() { } // IncPeerProxiedRequest increments the # of proxied requests to peer kube-apiserver -func IncPeerProxiedRequest(ctx context.Context, status string) { - peerProxiedRequestsTotal.WithContext(ctx).WithLabelValues(status).Add(1) +func IncPeerProxiedRequest(ctx context.Context, status, g, v, r string) { + peerProxiedRequestsTotal.WithContext(ctx).WithLabelValues(status, g, v, r).Add(1) +} + +// IncPeerProxyError increments the # of errors encountered during peer proxying +func IncPeerProxyError(ctx context.Context, e, g, v, r string) { + peerProxyErrorsTotal.WithContext(ctx).WithLabelValues(e, g, v, r).Add(1) +} + +// IncPeerDiscoverySyncError increments the # of errors encountered during peer discovery sync +func IncPeerDiscoverySyncError(ctx context.Context, e string) { + peerDiscoverySyncErrorsTotal.WithContext(ctx).WithLabelValues(e).Add(1) } diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/doc.go b/vendor/k8s.io/apiserver/pkg/util/proxy/doc.go new file mode 100644 index 0000000000..46f3775b72 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/doc.go @@ -0,0 +1,36 @@ +/* +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. +*/ + +// Among other files, this directory contains functionality for two +// stream proxies: streamtranslator.go and streamtunnel.go. Both of +// these proxies allow the inter-connection of WebSocket and SPDY +// streaming connections. +// +// The stream translator proxy is used for the RemoteCommand +// subprotocol (e.g. kubectl exec, cp, and attach), and it connects +// the output streams of a WebSocket connection (e.g. STDIN, STDOUT, +// STDERR, TTY resize, and error streams) to the input streams of a +// SPDY connection. +// +// The stream tunnel proxy tunnels SPDY frames through a WebSocket +// connection, and it is used for the PortForward subprotocol (e.g. +// kubectl port-forward). This proxy implements tunneling by transparently +// encoding and decoding SPDY framed data into and out of the payload of a +// WebSocket data frame. The primary structure for this tunneling is +// the TunnelingConnection. A lot of the other code in streamtunnel.go +// is for properly upgrading both the upstream SPDY connection and the +// downstream WebSocket connection before streaming begins. +package proxy diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/endpointslice.go b/vendor/k8s.io/apiserver/pkg/util/proxy/endpointslice.go new file mode 100644 index 0000000000..865bc794b5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/endpointslice.go @@ -0,0 +1,114 @@ +/* +Copyright 2025 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 proxy + +import ( + "fmt" + + discoveryv1 "k8s.io/api/discovery/v1" + "k8s.io/apimachinery/pkg/labels" + discoveryv1informer "k8s.io/client-go/informers/discovery/v1" + discoveryv1lister "k8s.io/client-go/listers/discovery/v1" + "k8s.io/client-go/tools/cache" +) + +// EndpointSliceGetter is an interface for a helper that lets you easily get all +// EndpointSlices for a Service. +type EndpointSliceGetter interface { + // GetEndpointSlices returns all of the known slices associated with the given + // service. If there are no slices associated with the service, it will return an + // empty list, not an error. + GetEndpointSlices(namespaceName, serviceName string) ([]*discoveryv1.EndpointSlice, error) +} + +const indexKey = "namespaceName_serviceName" + +// ensureServiceNameIndexer ensures that indexer has a namespace/serviceName indexer +func ensureServiceNameIndexer(indexer cache.Indexer) error { + if _, exists := indexer.GetIndexers()[indexKey]; exists { + return nil + } + err := indexer.AddIndexers(map[string]cache.IndexFunc{indexKey: func(obj any) ([]string, error) { + ep, ok := obj.(*discoveryv1.EndpointSlice) + if !ok { + return nil, fmt.Errorf("expected *discoveryv1.EndpointSlice, got %T", obj) + } + serviceName, labelExists := ep.Labels[discoveryv1.LabelServiceName] + if !labelExists { + // Not associated with a service; don't add to this index. + return nil, nil + } + return []string{ep.Namespace + "/" + serviceName}, nil + }}) + if err != nil { + // Check if the indexer exists now; if so, that means we were racing with + // another thread, and they successfully installed the indexer, so we can + // ignore the error. + if _, exists := indexer.GetIndexers()[indexKey]; exists { + err = nil + } + } + return err +} + +// NewEndpointSliceIndexerGetter returns an EndpointSliceGetter that wraps an informer and +// updates its indexes so that you can efficiently find the EndpointSlices associated with +// a Service later. (Note that sliceInformer will continue the additional indexing for as +// long as it runs, even if if the EndpointSliceGetter is destroyed. Use +// NewEndpointSliceListerGetter if you want want to fetch EndpointSlices without changing +// the underlying cache.) +func NewEndpointSliceIndexerGetter(sliceInformer discoveryv1informer.EndpointSliceInformer) (EndpointSliceGetter, error) { + indexer := sliceInformer.Informer().GetIndexer() + if err := ensureServiceNameIndexer(indexer); err != nil { + return nil, err + } + return &endpointSliceIndexerGetter{indexer: indexer}, nil +} + +type endpointSliceIndexerGetter struct { + indexer cache.Indexer +} + +func (e *endpointSliceIndexerGetter) GetEndpointSlices(namespaceName, serviceName string) ([]*discoveryv1.EndpointSlice, error) { + objs, err := e.indexer.ByIndex(indexKey, namespaceName+"/"+serviceName) + if err != nil { + return nil, err + } + eps := make([]*discoveryv1.EndpointSlice, 0, len(objs)) + for _, obj := range objs { + ep, ok := obj.(*discoveryv1.EndpointSlice) + if !ok { + return nil, fmt.Errorf("expected *discoveryv1.EndpointSlice, got %T", obj) + } + eps = append(eps, ep) + } + return eps, nil +} + +// NewEndpointSliceListerGetter returns an EndpointSliceGetter that uses a lister to do a +// full selection on every lookup. +func NewEndpointSliceListerGetter(sliceLister discoveryv1lister.EndpointSliceLister) (EndpointSliceGetter, error) { + return &endpointSliceListerGetter{lister: sliceLister}, nil +} + +type endpointSliceListerGetter struct { + lister discoveryv1lister.EndpointSliceLister +} + +func (e *endpointSliceListerGetter) GetEndpointSlices(namespaceName, serviceName string) ([]*discoveryv1.EndpointSlice, error) { + return e.lister.EndpointSlices(namespaceName).List(labels.SelectorFromSet(labels.Set{discoveryv1.LabelServiceName: serviceName})) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/util/proxy/metrics/metrics.go new file mode 100644 index 0000000000..f09724716d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/metrics/metrics.go @@ -0,0 +1,101 @@ +/* +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 metrics + +import ( + "context" + "sync" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + subsystem = "apiserver" + statuscode = "code" +) + +var registerMetricsOnce sync.Once + +var ( + // streamTranslatorRequestsTotal counts the number of requests that were handled by + // the StreamTranslatorProxy (RemoteCommand subprotocol). + streamTranslatorRequestsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: subsystem, + Name: "stream_translator_requests_total", + Help: "Total number of requests that were handled by the StreamTranslatorProxy, which processes streaming RemoteCommand/V5", + StabilityLevel: metrics.ALPHA, + }, + []string{statuscode}, + ) + // streamTunnelRequestsTotal counts the number of requests that were handled by + // the StreamTunnelProxy (PortForward subprotocol). + streamTunnelRequestsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: subsystem, + Name: "stream_tunnel_requests_total", + Help: "Total number of requests that were handled by the StreamTunnelProxy, which processes streaming PortForward/V2", + StabilityLevel: metrics.ALPHA, + }, + []string{statuscode}, + ) + // websocketStreamingRequestsTotal counts WebSocket streaming requests (exec/attach/portforward) + // routed by the API server, labeled by subresource and proxy_type. + websocketStreamingRequestsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: subsystem, + Name: "websocket_streaming_requests_total", + Help: "Total number of WebSocket streaming requests (exec/attach/portforward) routed by the API server, " + + "labeled by subresource and proxy_type. proxy_type is proxied_to_kubelet when the kubelet " + + "handles the request directly; otherwise translated_at_apiserver.", + StabilityLevel: metrics.ALPHA, + }, + []string{"subresource", "proxy_type"}, + ) +) + +func Register() { + registerMetricsOnce.Do(func() { + legacyregistry.MustRegister(streamTranslatorRequestsTotal) + legacyregistry.MustRegister(streamTunnelRequestsTotal) + legacyregistry.MustRegister(websocketStreamingRequestsTotal) + }) +} + +func ResetForTest() { + streamTranslatorRequestsTotal.Reset() + streamTunnelRequestsTotal.Reset() + websocketStreamingRequestsTotal.Reset() +} + +// IncStreamTranslatorRequest increments the # of requests handled by the StreamTranslatorProxy. +func IncStreamTranslatorRequest(ctx context.Context, status string) { + streamTranslatorRequestsTotal.WithContext(ctx).WithLabelValues(status).Add(1) +} + +// IncStreamTunnelRequest increments the # of requests handled by the StreamTunnelProxy. +func IncStreamTunnelRequest(ctx context.Context, status string) { + streamTunnelRequestsTotal.WithContext(ctx).WithLabelValues(status).Add(1) +} + +// IncWebSocketStreamingRequest increments the count of WebSocket streaming requests +// routed by the API server with the given subresource (exec/attach/portforward) and +// proxy_type (proxied_to_kubelet or translated_at_apiserver). +func IncWebSocketStreamingRequest(ctx context.Context, subresource, proxyType string) { + websocketStreamingRequestsTotal.WithContext(ctx).WithLabelValues(subresource, proxyType).Add(1) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/proxy.go b/vendor/k8s.io/apiserver/pkg/util/proxy/proxy.go new file mode 100644 index 0000000000..d64120163d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/proxy.go @@ -0,0 +1,187 @@ +/* +Copyright 2017 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 proxy + +import ( + "context" + "fmt" + "math/rand" + "net" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + v1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" + "k8s.io/apimachinery/pkg/api/errors" + utilnet "k8s.io/apimachinery/pkg/util/net" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + listersv1 "k8s.io/client-go/listers/core/v1" +) + +const ( + // taken from https://github.com/kubernetes/kubernetes/blob/release-1.27/staging/src/k8s.io/kube-aggregator/pkg/apiserver/handler_proxy.go#L47 + aggregatedDiscoveryTimeout = 5 * time.Second +) + +// findServicePort finds the service port by name or numerically. +func findServicePort(svc *v1.Service, port int32) (*v1.ServicePort, error) { + for _, svcPort := range svc.Spec.Ports { + if svcPort.Port == port { + return &svcPort, nil + } + } + return nil, errors.NewServiceUnavailable(fmt.Sprintf("no service port %d found for service %q", port, svc.Name)) +} + +// ResolveEndpoint returns a URL to which one can send traffic for the specified service. +// If the service is dual-stack, the URL will preferentially point to an endpoint of the +// service's primary IP family. +func ResolveEndpoint(services listersv1.ServiceLister, endpointSlices EndpointSliceGetter, namespace, id string, port int32) (*url.URL, error) { + svc, err := services.Services(namespace).Get(id) + if err != nil { + return nil, err + } + + switch { + case svc.Spec.Type == v1.ServiceTypeClusterIP, svc.Spec.Type == v1.ServiceTypeLoadBalancer, svc.Spec.Type == v1.ServiceTypeNodePort: + // these are fine + default: + return nil, fmt.Errorf("unsupported service type %q", svc.Spec.Type) + } + + svcPort, err := findServicePort(svc, port) + if err != nil { + return nil, err + } + + slices, err := endpointSlices.GetEndpointSlices(namespace, svc.Name) + if err != nil { + return nil, err + } + if len(slices) == 0 { + return nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", svc.Name)) + } else if len(slices) > 1 && len(svc.Spec.IPFamilies) > 0 { + // If there are multiple slices, we want to look at them in a random + // order, but we need to look at all of the slices of the primary IP + // family first. + preferredAddressType := discoveryv1.AddressType(svc.Spec.IPFamilies[0]) + randomOrder := rand.Perm(len(slices)) + sort.Slice(slices, func(i, j int) bool { + if slices[i].AddressType != slices[j].AddressType { + return slices[i].AddressType == preferredAddressType + } + return randomOrder[i] < randomOrder[j] + }) + } + + // Find a slice that has the port. + for _, slice := range slices { + for i := range slice.Ports { + if slice.Ports[i].Name == nil || *slice.Ports[i].Name != svcPort.Name { + continue + } + if slice.Ports[i].Port == nil { + continue + } + if len(slice.Endpoints) == 0 { + continue + } + + // Starting from a random index, find a Ready endpoint + offset := rand.Intn(len(slice.Endpoints)) + for epi := range slice.Endpoints { + ep := &slice.Endpoints[(epi+offset)%len(slice.Endpoints)] + if ep.Conditions.Ready == nil || *ep.Conditions.Ready { + // (Addresses is an array but only Addresses[0] is used.) + ip := ep.Addresses[0] + port := int(*slice.Ports[i].Port) + return &url.URL{ + Scheme: "https", + Host: net.JoinHostPort(ip, strconv.Itoa(port)), + }, nil + } + } + } + } + return nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", id)) +} + +func ResolveCluster(services listersv1.ServiceLister, namespace, id string, port int32) (*url.URL, error) { + svc, err := services.Services(namespace).Get(id) + if err != nil { + return nil, err + } + + switch { + case svc.Spec.Type == v1.ServiceTypeClusterIP && svc.Spec.ClusterIP == v1.ClusterIPNone: + return nil, fmt.Errorf(`cannot route to service with ClusterIP "None"`) + // use IP from a clusterIP for these service types + case svc.Spec.Type == v1.ServiceTypeClusterIP, svc.Spec.Type == v1.ServiceTypeLoadBalancer, svc.Spec.Type == v1.ServiceTypeNodePort: + svcPort, err := findServicePort(svc, port) + if err != nil { + return nil, err + } + return &url.URL{ + Scheme: "https", + Host: net.JoinHostPort(svc.Spec.ClusterIP, fmt.Sprintf("%d", svcPort.Port)), + }, nil + case svc.Spec.Type == v1.ServiceTypeExternalName: + return &url.URL{ + Scheme: "https", + Host: net.JoinHostPort(svc.Spec.ExternalName, fmt.Sprintf("%d", port)), + }, nil + default: + return nil, fmt.Errorf("unsupported service type %q", svc.Spec.Type) + } +} + +// NewRequestForProxy returns a shallow copy of the original request with a context that may include a timeout for discovery requests +func NewRequestForProxy(location *url.URL, req *http.Request) (*http.Request, context.CancelFunc) { + newCtx := req.Context() + cancelFn := func() {} + + if requestInfo, ok := genericapirequest.RequestInfoFrom(req.Context()); ok { + // trim leading and trailing slashes. Then "/apis/group/version" requests are for discovery, so if we have exactly three + // segments that we are going to proxy, we have a discovery request. + if !requestInfo.IsResourceRequest && len(strings.Split(strings.Trim(requestInfo.Path, "/"), "/")) == 3 { + // discovery requests are used by kubectl and others to determine which resources a server has. This is a cheap call that + // should be fast for every aggregated apiserver. Latency for aggregation is expected to be low (as for all extensions) + // so forcing a short timeout here helps responsiveness of all clients. + newCtx, cancelFn = context.WithTimeout(newCtx, aggregatedDiscoveryTimeout) + } + } + + // WithContext creates a shallow clone of the request with the same context. + newReq := req.WithContext(newCtx) + newReq.Header = utilnet.CloneHeader(req.Header) + newReq.URL = location + newReq.Host = location.Host + + // If the original request has an audit ID, let's make sure we propagate this + // to the aggregated server. + if auditID, found := audit.AuditIDFrom(req.Context()); found { + newReq.Header.Set(auditinternal.HeaderAuditID, string(auditID)) + } + + return newReq, cancelFn +} diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go b/vendor/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go new file mode 100644 index 0000000000..a85a5c5d0e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/streamtranslator.go @@ -0,0 +1,187 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proxy + +import ( + "fmt" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/mxk/go-flowrate/flowrate" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + constants "k8s.io/apimachinery/pkg/util/remotecommand" + "k8s.io/apiserver/pkg/util/proxy/metrics" + "k8s.io/client-go/tools/remotecommand" + clientspdy "k8s.io/client-go/transport/spdy" + "k8s.io/client-go/util/exec" + "k8s.io/streaming/pkg/httpstream/spdy" +) + +// StreamTranslatorHandler is a handler which translates WebSocket stream data +// to SPDY to proxy to kubelet (and ContainerRuntime). +type StreamTranslatorHandler struct { + // Location is the location of the upstream proxy. It is used as the location to Dial on the upstream server + // for upgrade requests. + Location *url.URL + // Transport provides an optional round tripper to use to proxy. If nil, the default proxy transport is used + Transport http.RoundTripper + // MaxBytesPerSec throttles stream Reader/Writer if necessary + MaxBytesPerSec int64 + // Options define the requested streams (e.g. stdin, stdout). + Options Options +} + +// NewStreamTranslatorHandler creates a new proxy handler. Responder is required for returning +// errors to the caller. +func NewStreamTranslatorHandler(location *url.URL, transport http.RoundTripper, maxBytesPerSec int64, opts Options) *StreamTranslatorHandler { + return &StreamTranslatorHandler{ + Location: location, + Transport: transport, + MaxBytesPerSec: maxBytesPerSec, + Options: opts, + } +} + +func (h *StreamTranslatorHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + // Create WebSocket server, including particular streams requested. If this websocket + // endpoint is not able to be upgraded, the websocket library will return errors + // to the client. + websocketStreams, err := webSocketServerStreams(req, w, h.Options) + if err != nil { + // Client error increments bad request status code. + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusBadRequest)) + return + } + defer websocketStreams.conn.Close() + + // Creating SPDY executor, ensuring redirects are not followed. + spdyRoundTripper, err := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{UpgradeTransport: h.Transport, PingPeriod: 5 * time.Second}) + if err != nil { + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusInternalServerError)) + websocketStreams.writeStatus(apierrors.NewInternalError(err)) //nolint:errcheck + return + } + spdyExecutor, err := remotecommand.NewSPDYExecutorRejectRedirects( + spdyRoundTripper, + clientspdy.NewUpgraderForStreaming(spdyRoundTripper), + "POST", + h.Location, + ) + if err != nil { + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusInternalServerError)) + websocketStreams.writeStatus(apierrors.NewInternalError(err)) //nolint:errcheck + return + } + + // Wire the WebSocket server streams output to the SPDY client input. The stdin/stdout/stderr streams + // can be throttled if the transfer rate exceeds the "MaxBytesPerSec" (zero means unset). Throttling + // the streams instead of the underlying connection *may* not perform the same if two streams + // traveling the same direction (e.g. stdout, stderr) are being maxed out. + opts := remotecommand.StreamOptions{} + if h.Options.Stdin { + stdin := websocketStreams.stdinStream + if h.MaxBytesPerSec > 0 { + stdin = flowrate.NewReader(stdin, h.MaxBytesPerSec) + } + opts.Stdin = stdin + } + if h.Options.Stdout { + stdout := websocketStreams.stdoutStream + if h.MaxBytesPerSec > 0 { + stdout = flowrate.NewWriter(stdout, h.MaxBytesPerSec) + } + opts.Stdout = stdout + } + if h.Options.Stderr { + stderr := websocketStreams.stderrStream + if h.MaxBytesPerSec > 0 { + stderr = flowrate.NewWriter(stderr, h.MaxBytesPerSec) + } + opts.Stderr = stderr + } + if h.Options.Tty { + opts.Tty = true + opts.TerminalSizeQueue = &translatorSizeQueue{resizeChan: websocketStreams.resizeChan} + } + // Start the SPDY client with connected streams. Output from the WebSocket server + // streams will be forwarded into the SPDY client. Report SPDY execution errors + // through the websocket error stream. + err = spdyExecutor.StreamWithContext(req.Context(), opts) + if err != nil { + //nolint:errcheck // Ignore writeStatus returned error + if statusErr, ok := err.(*apierrors.StatusError); ok { + // Increment status code returned within status error. + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(int(statusErr.Status().Code))) + websocketStreams.writeStatus(statusErr) + } else if exitErr, ok := err.(exec.CodeExitError); ok && exitErr.Exited() { + // Returned an exit code from the container, so not an error in + // stream translator--add StatusOK to metrics. + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusOK)) + websocketStreams.writeStatus(codeExitToStatusError(exitErr)) + } else { + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusInternalServerError)) + websocketStreams.writeStatus(apierrors.NewInternalError(err)) + } + return + } + + metrics.IncStreamTranslatorRequest(req.Context(), strconv.Itoa(http.StatusOK)) + // Write the success status back to the WebSocket client. + //nolint:errcheck + websocketStreams.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{ + Status: metav1.StatusSuccess, + }}) +} + +// translatorSizeQueue feeds the size events from the WebSocket +// resizeChan into the SPDY client input. Implements TerminalSizeQueue +// interface. +type translatorSizeQueue struct { + resizeChan chan remotecommand.TerminalSize +} + +func (t *translatorSizeQueue) Next() *remotecommand.TerminalSize { + size, ok := <-t.resizeChan + if !ok { + return nil + } + return &size +} + +// codeExitToStatusError converts a passed CodeExitError to the type necessary +// to send through an error stream using "writeStatus". +func codeExitToStatusError(exitErr exec.CodeExitError) *apierrors.StatusError { + rc := exitErr.ExitStatus() + return &apierrors.StatusError{ + ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Reason: constants.NonZeroExitCodeReason, + Details: &metav1.StatusDetails{ + Causes: []metav1.StatusCause{ + { + Type: constants.ExitCodeCauseType, + Message: fmt.Sprintf("%d", rc), + }, + }, + }, + Message: fmt.Sprintf("command terminated with non-zero exit code: %v", exitErr), + }, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/streamtunnel.go b/vendor/k8s.io/apiserver/pkg/util/proxy/streamtunnel.go new file mode 100644 index 0000000000..429ab78ebf --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/streamtunnel.go @@ -0,0 +1,470 @@ +/* +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 proxy + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "net" + "net/http" + "strconv" + "strings" + "sync" + "time" + + gwebsocket "github.com/gorilla/websocket" + + utilnet "k8s.io/apimachinery/pkg/util/net" + constants "k8s.io/apimachinery/pkg/util/portforward" + "k8s.io/apiserver/pkg/util/proxy/metrics" + "k8s.io/client-go/tools/portforward" + "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/httpstream/spdy" + "k8s.io/streaming/pkg/httpstream/wsstream" +) + +// TunnelingHandler is a handler which tunnels SPDY through WebSockets. +type TunnelingHandler struct { + // Used to communicate between upstream SPDY and downstream tunnel. + upgradeHandler http.Handler +} + +// NewTunnelingHandler is used to create the tunnel between an upstream +// SPDY connection and a downstream tunneling connection through the stored +// UpgradeAwareProxy. +func NewTunnelingHandler(upgradeHandler http.Handler) *TunnelingHandler { + return &TunnelingHandler{upgradeHandler: upgradeHandler} +} + +// ServeHTTP uses the upgradeHandler to tunnel between a downstream tunneling +// connection and an upstream SPDY connection. The tunneling connection is +// a wrapped WebSockets connection which communicates SPDY framed data. In the +// case the upstream upgrade fails, we delegate communication to the passed +// in "w" ResponseWriter. +func (h *TunnelingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + klog.V(4).Infoln("TunnelingHandler ServeHTTP") + + spdyProtocols := spdyProtocolsFromWebsocketProtocols(req) + if len(spdyProtocols) == 0 { + metrics.IncStreamTunnelRequest(req.Context(), strconv.Itoa(http.StatusBadRequest)) + http.Error(w, "unable to upgrade: no tunneling spdy protocols provided", http.StatusBadRequest) + return + } + + spdyRequest := createSPDYRequest(req, spdyProtocols...) + + // The fields "w" and "conn" are mutually exclusive. Either a successful upgrade occurs + // and the "conn" is hijacked and used in the subsequent upgradeHandler, or + // the upgrade failed, and "w" is the delegate used for the non-upgrade response. + writer := &tunnelingResponseWriter{ + // "w" is used in the non-upgrade error cases called in the upgradeHandler. + w: w, + // "conn" is returned in the successful upgrade case when hijacked in the upgradeHandler. + conn: &headerInterceptingConn{ + initializableConn: &tunnelingWebsocketUpgraderConn{ + w: w, + req: req, + }, + }, + } + + klog.V(4).Infoln("Tunnel spdy through websockets using the UpgradeAwareProxy") + h.upgradeHandler.ServeHTTP(writer, spdyRequest) +} + +// createSPDYRequest modifies the passed request to remove +// WebSockets headers and add SPDY upgrade information, including +// spdy protocols acceptable to the client. +func createSPDYRequest(req *http.Request, spdyProtocols ...string) *http.Request { + clone := utilnet.CloneRequest(req) + // Clean up the websocket headers from the http request. + clone.Header.Del(wsstream.WebSocketProtocolHeader) + clone.Header.Del("Sec-Websocket-Key") + clone.Header.Del("Sec-Websocket-Version") + clone.Header.Del(httpstream.HeaderUpgrade) + // Update the http request for an upstream SPDY upgrade. + clone.Method = "POST" + clone.Body = nil // Remove the request body which is unused. + clone.Header.Set(httpstream.HeaderUpgrade, spdy.HeaderSpdy31) + clone.Header.Del(httpstream.HeaderProtocolVersion) + for i := range spdyProtocols { + clone.Header.Add(httpstream.HeaderProtocolVersion, spdyProtocols[i]) + } + return clone +} + +// spdyProtocolsFromWebsocketProtocols returns a list of spdy protocols by filtering +// to Kubernetes websocket subprotocols prefixed with "SPDY/3.1+", then removing the prefix +func spdyProtocolsFromWebsocketProtocols(req *http.Request) []string { + var spdyProtocols []string + for _, protocol := range gwebsocket.Subprotocols(req) { + if strings.HasPrefix(protocol, constants.WebsocketsSPDYTunnelingPrefix) && strings.HasSuffix(protocol, constants.KubernetesSuffix) { + spdyProtocols = append(spdyProtocols, strings.TrimPrefix(protocol, constants.WebsocketsSPDYTunnelingPrefix)) + } + } + return spdyProtocols +} + +var _ http.ResponseWriter = &tunnelingResponseWriter{} +var _ http.Hijacker = &tunnelingResponseWriter{} + +// tunnelingResponseWriter implements the http.ResponseWriter and http.Hijacker interfaces. +// Only non-upgrade responses can be written using WriteHeader() and Write(). +// Once Write or WriteHeader is called, Hijack returns an error. +// Once Hijack is called, Write, WriteHeader, and Hijack return errors. +type tunnelingResponseWriter struct { + // w is used to delegate Header(), WriteHeader(), and Write() calls + w http.ResponseWriter + // conn is returned from Hijack() + conn net.Conn + // mu guards writes + mu sync.Mutex + // wrote tracks whether WriteHeader or Write has been called + written bool + // hijacked tracks whether Hijack has been called + hijacked bool +} + +// Hijack returns a delegate "net.Conn". +// An error is returned if Write(), WriteHeader(), or Hijack() was previously called. +// The returned bufio.ReadWriter is always nil. +func (w *tunnelingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + w.mu.Lock() + defer w.mu.Unlock() + if w.written { + klog.Errorf("Hijack called after write") + return nil, nil, errors.New("connection has already been written to") + } + if w.hijacked { + klog.Errorf("Hijack called after hijack") + return nil, nil, errors.New("connection has already been hijacked") + } + w.hijacked = true + klog.V(6).Infof("Hijack returning websocket tunneling net.Conn") + return w.conn, nil, nil +} + +// Header is delegated to the stored "http.ResponseWriter". +func (w *tunnelingResponseWriter) Header() http.Header { + return w.w.Header() +} + +// Write is delegated to the stored "http.ResponseWriter". +func (w *tunnelingResponseWriter) Write(p []byte) (int, error) { + w.mu.Lock() + defer w.mu.Unlock() + if w.hijacked { + klog.Errorf("Write called after hijack") + return 0, http.ErrHijacked + } + w.written = true + return w.w.Write(p) +} + +// WriteHeader is delegated to the stored "http.ResponseWriter". +func (w *tunnelingResponseWriter) WriteHeader(statusCode int) { + w.mu.Lock() + defer w.mu.Unlock() + if w.written { + klog.Errorf("WriteHeader called after write") + return + } + if w.hijacked { + klog.Errorf("WriteHeader called after hijack") + return + } + w.written = true + + if statusCode == http.StatusSwitchingProtocols { + // 101 upgrade responses must come via the hijacked connection, not WriteHeader + klog.Errorf("WriteHeader called with 101 upgrade") + http.Error(w.w, "unexpected upgrade", http.StatusInternalServerError) + return + } + + // pass through non-upgrade responses we don't need to translate + w.w.WriteHeader(statusCode) +} + +// headerInterceptingConn wraps the tunneling "net.Conn" to drain the +// HTTP response status/headers from the upstream SPDY connection, then use +// that to decide how to initialize the delegate connection for writes. +type headerInterceptingConn struct { + // initializableConn is delegated to for all net.Conn methods. + // initializableConn.Write() is not called until response headers have been read + // and initializableConn#InitializeWrite() has been called with the result. + initializableConn + + lock sync.Mutex + headerBuffer []byte + initialized bool + initializeErr error +} + +// initializableConn is a connection that will be initialized before any calls to Write are made +type initializableConn interface { + net.Conn + // InitializeWrite is called when the backend response headers have been read. + // backendResponse contains the parsed headers. + // backendResponseBytes are the raw bytes the headers were parsed from. + InitializeWrite(backendResponse *http.Response, backendResponseBytes []byte) error +} + +const maxHeaderBytes = 1 << 20 + +// token for normal header / body separation (\r\n\r\n, but go tolerates the leading \r being absent) +var lfCRLF = []byte("\n\r\n") + +// token for header / body separation without \r (which go tolerates) +var lfLF = []byte("\n\n") + +// Write intercepts to initially swallow the HTTP response, then +// delegate to the tunneling "net.Conn" once the response has been +// seen and processed. +func (h *headerInterceptingConn) Write(b []byte) (int, error) { + h.lock.Lock() + defer h.lock.Unlock() + + if h.initializeErr != nil { + return 0, h.initializeErr + } + if h.initialized { + return h.initializableConn.Write(b) + } + + // Guard against excessive buffering + if len(h.headerBuffer)+len(b) > maxHeaderBytes { + return 0, fmt.Errorf("header size limit exceeded") + } + + // Accumulate into headerBuffer + h.headerBuffer = append(h.headerBuffer, b...) + + // Attempt to parse http response headers + var headerBytes, bodyBytes []byte + if i := bytes.Index(h.headerBuffer, lfCRLF); i != -1 { + // headers terminated with \n\r\n + headerBytes = h.headerBuffer[0 : i+len(lfCRLF)] + bodyBytes = h.headerBuffer[i+len(lfCRLF):] + } else if i := bytes.Index(h.headerBuffer, lfLF); i != -1 { + // headers terminated with \n\n (which go tolerates) + headerBytes = h.headerBuffer[0 : i+len(lfLF)] + bodyBytes = h.headerBuffer[i+len(lfLF):] + } else { + // don't yet have a complete set of headers yet + return len(b), nil + } + resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(headerBytes)), nil) + if err != nil { + klog.Errorf("invalid headers: %v", err) + h.initializeErr = err + return len(b), err + } + resp.Body.Close() //nolint:errcheck + + h.headerBuffer = nil + h.initialized = true + h.initializeErr = h.initializableConn.InitializeWrite(resp, headerBytes) + if h.initializeErr != nil { + return len(b), h.initializeErr + } + if len(bodyBytes) > 0 { + _, err = h.initializableConn.Write(bodyBytes) + } + return len(b), err +} + +type tunnelingWebsocketUpgraderConn struct { + // req is the websocket request, used for upgrading + req *http.Request + // w is the websocket writer, used for upgrading and writing error responses + w http.ResponseWriter + + // lock guards conn and err + lock sync.RWMutex + // if conn is non-nil, InitializeWrite succeeded + conn net.Conn + // if err is non-nil, InitializeWrite failed or Close was called before InitializeWrite + err error +} + +func (u *tunnelingWebsocketUpgraderConn) InitializeWrite(backendResponse *http.Response, backendResponseBytes []byte) (err error) { + // make sure we close a connection we open in error cases + var conn net.Conn + defer func() { + if err != nil && conn != nil { + conn.Close() //nolint:errcheck + } + }() + + u.lock.Lock() + defer u.lock.Unlock() + if u.conn != nil { + return fmt.Errorf("InitializeWrite already called") + } + if u.err != nil { + return u.err + } + + if backendResponse.StatusCode == http.StatusSwitchingProtocols { + connectionHeader := strings.ToLower(backendResponse.Header.Get(httpstream.HeaderConnection)) + upgradeHeader := strings.ToLower(backendResponse.Header.Get(httpstream.HeaderUpgrade)) + if !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(spdy.HeaderSpdy31)) { + klog.Errorf("unable to upgrade: missing upgrade headers in response: %#v", backendResponse.Header) + u.err = fmt.Errorf("unable to upgrade: missing upgrade headers in response") + metrics.IncStreamTunnelRequest(context.Background(), strconv.Itoa(http.StatusInternalServerError)) + http.Error(u.w, u.err.Error(), http.StatusInternalServerError) + return u.err + } + + // Translate the server's chosen SPDY protocol into the tunneled websocket protocol for the handshake + var serverWebsocketProtocols []string + if backendSPDYProtocol := strings.TrimSpace(backendResponse.Header.Get(httpstream.HeaderProtocolVersion)); backendSPDYProtocol != "" { + serverWebsocketProtocols = []string{constants.WebsocketsSPDYTunnelingPrefix + backendSPDYProtocol} + } else { + serverWebsocketProtocols = []string{} + } + + // Try to upgrade the websocket connection. + // Beyond this point, we don't need to write errors to the response. + var upgrader = gwebsocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { return true }, + Subprotocols: serverWebsocketProtocols, + } + conn, err := upgrader.Upgrade(u.w, u.req, nil) + if err != nil { + klog.Errorf("error upgrading websocket connection: %v", err) + metrics.IncStreamTunnelRequest(context.Background(), strconv.Itoa(http.StatusInternalServerError)) + u.err = err + return u.err + } + + klog.V(4).Infof("websocket connection created: %s", conn.Subprotocol()) + metrics.IncStreamTunnelRequest(context.Background(), strconv.Itoa(http.StatusSwitchingProtocols)) + u.conn = portforward.NewTunnelingConnection("server", conn) + return nil + } + + // anything other than an upgrade should pass through the backend response + klog.Errorf("SPDY upgrade failed: %s", backendResponse.Status) + metrics.IncStreamTunnelRequest(context.Background(), strconv.Itoa(backendResponse.StatusCode)) + + // try to hijack + conn, _, err = u.w.(http.Hijacker).Hijack() + if err != nil { + klog.Errorf("Unable to hijack response: %v", err) + u.err = err + return u.err + } + // replay the backend response bytes to the hijacked conn + conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) //nolint:errcheck + _, err = conn.Write(backendResponseBytes) + if err != nil { + u.err = err + return u.err + } + u.conn = conn + return nil +} + +func (u *tunnelingWebsocketUpgraderConn) Read(b []byte) (n int, err error) { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.Read(b) + } + if u.err != nil { + return 0, u.err + } + // return empty read without blocking until we are initialized + return 0, nil +} +func (u *tunnelingWebsocketUpgraderConn) Write(b []byte) (n int, err error) { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.Write(b) + } + if u.err != nil { + return 0, u.err + } + return 0, fmt.Errorf("Write called before Initialize") +} +func (u *tunnelingWebsocketUpgraderConn) Close() error { + u.lock.Lock() + defer u.lock.Unlock() + if u.conn != nil { + return u.conn.Close() + } + if u.err != nil { + return u.err + } + // record that we closed so we don't write again or try to initialize + u.err = fmt.Errorf("connection closed") + // write a response + http.Error(u.w, u.err.Error(), http.StatusInternalServerError) + return nil +} +func (u *tunnelingWebsocketUpgraderConn) LocalAddr() net.Addr { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.LocalAddr() + } + return noopAddr{} +} +func (u *tunnelingWebsocketUpgraderConn) RemoteAddr() net.Addr { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.RemoteAddr() + } + return noopAddr{} +} +func (u *tunnelingWebsocketUpgraderConn) SetDeadline(t time.Time) error { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.SetDeadline(t) + } + return nil +} +func (u *tunnelingWebsocketUpgraderConn) SetReadDeadline(t time.Time) error { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.SetReadDeadline(t) + } + return nil +} +func (u *tunnelingWebsocketUpgraderConn) SetWriteDeadline(t time.Time) error { + u.lock.RLock() + defer u.lock.RUnlock() + if u.conn != nil { + return u.conn.SetWriteDeadline(t) + } + return nil +} + +type noopAddr struct{} + +func (n noopAddr) Network() string { return "" } +func (n noopAddr) String() string { return "" } diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/translatinghandler.go b/vendor/k8s.io/apiserver/pkg/util/proxy/translatinghandler.go new file mode 100644 index 0000000000..6f6c008824 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/translatinghandler.go @@ -0,0 +1,51 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proxy + +import ( + "net/http" + + "k8s.io/klog/v2" +) + +// translatingHandler wraps the delegate handler, implementing the +// http.Handler interface. The delegate handles all requests unless +// the request satisfies the passed "shouldTranslate" function +// (currently only for WebSocket/V5 request), in which case the translator +// handles the request. +type translatingHandler struct { + delegate http.Handler + translator http.Handler + shouldTranslate func(*http.Request) bool +} + +func NewTranslatingHandler(delegate http.Handler, translator http.Handler, shouldTranslate func(*http.Request) bool) http.Handler { + return &translatingHandler{ + delegate: delegate, + translator: translator, + shouldTranslate: shouldTranslate, + } +} + +func (t *translatingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if t.shouldTranslate(req) { + klog.V(4).Infof("request handled by translator proxy") + t.translator.ServeHTTP(w, req) + return + } + t.delegate.ServeHTTP(w, req) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/proxy/websocket.go b/vendor/k8s.io/apiserver/pkg/util/proxy/websocket.go new file mode 100644 index 0000000000..837c468108 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/proxy/websocket.go @@ -0,0 +1,200 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proxy + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + constants "k8s.io/apimachinery/pkg/util/remotecommand" + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/tools/remotecommand" + "k8s.io/streaming/pkg/httpstream/wsstream" +) + +const ( + // idleTimeout is the read/write deadline set for websocket server connection. Reading + // or writing the connection will return an i/o timeout if this deadline is exceeded. + // Currently, we use the same value as the kubelet websocket server. + defaultIdleConnectionTimeout = 4 * time.Hour + + // Deadline for writing errors to the websocket connection before io/timeout. + writeErrorDeadline = 10 * time.Second +) + +// Options contains details about which streams are required for +// remote command execution. +type Options struct { + Stdin bool + Stdout bool + Stderr bool + Tty bool +} + +// conns contains the connection and streams used when +// forwarding an attach or execute session into a container. +type conns struct { + conn io.Closer + stdinStream io.ReadCloser + stdoutStream io.WriteCloser + stderrStream io.WriteCloser + writeStatus func(status *apierrors.StatusError) error + resizeStream io.ReadCloser + resizeChan chan remotecommand.TerminalSize + tty bool +} + +// Create WebSocket server streams to respond to a WebSocket client. Creates the streams passed +// in the stream options. +func webSocketServerStreams(req *http.Request, w http.ResponseWriter, opts Options) (*conns, error) { + ctx, err := createWebSocketStreams(req, w, opts) + if err != nil { + return nil, err + } + + if ctx.resizeStream != nil { + ctx.resizeChan = make(chan remotecommand.TerminalSize) + go func() { + // Resize channel closes in panic case, and panic does not take down caller. + defer func() { + if p := recover(); p != nil { + // Standard panic logging. + for _, fn := range runtime.PanicHandlers { + fn(req.Context(), p) + } + } + }() + handleResizeEvents(req.Context(), ctx.resizeStream, ctx.resizeChan) + }() + } + + return ctx, nil +} + +// Read terminal resize events off of passed stream and queue into passed channel. +func handleResizeEvents(ctx context.Context, stream io.Reader, channel chan<- remotecommand.TerminalSize) { + defer close(channel) + + decoder := json.NewDecoder(stream) + for { + size := remotecommand.TerminalSize{} + if err := decoder.Decode(&size); err != nil { + break + } + + select { + case channel <- size: + case <-ctx.Done(): + // To avoid leaking this routine, exit if the http request finishes. This path + // would generally be hit if starting the process fails and nothing is started to + // ingest these resize events. + return + } + } +} + +// createChannels returns the standard channel types for a shell connection (STDIN 0, STDOUT 1, STDERR 2) +// along with the approximate duplex value. It also creates the error (3) and resize (4) channels. +func createChannels(opts Options) []wsstream.ChannelType { + // open the requested channels, and always open the error channel + channels := make([]wsstream.ChannelType, 5) + channels[constants.StreamStdIn] = readChannel(opts.Stdin) + channels[constants.StreamStdOut] = writeChannel(opts.Stdout) + channels[constants.StreamStdErr] = writeChannel(opts.Stderr) + channels[constants.StreamErr] = wsstream.WriteChannel + channels[constants.StreamResize] = wsstream.ReadChannel + return channels +} + +// readChannel returns wsstream.ReadChannel if real is true, or wsstream.IgnoreChannel. +func readChannel(real bool) wsstream.ChannelType { + if real { + return wsstream.ReadChannel + } + return wsstream.IgnoreChannel +} + +// writeChannel returns wsstream.WriteChannel if real is true, or wsstream.IgnoreChannel. +func writeChannel(real bool) wsstream.ChannelType { + if real { + return wsstream.WriteChannel + } + return wsstream.IgnoreChannel +} + +// createWebSocketStreams returns a "conns" struct containing the websocket connection and +// streams needed to perform an exec or an attach. +func createWebSocketStreams(req *http.Request, w http.ResponseWriter, opts Options) (*conns, error) { + channels := createChannels(opts) + conn := wsstream.NewConn(map[string]wsstream.ChannelProtocolConfig{ + // WebSocket server only supports remote command version 5. + constants.StreamProtocolV5Name: { + Binary: true, + Channels: channels, + }, + }) + conn.SetIdleTimeout(defaultIdleConnectionTimeout) + // Opening the connection responds to WebSocket client, negotiating + // the WebSocket upgrade connection and the subprotocol. + _, streams, err := conn.Open(w, req) + if err != nil { + return nil, err + } + + // Send an empty message to the lowest writable channel to notify the client the connection is established + switch { + case opts.Stdout: + _, err = streams[constants.StreamStdOut].Write([]byte{}) + case opts.Stderr: + _, err = streams[constants.StreamStdErr].Write([]byte{}) + default: + _, err = streams[constants.StreamErr].Write([]byte{}) + } + if err != nil { + conn.Close() + return nil, fmt.Errorf("write error during websocket server creation: %v", err) + } + + ctx := &conns{ + conn: conn, + stdinStream: streams[constants.StreamStdIn], + stdoutStream: streams[constants.StreamStdOut], + stderrStream: streams[constants.StreamStdErr], + tty: opts.Tty, + resizeStream: streams[constants.StreamResize], + } + + // writeStatus returns a WriteStatusFunc that marshals a given api Status + // as json in the error channel. + ctx.writeStatus = func(status *apierrors.StatusError) error { + bs, err := json.Marshal(status.Status()) + if err != nil { + return err + } + // Write status error to error stream with deadline. + conn.SetWriteDeadline(writeErrorDeadline) + _, err = streams[constants.StreamErr].Write(bs) + return err + } + + return ctx, nil +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go index 3df8e580e4..65bf08ee59 100644 --- a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go @@ -204,21 +204,18 @@ func (w *WebhookAuthorizer) Authorize(ctx context.Context, attr authorizer.Attri Verb: attr.GetVerb(), } } - // skipping match when feature is not enabled - if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StructuredAuthorizationConfiguration) { - // Process Match Conditions before calling the webhook - matches, err := w.match(ctx, r) - // If at least one matchCondition evaluates to an error (but none are FALSE): - // If failurePolicy=Deny, then the webhook rejects the request - // If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped - if err != nil { - return w.decisionOnError, "", err - } - // If at least one matchCondition successfully evaluates to FALSE, - // then the webhook is skipped. - if !matches { - return authorizer.DecisionNoOpinion, "", nil - } + // Process Match Conditions before calling the webhook + matches, err := w.match(ctx, r) + // If at least one matchCondition evaluates to an error (but none are FALSE): + // If failurePolicy=Deny, then the webhook rejects the request + // If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped + if err != nil { + return w.decisionOnError, "", err + } + // If at least one matchCondition successfully evaluates to FALSE, + // then the webhook is skipped. + if !matches { + return authorizer.DecisionNoOpinion, "", nil } // If all evaluated successfully and ALL matchConditions evaluate to TRUE, // then the webhook is called. diff --git a/vendor/k8s.io/cli-runtime/pkg/printers/kyaml.go b/vendor/k8s.io/cli-runtime/pkg/printers/kyaml.go index 285da2037d..8b1d69b45f 100644 --- a/vendor/k8s.io/cli-runtime/pkg/printers/kyaml.go +++ b/vendor/k8s.io/cli-runtime/pkg/printers/kyaml.go @@ -54,6 +54,8 @@ func (p *KYAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error { if InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj.Object.Object)).Type().PkgPath()) { return errors.New(InternalObjectPrinterErr) } + return p.encoder.FromObject(obj, w) + case *runtime.Unknown: return p.encoder.FromYAML(bytes.NewReader(obj.Raw), w) } diff --git a/vendor/k8s.io/cli-runtime/pkg/resource/visitor.go b/vendor/k8s.io/cli-runtime/pkg/resource/visitor.go index 76cfbbda82..fb37db367c 100644 --- a/vendor/k8s.io/cli-runtime/pkg/resource/visitor.go +++ b/vendor/k8s.io/cli-runtime/pkg/resource/visitor.go @@ -220,7 +220,6 @@ func (l ConcurrentVisitorList) Visit(fn VisitorFunc) error { g.SetLimit(concurrency) for i := range l.visitors { - i := i g.Go(func() error { return l.visitors[i].Visit(fn) }) diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/applyconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/applyconfiguration.go new file mode 100644 index 0000000000..63582a6365 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/applyconfiguration.go @@ -0,0 +1,81 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ApplyConfigurationApplyConfiguration represents a declarative configuration of the ApplyConfiguration type for use +// with apply. +// +// ApplyConfiguration defines the desired configuration values of an object. +type ApplyConfigurationApplyConfiguration struct { + // expression will be evaluated by CEL to create an apply configuration. + // ref: https://github.com/google/cel-spec + // + // Apply configurations are declared in CEL using object initialization. For example, this CEL expression + // returns an apply configuration to set a single field: + // + // Object{ + // spec: Object.spec{ + // serviceAccountName: "example" + // } + // } + // + // Apply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of + // values not included in the apply configuration. + // + // CEL expressions have access to the object types needed to create apply configurations: + // + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the + // object. No other metadata properties are accessible. + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + Expression *string `json:"expression,omitempty"` +} + +// ApplyConfigurationApplyConfiguration constructs a declarative configuration of the ApplyConfiguration type for use with +// apply. +func ApplyConfiguration() *ApplyConfigurationApplyConfiguration { + return &ApplyConfigurationApplyConfiguration{} +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *ApplyConfigurationApplyConfiguration) WithExpression(value string) *ApplyConfigurationApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/expressionwarning.go index 31219c7e80..44105d0167 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/expressionwarning.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/expressionwarning.go @@ -23,11 +23,11 @@ package v1 // // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarningApplyConfiguration struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef *string `json:"fieldRef,omitempty"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning *string `json:"warning,omitempty"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/jsonpatch.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/jsonpatch.go new file mode 100644 index 0000000000..800a835a47 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/jsonpatch.go @@ -0,0 +1,105 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// JSONPatchApplyConfiguration represents a declarative configuration of the JSONPatch type for use +// with apply. +// +// JSONPatch defines a JSON Patch. +type JSONPatchApplyConfiguration struct { + // expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/). + // ref: https://github.com/google/cel-spec + // + // expression must return an array of JSONPatch values. + // + // For example, this CEL expression returns a JSON patch to conditionally modify a value: + // + // [ + // JSONPatch{op: "test", path: "/spec/example", value: "Red"}, + // JSONPatch{op: "replace", path: "/spec/example", value: "Green"} + // ] + // + // To define an object for the patch value, use Object types. For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/spec/selector", + // value: Object.spec.selector{matchLabels: {"environment": "test"}} + // } + // ] + // + // To use strings containing '/' and '~' as JSONPatch path keys, use "jsonpatch.escapeKey". For example: + // + // [ + // JSONPatch{ + // op: "add", + // path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"), + // value: "test" + // }, + // ] + // + // CEL expressions have access to the types needed to create JSON patches and objects: + // + // - 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'. + // See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string, + // integer, array, map or object. If set, the 'path' and 'from' fields must be set to a + // [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL + // function may be used to escape path keys containing '/' and '~'. + // - 'Object' - CEL type of the resource object. + // - 'Object.' - CEL type of object field (such as 'Object.spec') + // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers') + // + // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables: + // + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. + // - 'variables' - Map of composited variables, from its name to its lazily evaluated value. + // For example, a variable named 'foo' can be accessed as 'variables.foo'. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // + // CEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries) + // as well as: + // + // - 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively). + // + // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. + // Required. + Expression *string `json:"expression,omitempty"` +} + +// JSONPatchApplyConfiguration constructs a declarative configuration of the JSONPatch type for use with +// apply. +func JSONPatch() *JSONPatchApplyConfiguration { + return &JSONPatchApplyConfiguration{} +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *JSONPatchApplyConfiguration) WithExpression(value string) *JSONPatchApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go index 1e149da4ec..785fbbf023 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go @@ -23,7 +23,7 @@ package v1 // // MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. type MatchConditionApplyConfiguration struct { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -33,7 +33,7 @@ type MatchConditionApplyConfiguration struct { // // Required. Name *string `json:"name,omitempty"` - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchresources.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchresources.go index cd1a3d5fcf..29ee198b3a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchresources.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchresources.go @@ -30,7 +30,7 @@ import ( // on whether it meets the match criteria. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) type MatchResourcesApplyConfiguration struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -74,7 +74,7 @@ type MatchResourcesApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -86,10 +86,10 @@ type MatchResourcesApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. ResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"resourceRules,omitempty"` - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) ExcludeResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"excludeResourceRules,omitempty"` // matchPolicy defines how the "MatchResources" list is used to match incoming requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicy.go new file mode 100644 index 0000000000..f99f055b3c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicy.go @@ -0,0 +1,274 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// MutatingAdmissionPolicyApplyConfiguration represents a declarative configuration of the MutatingAdmissionPolicy type for use +// with apply. +// +// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. +type MutatingAdmissionPolicyApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // spec defines the desired behavior of the MutatingAdmissionPolicy. + Spec *MutatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` +} + +// MutatingAdmissionPolicy constructs a declarative configuration of the MutatingAdmissionPolicy type for use with +// apply. +func MutatingAdmissionPolicy(name string) *MutatingAdmissionPolicyApplyConfiguration { + b := &MutatingAdmissionPolicyApplyConfiguration{} + b.WithName(name) + b.WithKind("MutatingAdmissionPolicy") + b.WithAPIVersion("admissionregistration.k8s.io/v1") + return b +} + +// ExtractMutatingAdmissionPolicyFrom extracts the applied configuration owned by fieldManager from +// mutatingAdmissionPolicy for the specified subresource. Pass an empty string for subresource to extract +// the main resource. Common subresources include "status", "scale", etc. +// mutatingAdmissionPolicy must be a unmodified MutatingAdmissionPolicy API object that was retrieved from the Kubernetes API. +// ExtractMutatingAdmissionPolicyFrom provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractMutatingAdmissionPolicyFrom(mutatingAdmissionPolicy *admissionregistrationv1.MutatingAdmissionPolicy, fieldManager string, subresource string) (*MutatingAdmissionPolicyApplyConfiguration, error) { + b := &MutatingAdmissionPolicyApplyConfiguration{} + err := managedfields.ExtractInto(mutatingAdmissionPolicy, internal.Parser().Type("io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicy"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(mutatingAdmissionPolicy.Name) + + b.WithKind("MutatingAdmissionPolicy") + b.WithAPIVersion("admissionregistration.k8s.io/v1") + return b, nil +} + +// ExtractMutatingAdmissionPolicy extracts the applied configuration owned by fieldManager from +// mutatingAdmissionPolicy. If no managedFields are found in mutatingAdmissionPolicy for fieldManager, a +// MutatingAdmissionPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// mutatingAdmissionPolicy must be a unmodified MutatingAdmissionPolicy API object that was retrieved from the Kubernetes API. +// ExtractMutatingAdmissionPolicy provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractMutatingAdmissionPolicy(mutatingAdmissionPolicy *admissionregistrationv1.MutatingAdmissionPolicy, fieldManager string) (*MutatingAdmissionPolicyApplyConfiguration, error) { + return ExtractMutatingAdmissionPolicyFrom(mutatingAdmissionPolicy, fieldManager, "") +} + +func (b MutatingAdmissionPolicyApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithKind(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithAPIVersion(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithName(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithGenerateName(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithNamespace(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithUID(value types.UID) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithResourceVersion(value string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithGeneration(value int64) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithLabels(entries map[string]string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithFinalizers(values ...string) *MutatingAdmissionPolicyApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *MutatingAdmissionPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *MutatingAdmissionPolicyApplyConfiguration) WithSpec(value *MutatingAdmissionPolicySpecApplyConfiguration) *MutatingAdmissionPolicyApplyConfiguration { + b.Spec = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *MutatingAdmissionPolicyApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *MutatingAdmissionPolicyApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *MutatingAdmissionPolicyApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *MutatingAdmissionPolicyApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybinding.go new file mode 100644 index 0000000000..4bb30baa6f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybinding.go @@ -0,0 +1,284 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// MutatingAdmissionPolicyBindingApplyConfiguration represents a declarative configuration of the MutatingAdmissionPolicyBinding type for use +// with apply. +// +// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. +// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators +// configure policies for clusters. +// +// For a given admission request, each binding will cause its policy to be +// evaluated N times, where N is 1 for policies/bindings that don't use +// params, otherwise N is the number of parameters selected by the binding. +// Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget). +// +// Adding/removing policies, bindings, or params can not affect whether a +// given (policy, binding, param) combination is within its own CEL budget. +type MutatingAdmissionPolicyBindingApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. + Spec *MutatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` +} + +// MutatingAdmissionPolicyBinding constructs a declarative configuration of the MutatingAdmissionPolicyBinding type for use with +// apply. +func MutatingAdmissionPolicyBinding(name string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b := &MutatingAdmissionPolicyBindingApplyConfiguration{} + b.WithName(name) + b.WithKind("MutatingAdmissionPolicyBinding") + b.WithAPIVersion("admissionregistration.k8s.io/v1") + return b +} + +// ExtractMutatingAdmissionPolicyBindingFrom extracts the applied configuration owned by fieldManager from +// mutatingAdmissionPolicyBinding for the specified subresource. Pass an empty string for subresource to extract +// the main resource. Common subresources include "status", "scale", etc. +// mutatingAdmissionPolicyBinding must be a unmodified MutatingAdmissionPolicyBinding API object that was retrieved from the Kubernetes API. +// ExtractMutatingAdmissionPolicyBindingFrom provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractMutatingAdmissionPolicyBindingFrom(mutatingAdmissionPolicyBinding *admissionregistrationv1.MutatingAdmissionPolicyBinding, fieldManager string, subresource string) (*MutatingAdmissionPolicyBindingApplyConfiguration, error) { + b := &MutatingAdmissionPolicyBindingApplyConfiguration{} + err := managedfields.ExtractInto(mutatingAdmissionPolicyBinding, internal.Parser().Type("io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBinding"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(mutatingAdmissionPolicyBinding.Name) + + b.WithKind("MutatingAdmissionPolicyBinding") + b.WithAPIVersion("admissionregistration.k8s.io/v1") + return b, nil +} + +// ExtractMutatingAdmissionPolicyBinding extracts the applied configuration owned by fieldManager from +// mutatingAdmissionPolicyBinding. If no managedFields are found in mutatingAdmissionPolicyBinding for fieldManager, a +// MutatingAdmissionPolicyBindingApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// mutatingAdmissionPolicyBinding must be a unmodified MutatingAdmissionPolicyBinding API object that was retrieved from the Kubernetes API. +// ExtractMutatingAdmissionPolicyBinding provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractMutatingAdmissionPolicyBinding(mutatingAdmissionPolicyBinding *admissionregistrationv1.MutatingAdmissionPolicyBinding, fieldManager string) (*MutatingAdmissionPolicyBindingApplyConfiguration, error) { + return ExtractMutatingAdmissionPolicyBindingFrom(mutatingAdmissionPolicyBinding, fieldManager, "") +} + +func (b MutatingAdmissionPolicyBindingApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithKind(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithAPIVersion(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithName(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithGenerateName(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithNamespace(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithUID(value types.UID) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithResourceVersion(value string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithGeneration(value int64) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithLabels(entries map[string]string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithAnnotations(entries map[string]string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithFinalizers(values ...string) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) WithSpec(value *MutatingAdmissionPolicyBindingSpecApplyConfiguration) *MutatingAdmissionPolicyBindingApplyConfiguration { + b.Spec = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *MutatingAdmissionPolicyBindingApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybindingspec.go new file mode 100644 index 0000000000..a62e5dbb28 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicybindingspec.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// MutatingAdmissionPolicyBindingSpecApplyConfiguration represents a declarative configuration of the MutatingAdmissionPolicyBindingSpec type for use +// with apply. +// +// MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding. +type MutatingAdmissionPolicyBindingSpecApplyConfiguration struct { + // policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to. + // If the referenced resource does not exist, this binding is considered invalid and will be ignored + // Required. + PolicyName *string `json:"policyName,omitempty"` + // paramRef specifies the parameter resource used to configure the admission control policy. + // It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy. + // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied. + // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. + ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` + // matchResources limits what resources match this binding and may be mutated by it. + // Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and + // matchConditions before the resource may be mutated. + // When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints + // and matchConditions must match for the resource to be mutated. + // Additionally, matchResources.resourceRules are optional and do not constraint matching when unset. + // Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` +} + +// MutatingAdmissionPolicyBindingSpecApplyConfiguration constructs a declarative configuration of the MutatingAdmissionPolicyBindingSpec type for use with +// apply. +func MutatingAdmissionPolicyBindingSpec() *MutatingAdmissionPolicyBindingSpecApplyConfiguration { + return &MutatingAdmissionPolicyBindingSpecApplyConfiguration{} +} + +// WithPolicyName sets the PolicyName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PolicyName field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingSpecApplyConfiguration) WithPolicyName(value string) *MutatingAdmissionPolicyBindingSpecApplyConfiguration { + b.PolicyName = &value + return b +} + +// WithParamRef sets the ParamRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParamRef field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingSpecApplyConfiguration) WithParamRef(value *ParamRefApplyConfiguration) *MutatingAdmissionPolicyBindingSpecApplyConfiguration { + b.ParamRef = value + return b +} + +// WithMatchResources sets the MatchResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchResources field is set to the value of the last call. +func (b *MutatingAdmissionPolicyBindingSpecApplyConfiguration) WithMatchResources(value *MatchResourcesApplyConfiguration) *MutatingAdmissionPolicyBindingSpecApplyConfiguration { + b.MatchResources = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicyspec.go new file mode 100644 index 0000000000..fc52a5595f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingadmissionpolicyspec.go @@ -0,0 +1,172 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" +) + +// MutatingAdmissionPolicySpecApplyConfiguration represents a declarative configuration of the MutatingAdmissionPolicySpec type for use +// with apply. +// +// MutatingAdmissionPolicySpec defines the desired behavior of the admission policy. +type MutatingAdmissionPolicySpecApplyConfiguration struct { + // paramKind specifies the kind of resources used to parameterize this policy. + // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. + // If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. + // If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null. + ParamKind *ParamKindApplyConfiguration `json:"paramKind,omitempty"` + // matchConstraints specifies what resources this policy is designed to validate. + // The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints. + // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API + // MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding. + // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. + // '*' matches CREATE, UPDATE and CONNECT. + // Required. + MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` + // variables contain definitions of variables that can be used in composition of other expressions. + // Each variable is defined as a named CEL expression. + // The variables defined here will be available under `variables` in other expressions of the policy + // except matchConditions because matchConditions are evaluated before the rest of the policy. + // + // The expression of a variable can refer to other variables defined earlier in the list but not those after. + // Thus, variables must be sorted by the order of first appearance and acyclic. + Variables []VariableApplyConfiguration `json:"variables,omitempty"` + // mutations contain operations to perform on matching objects. + // mutations may not be empty; a minimum of one mutation is required. + // mutations are evaluated in order, and are reinvoked according to + // the reinvocationPolicy. + // The mutations of a policy are invoked for each binding of this policy + // and reinvocation of mutations occurs on a per binding basis. + Mutations []MutationApplyConfiguration `json:"mutations,omitempty"` + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // + // A policy is invalid if paramKind refers to a non-existent Kind. + // A binding is invalid if paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // Allowed values are Ignore or Fail. Defaults to Fail. + FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy,omitempty"` + // matchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the matchConstraints. + // An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` + // reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding + // as part of a single admission evaluation. + // Allowed values are "Never" and "IfNeeded". + // + // Never: These mutations will not be called more than once per binding in a single admission evaluation. + // + // IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of + // order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only + // reinvoked when mutations change the object after this mutation is invoked. + // Required. + ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` +} + +// MutatingAdmissionPolicySpecApplyConfiguration constructs a declarative configuration of the MutatingAdmissionPolicySpec type for use with +// apply. +func MutatingAdmissionPolicySpec() *MutatingAdmissionPolicySpecApplyConfiguration { + return &MutatingAdmissionPolicySpecApplyConfiguration{} +} + +// WithParamKind sets the ParamKind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParamKind field is set to the value of the last call. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithParamKind(value *ParamKindApplyConfiguration) *MutatingAdmissionPolicySpecApplyConfiguration { + b.ParamKind = value + return b +} + +// WithMatchConstraints sets the MatchConstraints field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MatchConstraints field is set to the value of the last call. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithMatchConstraints(value *MatchResourcesApplyConfiguration) *MutatingAdmissionPolicySpecApplyConfiguration { + b.MatchConstraints = value + return b +} + +// WithVariables adds the given value to the Variables field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Variables field. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithVariables(values ...*VariableApplyConfiguration) *MutatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithVariables") + } + b.Variables = append(b.Variables, *values[i]) + } + return b +} + +// WithMutations adds the given value to the Mutations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Mutations field. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithMutations(values ...*MutationApplyConfiguration) *MutatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMutations") + } + b.Mutations = append(b.Mutations, *values[i]) + } + return b +} + +// WithFailurePolicy sets the FailurePolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the FailurePolicy field is set to the value of the last call. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithFailurePolicy(value admissionregistrationv1.FailurePolicyType) *MutatingAdmissionPolicySpecApplyConfiguration { + b.FailurePolicy = &value + return b +} + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} + +// WithReinvocationPolicy sets the ReinvocationPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ReinvocationPolicy field is set to the value of the last call. +func (b *MutatingAdmissionPolicySpecApplyConfiguration) WithReinvocationPolicy(value admissionregistrationv1.ReinvocationPolicyType) *MutatingAdmissionPolicySpecApplyConfiguration { + b.ReinvocationPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go index 498611b5dd..47e691f12d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go @@ -28,23 +28,23 @@ import ( // // MutatingWebhook describes an admission webhook and the resources and operations it applies to. type MutatingWebhookApplyConfiguration struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name *string `json:"name,omitempty"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. Rules []RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy,omitempty"` // matchPolicy defines how the "rules" list is used to match incoming requests. @@ -62,7 +62,7 @@ type MutatingWebhookApplyConfiguration struct { // // Defaults to "Equivalent" MatchPolicy *admissionregistrationv1.MatchPolicyType `json:"matchPolicy,omitempty"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -106,7 +106,7 @@ type MutatingWebhookApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -118,20 +118,20 @@ type MutatingWebhookApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. // Requests with the dryRun attribute will be auto-rejected if they match a webhook with // sideEffects == Unknown or Some. SideEffects *admissionregistrationv1.SideEffectClass `json:"sideEffects,omitempty"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. // Default to 10 seconds. TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -155,7 +155,7 @@ type MutatingWebhookApplyConfiguration struct { // // Defaults to "Never". ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhookconfiguration.go index 87909f254b..dcb0b81cca 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhookconfiguration.go @@ -33,9 +33,9 @@ import ( // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. type MutatingWebhookConfigurationApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. Webhooks []MutatingWebhookApplyConfiguration `json:"webhooks,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutation.go new file mode 100644 index 0000000000..f47749d3cd --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutation.go @@ -0,0 +1,72 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" +) + +// MutationApplyConfiguration represents a declarative configuration of the Mutation type for use +// with apply. +// +// Mutation specifies the CEL expression which is used to apply the Mutation. +type MutationApplyConfiguration struct { + // patchType indicates the patch strategy used. + // Allowed values are "ApplyConfiguration" and "JSONPatch". + // Required. + PatchType *admissionregistrationv1.PatchType `json:"patchType,omitempty"` + // applyConfiguration defines the desired configuration values of an object. + // The configuration is applied to the admission object using + // [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff). + // A CEL expression is used to create apply configuration. + ApplyConfiguration *ApplyConfigurationApplyConfiguration `json:"applyConfiguration,omitempty"` + // jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object. + // A CEL expression is used to create the JSON patch. + JSONPatch *JSONPatchApplyConfiguration `json:"jsonPatch,omitempty"` +} + +// MutationApplyConfiguration constructs a declarative configuration of the Mutation type for use with +// apply. +func Mutation() *MutationApplyConfiguration { + return &MutationApplyConfiguration{} +} + +// WithPatchType sets the PatchType field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PatchType field is set to the value of the last call. +func (b *MutationApplyConfiguration) WithPatchType(value admissionregistrationv1.PatchType) *MutationApplyConfiguration { + b.PatchType = &value + return b +} + +// WithApplyConfiguration sets the ApplyConfiguration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ApplyConfiguration field is set to the value of the last call. +func (b *MutationApplyConfiguration) WithApplyConfiguration(value *ApplyConfigurationApplyConfiguration) *MutationApplyConfiguration { + b.ApplyConfiguration = value + return b +} + +// WithJSONPatch sets the JSONPatch field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the JSONPatch field is set to the value of the last call. +func (b *MutationApplyConfiguration) WithJSONPatch(value *JSONPatchApplyConfiguration) *MutationApplyConfiguration { + b.JSONPatch = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/namedrulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/namedrulewithoperations.go index fe7a6b8c0c..326337c8cc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/namedrulewithoperations.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/namedrulewithoperations.go @@ -27,7 +27,7 @@ import ( // // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. type NamedRuleWithOperationsApplyConfiguration struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. ResourceNames []string `json:"resourceNames,omitempty"` // RuleWithOperations is a tuple of Operations and Resources. RuleWithOperationsApplyConfiguration `json:",inline"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramkind.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramkind.go index 5c6729fc63..7a140feddc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramkind.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramkind.go @@ -23,11 +23,11 @@ package v1 // // ParamKind is a tuple of Group Kind and Version. type ParamKindApplyConfiguration struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion *string `json:"apiVersion,omitempty"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind *string `json:"kind,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramref.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramref.go index eb9f6c47aa..25690d06d1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramref.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/paramref.go @@ -62,7 +62,7 @@ type ParamRefApplyConfiguration struct { // One of `name` or `selector` must be set, but `name` and `selector` are // mutually exclusive properties. If one is set, the other must be unset. Selector *metav1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rule.go index 056e944fec..aa1d948a99 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rule.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rule.go @@ -28,15 +28,15 @@ import ( // Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended // to make sure that all the tuple expansions are valid. type RuleApplyConfiguration struct { - // APIGroups is the API groups the resources belong to. '*' is all groups. + // apiGroups is the API groups the resources belong to. '*' is all groups. // If '*' is present, the length of the slice must be one. // Required. APIGroups []string `json:"apiGroups,omitempty"` - // APIVersions is the API versions the resources belong to. '*' is all versions. + // apiVersions is the API versions the resources belong to. '*' is all versions. // If '*' is present, the length of the slice must be one. // Required. APIVersions []string `json:"apiVersions,omitempty"` - // Resources is a list of resources this rule applies to. + // resources is a list of resources this rule applies to. // // For example: // 'pods' means pods. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rulewithoperations.go index a4a1643fec..575e1ab35c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rulewithoperations.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/rulewithoperations.go @@ -28,7 +28,7 @@ import ( // RuleWithOperations is a tuple of Operations and Resources. It is recommended to make // sure that all the tuple expansions are valid. type RuleWithOperationsApplyConfiguration struct { - // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * + // operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * // for all of those operations and any future admission operations that are added. // If '*' is present, the length of the slice must be one. // Required. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/servicereference.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/servicereference.go index c93b61150f..e15728ae18 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/servicereference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/servicereference.go @@ -23,16 +23,16 @@ package v1 // // ServiceReference holds a reference to Service.legacy.k8s.io type ServiceReferenceApplyConfiguration struct { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required Namespace *string `json:"namespace,omitempty"` - // `name` is the name of the service. + // name is the name of the service. // Required Name *string `json:"name,omitempty"` - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. Path *string `json:"path,omitempty"` - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. // `port` should be a valid port number (1-65535, inclusive). Port *int32 `json:"port,omitempty"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/typechecking.go index f6077ee39e..5140aedb51 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/typechecking.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/typechecking.go @@ -24,7 +24,7 @@ package v1 // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeCheckingApplyConfiguration struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicy.go index 22d965fa81..6e06ed3e5f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicy.go @@ -33,11 +33,11 @@ import ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicyApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybinding.go index 5a083a0568..590aabda81 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybinding.go @@ -43,9 +43,9 @@ import ( // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBindingApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. Spec *ValidatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybindingspec.go index 31d98bb947..d783b4c41c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybindingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicybindingspec.go @@ -27,7 +27,7 @@ import ( // // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. PolicyName *string `json:"policyName,omitempty"` @@ -36,7 +36,7 @@ type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicyspec.go index b3f6989a72..5f9336d4dd 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicyspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicyspec.go @@ -27,18 +27,18 @@ import ( // // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpecApplyConfiguration struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. ParamKind *ParamKindApplyConfiguration `json:"paramKind,omitempty"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. Validations []ValidationApplyConfiguration `json:"validations,omitempty"` @@ -61,7 +61,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is // required. AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -76,7 +76,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the policy is skipped MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicystatus.go index 0b3ea76124..382ca9b260 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicystatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingadmissionpolicystatus.go @@ -27,12 +27,12 @@ import ( // // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. type ValidatingAdmissionPolicyStatusApplyConfiguration struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go index 02298017cb..3312b9d27d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go @@ -28,23 +28,23 @@ import ( // // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. type ValidatingWebhookApplyConfiguration struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name *string `json:"name,omitempty"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. Rules []RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Fail. FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy,omitempty"` // matchPolicy defines how the "rules" list is used to match incoming requests. @@ -62,7 +62,7 @@ type ValidatingWebhookApplyConfiguration struct { // // Defaults to "Equivalent" MatchPolicy *admissionregistrationv1.MatchPolicyType `json:"matchPolicy,omitempty"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -106,7 +106,7 @@ type ValidatingWebhookApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -118,20 +118,20 @@ type ValidatingWebhookApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. // Requests with the dryRun attribute will be auto-rejected if they match a webhook with // sideEffects == Unknown or Some. SideEffects *admissionregistrationv1.SideEffectClass `json:"sideEffects,omitempty"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. // Default to 10 seconds. TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -139,7 +139,7 @@ type ValidatingWebhookApplyConfiguration struct { // include any versions known to the API Server, calls to the webhook will fail // and be subject to the failure policy. AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhookconfiguration.go index fdf7923e96..c3ac1fafdd 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhookconfiguration.go @@ -33,9 +33,9 @@ import ( // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. type ValidatingWebhookConfigurationApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. Webhooks []ValidatingWebhookApplyConfiguration `json:"webhooks,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validation.go index 2ad6756d01..32dc38391a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validation.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validation.go @@ -27,7 +27,7 @@ import ( // // Validation specifies the CEL expression which is used to apply the validation. type ValidationApplyConfiguration struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -69,7 +69,7 @@ type ValidationApplyConfiguration struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression *string `json:"expression,omitempty"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -77,7 +77,7 @@ type ValidationApplyConfiguration struct { // The message must not contain line breaks. // If unset, the message is "failed Expression: {Expression}". Message *string `json:"message,omitempty"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/variable.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/variable.go index a99f837944..eb89ec088f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/variable.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/variable.go @@ -23,11 +23,11 @@ package v1 // // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. type VariableApplyConfiguration struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name *string `json:"name,omitempty"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression *string `json:"expression,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/webhookclientconfig.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/webhookclientconfig.go index 10f3d48de4..b379de8524 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/webhookclientconfig.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/webhookclientconfig.go @@ -24,7 +24,7 @@ package v1 // WebhookClientConfig contains the information to make a TLS // connection with the webhook type WebhookClientConfigApplyConfiguration struct { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -50,12 +50,12 @@ type WebhookClientConfigApplyConfiguration struct { // allowed. Fragments ("#...") and query parameters ("?...") are not // allowed, either. URL *string `json:"url,omitempty"` - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. Service *ServiceReferenceApplyConfiguration `json:"service,omitempty"` - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. CABundle []byte `json:"caBundle,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go index 220c5d2c93..c52e4d372a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go @@ -23,11 +23,11 @@ package v1alpha1 // // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarningApplyConfiguration struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef *string `json:"fieldRef,omitempty"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning *string `json:"warning,omitempty"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go index 7b758dbf4b..34fdee402c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go @@ -21,7 +21,7 @@ package v1alpha1 // MatchConditionApplyConfiguration represents a declarative configuration of the MatchCondition type for use // with apply. type MatchConditionApplyConfiguration struct { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -31,7 +31,7 @@ type MatchConditionApplyConfiguration struct { // // Required. Name *string `json:"name,omitempty"` - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go index 5bdeab094b..e6b5a8acee 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchresources.go @@ -30,7 +30,7 @@ import ( // on whether it meets the match criteria. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) type MatchResourcesApplyConfiguration struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -74,7 +74,7 @@ type MatchResourcesApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *v1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the policy based on if the + // objectSelector decides whether to run the policy based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the policy's expression (CEL), and // is considered to match if either object matches the selector. A null @@ -86,10 +86,10 @@ type MatchResourcesApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *v1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // ResourceRules describes what operations on what resources/subresources the admission policy matches. + // resourceRules describes what operations on what resources/subresources the admission policy matches. // The policy cares about an operation if it matches _any_ Rule. ResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"resourceRules,omitempty"` - // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the policy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) ExcludeResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"excludeResourceRules,omitempty"` // matchPolicy defines how the "MatchResources" list is used to match incoming requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicy.go index be5b791247..678e4d612a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicy.go @@ -33,9 +33,9 @@ import ( // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. type MutatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. Spec *MutatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go index 4964a3106d..5286ce24c5 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go @@ -43,9 +43,9 @@ import ( // given (policy, binding, param) combination is within its own CEL budget. type MutatingAdmissionPolicyBindingApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. Spec *MutatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go index b9e309edc2..45c12f191d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/namedrulewithoperations.go @@ -28,7 +28,7 @@ import ( // // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. type NamedRuleWithOperationsApplyConfiguration struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. ResourceNames []string `json:"resourceNames,omitempty"` // RuleWithOperations is a tuple of Operations and Resources. v1.RuleWithOperationsApplyConfiguration `json:",inline"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go index 7e008e329c..26227c10a1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramkind.go @@ -23,11 +23,11 @@ package v1alpha1 // // ParamKind is a tuple of Group Kind and Version. type ParamKindApplyConfiguration struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion *string `json:"apiVersion,omitempty"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind *string `json:"kind,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go index 6b77cd0eae..ce2ecf1a00 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramref.go @@ -29,7 +29,7 @@ import ( // ParamRef describes how to locate the params to be used as input to // expressions of rules applied by a policy binding. type ParamRefApplyConfiguration struct { - // `name` is the name of the resource being referenced. + // name is the name of the resource being referenced. // // `name` and `selector` are mutually exclusive properties. If one is set, // the other must be unset. @@ -58,7 +58,7 @@ type ParamRefApplyConfiguration struct { // One of `name` or `selector` must be set, but `name` and `selector` are // mutually exclusive properties. If one is set, the other must be unset. Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go index 3b5bff0f3c..c455b88165 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go @@ -24,7 +24,7 @@ package v1alpha1 // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeCheckingApplyConfiguration struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go index 7f85ed8e2f..9191eaab20 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -33,11 +33,11 @@ import ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go index 0760e92744..ad61dad084 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -43,9 +43,9 @@ import ( // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBindingApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. Spec *ValidatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go index bbbd59c97a..f157dc55d9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go @@ -27,7 +27,7 @@ import ( // // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. PolicyName *string `json:"policyName,omitempty"` @@ -36,7 +36,7 @@ type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go index ba20af8851..969f718178 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go @@ -27,18 +27,18 @@ import ( // // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpecApplyConfiguration struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. ParamKind *ParamKindApplyConfiguration `json:"paramKind,omitempty"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. Validations []ValidationApplyConfiguration `json:"validations,omitempty"` @@ -61,7 +61,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is // required. AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -76,7 +76,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the policy is skipped MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go index bd33b85564..2158263448 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go @@ -27,12 +27,12 @@ import ( // // ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. type ValidatingAdmissionPolicyStatusApplyConfiguration struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go index 24416b210e..b21800a8a3 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go @@ -27,7 +27,7 @@ import ( // // Validation specifies the CEL expression which is used to apply the validation. type ValidationApplyConfiguration struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -69,7 +69,7 @@ type ValidationApplyConfiguration struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression *string `json:"expression,omitempty"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -77,7 +77,7 @@ type ValidationApplyConfiguration struct { // The message must not contain line breaks. // If unset, the message is "failed Expression: {Expression}". Message *string `json:"message,omitempty"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/variable.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/variable.go index df7e1c9db6..284234926b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/variable.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/variable.go @@ -23,11 +23,11 @@ package v1alpha1 // // Variable is the definition of a variable that is used for composition. type VariableApplyConfiguration struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name *string `json:"name,omitempty"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression *string `json:"expression,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/expressionwarning.go index 0b0235f6f0..39e6ca9d28 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/expressionwarning.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/expressionwarning.go @@ -23,11 +23,11 @@ package v1beta1 // // ExpressionWarning is a warning information that targets a specific expression. type ExpressionWarningApplyConfiguration struct { - // The path to the field that refers the expression. + // fieldRef is the path to the field that refers to the expression. // For example, the reference to the expression of the first item of // validations is "spec.validations[0].expression" FieldRef *string `json:"fieldRef,omitempty"` - // The content of type checking information in a human-readable form. + // warning contains the content of type checking information in a human-readable form. // Each line of the warning contains the type that the expression is checked // against, followed by the type check error from the compiler. Warning *string `json:"warning,omitempty"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go index a5c4b433ed..93c1aeb07c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go @@ -23,7 +23,7 @@ package v1beta1 // // MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. type MatchConditionApplyConfiguration struct { - // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // name is an identifier for this match condition, used for strategic merging of MatchConditions, // as well as providing an identifier for logging purposes. A good name should be descriptive of // the associated expression. // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and @@ -33,7 +33,7 @@ type MatchConditionApplyConfiguration struct { // // Required. Name *string `json:"name,omitempty"` - // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // expression represents the expression which will be evaluated by CEL. Must evaluate to bool. // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: // // 'object' - The object from the incoming request. The value is null for DELETE requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchresources.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchresources.go index a74a65fd64..836b0a1218 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchresources.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchresources.go @@ -30,7 +30,7 @@ import ( // on whether it meets the match criteria. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) type MatchResourcesApplyConfiguration struct { - // NamespaceSelector decides whether to run the admission control policy on an object based + // namespaceSelector decides whether to run the admission control policy on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -74,7 +74,7 @@ type MatchResourcesApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *v1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the validation based on if the + // objectSelector decides whether to run the validation based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the cel validation, and // is considered to match if either object matches the selector. A null @@ -86,10 +86,10 @@ type MatchResourcesApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *v1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. // The policy cares about an operation if it matches _any_ Rule. ResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"resourceRules,omitempty"` - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) ExcludeResourceRules []NamedRuleWithOperationsApplyConfiguration `json:"excludeResourceRules,omitempty"` // matchPolicy defines how the "MatchResources" list is used to match incoming requests. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicy.go index 8812dee130..9dbdd7dbd9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicy.go @@ -33,9 +33,9 @@ import ( // MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain. type MutatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the MutatingAdmissionPolicy. + // spec defines the desired behavior of the MutatingAdmissionPolicy. Spec *MutatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go index 7ee4a731e1..560d1b1469 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go @@ -43,9 +43,9 @@ import ( // given (policy, binding, param) combination is within its own CEL budget. type MutatingAdmissionPolicyBindingApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the MutatingAdmissionPolicyBinding. + // spec defines the desired behavior of the MutatingAdmissionPolicyBinding. Spec *MutatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go index af93de8a95..d70d551d3e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go @@ -30,23 +30,23 @@ import ( // // MutatingWebhook describes an admission webhook and the resources and operations it applies to. type MutatingWebhookApplyConfiguration struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name *string `json:"name,omitempty"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. Rules []v1.RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. FailurePolicy *admissionregistrationv1beta1.FailurePolicyType `json:"failurePolicy,omitempty"` // matchPolicy defines how the "rules" list is used to match incoming requests. @@ -64,7 +64,7 @@ type MutatingWebhookApplyConfiguration struct { // // Defaults to "Exact" MatchPolicy *admissionregistrationv1beta1.MatchPolicyType `json:"matchPolicy,omitempty"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -108,7 +108,7 @@ type MutatingWebhookApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -120,20 +120,20 @@ type MutatingWebhookApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. // Requests with the dryRun attribute will be auto-rejected if they match a webhook with // sideEffects == Unknown or Some. Defaults to Unknown. SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. // Default to 30 seconds. TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -158,7 +158,7 @@ type MutatingWebhookApplyConfiguration struct { // // Defaults to "Never". ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhookconfiguration.go index d51d71a328..63bce15404 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhookconfiguration.go @@ -34,9 +34,9 @@ import ( // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead. type MutatingWebhookConfigurationApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. Webhooks []MutatingWebhookApplyConfiguration `json:"webhooks,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/namedrulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/namedrulewithoperations.go index 8b189dbb89..0da66790cc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/namedrulewithoperations.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/namedrulewithoperations.go @@ -28,7 +28,7 @@ import ( // // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. type NamedRuleWithOperationsApplyConfiguration struct { - // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. + // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. ResourceNames []string `json:"resourceNames,omitempty"` // RuleWithOperations is a tuple of Operations and Resources. v1.RuleWithOperationsApplyConfiguration `json:",inline"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramkind.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramkind.go index dbbef1b6e0..2ee21d0fc9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramkind.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramkind.go @@ -23,11 +23,11 @@ package v1beta1 // // ParamKind is a tuple of Group Kind and Version. type ParamKindApplyConfiguration struct { - // APIVersion is the API group version the resources belong to. + // apiVersion is the API group version the resources belong to. // In format of "group/version". // Required. APIVersion *string `json:"apiVersion,omitempty"` - // Kind is the API kind the resources belong to. + // kind is the API kind the resources belong to. // Required. Kind *string `json:"kind,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramref.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramref.go index 724cd1a0de..3e598a06d9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramref.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramref.go @@ -62,7 +62,7 @@ type ParamRefApplyConfiguration struct { // One of `name` or `selector` must be set, but `name` and `selector` are // mutually exclusive properties. If one is set, the other must be unset. Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - // `parameterNotFoundAction` controls the behavior of the binding when the resource + // parameterNotFoundAction controls the behavior of the binding when the resource // exists, and name or selector is valid, but there are no parameters // matched by the binding. If the value is set to `Allow`, then no // matched parameters will be treated as successful validation by the binding. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/servicereference.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/servicereference.go index 9591d48a87..b1c44013a2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/servicereference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/servicereference.go @@ -23,18 +23,18 @@ package v1beta1 // // ServiceReference holds a reference to Service.legacy.k8s.io type ServiceReferenceApplyConfiguration struct { - // `namespace` is the namespace of the service. + // namespace is the namespace of the service. // Required Namespace *string `json:"namespace,omitempty"` - // `name` is the name of the service. + // name is the name of the service. // Required Name *string `json:"name,omitempty"` - // `path` is an optional URL path which will be sent in any request to + // path is an optional URL path which will be sent in any request to // this service. Path *string `json:"path,omitempty"` - // If specified, the port on the service that hosting webhook. + // port is the port on the service that hosts the webhook. // Default to 443 for backward compatibility. - // `port` should be a valid port number (1-65535, inclusive). + // port should be a valid port number (1-65535, inclusive). Port *int32 `json:"port,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/typechecking.go index b3b26edb83..87a0ea3be6 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/typechecking.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/typechecking.go @@ -24,7 +24,7 @@ package v1beta1 // TypeChecking contains results of type checking the expressions in the // ValidatingAdmissionPolicy type TypeCheckingApplyConfiguration struct { - // The type checking warnings for each expression. + // expressionWarnings contains the type checking warnings for each expression. ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicy.go index b8eba927d3..bc1ad6473a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicy.go @@ -33,11 +33,11 @@ import ( // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. type ValidatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicy. + // spec defines the desired behavior of the ValidatingAdmissionPolicy. Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` - // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy // behaves in the expected way. // Populated by the system. // Read-only. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybinding.go index db33d910c2..fd658f9a45 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybinding.go @@ -43,9 +43,9 @@ import ( // given (policy, binding, param) combination is within its own CEL budget. type ValidatingAdmissionPolicyBindingApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding. + // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding. Spec *ValidatingAdmissionPolicyBindingSpecApplyConfiguration `json:"spec,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybindingspec.go index 7b1c0af26b..874cb907b0 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybindingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybindingspec.go @@ -27,7 +27,7 @@ import ( // // ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding. type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { - // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. + // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. // If the referenced resource does not exist, this binding is considered invalid and will be ignored // Required. PolicyName *string `json:"policyName,omitempty"` @@ -36,7 +36,7 @@ type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param. ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` - // MatchResources declares what resources match this binding and will be validated by it. + // matchResources declares what resources match this binding and will be validated by it. // Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. // If this is unset, all resources matched by the policy are validated by this binding // When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicyspec.go index 4600fb9da4..1d599eabd4 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicyspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicyspec.go @@ -27,18 +27,18 @@ import ( // // ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy. type ValidatingAdmissionPolicySpecApplyConfiguration struct { - // ParamKind specifies the kind of resources used to parameterize this policy. + // paramKind specifies the kind of resources used to parameterize this policy. // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. // If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. // If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null. ParamKind *ParamKindApplyConfiguration `json:"paramKind,omitempty"` - // MatchConstraints specifies what resources this policy is designed to validate. + // matchConstraints specifies what resources this policy is designed to validate. // The AdmissionPolicy cares about a request if it matches _all_ Constraints. // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API // ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. // Required. MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` - // Validations contain CEL expressions which is used to apply the validation. + // validations contain CEL expressions which is used to apply the validation. // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is // required. Validations []ValidationApplyConfiguration `json:"validations,omitempty"` @@ -61,7 +61,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is // required. AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be validated. + // matchConditions is a list of conditions that must be met for a request to be validated. // Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. @@ -76,7 +76,7 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { // - If failurePolicy=Fail, reject the request // - If failurePolicy=Ignore, the policy is skipped MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` - // Variables contain definitions of variables that can be used in composition of other expressions. + // variables contain definitions of variables that can be used in composition of other expressions. // Each variable is defined as a named CEL expression. // The variables defined here will be available under `variables` in other expressions of the policy // except MatchConditions because MatchConditions are evaluated before the rest of the policy. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicystatus.go index 9e05da1395..573286c146 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicystatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicystatus.go @@ -27,12 +27,12 @@ import ( // // ValidatingAdmissionPolicyStatus represents the status of an admission validation policy. type ValidatingAdmissionPolicyStatusApplyConfiguration struct { - // The generation observed by the controller. + // observedGeneration is the generation observed by the controller. ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // The results of type checking for each expression. + // typeChecking contains the results of type checking for each expression. // Presence of this field indicates the completion of the type checking. TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` - // The conditions represent the latest available observations of a policy's current state. + // conditions represent the latest available observations of a policy's current state. Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go index c3df12b87b..f50cb4668e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go @@ -29,23 +29,23 @@ import ( // // ValidatingWebhook describes an admission webhook and the resources and operations it applies to. type ValidatingWebhookApplyConfiguration struct { - // The name of the admission webhook. + // name is the name of the admission webhook. // Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where // "imagepolicy" is the name of the webhook, and kubernetes.io is the name // of the organization. // Required. Name *string `json:"name,omitempty"` - // ClientConfig defines how to communicate with the hook. + // clientConfig defines how to communicate with the hook. // Required ClientConfig *WebhookClientConfigApplyConfiguration `json:"clientConfig,omitempty"` - // Rules describes what operations on what resources/subresources the webhook cares about. + // rules describes what operations on what resources/subresources the webhook cares about. // The webhook cares about an operation if it matches _any_ Rule. // However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks // from putting the cluster in a state which cannot be recovered from without completely // disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called // on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects. Rules []v1.RuleWithOperationsApplyConfiguration `json:"rules,omitempty"` - // FailurePolicy defines how unrecognized errors from the admission endpoint are handled - + // failurePolicy defines how unrecognized errors from the admission endpoint are handled - // allowed values are Ignore or Fail. Defaults to Ignore. FailurePolicy *admissionregistrationv1beta1.FailurePolicyType `json:"failurePolicy,omitempty"` // matchPolicy defines how the "rules" list is used to match incoming requests. @@ -63,7 +63,7 @@ type ValidatingWebhookApplyConfiguration struct { // // Defaults to "Exact" MatchPolicy *admissionregistrationv1beta1.MatchPolicyType `json:"matchPolicy,omitempty"` - // NamespaceSelector decides whether to run the webhook on an object based + // namespaceSelector decides whether to run the webhook on an object based // on whether the namespace for that object matches the selector. If the // object itself is a namespace, the matching is performed on // object.metadata.labels. If the object is another cluster scoped resource, @@ -107,7 +107,7 @@ type ValidatingWebhookApplyConfiguration struct { // // Default to the empty LabelSelector, which matches everything. NamespaceSelector *metav1.LabelSelectorApplyConfiguration `json:"namespaceSelector,omitempty"` - // ObjectSelector decides whether to run the webhook based on if the + // objectSelector decides whether to run the webhook based on if the // object has matching labels. objectSelector is evaluated against both // the oldObject and newObject that would be sent to the webhook, and // is considered to match if either object matches the selector. A null @@ -119,20 +119,20 @@ type ValidatingWebhookApplyConfiguration struct { // users may skip the admission webhook by setting the labels. // Default to the empty LabelSelector, which matches everything. ObjectSelector *metav1.LabelSelectorApplyConfiguration `json:"objectSelector,omitempty"` - // SideEffects states whether this webhook has side effects. + // sideEffects states whether this webhook has side effects. // Acceptable values are: Unknown, None, Some, NoneOnDryRun // Webhooks with side effects MUST implement a reconciliation system, since a request may be // rejected by a future step in the admission chain and the side effects therefore need to be undone. // Requests with the dryRun attribute will be auto-rejected if they match a webhook with // sideEffects == Unknown or Some. Defaults to Unknown. SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` - // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, + // timeoutSeconds specifies the timeout for this webhook. After the timeout passes, // the webhook call will be ignored or the API call will fail based on the // failure policy. // The timeout value must be between 1 and 30 seconds. // Default to 30 seconds. TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` + // admissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. API server will try to use first version in // the list which it supports. If none of the versions specified in this list // supported by API server, validation will fail for this object. @@ -141,7 +141,7 @@ type ValidatingWebhookApplyConfiguration struct { // and be subject to the failure policy. // Default to `['v1beta1']`. AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` - // MatchConditions is a list of conditions that must be met for a request to be sent to this + // matchConditions is a list of conditions that must be met for a request to be sent to this // webhook. Match conditions filter requests that have already been matched by the rules, // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. // There are a maximum of 64 match conditions allowed. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhookconfiguration.go index 66b74b31d8..dd53f3b334 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhookconfiguration.go @@ -34,9 +34,9 @@ import ( // Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead. type ValidatingWebhookConfigurationApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Webhooks is a list of webhooks and the affected resources and operations. + // webhooks is a list of webhooks and the affected resources and operations. Webhooks []ValidatingWebhookApplyConfiguration `json:"webhooks,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validation.go index 6505b8b498..47ccf0f316 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validation.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validation.go @@ -27,7 +27,7 @@ import ( // // Validation specifies the CEL expression which is used to apply the validation. type ValidationApplyConfiguration struct { - // Expression represents the expression which will be evaluated by CEL. + // expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // @@ -69,7 +69,7 @@ type ValidationApplyConfiguration struct { // non-intersecting keys are appended, retaining their partial order. // Required. Expression *string `json:"expression,omitempty"` - // Message represents the message displayed when validation fails. The message is required if the Expression contains + // message represents the message displayed when validation fails. The message is required if the Expression contains // line breaks. The message must not contain line breaks. // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" @@ -77,7 +77,7 @@ type ValidationApplyConfiguration struct { // The message must not contain line breaks. // If unset, the message is "failed Expression: {Expression}". Message *string `json:"message,omitempty"` - // Reason represents a machine-readable description of why this validation failed. + // reason represents a machine-readable description of why this validation failed. // If this is the first validation in the list to fail, this reason, as well as the // corresponding HTTP response code, are used in the // HTTP response to the client. diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/variable.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/variable.go index db334f2265..0419a986ca 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/variable.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/variable.go @@ -23,11 +23,11 @@ package v1beta1 // // Variable is the definition of a variable that is used for composition. A variable is defined as a named expression. type VariableApplyConfiguration struct { - // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. + // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. // The variable can be accessed in other expressions through `variables` // For example, if name is "foo", the variable will be available as `variables.foo` Name *string `json:"name,omitempty"` - // Expression is the expression that will be evaluated as the value of the variable. + // expression is the expression that will be evaluated as the value of the variable. // The CEL expression has access to the same identifiers as the CEL expressions in Validation. Expression *string `json:"expression,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/webhookclientconfig.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/webhookclientconfig.go index 593ff43ebf..6710952156 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/webhookclientconfig.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/webhookclientconfig.go @@ -24,7 +24,7 @@ package v1beta1 // WebhookClientConfig contains the information to make a TLS // connection with the webhook type WebhookClientConfigApplyConfiguration struct { - // `url` gives the location of the webhook, in standard URL form + // url gives the location of the webhook, in standard URL form // (`scheme://host:port/path`). Exactly one of `url` or `service` // must be specified. // @@ -50,12 +50,12 @@ type WebhookClientConfigApplyConfiguration struct { // allowed. Fragments ("#...") and query parameters ("?...") are not // allowed, either. URL *string `json:"url,omitempty"` - // `service` is a reference to the service for this webhook. Either + // service is a reference to the service for this webhook. Either // `service` or `url` must be specified. // // If the webhook is running within the cluster, then you should use `service`. Service *ServiceReferenceApplyConfiguration `json:"service,omitempty"` - // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. // If unspecified, system trust roots on the apiserver are used. CABundle []byte `json:"caBundle,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/serverstorageversion.go b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/serverstorageversion.go index 94379ddc5a..5d6e1446fc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/serverstorageversion.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/serverstorageversion.go @@ -24,15 +24,16 @@ package v1alpha1 // An API server instance reports the version it can decode and the version it // encodes objects to when persisting objects in the backend. type ServerStorageVersionApplyConfiguration struct { - // The ID of the reporting API server. + // apiServerID is the ID of the reporting API server. APIServerID *string `json:"apiServerID,omitempty"` - // The API server encodes the object to this version when persisting it in + // encodingVersion the API server encodes the object to when persisting it in // the backend (e.g., etcd). EncodingVersion *string `json:"encodingVersion,omitempty"` + // decodableVersions are the encoding versions the API server can handle to decode. // The API server can decode objects encoded in these versions. // The encodingVersion must be included in the decodableVersions. DecodableVersions []string `json:"decodableVersions,omitempty"` - // The API server can serve these versions. + // servedVersions lists all versions the API server can serve. // DecodableVersions must include all ServedVersions. ServedVersions []string `json:"servedVersions,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversion.go b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversion.go index e9f41cc277..46b2349b1d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversion.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversion.go @@ -33,11 +33,12 @@ import ( // Storage version of a specific resource. type StorageVersionApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object metadata. // The name is .. *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // Spec is an empty spec. It is here to comply with Kubernetes API style. + // spec is an empty spec. It is here to comply with Kubernetes API style. Spec *apiserverinternalv1alpha1.StorageVersionSpec `json:"spec,omitempty"` - // API server instances report the version they can decode and the version they + // status on the version the API server instance can decode from and // encode objects to when persisting objects in the backend. Status *StorageVersionStatusApplyConfiguration `json:"status,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversioncondition.go b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversioncondition.go index 84752a4599..c78cd9affe 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversioncondition.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversioncondition.go @@ -28,17 +28,17 @@ import ( // // Describes the state of the storageVersion at a certain point. type StorageVersionConditionApplyConfiguration struct { - // Type of the condition. + // type of the condition. Type *apiserverinternalv1alpha1.StorageVersionConditionType `json:"type,omitempty"` - // Status of the condition, one of True, False, Unknown. + // status of the condition, one of True, False, Unknown. Status *apiserverinternalv1alpha1.ConditionStatus `json:"status,omitempty"` - // If set, this represents the .metadata.generation that the condition was set based upon. + // observedGeneration represents the .metadata.generation that the condition was set based upon, if field is set. ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // Last time the condition transitioned from one status to another. + // lastTransitionTime is the last time the condition transitioned from one status to another. LastTransitionTime *v1.Time `json:"lastTransitionTime,omitempty"` - // The reason for the condition's last transition. + // reason for the condition's last transition. Reason *string `json:"reason,omitempty"` - // A human readable message indicating details about the transition. + // message is a human readable string indicating details about the transition. Message *string `json:"message,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversionstatus.go b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversionstatus.go index 00a71ad5a2..a24c66e245 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversionstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1/storageversionstatus.go @@ -24,14 +24,15 @@ package v1alpha1 // API server instances report the versions they can decode and the version they // encode objects to when persisting objects in the backend. type StorageVersionStatusApplyConfiguration struct { - // The reported versions per API server instance. + // storageVersions lists the reported versions per API server instance. StorageVersions []ServerStorageVersionApplyConfiguration `json:"storageVersions,omitempty"` - // If all API server instances agree on the same encoding storage version, - // then this field is set to that version. Otherwise this field is left empty. + // commonEncodingVersion is set to an encoding storage version if all API server + // instances share that same version. If they don't share one storage version, this + // field is left empty. // API servers should finish updating its storageVersionStatus entry before // serving write operations, so that this field will be in sync with the reality. CommonEncodingVersion *string `json:"commonEncodingVersion,omitempty"` - // The latest available observations of the storageVersion's state. + // conditions lists the latest available observations of the storageVersion's state. Conditions []StorageVersionConditionApplyConfiguration `json:"conditions,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricsource.go deleted file mode 100644 index 392e491cf9..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricsource.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// ContainerResourceMetricSourceApplyConfiguration represents a declarative configuration of the ContainerResourceMetricSource type for use -// with apply. -// -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ContainerResourceMetricSourceApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty"` - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty"` - // container is the name of the container in the pods of the scaling target - Container *string `json:"container,omitempty"` -} - -// ContainerResourceMetricSourceApplyConfiguration constructs a declarative configuration of the ContainerResourceMetricSource type for use with -// apply. -func ContainerResourceMetricSource() *ContainerResourceMetricSourceApplyConfiguration { - return &ContainerResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *ContainerResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTargetAverageUtilization sets the TargetAverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageUtilization field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithTargetAverageUtilization(value int32) *ContainerResourceMetricSourceApplyConfiguration { - b.TargetAverageUtilization = &value - return b -} - -// WithTargetAverageValue sets the TargetAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageValue field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithTargetAverageValue(value resource.Quantity) *ContainerResourceMetricSourceApplyConfiguration { - b.TargetAverageValue = &value - return b -} - -// WithContainer sets the Container field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Container field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithContainer(value string) *ContainerResourceMetricSourceApplyConfiguration { - b.Container = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricstatus.go deleted file mode 100644 index e69d2bad8a..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/containerresourcemetricstatus.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// ContainerResourceMetricStatusApplyConfiguration represents a declarative configuration of the ContainerResourceMetricStatus type for use -// with apply. -// -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ContainerResourceMetricStatusApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty"` - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty"` - // container is the name of the container in the pods of the scaling target - Container *string `json:"container,omitempty"` -} - -// ContainerResourceMetricStatusApplyConfiguration constructs a declarative configuration of the ContainerResourceMetricStatus type for use with -// apply. -func ContainerResourceMetricStatus() *ContainerResourceMetricStatusApplyConfiguration { - return &ContainerResourceMetricStatusApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithName(value v1.ResourceName) *ContainerResourceMetricStatusApplyConfiguration { - b.Name = &value - return b -} - -// WithCurrentAverageUtilization sets the CurrentAverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageUtilization field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithCurrentAverageUtilization(value int32) *ContainerResourceMetricStatusApplyConfiguration { - b.CurrentAverageUtilization = &value - return b -} - -// WithCurrentAverageValue sets the CurrentAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageValue field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithCurrentAverageValue(value resource.Quantity) *ContainerResourceMetricStatusApplyConfiguration { - b.CurrentAverageValue = &value - return b -} - -// WithContainer sets the Container field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Container field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithContainer(value string) *ContainerResourceMetricStatusApplyConfiguration { - b.Container = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/crossversionobjectreference.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/crossversionobjectreference.go deleted file mode 100644 index 40c8e450f5..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/crossversionobjectreference.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -// CrossVersionObjectReferenceApplyConfiguration represents a declarative configuration of the CrossVersionObjectReference type for use -// with apply. -// -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -type CrossVersionObjectReferenceApplyConfiguration struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - Kind *string `json:"kind,omitempty"` - // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - Name *string `json:"name,omitempty"` - // API version of the referent - APIVersion *string `json:"apiVersion,omitempty"` -} - -// CrossVersionObjectReferenceApplyConfiguration constructs a declarative configuration of the CrossVersionObjectReference type for use with -// apply. -func CrossVersionObjectReference() *CrossVersionObjectReferenceApplyConfiguration { - return &CrossVersionObjectReferenceApplyConfiguration{} -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithKind(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.Kind = &value - return b -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithName(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.Name = &value - return b -} - -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithAPIVersion(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.APIVersion = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricsource.go deleted file mode 100644 index 3b07217257..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricsource.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// ExternalMetricSourceApplyConfiguration represents a declarative configuration of the ExternalMetricSource type for use -// with apply. -// -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -// Exactly one "target" type should be set. -type ExternalMetricSourceApplyConfiguration struct { - // metricName is the name of the metric in question. - MetricName *string `json:"metricName,omitempty"` - // metricSelector is used to identify a specific time series - // within a given metric. - MetricSelector *v1.LabelSelectorApplyConfiguration `json:"metricSelector,omitempty"` - // targetValue is the target value of the metric (as a quantity). - // Mutually exclusive with TargetAverageValue. - TargetValue *resource.Quantity `json:"targetValue,omitempty"` - // targetAverageValue is the target per-pod value of global metric (as a quantity). - // Mutually exclusive with TargetValue. - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty"` -} - -// ExternalMetricSourceApplyConfiguration constructs a declarative configuration of the ExternalMetricSource type for use with -// apply. -func ExternalMetricSource() *ExternalMetricSourceApplyConfiguration { - return &ExternalMetricSourceApplyConfiguration{} -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithMetricName(value string) *ExternalMetricSourceApplyConfiguration { - b.MetricName = &value - return b -} - -// WithMetricSelector sets the MetricSelector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricSelector field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithMetricSelector(value *v1.LabelSelectorApplyConfiguration) *ExternalMetricSourceApplyConfiguration { - b.MetricSelector = value - return b -} - -// WithTargetValue sets the TargetValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetValue field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithTargetValue(value resource.Quantity) *ExternalMetricSourceApplyConfiguration { - b.TargetValue = &value - return b -} - -// WithTargetAverageValue sets the TargetAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageValue field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithTargetAverageValue(value resource.Quantity) *ExternalMetricSourceApplyConfiguration { - b.TargetAverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricstatus.go deleted file mode 100644 index c7e3629a9a..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/externalmetricstatus.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// ExternalMetricStatusApplyConfiguration represents a declarative configuration of the ExternalMetricStatus type for use -// with apply. -// -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -type ExternalMetricStatusApplyConfiguration struct { - // metricName is the name of a metric used for autoscaling in - // metric system. - MetricName *string `json:"metricName,omitempty"` - // metricSelector is used to identify a specific time series - // within a given metric. - MetricSelector *v1.LabelSelectorApplyConfiguration `json:"metricSelector,omitempty"` - // currentValue is the current value of the metric (as a quantity) - CurrentValue *resource.Quantity `json:"currentValue,omitempty"` - // currentAverageValue is the current value of metric averaged over autoscaled pods. - CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty"` -} - -// ExternalMetricStatusApplyConfiguration constructs a declarative configuration of the ExternalMetricStatus type for use with -// apply. -func ExternalMetricStatus() *ExternalMetricStatusApplyConfiguration { - return &ExternalMetricStatusApplyConfiguration{} -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithMetricName(value string) *ExternalMetricStatusApplyConfiguration { - b.MetricName = &value - return b -} - -// WithMetricSelector sets the MetricSelector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricSelector field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithMetricSelector(value *v1.LabelSelectorApplyConfiguration) *ExternalMetricStatusApplyConfiguration { - b.MetricSelector = value - return b -} - -// WithCurrentValue sets the CurrentValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentValue field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithCurrentValue(value resource.Quantity) *ExternalMetricStatusApplyConfiguration { - b.CurrentValue = &value - return b -} - -// WithCurrentAverageValue sets the CurrentAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageValue field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithCurrentAverageValue(value resource.Quantity) *ExternalMetricStatusApplyConfiguration { - b.CurrentAverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalercondition.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalercondition.go deleted file mode 100644 index 302df35a73..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalercondition.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// HorizontalPodAutoscalerConditionApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerCondition type for use -// with apply. -// -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -type HorizontalPodAutoscalerConditionApplyConfiguration struct { - // type describes the current condition - Type *autoscalingv2beta1.HorizontalPodAutoscalerConditionType `json:"type,omitempty"` - // status is the status of the condition (True, False, Unknown) - Status *v1.ConditionStatus `json:"status,omitempty"` - // lastTransitionTime is the last time the condition transitioned from - // one status to another - LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"` - // reason is the reason for the condition's last transition. - Reason *string `json:"reason,omitempty"` - // message is a human-readable explanation containing details about - // the transition - Message *string `json:"message,omitempty"` -} - -// HorizontalPodAutoscalerConditionApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerCondition type for use with -// apply. -func HorizontalPodAutoscalerCondition() *HorizontalPodAutoscalerConditionApplyConfiguration { - return &HorizontalPodAutoscalerConditionApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithType(value autoscalingv2beta1.HorizontalPodAutoscalerConditionType) *HorizontalPodAutoscalerConditionApplyConfiguration { - b.Type = &value - return b -} - -// WithStatus sets the Status field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Status field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithStatus(value v1.ConditionStatus) *HorizontalPodAutoscalerConditionApplyConfiguration { - b.Status = &value - return b -} - -// WithLastTransitionTime sets the LastTransitionTime field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the LastTransitionTime field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithLastTransitionTime(value metav1.Time) *HorizontalPodAutoscalerConditionApplyConfiguration { - b.LastTransitionTime = &value - return b -} - -// WithReason sets the Reason field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Reason field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithReason(value string) *HorizontalPodAutoscalerConditionApplyConfiguration { - b.Reason = &value - return b -} - -// WithMessage sets the Message field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Message field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithMessage(value string) *HorizontalPodAutoscalerConditionApplyConfiguration { - b.Message = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerspec.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerspec.go deleted file mode 100644 index bbe6a8febf..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerspec.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -// HorizontalPodAutoscalerSpecApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerSpec type for use -// with apply. -// -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -type HorizontalPodAutoscalerSpecApplyConfiguration struct { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - ScaleTargetRef *CrossVersionObjectReferenceApplyConfiguration `json:"scaleTargetRef,omitempty"` - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - MinReplicas *int32 `json:"minReplicas,omitempty"` - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - MaxReplicas *int32 `json:"maxReplicas,omitempty"` - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - Metrics []MetricSpecApplyConfiguration `json:"metrics,omitempty"` -} - -// HorizontalPodAutoscalerSpecApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerSpec type for use with -// apply. -func HorizontalPodAutoscalerSpec() *HorizontalPodAutoscalerSpecApplyConfiguration { - return &HorizontalPodAutoscalerSpecApplyConfiguration{} -} - -// WithScaleTargetRef sets the ScaleTargetRef field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ScaleTargetRef field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithScaleTargetRef(value *CrossVersionObjectReferenceApplyConfiguration) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.ScaleTargetRef = value - return b -} - -// WithMinReplicas sets the MinReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MinReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMinReplicas(value int32) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.MinReplicas = &value - return b -} - -// WithMaxReplicas sets the MaxReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MaxReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMaxReplicas(value int32) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.MaxReplicas = &value - return b -} - -// WithMetrics adds the given value to the Metrics field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Metrics field. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMetrics(values ...*MetricSpecApplyConfiguration) *HorizontalPodAutoscalerSpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithMetrics") - } - b.Metrics = append(b.Metrics, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerstatus.go deleted file mode 100644 index 831ad5cf6f..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscalerstatus.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// HorizontalPodAutoscalerStatusApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerStatus type for use -// with apply. -// -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -type HorizontalPodAutoscalerStatusApplyConfiguration struct { - // observedGeneration is the most recent generation observed by this autoscaler. - ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - LastScaleTime *v1.Time `json:"lastScaleTime,omitempty"` - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - CurrentReplicas *int32 `json:"currentReplicas,omitempty"` - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - DesiredReplicas *int32 `json:"desiredReplicas,omitempty"` - // currentMetrics is the last read state of the metrics used by this autoscaler. - CurrentMetrics []MetricStatusApplyConfiguration `json:"currentMetrics,omitempty"` - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - Conditions []HorizontalPodAutoscalerConditionApplyConfiguration `json:"conditions,omitempty"` -} - -// HorizontalPodAutoscalerStatusApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerStatus type for use with -// apply. -func HorizontalPodAutoscalerStatus() *HorizontalPodAutoscalerStatusApplyConfiguration { - return &HorizontalPodAutoscalerStatusApplyConfiguration{} -} - -// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ObservedGeneration field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithObservedGeneration(value int64) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.ObservedGeneration = &value - return b -} - -// WithLastScaleTime sets the LastScaleTime field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the LastScaleTime field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithLastScaleTime(value v1.Time) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.LastScaleTime = &value - return b -} - -// WithCurrentReplicas sets the CurrentReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithCurrentReplicas(value int32) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.CurrentReplicas = &value - return b -} - -// WithDesiredReplicas sets the DesiredReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DesiredReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithDesiredReplicas(value int32) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.DesiredReplicas = &value - return b -} - -// WithCurrentMetrics adds the given value to the CurrentMetrics field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the CurrentMetrics field. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithCurrentMetrics(values ...*MetricStatusApplyConfiguration) *HorizontalPodAutoscalerStatusApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithCurrentMetrics") - } - b.CurrentMetrics = append(b.CurrentMetrics, *values[i]) - } - return b -} - -// WithConditions adds the given value to the Conditions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Conditions field. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithConditions(values ...*HorizontalPodAutoscalerConditionApplyConfiguration) *HorizontalPodAutoscalerStatusApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithConditions") - } - b.Conditions = append(b.Conditions, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricspec.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricspec.go deleted file mode 100644 index d48043c322..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricspec.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" -) - -// MetricSpecApplyConfiguration represents a declarative configuration of the MetricSpec type for use -// with apply. -// -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -type MetricSpecApplyConfiguration struct { - // type is the type of metric source. It should be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each mapping to a matching field in the object. - Type *autoscalingv2beta1.MetricSourceType `json:"type,omitempty"` - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - Object *ObjectMetricSourceApplyConfiguration `json:"object,omitempty"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - Pods *PodsMetricSourceApplyConfiguration `json:"pods,omitempty"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - Resource *ResourceMetricSourceApplyConfiguration `json:"resource,omitempty"` - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - ContainerResource *ContainerResourceMetricSourceApplyConfiguration `json:"containerResource,omitempty"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - External *ExternalMetricSourceApplyConfiguration `json:"external,omitempty"` -} - -// MetricSpecApplyConfiguration constructs a declarative configuration of the MetricSpec type for use with -// apply. -func MetricSpec() *MetricSpecApplyConfiguration { - return &MetricSpecApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithType(value autoscalingv2beta1.MetricSourceType) *MetricSpecApplyConfiguration { - b.Type = &value - return b -} - -// WithObject sets the Object field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Object field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithObject(value *ObjectMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Object = value - return b -} - -// WithPods sets the Pods field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Pods field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithPods(value *PodsMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Pods = value - return b -} - -// WithResource sets the Resource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Resource field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithResource(value *ResourceMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Resource = value - return b -} - -// WithContainerResource sets the ContainerResource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ContainerResource field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithContainerResource(value *ContainerResourceMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.ContainerResource = value - return b -} - -// WithExternal sets the External field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the External field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithExternal(value *ExternalMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.External = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricstatus.go deleted file mode 100644 index 7ec38582de..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/metricstatus.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" -) - -// MetricStatusApplyConfiguration represents a declarative configuration of the MetricStatus type for use -// with apply. -// -// MetricStatus describes the last-read state of a single metric. -type MetricStatusApplyConfiguration struct { - // type is the type of metric source. It will be one of "ContainerResource", - // "External", "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - Type *autoscalingv2beta1.MetricSourceType `json:"type,omitempty"` - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - Object *ObjectMetricStatusApplyConfiguration `json:"object,omitempty"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - Pods *PodsMetricStatusApplyConfiguration `json:"pods,omitempty"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - Resource *ResourceMetricStatusApplyConfiguration `json:"resource,omitempty"` - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - ContainerResource *ContainerResourceMetricStatusApplyConfiguration `json:"containerResource,omitempty"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - External *ExternalMetricStatusApplyConfiguration `json:"external,omitempty"` -} - -// MetricStatusApplyConfiguration constructs a declarative configuration of the MetricStatus type for use with -// apply. -func MetricStatus() *MetricStatusApplyConfiguration { - return &MetricStatusApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithType(value autoscalingv2beta1.MetricSourceType) *MetricStatusApplyConfiguration { - b.Type = &value - return b -} - -// WithObject sets the Object field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Object field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithObject(value *ObjectMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Object = value - return b -} - -// WithPods sets the Pods field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Pods field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithPods(value *PodsMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Pods = value - return b -} - -// WithResource sets the Resource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Resource field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithResource(value *ResourceMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Resource = value - return b -} - -// WithContainerResource sets the ContainerResource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ContainerResource field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithContainerResource(value *ContainerResourceMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.ContainerResource = value - return b -} - -// WithExternal sets the External field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the External field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithExternal(value *ExternalMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.External = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricsource.go deleted file mode 100644 index 103280e268..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricsource.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// ObjectMetricSourceApplyConfiguration represents a declarative configuration of the ObjectMetricSource type for use -// with apply. -// -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricSourceApplyConfiguration struct { - // target is the described Kubernetes object. - Target *CrossVersionObjectReferenceApplyConfiguration `json:"target,omitempty"` - // metricName is the name of the metric in question. - MetricName *string `json:"metricName,omitempty"` - // targetValue is the target value of the metric (as a quantity). - TargetValue *resource.Quantity `json:"targetValue,omitempty"` - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - AverageValue *resource.Quantity `json:"averageValue,omitempty"` -} - -// ObjectMetricSourceApplyConfiguration constructs a declarative configuration of the ObjectMetricSource type for use with -// apply. -func ObjectMetricSource() *ObjectMetricSourceApplyConfiguration { - return &ObjectMetricSourceApplyConfiguration{} -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithTarget(value *CrossVersionObjectReferenceApplyConfiguration) *ObjectMetricSourceApplyConfiguration { - b.Target = value - return b -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithMetricName(value string) *ObjectMetricSourceApplyConfiguration { - b.MetricName = &value - return b -} - -// WithTargetValue sets the TargetValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetValue field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithTargetValue(value resource.Quantity) *ObjectMetricSourceApplyConfiguration { - b.TargetValue = &value - return b -} - -// WithSelector sets the Selector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Selector field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *ObjectMetricSourceApplyConfiguration { - b.Selector = value - return b -} - -// WithAverageValue sets the AverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageValue field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithAverageValue(value resource.Quantity) *ObjectMetricSourceApplyConfiguration { - b.AverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricstatus.go deleted file mode 100644 index b58d0e28db..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/objectmetricstatus.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// ObjectMetricStatusApplyConfiguration represents a declarative configuration of the ObjectMetricStatus type for use -// with apply. -// -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricStatusApplyConfiguration struct { - // target is the described Kubernetes object. - Target *CrossVersionObjectReferenceApplyConfiguration `json:"target,omitempty"` - // metricName is the name of the metric in question. - MetricName *string `json:"metricName,omitempty"` - // currentValue is the current value of the metric (as a quantity). - CurrentValue *resource.Quantity `json:"currentValue,omitempty"` - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the ObjectMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - AverageValue *resource.Quantity `json:"averageValue,omitempty"` -} - -// ObjectMetricStatusApplyConfiguration constructs a declarative configuration of the ObjectMetricStatus type for use with -// apply. -func ObjectMetricStatus() *ObjectMetricStatusApplyConfiguration { - return &ObjectMetricStatusApplyConfiguration{} -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithTarget(value *CrossVersionObjectReferenceApplyConfiguration) *ObjectMetricStatusApplyConfiguration { - b.Target = value - return b -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithMetricName(value string) *ObjectMetricStatusApplyConfiguration { - b.MetricName = &value - return b -} - -// WithCurrentValue sets the CurrentValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentValue field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithCurrentValue(value resource.Quantity) *ObjectMetricStatusApplyConfiguration { - b.CurrentValue = &value - return b -} - -// WithSelector sets the Selector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Selector field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *ObjectMetricStatusApplyConfiguration { - b.Selector = value - return b -} - -// WithAverageValue sets the AverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageValue field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithAverageValue(value resource.Quantity) *ObjectMetricStatusApplyConfiguration { - b.AverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricsource.go deleted file mode 100644 index 47ceaee50b..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricsource.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// PodsMetricSourceApplyConfiguration represents a declarative configuration of the PodsMetricSource type for use -// with apply. -// -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -type PodsMetricSourceApplyConfiguration struct { - // metricName is the name of the metric in question - MetricName *string `json:"metricName,omitempty"` - // targetAverageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty"` - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping - // When unset, just the metricName will be used to gather metrics. - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` -} - -// PodsMetricSourceApplyConfiguration constructs a declarative configuration of the PodsMetricSource type for use with -// apply. -func PodsMetricSource() *PodsMetricSourceApplyConfiguration { - return &PodsMetricSourceApplyConfiguration{} -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *PodsMetricSourceApplyConfiguration) WithMetricName(value string) *PodsMetricSourceApplyConfiguration { - b.MetricName = &value - return b -} - -// WithTargetAverageValue sets the TargetAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageValue field is set to the value of the last call. -func (b *PodsMetricSourceApplyConfiguration) WithTargetAverageValue(value resource.Quantity) *PodsMetricSourceApplyConfiguration { - b.TargetAverageValue = &value - return b -} - -// WithSelector sets the Selector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Selector field is set to the value of the last call. -func (b *PodsMetricSourceApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *PodsMetricSourceApplyConfiguration { - b.Selector = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricstatus.go deleted file mode 100644 index 140f0a2292..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/podsmetricstatus.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// PodsMetricStatusApplyConfiguration represents a declarative configuration of the PodsMetricStatus type for use -// with apply. -// -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -type PodsMetricStatusApplyConfiguration struct { - // metricName is the name of the metric in question - MetricName *string `json:"metricName,omitempty"` - // currentAverageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty"` - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set in the PodsMetricSource, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` -} - -// PodsMetricStatusApplyConfiguration constructs a declarative configuration of the PodsMetricStatus type for use with -// apply. -func PodsMetricStatus() *PodsMetricStatusApplyConfiguration { - return &PodsMetricStatusApplyConfiguration{} -} - -// WithMetricName sets the MetricName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MetricName field is set to the value of the last call. -func (b *PodsMetricStatusApplyConfiguration) WithMetricName(value string) *PodsMetricStatusApplyConfiguration { - b.MetricName = &value - return b -} - -// WithCurrentAverageValue sets the CurrentAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageValue field is set to the value of the last call. -func (b *PodsMetricStatusApplyConfiguration) WithCurrentAverageValue(value resource.Quantity) *PodsMetricStatusApplyConfiguration { - b.CurrentAverageValue = &value - return b -} - -// WithSelector sets the Selector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Selector field is set to the value of the last call. -func (b *PodsMetricStatusApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *PodsMetricStatusApplyConfiguration { - b.Selector = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricsource.go deleted file mode 100644 index 0c3c849e3c..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricsource.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// ResourceMetricSourceApplyConfiguration represents a declarative configuration of the ResourceMetricSource type for use -// with apply. -// -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ResourceMetricSourceApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // targetAverageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty"` - // targetAverageValue is the target value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty"` -} - -// ResourceMetricSourceApplyConfiguration constructs a declarative configuration of the ResourceMetricSource type for use with -// apply. -func ResourceMetricSource() *ResourceMetricSourceApplyConfiguration { - return &ResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *ResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTargetAverageUtilization sets the TargetAverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageUtilization field is set to the value of the last call. -func (b *ResourceMetricSourceApplyConfiguration) WithTargetAverageUtilization(value int32) *ResourceMetricSourceApplyConfiguration { - b.TargetAverageUtilization = &value - return b -} - -// WithTargetAverageValue sets the TargetAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the TargetAverageValue field is set to the value of the last call. -func (b *ResourceMetricSourceApplyConfiguration) WithTargetAverageValue(value resource.Quantity) *ResourceMetricSourceApplyConfiguration { - b.TargetAverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricstatus.go deleted file mode 100644 index 61db2eae0d..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/resourcemetricstatus.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta1 - -import ( - v1 "k8s.io/api/core/v1" - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// ResourceMetricStatusApplyConfiguration represents a declarative configuration of the ResourceMetricStatus type for use -// with apply. -// -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ResourceMetricStatusApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // currentAverageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. It will only be - // present if `targetAverageValue` was set in the corresponding metric - // specification. - CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty"` - // currentAverageValue is the current value of the average of the - // resource metric across all relevant pods, as a raw value (instead of as - // a percentage of the request), similar to the "pods" metric source type. - // It will always be set, regardless of the corresponding metric specification. - CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty"` -} - -// ResourceMetricStatusApplyConfiguration constructs a declarative configuration of the ResourceMetricStatus type for use with -// apply. -func ResourceMetricStatus() *ResourceMetricStatusApplyConfiguration { - return &ResourceMetricStatusApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ResourceMetricStatusApplyConfiguration) WithName(value v1.ResourceName) *ResourceMetricStatusApplyConfiguration { - b.Name = &value - return b -} - -// WithCurrentAverageUtilization sets the CurrentAverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageUtilization field is set to the value of the last call. -func (b *ResourceMetricStatusApplyConfiguration) WithCurrentAverageUtilization(value int32) *ResourceMetricStatusApplyConfiguration { - b.CurrentAverageUtilization = &value - return b -} - -// WithCurrentAverageValue sets the CurrentAverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentAverageValue field is set to the value of the last call. -func (b *ResourceMetricStatusApplyConfiguration) WithCurrentAverageValue(value resource.Quantity) *ResourceMetricStatusApplyConfiguration { - b.CurrentAverageValue = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricsource.go deleted file mode 100644 index babb8e8bb0..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricsource.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// ContainerResourceMetricSourceApplyConfiguration represents a declarative configuration of the ContainerResourceMetricSource type for use -// with apply. -// -// ContainerResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ContainerResourceMetricSourceApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // target specifies the target value for the given metric - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` - // container is the name of the container in the pods of the scaling target - Container *string `json:"container,omitempty"` -} - -// ContainerResourceMetricSourceApplyConfiguration constructs a declarative configuration of the ContainerResourceMetricSource type for use with -// apply. -func ContainerResourceMetricSource() *ContainerResourceMetricSourceApplyConfiguration { - return &ContainerResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *ContainerResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *ContainerResourceMetricSourceApplyConfiguration { - b.Target = value - return b -} - -// WithContainer sets the Container field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Container field is set to the value of the last call. -func (b *ContainerResourceMetricSourceApplyConfiguration) WithContainer(value string) *ContainerResourceMetricSourceApplyConfiguration { - b.Container = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricstatus.go deleted file mode 100644 index 771e9fdfcf..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/containerresourcemetricstatus.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// ContainerResourceMetricStatusApplyConfiguration represents a declarative configuration of the ContainerResourceMetricStatus type for use -// with apply. -// -// ContainerResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing a single container in each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ContainerResourceMetricStatusApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // current contains the current value for the given metric - Current *MetricValueStatusApplyConfiguration `json:"current,omitempty"` - // container is the name of the container in the pods of the scaling target - Container *string `json:"container,omitempty"` -} - -// ContainerResourceMetricStatusApplyConfiguration constructs a declarative configuration of the ContainerResourceMetricStatus type for use with -// apply. -func ContainerResourceMetricStatus() *ContainerResourceMetricStatusApplyConfiguration { - return &ContainerResourceMetricStatusApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithName(value v1.ResourceName) *ContainerResourceMetricStatusApplyConfiguration { - b.Name = &value - return b -} - -// WithCurrent sets the Current field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Current field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithCurrent(value *MetricValueStatusApplyConfiguration) *ContainerResourceMetricStatusApplyConfiguration { - b.Current = value - return b -} - -// WithContainer sets the Container field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Container field is set to the value of the last call. -func (b *ContainerResourceMetricStatusApplyConfiguration) WithContainer(value string) *ContainerResourceMetricStatusApplyConfiguration { - b.Container = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/crossversionobjectreference.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/crossversionobjectreference.go deleted file mode 100644 index df6708a19d..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/crossversionobjectreference.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// CrossVersionObjectReferenceApplyConfiguration represents a declarative configuration of the CrossVersionObjectReference type for use -// with apply. -// -// CrossVersionObjectReference contains enough information to let you identify the referred resource. -type CrossVersionObjectReferenceApplyConfiguration struct { - // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - Kind *string `json:"kind,omitempty"` - // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - Name *string `json:"name,omitempty"` - // apiVersion is the API version of the referent - APIVersion *string `json:"apiVersion,omitempty"` -} - -// CrossVersionObjectReferenceApplyConfiguration constructs a declarative configuration of the CrossVersionObjectReference type for use with -// apply. -func CrossVersionObjectReference() *CrossVersionObjectReferenceApplyConfiguration { - return &CrossVersionObjectReferenceApplyConfiguration{} -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithKind(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.Kind = &value - return b -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithName(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.Name = &value - return b -} - -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *CrossVersionObjectReferenceApplyConfiguration) WithAPIVersion(value string) *CrossVersionObjectReferenceApplyConfiguration { - b.APIVersion = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricsource.go deleted file mode 100644 index 6baca7f05d..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricsource.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// ExternalMetricSourceApplyConfiguration represents a declarative configuration of the ExternalMetricSource type for use -// with apply. -// -// ExternalMetricSource indicates how to scale on a metric not associated with -// any Kubernetes object (for example length of queue in cloud -// messaging service, or QPS from loadbalancer running outside of cluster). -type ExternalMetricSourceApplyConfiguration struct { - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` - // target specifies the target value for the given metric - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// ExternalMetricSourceApplyConfiguration constructs a declarative configuration of the ExternalMetricSource type for use with -// apply. -func ExternalMetricSource() *ExternalMetricSourceApplyConfiguration { - return &ExternalMetricSourceApplyConfiguration{} -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *ExternalMetricSourceApplyConfiguration { - b.Metric = value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ExternalMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *ExternalMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricstatus.go deleted file mode 100644 index 725f563544..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/externalmetricstatus.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// ExternalMetricStatusApplyConfiguration represents a declarative configuration of the ExternalMetricStatus type for use -// with apply. -// -// ExternalMetricStatus indicates the current value of a global metric -// not associated with any Kubernetes object. -type ExternalMetricStatusApplyConfiguration struct { - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` - // current contains the current value for the given metric - Current *MetricValueStatusApplyConfiguration `json:"current,omitempty"` -} - -// ExternalMetricStatusApplyConfiguration constructs a declarative configuration of the ExternalMetricStatus type for use with -// apply. -func ExternalMetricStatus() *ExternalMetricStatusApplyConfiguration { - return &ExternalMetricStatusApplyConfiguration{} -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *ExternalMetricStatusApplyConfiguration { - b.Metric = value - return b -} - -// WithCurrent sets the Current field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Current field is set to the value of the last call. -func (b *ExternalMetricStatusApplyConfiguration) WithCurrent(value *MetricValueStatusApplyConfiguration) *ExternalMetricStatusApplyConfiguration { - b.Current = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerbehavior.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerbehavior.go deleted file mode 100644 index 355e15ff52..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerbehavior.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// HorizontalPodAutoscalerBehaviorApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerBehavior type for use -// with apply. -// -// HorizontalPodAutoscalerBehavior configures the scaling behavior of the target -// in both Up and Down directions (scaleUp and scaleDown fields respectively). -type HorizontalPodAutoscalerBehaviorApplyConfiguration struct { - // scaleUp is scaling policy for scaling Up. - // If not set, the default value is the higher of: - // * increase no more than 4 pods per 60 seconds - // * double the number of pods per 60 seconds - // No stabilization is used. - ScaleUp *HPAScalingRulesApplyConfiguration `json:"scaleUp,omitempty"` - // scaleDown is scaling policy for scaling Down. - // If not set, the default value is to allow to scale down to minReplicas pods, with a - // 300 second stabilization window (i.e., the highest recommendation for - // the last 300sec is used). - ScaleDown *HPAScalingRulesApplyConfiguration `json:"scaleDown,omitempty"` -} - -// HorizontalPodAutoscalerBehaviorApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerBehavior type for use with -// apply. -func HorizontalPodAutoscalerBehavior() *HorizontalPodAutoscalerBehaviorApplyConfiguration { - return &HorizontalPodAutoscalerBehaviorApplyConfiguration{} -} - -// WithScaleUp sets the ScaleUp field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ScaleUp field is set to the value of the last call. -func (b *HorizontalPodAutoscalerBehaviorApplyConfiguration) WithScaleUp(value *HPAScalingRulesApplyConfiguration) *HorizontalPodAutoscalerBehaviorApplyConfiguration { - b.ScaleUp = value - return b -} - -// WithScaleDown sets the ScaleDown field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ScaleDown field is set to the value of the last call. -func (b *HorizontalPodAutoscalerBehaviorApplyConfiguration) WithScaleDown(value *HPAScalingRulesApplyConfiguration) *HorizontalPodAutoscalerBehaviorApplyConfiguration { - b.ScaleDown = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerspec.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerspec.go deleted file mode 100644 index 50ee3fae7b..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerspec.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// HorizontalPodAutoscalerSpecApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerSpec type for use -// with apply. -// -// HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. -type HorizontalPodAutoscalerSpecApplyConfiguration struct { - // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics - // should be collected, as well as to actually change the replica count. - ScaleTargetRef *CrossVersionObjectReferenceApplyConfiguration `json:"scaleTargetRef,omitempty"` - // minReplicas is the lower limit for the number of replicas to which the autoscaler - // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the - // alpha feature gate HPAScaleToZero is enabled and at least one Object or External - // metric is configured. Scaling is active as long as at least one metric value is - // available. - MinReplicas *int32 `json:"minReplicas,omitempty"` - // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. - // It cannot be less that minReplicas. - MaxReplicas *int32 `json:"maxReplicas,omitempty"` - // metrics contains the specifications for which to use to calculate the - // desired replica count (the maximum replica count across all metrics will - // be used). The desired replica count is calculated multiplying the - // ratio between the target value and the current value by the current - // number of pods. Ergo, metrics used must decrease as the pod count is - // increased, and vice-versa. See the individual metric source types for - // more information about how each type of metric must respond. - // If not set, the default metric will be set to 80% average CPU utilization. - Metrics []MetricSpecApplyConfiguration `json:"metrics,omitempty"` - // behavior configures the scaling behavior of the target - // in both Up and Down directions (scaleUp and scaleDown fields respectively). - // If not set, the default HPAScalingRules for scale up and scale down are used. - Behavior *HorizontalPodAutoscalerBehaviorApplyConfiguration `json:"behavior,omitempty"` -} - -// HorizontalPodAutoscalerSpecApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerSpec type for use with -// apply. -func HorizontalPodAutoscalerSpec() *HorizontalPodAutoscalerSpecApplyConfiguration { - return &HorizontalPodAutoscalerSpecApplyConfiguration{} -} - -// WithScaleTargetRef sets the ScaleTargetRef field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ScaleTargetRef field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithScaleTargetRef(value *CrossVersionObjectReferenceApplyConfiguration) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.ScaleTargetRef = value - return b -} - -// WithMinReplicas sets the MinReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MinReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMinReplicas(value int32) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.MinReplicas = &value - return b -} - -// WithMaxReplicas sets the MaxReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MaxReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMaxReplicas(value int32) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.MaxReplicas = &value - return b -} - -// WithMetrics adds the given value to the Metrics field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Metrics field. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithMetrics(values ...*MetricSpecApplyConfiguration) *HorizontalPodAutoscalerSpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithMetrics") - } - b.Metrics = append(b.Metrics, *values[i]) - } - return b -} - -// WithBehavior sets the Behavior field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Behavior field is set to the value of the last call. -func (b *HorizontalPodAutoscalerSpecApplyConfiguration) WithBehavior(value *HorizontalPodAutoscalerBehaviorApplyConfiguration) *HorizontalPodAutoscalerSpecApplyConfiguration { - b.Behavior = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerstatus.go deleted file mode 100644 index ffbdc1c32f..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalerstatus.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// HorizontalPodAutoscalerStatusApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerStatus type for use -// with apply. -// -// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler. -type HorizontalPodAutoscalerStatusApplyConfiguration struct { - // observedGeneration is the most recent generation observed by this autoscaler. - ObservedGeneration *int64 `json:"observedGeneration,omitempty"` - // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods, - // used by the autoscaler to control how often the number of pods is changed. - LastScaleTime *v1.Time `json:"lastScaleTime,omitempty"` - // currentReplicas is current number of replicas of pods managed by this autoscaler, - // as last seen by the autoscaler. - CurrentReplicas *int32 `json:"currentReplicas,omitempty"` - // desiredReplicas is the desired number of replicas of pods managed by this autoscaler, - // as last calculated by the autoscaler. - DesiredReplicas *int32 `json:"desiredReplicas,omitempty"` - // currentMetrics is the last read state of the metrics used by this autoscaler. - CurrentMetrics []MetricStatusApplyConfiguration `json:"currentMetrics,omitempty"` - // conditions is the set of conditions required for this autoscaler to scale its target, - // and indicates whether or not those conditions are met. - Conditions []HorizontalPodAutoscalerConditionApplyConfiguration `json:"conditions,omitempty"` -} - -// HorizontalPodAutoscalerStatusApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerStatus type for use with -// apply. -func HorizontalPodAutoscalerStatus() *HorizontalPodAutoscalerStatusApplyConfiguration { - return &HorizontalPodAutoscalerStatusApplyConfiguration{} -} - -// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ObservedGeneration field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithObservedGeneration(value int64) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.ObservedGeneration = &value - return b -} - -// WithLastScaleTime sets the LastScaleTime field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the LastScaleTime field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithLastScaleTime(value v1.Time) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.LastScaleTime = &value - return b -} - -// WithCurrentReplicas sets the CurrentReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the CurrentReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithCurrentReplicas(value int32) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.CurrentReplicas = &value - return b -} - -// WithDesiredReplicas sets the DesiredReplicas field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DesiredReplicas field is set to the value of the last call. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithDesiredReplicas(value int32) *HorizontalPodAutoscalerStatusApplyConfiguration { - b.DesiredReplicas = &value - return b -} - -// WithCurrentMetrics adds the given value to the CurrentMetrics field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the CurrentMetrics field. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithCurrentMetrics(values ...*MetricStatusApplyConfiguration) *HorizontalPodAutoscalerStatusApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithCurrentMetrics") - } - b.CurrentMetrics = append(b.CurrentMetrics, *values[i]) - } - return b -} - -// WithConditions adds the given value to the Conditions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Conditions field. -func (b *HorizontalPodAutoscalerStatusApplyConfiguration) WithConditions(values ...*HorizontalPodAutoscalerConditionApplyConfiguration) *HorizontalPodAutoscalerStatusApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithConditions") - } - b.Conditions = append(b.Conditions, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingpolicy.go deleted file mode 100644 index ca07910b90..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingpolicy.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" -) - -// HPAScalingPolicyApplyConfiguration represents a declarative configuration of the HPAScalingPolicy type for use -// with apply. -// -// HPAScalingPolicy is a single policy which must hold true for a specified past interval. -type HPAScalingPolicyApplyConfiguration struct { - // type is used to specify the scaling policy. - Type *autoscalingv2beta2.HPAScalingPolicyType `json:"type,omitempty"` - // value contains the amount of change which is permitted by the policy. - // It must be greater than zero - Value *int32 `json:"value,omitempty"` - // periodSeconds specifies the window of time for which the policy should hold true. - // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). - PeriodSeconds *int32 `json:"periodSeconds,omitempty"` -} - -// HPAScalingPolicyApplyConfiguration constructs a declarative configuration of the HPAScalingPolicy type for use with -// apply. -func HPAScalingPolicy() *HPAScalingPolicyApplyConfiguration { - return &HPAScalingPolicyApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *HPAScalingPolicyApplyConfiguration) WithType(value autoscalingv2beta2.HPAScalingPolicyType) *HPAScalingPolicyApplyConfiguration { - b.Type = &value - return b -} - -// WithValue sets the Value field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Value field is set to the value of the last call. -func (b *HPAScalingPolicyApplyConfiguration) WithValue(value int32) *HPAScalingPolicyApplyConfiguration { - b.Value = &value - return b -} - -// WithPeriodSeconds sets the PeriodSeconds field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PeriodSeconds field is set to the value of the last call. -func (b *HPAScalingPolicyApplyConfiguration) WithPeriodSeconds(value int32) *HPAScalingPolicyApplyConfiguration { - b.PeriodSeconds = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingrules.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingrules.go deleted file mode 100644 index a87dc3d3c9..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/hpascalingrules.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" -) - -// HPAScalingRulesApplyConfiguration represents a declarative configuration of the HPAScalingRules type for use -// with apply. -// -// HPAScalingRules configures the scaling behavior for one direction. -// These Rules are applied after calculating DesiredReplicas from metrics for the HPA. -// They can limit the scaling velocity by specifying scaling policies. -// They can prevent flapping by specifying the stabilization window, so that the -// number of replicas is not set instantly, instead, the safest value from the stabilization -// window is chosen. -type HPAScalingRulesApplyConfiguration struct { - // stabilizationWindowSeconds is the number of seconds for which past recommendations should be - // considered while scaling up or scaling down. - // StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). - // If not set, use the default values: - // - For scale up: 0 (i.e. no stabilization is done). - // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). - StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty"` - // selectPolicy is used to specify which policy should be used. - // If not set, the default value MaxPolicySelect is used. - SelectPolicy *autoscalingv2beta2.ScalingPolicySelect `json:"selectPolicy,omitempty"` - // policies is a list of potential scaling polices which can be used during scaling. - // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid - Policies []HPAScalingPolicyApplyConfiguration `json:"policies,omitempty"` -} - -// HPAScalingRulesApplyConfiguration constructs a declarative configuration of the HPAScalingRules type for use with -// apply. -func HPAScalingRules() *HPAScalingRulesApplyConfiguration { - return &HPAScalingRulesApplyConfiguration{} -} - -// WithStabilizationWindowSeconds sets the StabilizationWindowSeconds field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the StabilizationWindowSeconds field is set to the value of the last call. -func (b *HPAScalingRulesApplyConfiguration) WithStabilizationWindowSeconds(value int32) *HPAScalingRulesApplyConfiguration { - b.StabilizationWindowSeconds = &value - return b -} - -// WithSelectPolicy sets the SelectPolicy field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SelectPolicy field is set to the value of the last call. -func (b *HPAScalingRulesApplyConfiguration) WithSelectPolicy(value autoscalingv2beta2.ScalingPolicySelect) *HPAScalingRulesApplyConfiguration { - b.SelectPolicy = &value - return b -} - -// WithPolicies adds the given value to the Policies field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Policies field. -func (b *HPAScalingRulesApplyConfiguration) WithPolicies(values ...*HPAScalingPolicyApplyConfiguration) *HPAScalingRulesApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithPolicies") - } - b.Policies = append(b.Policies, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricidentifier.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricidentifier.go deleted file mode 100644 index 9fd064cb9c..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricidentifier.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/client-go/applyconfigurations/meta/v1" -) - -// MetricIdentifierApplyConfiguration represents a declarative configuration of the MetricIdentifier type for use -// with apply. -// -// MetricIdentifier defines the name and optionally selector for a metric -type MetricIdentifierApplyConfiguration struct { - // name is the name of the given metric - Name *string `json:"name,omitempty"` - // selector is the string-encoded form of a standard kubernetes label selector for the given metric - // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. - // When unset, just the metricName will be used to gather metrics. - Selector *v1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` -} - -// MetricIdentifierApplyConfiguration constructs a declarative configuration of the MetricIdentifier type for use with -// apply. -func MetricIdentifier() *MetricIdentifierApplyConfiguration { - return &MetricIdentifierApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *MetricIdentifierApplyConfiguration) WithName(value string) *MetricIdentifierApplyConfiguration { - b.Name = &value - return b -} - -// WithSelector sets the Selector field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Selector field is set to the value of the last call. -func (b *MetricIdentifierApplyConfiguration) WithSelector(value *v1.LabelSelectorApplyConfiguration) *MetricIdentifierApplyConfiguration { - b.Selector = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricspec.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricspec.go deleted file mode 100644 index 92eb2fa644..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricspec.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" -) - -// MetricSpecApplyConfiguration represents a declarative configuration of the MetricSpec type for use -// with apply. -// -// MetricSpec specifies how to scale based on a single metric -// (only `type` and one other matching field should be set at once). -type MetricSpecApplyConfiguration struct { - // type is the type of metric source. It should be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each mapping to a matching field in the object. - Type *autoscalingv2beta2.MetricSourceType `json:"type,omitempty"` - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - Object *ObjectMetricSourceApplyConfiguration `json:"object,omitempty"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - Pods *PodsMetricSourceApplyConfiguration `json:"pods,omitempty"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - Resource *ResourceMetricSourceApplyConfiguration `json:"resource,omitempty"` - // container resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in - // each pod of the current scale target (e.g. CPU or memory). Such metrics are - // built in to Kubernetes, and have special scaling options on top of those - // available to normal per-pod metrics using the "pods" source. - ContainerResource *ContainerResourceMetricSourceApplyConfiguration `json:"containerResource,omitempty"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - External *ExternalMetricSourceApplyConfiguration `json:"external,omitempty"` -} - -// MetricSpecApplyConfiguration constructs a declarative configuration of the MetricSpec type for use with -// apply. -func MetricSpec() *MetricSpecApplyConfiguration { - return &MetricSpecApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithType(value autoscalingv2beta2.MetricSourceType) *MetricSpecApplyConfiguration { - b.Type = &value - return b -} - -// WithObject sets the Object field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Object field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithObject(value *ObjectMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Object = value - return b -} - -// WithPods sets the Pods field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Pods field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithPods(value *PodsMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Pods = value - return b -} - -// WithResource sets the Resource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Resource field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithResource(value *ResourceMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.Resource = value - return b -} - -// WithContainerResource sets the ContainerResource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ContainerResource field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithContainerResource(value *ContainerResourceMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.ContainerResource = value - return b -} - -// WithExternal sets the External field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the External field is set to the value of the last call. -func (b *MetricSpecApplyConfiguration) WithExternal(value *ExternalMetricSourceApplyConfiguration) *MetricSpecApplyConfiguration { - b.External = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricstatus.go deleted file mode 100644 index 16dc67814f..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricstatus.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" -) - -// MetricStatusApplyConfiguration represents a declarative configuration of the MetricStatus type for use -// with apply. -// -// MetricStatus describes the last-read state of a single metric. -type MetricStatusApplyConfiguration struct { - // type is the type of metric source. It will be one of "ContainerResource", "External", - // "Object", "Pods" or "Resource", each corresponds to a matching field in the object. - Type *autoscalingv2beta2.MetricSourceType `json:"type,omitempty"` - // object refers to a metric describing a single kubernetes object - // (for example, hits-per-second on an Ingress object). - Object *ObjectMetricStatusApplyConfiguration `json:"object,omitempty"` - // pods refers to a metric describing each pod in the current scale target - // (for example, transactions-processed-per-second). The values will be - // averaged together before being compared to the target value. - Pods *PodsMetricStatusApplyConfiguration `json:"pods,omitempty"` - // resource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - Resource *ResourceMetricStatusApplyConfiguration `json:"resource,omitempty"` - // containerResource refers to a resource metric (such as those specified in - // requests and limits) known to Kubernetes describing a single container in each pod in the - // current scale target (e.g. CPU or memory). Such metrics are built in to - // Kubernetes, and have special scaling options on top of those available - // to normal per-pod metrics using the "pods" source. - ContainerResource *ContainerResourceMetricStatusApplyConfiguration `json:"containerResource,omitempty"` - // external refers to a global metric that is not associated - // with any Kubernetes object. It allows autoscaling based on information - // coming from components running outside of cluster - // (for example length of queue in cloud messaging service, or - // QPS from loadbalancer running outside of cluster). - External *ExternalMetricStatusApplyConfiguration `json:"external,omitempty"` -} - -// MetricStatusApplyConfiguration constructs a declarative configuration of the MetricStatus type for use with -// apply. -func MetricStatus() *MetricStatusApplyConfiguration { - return &MetricStatusApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithType(value autoscalingv2beta2.MetricSourceType) *MetricStatusApplyConfiguration { - b.Type = &value - return b -} - -// WithObject sets the Object field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Object field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithObject(value *ObjectMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Object = value - return b -} - -// WithPods sets the Pods field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Pods field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithPods(value *PodsMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Pods = value - return b -} - -// WithResource sets the Resource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Resource field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithResource(value *ResourceMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.Resource = value - return b -} - -// WithContainerResource sets the ContainerResource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ContainerResource field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithContainerResource(value *ContainerResourceMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.ContainerResource = value - return b -} - -// WithExternal sets the External field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the External field is set to the value of the last call. -func (b *MetricStatusApplyConfiguration) WithExternal(value *ExternalMetricStatusApplyConfiguration) *MetricStatusApplyConfiguration { - b.External = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metrictarget.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metrictarget.go deleted file mode 100644 index eedcd59d10..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metrictarget.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// MetricTargetApplyConfiguration represents a declarative configuration of the MetricTarget type for use -// with apply. -// -// MetricTarget defines the target value, average value, or average utilization of a specific metric -type MetricTargetApplyConfiguration struct { - // type represents whether the metric type is Utilization, Value, or AverageValue - Type *autoscalingv2beta2.MetricTargetType `json:"type,omitempty"` - // value is the target value of the metric (as a quantity). - Value *resource.Quantity `json:"value,omitempty"` - // averageValue is the target value of the average of the - // metric across all relevant pods (as a quantity) - AverageValue *resource.Quantity `json:"averageValue,omitempty"` - // averageUtilization is the target value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - // Currently only valid for Resource metric source type - AverageUtilization *int32 `json:"averageUtilization,omitempty"` -} - -// MetricTargetApplyConfiguration constructs a declarative configuration of the MetricTarget type for use with -// apply. -func MetricTarget() *MetricTargetApplyConfiguration { - return &MetricTargetApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *MetricTargetApplyConfiguration) WithType(value autoscalingv2beta2.MetricTargetType) *MetricTargetApplyConfiguration { - b.Type = &value - return b -} - -// WithValue sets the Value field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Value field is set to the value of the last call. -func (b *MetricTargetApplyConfiguration) WithValue(value resource.Quantity) *MetricTargetApplyConfiguration { - b.Value = &value - return b -} - -// WithAverageValue sets the AverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageValue field is set to the value of the last call. -func (b *MetricTargetApplyConfiguration) WithAverageValue(value resource.Quantity) *MetricTargetApplyConfiguration { - b.AverageValue = &value - return b -} - -// WithAverageUtilization sets the AverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageUtilization field is set to the value of the last call. -func (b *MetricTargetApplyConfiguration) WithAverageUtilization(value int32) *MetricTargetApplyConfiguration { - b.AverageUtilization = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricvaluestatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricvaluestatus.go deleted file mode 100644 index 49141abcc6..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/metricvaluestatus.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - resource "k8s.io/apimachinery/pkg/api/resource" -) - -// MetricValueStatusApplyConfiguration represents a declarative configuration of the MetricValueStatus type for use -// with apply. -// -// MetricValueStatus holds the current value for a metric -type MetricValueStatusApplyConfiguration struct { - // value is the current value of the metric (as a quantity). - Value *resource.Quantity `json:"value,omitempty"` - // averageValue is the current value of the average of the - // metric across all relevant pods (as a quantity) - AverageValue *resource.Quantity `json:"averageValue,omitempty"` - // averageUtilization is the current value of the average of the - // resource metric across all relevant pods, represented as a percentage of - // the requested value of the resource for the pods. - AverageUtilization *int32 `json:"averageUtilization,omitempty"` -} - -// MetricValueStatusApplyConfiguration constructs a declarative configuration of the MetricValueStatus type for use with -// apply. -func MetricValueStatus() *MetricValueStatusApplyConfiguration { - return &MetricValueStatusApplyConfiguration{} -} - -// WithValue sets the Value field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Value field is set to the value of the last call. -func (b *MetricValueStatusApplyConfiguration) WithValue(value resource.Quantity) *MetricValueStatusApplyConfiguration { - b.Value = &value - return b -} - -// WithAverageValue sets the AverageValue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageValue field is set to the value of the last call. -func (b *MetricValueStatusApplyConfiguration) WithAverageValue(value resource.Quantity) *MetricValueStatusApplyConfiguration { - b.AverageValue = &value - return b -} - -// WithAverageUtilization sets the AverageUtilization field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AverageUtilization field is set to the value of the last call. -func (b *MetricValueStatusApplyConfiguration) WithAverageUtilization(value int32) *MetricValueStatusApplyConfiguration { - b.AverageUtilization = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricsource.go deleted file mode 100644 index e99e081cea..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricsource.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// ObjectMetricSourceApplyConfiguration represents a declarative configuration of the ObjectMetricSource type for use -// with apply. -// -// ObjectMetricSource indicates how to scale on a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricSourceApplyConfiguration struct { - DescribedObject *CrossVersionObjectReferenceApplyConfiguration `json:"describedObject,omitempty"` - // target specifies the target value for the given metric - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` -} - -// ObjectMetricSourceApplyConfiguration constructs a declarative configuration of the ObjectMetricSource type for use with -// apply. -func ObjectMetricSource() *ObjectMetricSourceApplyConfiguration { - return &ObjectMetricSourceApplyConfiguration{} -} - -// WithDescribedObject sets the DescribedObject field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DescribedObject field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithDescribedObject(value *CrossVersionObjectReferenceApplyConfiguration) *ObjectMetricSourceApplyConfiguration { - b.DescribedObject = value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *ObjectMetricSourceApplyConfiguration { - b.Target = value - return b -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *ObjectMetricSourceApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *ObjectMetricSourceApplyConfiguration { - b.Metric = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricstatus.go deleted file mode 100644 index 4d5d016791..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/objectmetricstatus.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// ObjectMetricStatusApplyConfiguration represents a declarative configuration of the ObjectMetricStatus type for use -// with apply. -// -// ObjectMetricStatus indicates the current value of a metric describing a -// kubernetes object (for example, hits-per-second on an Ingress object). -type ObjectMetricStatusApplyConfiguration struct { - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` - // current contains the current value for the given metric - Current *MetricValueStatusApplyConfiguration `json:"current,omitempty"` - DescribedObject *CrossVersionObjectReferenceApplyConfiguration `json:"describedObject,omitempty"` -} - -// ObjectMetricStatusApplyConfiguration constructs a declarative configuration of the ObjectMetricStatus type for use with -// apply. -func ObjectMetricStatus() *ObjectMetricStatusApplyConfiguration { - return &ObjectMetricStatusApplyConfiguration{} -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *ObjectMetricStatusApplyConfiguration { - b.Metric = value - return b -} - -// WithCurrent sets the Current field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Current field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithCurrent(value *MetricValueStatusApplyConfiguration) *ObjectMetricStatusApplyConfiguration { - b.Current = value - return b -} - -// WithDescribedObject sets the DescribedObject field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DescribedObject field is set to the value of the last call. -func (b *ObjectMetricStatusApplyConfiguration) WithDescribedObject(value *CrossVersionObjectReferenceApplyConfiguration) *ObjectMetricStatusApplyConfiguration { - b.DescribedObject = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricsource.go deleted file mode 100644 index 11dd2f6e9b..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricsource.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// PodsMetricSourceApplyConfiguration represents a declarative configuration of the PodsMetricSource type for use -// with apply. -// -// PodsMetricSource indicates how to scale on a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -// The values will be averaged together before being compared to the target -// value. -type PodsMetricSourceApplyConfiguration struct { - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` - // target specifies the target value for the given metric - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// PodsMetricSourceApplyConfiguration constructs a declarative configuration of the PodsMetricSource type for use with -// apply. -func PodsMetricSource() *PodsMetricSourceApplyConfiguration { - return &PodsMetricSourceApplyConfiguration{} -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *PodsMetricSourceApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *PodsMetricSourceApplyConfiguration { - b.Metric = value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *PodsMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *PodsMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricstatus.go deleted file mode 100644 index 929c02d4a4..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/podsmetricstatus.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -// PodsMetricStatusApplyConfiguration represents a declarative configuration of the PodsMetricStatus type for use -// with apply. -// -// PodsMetricStatus indicates the current value of a metric describing each pod in -// the current scale target (for example, transactions-processed-per-second). -type PodsMetricStatusApplyConfiguration struct { - // metric identifies the target metric by name and selector - Metric *MetricIdentifierApplyConfiguration `json:"metric,omitempty"` - // current contains the current value for the given metric - Current *MetricValueStatusApplyConfiguration `json:"current,omitempty"` -} - -// PodsMetricStatusApplyConfiguration constructs a declarative configuration of the PodsMetricStatus type for use with -// apply. -func PodsMetricStatus() *PodsMetricStatusApplyConfiguration { - return &PodsMetricStatusApplyConfiguration{} -} - -// WithMetric sets the Metric field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Metric field is set to the value of the last call. -func (b *PodsMetricStatusApplyConfiguration) WithMetric(value *MetricIdentifierApplyConfiguration) *PodsMetricStatusApplyConfiguration { - b.Metric = value - return b -} - -// WithCurrent sets the Current field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Current field is set to the value of the last call. -func (b *PodsMetricStatusApplyConfiguration) WithCurrent(value *MetricValueStatusApplyConfiguration) *PodsMetricStatusApplyConfiguration { - b.Current = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricsource.go deleted file mode 100644 index ce7e7e5fe2..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricsource.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// ResourceMetricSourceApplyConfiguration represents a declarative configuration of the ResourceMetricSource type for use -// with apply. -// -// ResourceMetricSource indicates how to scale on a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). The values will be averaged -// together before being compared to the target. Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. Only one "target" type -// should be set. -type ResourceMetricSourceApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // target specifies the target value for the given metric - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// ResourceMetricSourceApplyConfiguration constructs a declarative configuration of the ResourceMetricSource type for use with -// apply. -func ResourceMetricSource() *ResourceMetricSourceApplyConfiguration { - return &ResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *ResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *ResourceMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *ResourceMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricstatus.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricstatus.go deleted file mode 100644 index 9a6f391900..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/resourcemetricstatus.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2beta2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// ResourceMetricStatusApplyConfiguration represents a declarative configuration of the ResourceMetricStatus type for use -// with apply. -// -// ResourceMetricStatus indicates the current value of a resource metric known to -// Kubernetes, as specified in requests and limits, describing each pod in the -// current scale target (e.g. CPU or memory). Such metrics are built in to -// Kubernetes, and have special scaling options on top of those available to -// normal per-pod metrics using the "pods" source. -type ResourceMetricStatusApplyConfiguration struct { - // name is the name of the resource in question. - Name *v1.ResourceName `json:"name,omitempty"` - // current contains the current value for the given metric - Current *MetricValueStatusApplyConfiguration `json:"current,omitempty"` -} - -// ResourceMetricStatusApplyConfiguration constructs a declarative configuration of the ResourceMetricStatus type for use with -// apply. -func ResourceMetricStatus() *ResourceMetricStatusApplyConfiguration { - return &ResourceMetricStatusApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *ResourceMetricStatusApplyConfiguration) WithName(value v1.ResourceName) *ResourceMetricStatusApplyConfiguration { - b.Name = &value - return b -} - -// WithCurrent sets the Current field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Current field is set to the value of the last call. -func (b *ResourceMetricStatusApplyConfiguration) WithCurrent(value *MetricValueStatusApplyConfiguration) *ResourceMetricStatusApplyConfiguration { - b.Current = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/podcertificaterequestspec.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/podcertificaterequestspec.go index 234420c40a..6e195e3837 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/podcertificaterequestspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/podcertificaterequestspec.go @@ -62,8 +62,7 @@ type PodCertificateRequestSpecApplyConfiguration struct { // `kubernetes.io` signers will never issue certificates with a lifetime // longer than 24 hours. MaxExpirationSeconds *int32 `json:"maxExpirationSeconds,omitempty"` - // pkixPublicKey is the PKIX-serialized public key the signer will issue the - // certificate to. + // The PKIX-serialized public key the signer will issue the certificate to. // // The key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, // or ED25519. Note that this list may be expanded in the future. @@ -74,9 +73,14 @@ type PodCertificateRequestSpecApplyConfiguration struct { // setting a status.conditions entry with a type of "Denied" and a reason of // "UnsupportedKeyType". It may also suggest a key type that it does support // in the message field. + // + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. Signer + // implementations should extract the public key from the StubPKCS10Request + // field. PKIXPublicKey []byte `json:"pkixPublicKey,omitempty"` - // proofOfPossession proves that the requesting kubelet holds the private - // key corresponding to pkixPublicKey. + // A proof that the requesting kubelet holds the private key corresponding + // to pkixPublicKey. // // It is contructed by signing the ASCII bytes of the pod's UID using // `pkixPublicKey`. @@ -93,9 +97,31 @@ type PodCertificateRequestSpecApplyConfiguration struct { // golang library function crypto/ecdsa.SignASN1) // // If the key is an ED25519 key, the the signature is as described by the - // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by - // the golang library crypto/ed25519.Sign). + // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the + // golang library crypto/ed25519.Sign). + // + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. ProofOfPossession []byte `json:"proofOfPossession,omitempty"` + // A PKCS#10 certificate signing request (DER-serialized) generated by + // Kubelet using the subject private key. + // + // Most signer implementations will ignore the contents of the CSR except to + // extract the subject public key. The API server automatically verifies the + // CSR signature during admission, so the signer does not need to repeat the + // verification. CSRs generated by kubelet are completely empty. + // + // The subject public key must be one of RSA3072, RSA4096, ECDSAP256, + // ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in + // the future. + // + // Signer implementations do not need to support all key types supported by + // kube-apiserver and kubelet. If a signer does not support the key type + // used for a given PodCertificateRequest, it must deny the request by + // setting a status.conditions entry with a type of "Denied" and a reason of + // "UnsupportedKeyType". It may also suggest a key type that it does support + // in the message field. + StubPKCS10Request []byte `json:"stubPKCS10Request,omitempty"` // unverifiedUserAnnotations allow pod authors to pass additional information to // the signer implementation. Kubernetes does not restrict or validate this // metadata in any way. @@ -199,6 +225,16 @@ func (b *PodCertificateRequestSpecApplyConfiguration) WithProofOfPossession(valu return b } +// WithStubPKCS10Request adds the given value to the StubPKCS10Request field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the StubPKCS10Request field. +func (b *PodCertificateRequestSpecApplyConfiguration) WithStubPKCS10Request(values ...byte) *PodCertificateRequestSpecApplyConfiguration { + for i := range values { + b.StubPKCS10Request = append(b.StubPKCS10Request, values[i]) + } + return b +} + // WithUnverifiedUserAnnotations puts the entries into the UnverifiedUserAnnotations field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the UnverifiedUserAnnotations field, diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/imagevolumestatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/imagevolumestatus.go new file mode 100644 index 0000000000..a16e44e508 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/imagevolumestatus.go @@ -0,0 +1,44 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ImageVolumeStatusApplyConfiguration represents a declarative configuration of the ImageVolumeStatus type for use +// with apply. +// +// ImageVolumeStatus represents the image-based volume status. +type ImageVolumeStatusApplyConfiguration struct { + // ImageRef is the digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + // The ImageRef length should not exceed 256 characters. + ImageRef *string `json:"imageRef,omitempty"` +} + +// ImageVolumeStatusApplyConfiguration constructs a declarative configuration of the ImageVolumeStatus type for use with +// apply. +func ImageVolumeStatus() *ImageVolumeStatusApplyConfiguration { + return &ImageVolumeStatusApplyConfiguration{} +} + +// WithImageRef sets the ImageRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ImageRef field is set to the value of the last call. +func (b *ImageVolumeStatusApplyConfiguration) WithImageRef(value string) *ImageVolumeStatusApplyConfiguration { + b.ImageRef = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/nodeallocatableresourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/nodeallocatableresourceclaimstatus.go new file mode 100644 index 0000000000..6e384b0028 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/nodeallocatableresourceclaimstatus.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NodeAllocatableResourceClaimStatusApplyConfiguration represents a declarative configuration of the NodeAllocatableResourceClaimStatus type for use +// with apply. +// +// NodeAllocatableResourceClaimStatus describes the status of node allocatable resources allocated via DRA. +type NodeAllocatableResourceClaimStatusApplyConfiguration struct { + // ResourceClaimName is the resource claim referenced by the pod that resulted in this node allocatable resource allocation. + ResourceClaimName *string `json:"resourceClaimName,omitempty"` + // Containers lists the names of all containers in this pod that reference the claim. + Containers []string `json:"containers,omitempty"` + // Resources is a map of the node-allocatable resource name to the aggregate quantity allocated to the claim. + Resources map[corev1.ResourceName]resource.Quantity `json:"resources,omitempty"` +} + +// NodeAllocatableResourceClaimStatusApplyConfiguration constructs a declarative configuration of the NodeAllocatableResourceClaimStatus type for use with +// apply. +func NodeAllocatableResourceClaimStatus() *NodeAllocatableResourceClaimStatusApplyConfiguration { + return &NodeAllocatableResourceClaimStatusApplyConfiguration{} +} + +// WithResourceClaimName sets the ResourceClaimName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimName field is set to the value of the last call. +func (b *NodeAllocatableResourceClaimStatusApplyConfiguration) WithResourceClaimName(value string) *NodeAllocatableResourceClaimStatusApplyConfiguration { + b.ResourceClaimName = &value + return b +} + +// WithContainers adds the given value to the Containers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Containers field. +func (b *NodeAllocatableResourceClaimStatusApplyConfiguration) WithContainers(values ...string) *NodeAllocatableResourceClaimStatusApplyConfiguration { + for i := range values { + b.Containers = append(b.Containers, values[i]) + } + return b +} + +// WithResources puts the entries into the Resources field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Resources field, +// overwriting an existing map entries in Resources field with the same key. +func (b *NodeAllocatableResourceClaimStatusApplyConfiguration) WithResources(entries map[corev1.ResourceName]resource.Quantity) *NodeAllocatableResourceClaimStatusApplyConfiguration { + if b.Resources == nil && len(entries) > 0 { + b.Resources = make(map[corev1.ResourceName]resource.Quantity, len(entries)) + } + for k, v := range entries { + b.Resources[k] = v + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumesource.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumesource.go index 8627148bfc..2d9d1dd5da 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumesource.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/persistentvolumesource.go @@ -94,8 +94,7 @@ type PersistentVolumeSourceApplyConfiguration struct { PhotonPersistentDisk *PhotonPersistentDiskVolumeSourceApplyConfiguration `json:"photonPersistentDisk,omitempty"` // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. PortworxVolume *PortworxVolumeSourceApplyConfiguration `json:"portworxVolume,omitempty"` // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. // Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podcondition.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podcondition.go index 55e55dd0f2..dc527cdf25 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podcondition.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podcondition.go @@ -32,7 +32,6 @@ type PodConditionApplyConfiguration struct { // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions Type *corev1.PodConditionType `json:"type,omitempty"` // If set, this represents the .metadata.generation that the pod condition was set based upon. - // The PodObservedGenerationTracking feature gate must be enabled to use this field. ObservedGeneration *int64 `json:"observedGeneration,omitempty"` // Status is the status of the condition. // Can be True, False, Unknown. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go index 93d2280f0d..554cfd0ffc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaim.go @@ -27,6 +27,14 @@ package v1 // // It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. // Containers that need access to the ResourceClaim reference it with this name. +// +// When the DRAWorkloadResourceClaims feature gate is enabled and this Pod +// belongs to a PodGroup, a PodResourceClaim is matched to a +// PodGroupResourceClaim if all of their fields are equal (Name, +// ResourceClaimName, and ResourceClaimTemplateName). A matched claim references +// a single ResourceClaim shared across all Pods in the PodGroup, reserved for +// the PodGroup in ResourceClaimStatus.ReservedFor rather than for individual +// Pods. type PodResourceClaimApplyConfiguration struct { // Name uniquely identifies this resource claim inside the pod. // This must be a DNS_LABEL. @@ -46,6 +54,16 @@ type PodResourceClaimApplyConfiguration struct { // generated component, will be used to form a unique name for the // ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. // + // When the DRAWorkloadResourceClaims feature gate is enabled and the pod + // belongs to a PodGroup that defines a PodGroupResourceClaim with the same + // Name and ResourceClaimTemplateName, this PodResourceClaim resolves to the + // ResourceClaim generated for the PodGroup. All pods in the group that + // define an equivalent PodResourceClaim matching the + // PodGroupResourceClaim's Name and ResourceClaimTemplateName share the same + // generated ResourceClaim. ResourceClaims generated for a PodGroup are + // owned by the PodGroup and their lifecycles are tied to the PodGroup + // instead of any individual pod. + // // This field is immutable and no changes will be made to the // corresponding ResourceClaim by the control plane after creating the // ResourceClaim. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaimstatus.go index f0673fa0f1..094e2b8747 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaimstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaimstatus.go @@ -30,9 +30,16 @@ type PodResourceClaimStatusApplyConfiguration struct { // which implies that the string must be a DNS_LABEL. Name *string `json:"name,omitempty"` // ResourceClaimName is the name of the ResourceClaim that was - // generated for the Pod in the namespace of the Pod. If this is - // unset, then generating a ResourceClaim was not necessary. The - // pod.spec.resourceClaims entry can be ignored in this case. + // generated for the Pod in the namespace of the Pod. + // + // When the DRAWorkloadResourceClaims feature is enabled and the + // corresponding PodResourceClaim matches a PodGroupResourceClaim + // made by the Pod's PodGroup, then this is the name of the + // ResourceClaim generated and reserved for the PodGroup. + // + // If this is unset, then generating a ResourceClaim was not + // necessary. The pod.spec.resourceClaims entry can be ignored in + // this case. ResourceClaimName *string `json:"resourceClaimName,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggroup.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggroup.go new file mode 100644 index 0000000000..4dd3b23ba9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podschedulinggroup.go @@ -0,0 +1,46 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// PodSchedulingGroupApplyConfiguration represents a declarative configuration of the PodSchedulingGroup type for use +// with apply. +// +// PodSchedulingGroup identifies the runtime scheduling group instance that a Pod belongs to. +// The scheduler uses this information to apply workload-aware scheduling semantics. +// Exactly one field must be specified. +type PodSchedulingGroupApplyConfiguration struct { + // PodGroupName specifies the name of the standalone PodGroup object + // that represents the runtime instance of this group. + // Must be a DNS subdomain. + PodGroupName *string `json:"podGroupName,omitempty"` +} + +// PodSchedulingGroupApplyConfiguration constructs a declarative configuration of the PodSchedulingGroup type for use with +// apply. +func PodSchedulingGroup() *PodSchedulingGroupApplyConfiguration { + return &PodSchedulingGroupApplyConfiguration{} +} + +// WithPodGroupName sets the PodGroupName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PodGroupName field is set to the value of the last call. +func (b *PodSchedulingGroupApplyConfiguration) WithPodGroupName(value string) *PodSchedulingGroupApplyConfiguration { + b.PodGroupName = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go index 1948c7131f..e67c18c41b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podspec.go @@ -233,7 +233,6 @@ type PodSpecApplyConfiguration struct { // When set to false, a new userns is created for the pod. Setting false is useful for // mitigating container breakout vulnerabilities even allowing users to run their // containers as root without actually having root privileges on the host. - // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. HostUsers *bool `json:"hostUsers,omitempty"` // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the @@ -273,14 +272,19 @@ type PodSpecApplyConfiguration struct { // This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. // Requires the HostnameOverride feature gate to be enabled. HostnameOverride *string `json:"hostnameOverride,omitempty"` - // WorkloadRef provides a reference to the Workload object that this Pod belongs to. - // This field is used by the scheduler to identify the PodGroup and apply the - // correct group scheduling policies. The Workload object referenced - // by this field may not exist at the time the Pod is created. - // This field is immutable, but a Workload object with the same name - // may be recreated with different policies. Doing this during pod scheduling + // SchedulingGroup provides a reference to the immediate scheduling runtime + // grouping object that this Pod belongs to. + // This field is used by the scheduler to identify the group and apply the + // correct group scheduling policies. The association with a group also + // impacts other lifecycle aspects of a Pod that are relevant in a wider context + // of scheduling like preemption, resource attachment, etc. If not specified, + // the Pod is treated as a single unit in all of these aspects. + // The group object referenced by this field may not exist at the time the + // Pod is created. + // This field is immutable, but a group object with the same name may be + // recreated with different policies. Doing this during pod scheduling // may result in the placement not conforming to the expected policies. - WorkloadRef *WorkloadReferenceApplyConfiguration `json:"workloadRef,omitempty"` + SchedulingGroup *PodSchedulingGroupApplyConfiguration `json:"schedulingGroup,omitempty"` } // PodSpecApplyConfiguration constructs a declarative configuration of the PodSpec type for use with @@ -678,10 +682,10 @@ func (b *PodSpecApplyConfiguration) WithHostnameOverride(value string) *PodSpecA return b } -// WithWorkloadRef sets the WorkloadRef field in the declarative configuration to the given value +// WithSchedulingGroup sets the SchedulingGroup field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the WorkloadRef field is set to the value of the last call. -func (b *PodSpecApplyConfiguration) WithWorkloadRef(value *WorkloadReferenceApplyConfiguration) *PodSpecApplyConfiguration { - b.WorkloadRef = value +// If called multiple times, the SchedulingGroup field is set to the value of the last call. +func (b *PodSpecApplyConfiguration) WithSchedulingGroup(value *PodSchedulingGroupApplyConfiguration) *PodSpecApplyConfiguration { + b.SchedulingGroup = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go index e50ca9335e..8328d9cdb1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go @@ -139,6 +139,12 @@ type PodStatusApplyConfiguration struct { // applied at the pod level if pod-level requests or limits are set in // PodSpec.Resources Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + // NodeAllocatableResourceClaimStatuses contains the status of node-allocatable resources + // that were allocated for this pod through DRA claims. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + NodeAllocatableResourceClaimStatuses []NodeAllocatableResourceClaimStatusApplyConfiguration `json:"nodeAllocatableResourceClaimStatuses,omitempty"` } // PodStatusApplyConfiguration constructs a declarative configuration of the PodStatus type for use with @@ -341,3 +347,16 @@ func (b *PodStatusApplyConfiguration) WithResources(value *ResourceRequirementsA b.Resources = value return b } + +// WithNodeAllocatableResourceClaimStatuses adds the given value to the NodeAllocatableResourceClaimStatuses field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the NodeAllocatableResourceClaimStatuses field. +func (b *PodStatusApplyConfiguration) WithNodeAllocatableResourceClaimStatuses(values ...*NodeAllocatableResourceClaimStatusApplyConfiguration) *PodStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithNodeAllocatableResourceClaimStatuses") + } + b.NodeAllocatableResourceClaimStatuses = append(b.NodeAllocatableResourceClaimStatuses, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcehealth.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcehealth.go index 684153c49b..061535b8d9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcehealth.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/resourcehealth.go @@ -41,6 +41,9 @@ type ResourceHealthApplyConfiguration struct { // // In future we may want to introduce the PermanentlyUnhealthy Status. Health *corev1.ResourceHealthStatus `json:"health,omitempty"` + // Message provides human-readable context for Health (e.g. "ECC error count exceeded threshold"). + // This field is populated by the kubelet when ResourceHealthStatusMessage is enabled if the DRA plugin returns a message, and is null otherwise. + Message *string `json:"message,omitempty"` } // ResourceHealthApplyConfiguration constructs a declarative configuration of the ResourceHealth type for use with @@ -64,3 +67,11 @@ func (b *ResourceHealthApplyConfiguration) WithHealth(value corev1.ResourceHealt b.Health = &value return b } + +// WithMessage sets the Message field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Message field is set to the value of the last call. +func (b *ResourceHealthApplyConfiguration) WithMessage(value string) *ResourceHealthApplyConfiguration { + b.Message = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/securitycontext.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/securitycontext.go index aee2635238..8147c54769 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/securitycontext.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/securitycontext.go @@ -83,7 +83,6 @@ type SecurityContextApplyConfiguration struct { // procMount denotes the type of proc mount to use for the containers. // The default value is Default which uses the container runtime defaults for // readonly paths and masked paths. - // This requires the ProcMountType feature flag to be enabled. // Note that this field cannot be set when spec.os.name is windows. ProcMount *corev1.ProcMountType `json:"procMount,omitempty"` // The seccomp options to use by this container. If seccomp options are diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumemountstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumemountstatus.go index ad4965a17d..693268ecb1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumemountstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumemountstatus.go @@ -37,6 +37,9 @@ type VolumeMountStatusApplyConfiguration struct { // An IfPossible value in the original VolumeMount must be translated to Disabled or Enabled, // depending on the mount result. RecursiveReadOnly *corev1.RecursiveReadOnlyMode `json:"recursiveReadOnly,omitempty"` + // volumeStatus represents volume-type-specific status about the mounted + // volume. + VolumeStatus *VolumeStatusApplyConfiguration `json:"volumeStatus,omitempty"` } // VolumeMountStatusApplyConfiguration constructs a declarative configuration of the VolumeMountStatus type for use with @@ -76,3 +79,11 @@ func (b *VolumeMountStatusApplyConfiguration) WithRecursiveReadOnly(value corev1 b.RecursiveReadOnly = &value return b } + +// WithVolumeStatus sets the VolumeStatus field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VolumeStatus field is set to the value of the last call. +func (b *VolumeMountStatusApplyConfiguration) WithVolumeStatus(value *VolumeStatusApplyConfiguration) *VolumeMountStatusApplyConfiguration { + b.VolumeStatus = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumesource.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumesource.go index 5d9a6b0f6d..2ce585f541 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumesource.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumesource.go @@ -116,8 +116,7 @@ type VolumeSourceApplyConfiguration struct { Projected *ProjectedVolumeSourceApplyConfiguration `json:"projected,omitempty"` // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. PortworxVolume *PortworxVolumeSourceApplyConfiguration `json:"portworxVolume,omitempty"` // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. // Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported. @@ -163,7 +162,7 @@ type VolumeSourceApplyConfiguration struct { // A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - // The volume will be mounted read-only (ro) and non-executable files (noexec). + // The volume will be mounted read-only (ro). // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. Image *ImageVolumeSourceApplyConfiguration `json:"image,omitempty"` diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumestatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumestatus.go new file mode 100644 index 0000000000..3d6a7f85d9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/volumestatus.go @@ -0,0 +1,43 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// VolumeStatusApplyConfiguration represents a declarative configuration of the VolumeStatus type for use +// with apply. +// +// VolumeStatus represents the status of a mounted volume. +// At most one of its members must be specified. +type VolumeStatusApplyConfiguration struct { + // image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + Image *ImageVolumeStatusApplyConfiguration `json:"image,omitempty"` +} + +// VolumeStatusApplyConfiguration constructs a declarative configuration of the VolumeStatus type for use with +// apply. +func VolumeStatus() *VolumeStatusApplyConfiguration { + return &VolumeStatusApplyConfiguration{} +} + +// WithImage sets the Image field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Image field is set to the value of the last call. +func (b *VolumeStatusApplyConfiguration) WithImage(value *ImageVolumeStatusApplyConfiguration) *VolumeStatusApplyConfiguration { + b.Image = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/workloadreference.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/workloadreference.go deleted file mode 100644 index 758c4517df..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/workloadreference.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -// WorkloadReferenceApplyConfiguration represents a declarative configuration of the WorkloadReference type for use -// with apply. -// -// WorkloadReference identifies the Workload object and PodGroup membership -// that a Pod belongs to. The scheduler uses this information to apply -// workload-aware scheduling semantics. -type WorkloadReferenceApplyConfiguration struct { - // Name defines the name of the Workload object this Pod belongs to. - // Workload must be in the same namespace as the Pod. - // If it doesn't match any existing Workload, the Pod will remain unschedulable - // until a Workload object is created and observed by the kube-scheduler. - // It must be a DNS subdomain. - Name *string `json:"name,omitempty"` - // PodGroup is the name of the PodGroup within the Workload that this Pod - // belongs to. If it doesn't match any existing PodGroup within the Workload, - // the Pod will remain unschedulable until the Workload object is recreated - // and observed by the kube-scheduler. It must be a DNS label. - PodGroup *string `json:"podGroup,omitempty"` - // PodGroupReplicaKey specifies the replica key of the PodGroup to which this - // Pod belongs. It is used to distinguish pods belonging to different replicas - // of the same pod group. The pod group policy is applied separately to each replica. - // When set, it must be a DNS label. - PodGroupReplicaKey *string `json:"podGroupReplicaKey,omitempty"` -} - -// WorkloadReferenceApplyConfiguration constructs a declarative configuration of the WorkloadReference type for use with -// apply. -func WorkloadReference() *WorkloadReferenceApplyConfiguration { - return &WorkloadReferenceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *WorkloadReferenceApplyConfiguration) WithName(value string) *WorkloadReferenceApplyConfiguration { - b.Name = &value - return b -} - -// WithPodGroup sets the PodGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PodGroup field is set to the value of the last call. -func (b *WorkloadReferenceApplyConfiguration) WithPodGroup(value string) *WorkloadReferenceApplyConfiguration { - b.PodGroup = &value - return b -} - -// WithPodGroupReplicaKey sets the PodGroupReplicaKey field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PodGroupReplicaKey field is set to the value of the last call. -func (b *WorkloadReferenceApplyConfiguration) WithPodGroupReplicaKey(value string) *WorkloadReferenceApplyConfiguration { - b.PodGroupReplicaKey = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go index 2d66c9ba08..c0b255cc73 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -39,6 +39,12 @@ func Parser() *typed.Parser { var parserOnce sync.Once var parser *typed.Parser var schemaYAML = typed.YAMLObject(`types: +- name: io.k8s.api.admissionregistration.v1.ApplyConfiguration + map: + fields: + - name: expression + type: + scalar: string - name: io.k8s.api.admissionregistration.v1.AuditAnnotation map: fields: @@ -61,6 +67,12 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.admissionregistration.v1.JSONPatch + map: + fields: + - name: expression + type: + scalar: string - name: io.k8s.api.admissionregistration.v1.MatchCondition map: fields: @@ -97,6 +109,87 @@ var schemaYAML = typed.YAMLObject(`types: namedType: io.k8s.api.admissionregistration.v1.NamedRuleWithOperations elementRelationship: atomic elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicy + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicySpec + default: {} +- name: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBinding + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingSpec + default: {} +- name: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingSpec + map: + fields: + - name: matchResources + type: + namedType: io.k8s.api.admissionregistration.v1.MatchResources + - name: paramRef + type: + namedType: io.k8s.api.admissionregistration.v1.ParamRef + - name: policyName + type: + scalar: string +- name: io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicySpec + map: + fields: + - name: failurePolicy + type: + scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name + - name: matchConstraints + type: + namedType: io.k8s.api.admissionregistration.v1.MatchResources + - name: mutations + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.Mutation + elementRelationship: atomic + - name: paramKind + type: + namedType: io.k8s.api.admissionregistration.v1.ParamKind + - name: reinvocationPolicy + type: + scalar: string + - name: variables + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.Variable + elementRelationship: atomic - name: io.k8s.api.admissionregistration.v1.MutatingWebhook map: fields: @@ -170,6 +263,19 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name +- name: io.k8s.api.admissionregistration.v1.Mutation + map: + fields: + - name: applyConfiguration + type: + namedType: io.k8s.api.admissionregistration.v1.ApplyConfiguration + - name: jsonPatch + type: + namedType: io.k8s.api.admissionregistration.v1.JSONPatch + - name: patchType + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1.NamedRuleWithOperations map: fields: @@ -3302,87 +3408,72 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource +- name: io.k8s.api.batch.v1.CronJob map: fields: - - name: container + - name: apiVersion type: scalar: string - default: "" - - name: name + - name: kind type: scalar: string - default: "" - - name: targetAverageUtilization + - name: metadata type: - scalar: numeric - - name: targetAverageValue + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricStatus + namedType: io.k8s.api.batch.v1.CronJobSpec + default: {} + - name: status + type: + namedType: io.k8s.api.batch.v1.CronJobStatus + default: {} +- name: io.k8s.api.batch.v1.CronJobSpec map: fields: - - name: container + - name: concurrencyPolicy type: scalar: string - default: "" - - name: currentAverageUtilization + - name: failedJobsHistoryLimit type: scalar: numeric - - name: currentAverageValue + - name: jobTemplate type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: name + namedType: io.k8s.api.batch.v1.JobTemplateSpec + default: {} + - name: schedule type: scalar: string default: "" -- name: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference - map: - fields: - - name: apiVersion + - name: startingDeadlineSeconds type: - scalar: string - - name: kind + scalar: numeric + - name: successfulJobsHistoryLimit type: - scalar: string - default: "" - - name: name + scalar: numeric + - name: suspend type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource - map: - fields: - - name: metricName + scalar: boolean + - name: timeZone type: scalar: string - default: "" - - name: metricSelector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: targetAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: targetValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus +- name: io.k8s.api.batch.v1.CronJobStatus map: fields: - - name: currentAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: currentValue + - name: active type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: metricName + list: + elementType: + namedType: io.k8s.api.core.v1.ObjectReference + elementRelationship: atomic + - name: lastScheduleTime type: - scalar: string - default: "" - - name: metricSelector + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: lastSuccessfulTime type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector -- name: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time +- name: io.k8s.api.batch.v1.Job map: fields: - name: apiVersion @@ -3397,15 +3488,18 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec + namedType: io.k8s.api.batch.v1.JobSpec default: {} - name: status type: - namedType: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerStatus + namedType: io.k8s.api.batch.v1.JobStatus default: {} -- name: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerCondition +- name: io.k8s.api.batch.v1.JobCondition map: fields: + - name: lastProbeTime + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - name: lastTransitionTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time @@ -3423,719 +3517,71 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerSpec +- name: io.k8s.api.batch.v1.JobSpec map: fields: - - name: maxReplicas + - name: activeDeadlineSeconds type: scalar: numeric - default: 0 - - name: metrics + - name: backoffLimit type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta1.MetricSpec - elementRelationship: atomic - - name: minReplicas + scalar: numeric + - name: backoffLimitPerIndex type: scalar: numeric - - name: scaleTargetRef + - name: completionMode type: - namedType: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference - default: {} -- name: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerStatus - map: - fields: - - name: conditions + scalar: string + - name: completions type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscalerCondition - elementRelationship: atomic - - name: currentMetrics + scalar: numeric + - name: managedBy type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta1.MetricStatus - elementRelationship: atomic - - name: currentReplicas + scalar: string + - name: manualSelector type: - scalar: numeric - default: 0 - - name: desiredReplicas + scalar: boolean + - name: maxFailedIndexes type: scalar: numeric - default: 0 - - name: lastScaleTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: observedGeneration + - name: parallelism type: scalar: numeric -- name: io.k8s.api.autoscaling.v2beta1.MetricSpec - map: - fields: - - name: containerResource + - name: podFailurePolicy type: - namedType: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricSource - - name: external + namedType: io.k8s.api.batch.v1.PodFailurePolicy + - name: podReplacementPolicy type: - namedType: io.k8s.api.autoscaling.v2beta1.ExternalMetricSource - - name: object + scalar: string + - name: selector type: - namedType: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource - - name: pods + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector + - name: successPolicy type: - namedType: io.k8s.api.autoscaling.v2beta1.PodsMetricSource - - name: resource + namedType: io.k8s.api.batch.v1.SuccessPolicy + - name: suspend type: - namedType: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource - - name: type + scalar: boolean + - name: template type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta1.MetricStatus + namedType: io.k8s.api.core.v1.PodTemplateSpec + default: {} + - name: ttlSecondsAfterFinished + type: + scalar: numeric +- name: io.k8s.api.batch.v1.JobStatus map: fields: - - name: containerResource - type: - namedType: io.k8s.api.autoscaling.v2beta1.ContainerResourceMetricStatus - - name: external + - name: active type: - namedType: io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus - - name: object + scalar: numeric + - name: completedIndexes type: - namedType: io.k8s.api.autoscaling.v2beta1.ObjectMetricStatus - - name: pods + scalar: string + - name: completionTime type: - namedType: io.k8s.api.autoscaling.v2beta1.PodsMetricStatus - - name: resource - type: - namedType: io.k8s.api.autoscaling.v2beta1.ResourceMetricStatus - - name: type - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta1.ObjectMetricSource - map: - fields: - - name: averageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: metricName - type: - scalar: string - default: "" - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference - default: {} - - name: targetValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta1.ObjectMetricStatus - map: - fields: - - name: averageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: currentValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: metricName - type: - scalar: string - default: "" - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta1.CrossVersionObjectReference - default: {} -- name: io.k8s.api.autoscaling.v2beta1.PodsMetricSource - map: - fields: - - name: metricName - type: - scalar: string - default: "" - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: targetAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta1.PodsMetricStatus - map: - fields: - - name: currentAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: metricName - type: - scalar: string - default: "" - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector -- name: io.k8s.api.autoscaling.v2beta1.ResourceMetricSource - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: targetAverageUtilization - type: - scalar: numeric - - name: targetAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta1.ResourceMetricStatus - map: - fields: - - name: currentAverageUtilization - type: - scalar: numeric - - name: currentAverageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource - map: - fields: - - name: container - type: - scalar: string - default: "" - - name: name - type: - scalar: string - default: "" - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricTarget - default: {} -- name: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricStatus - map: - fields: - - name: container - type: - scalar: string - default: "" - - name: current - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - default: {} - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - default: "" - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.ExternalMetricSource - map: - fields: - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricTarget - default: {} -- name: io.k8s.api.autoscaling.v2beta2.ExternalMetricStatus - map: - fields: - - name: current - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - default: {} - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} -- name: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy - map: - fields: - - name: periodSeconds - type: - scalar: numeric - default: 0 - - name: type - type: - scalar: string - default: "" - - name: value - type: - scalar: numeric - default: 0 -- name: io.k8s.api.autoscaling.v2beta2.HPAScalingRules - map: - fields: - - name: policies - type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy - elementRelationship: atomic - - name: selectPolicy - type: - scalar: string - - name: stabilizationWindowSeconds - type: - scalar: numeric -- name: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec - default: {} - - name: status - type: - namedType: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerStatus - default: {} -- name: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior - map: - fields: - - name: scaleDown - type: - namedType: io.k8s.api.autoscaling.v2beta2.HPAScalingRules - - name: scaleUp - type: - namedType: io.k8s.api.autoscaling.v2beta2.HPAScalingRules -- name: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerCondition - map: - fields: - - name: lastTransitionTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: message - type: - scalar: string - - name: reason - type: - scalar: string - - name: status - type: - scalar: string - default: "" - - name: type - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerSpec - map: - fields: - - name: behavior - type: - namedType: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior - - name: maxReplicas - type: - scalar: numeric - default: 0 - - name: metrics - type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta2.MetricSpec - elementRelationship: atomic - - name: minReplicas - type: - scalar: numeric - - name: scaleTargetRef - type: - namedType: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference - default: {} -- name: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerStatus - map: - fields: - - name: conditions - type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerCondition - elementRelationship: atomic - - name: currentMetrics - type: - list: - elementType: - namedType: io.k8s.api.autoscaling.v2beta2.MetricStatus - elementRelationship: atomic - - name: currentReplicas - type: - scalar: numeric - default: 0 - - name: desiredReplicas - type: - scalar: numeric - default: 0 - - name: lastScaleTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: observedGeneration - type: - scalar: numeric -- name: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector -- name: io.k8s.api.autoscaling.v2beta2.MetricSpec - map: - fields: - - name: containerResource - type: - namedType: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricSource - - name: external - type: - namedType: io.k8s.api.autoscaling.v2beta2.ExternalMetricSource - - name: object - type: - namedType: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource - - name: pods - type: - namedType: io.k8s.api.autoscaling.v2beta2.PodsMetricSource - - name: resource - type: - namedType: io.k8s.api.autoscaling.v2beta2.ResourceMetricSource - - name: type - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.MetricStatus - map: - fields: - - name: containerResource - type: - namedType: io.k8s.api.autoscaling.v2beta2.ContainerResourceMetricStatus - - name: external - type: - namedType: io.k8s.api.autoscaling.v2beta2.ExternalMetricStatus - - name: object - type: - namedType: io.k8s.api.autoscaling.v2beta2.ObjectMetricStatus - - name: pods - type: - namedType: io.k8s.api.autoscaling.v2beta2.PodsMetricStatus - - name: resource - type: - namedType: io.k8s.api.autoscaling.v2beta2.ResourceMetricStatus - - name: type - type: - scalar: string - default: "" -- name: io.k8s.api.autoscaling.v2beta2.MetricTarget - map: - fields: - - name: averageUtilization - type: - scalar: numeric - - name: averageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: type - type: - scalar: string - default: "" - - name: value - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - map: - fields: - - name: averageUtilization - type: - scalar: numeric - - name: averageValue - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - - name: value - type: - namedType: io.k8s.apimachinery.pkg.api.resource.Quantity -- name: io.k8s.api.autoscaling.v2beta2.ObjectMetricSource - map: - fields: - - name: describedObject - type: - namedType: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference - default: {} - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricTarget - default: {} -- name: io.k8s.api.autoscaling.v2beta2.ObjectMetricStatus - map: - fields: - - name: current - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - default: {} - - name: describedObject - type: - namedType: io.k8s.api.autoscaling.v2beta2.CrossVersionObjectReference - default: {} - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} -- name: io.k8s.api.autoscaling.v2beta2.PodsMetricSource - map: - fields: - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricTarget - default: {} -- name: io.k8s.api.autoscaling.v2beta2.PodsMetricStatus - map: - fields: - - name: current - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - default: {} - - name: metric - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricIdentifier - default: {} -- name: io.k8s.api.autoscaling.v2beta2.ResourceMetricSource - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: target - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricTarget - default: {} -- name: io.k8s.api.autoscaling.v2beta2.ResourceMetricStatus - map: - fields: - - name: current - type: - namedType: io.k8s.api.autoscaling.v2beta2.MetricValueStatus - default: {} - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.batch.v1.CronJob - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.batch.v1.CronJobSpec - default: {} - - name: status - type: - namedType: io.k8s.api.batch.v1.CronJobStatus - default: {} -- name: io.k8s.api.batch.v1.CronJobSpec - map: - fields: - - name: concurrencyPolicy - type: - scalar: string - - name: failedJobsHistoryLimit - type: - scalar: numeric - - name: jobTemplate - type: - namedType: io.k8s.api.batch.v1.JobTemplateSpec - default: {} - - name: schedule - type: - scalar: string - default: "" - - name: startingDeadlineSeconds - type: - scalar: numeric - - name: successfulJobsHistoryLimit - type: - scalar: numeric - - name: suspend - type: - scalar: boolean - - name: timeZone - type: - scalar: string -- name: io.k8s.api.batch.v1.CronJobStatus - map: - fields: - - name: active - type: - list: - elementType: - namedType: io.k8s.api.core.v1.ObjectReference - elementRelationship: atomic - - name: lastScheduleTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: lastSuccessfulTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time -- name: io.k8s.api.batch.v1.Job - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.batch.v1.JobSpec - default: {} - - name: status - type: - namedType: io.k8s.api.batch.v1.JobStatus - default: {} -- name: io.k8s.api.batch.v1.JobCondition - map: - fields: - - name: lastProbeTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: lastTransitionTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: message - type: - scalar: string - - name: reason - type: - scalar: string - - name: status - type: - scalar: string - default: "" - - name: type - type: - scalar: string - default: "" -- name: io.k8s.api.batch.v1.JobSpec - map: - fields: - - name: activeDeadlineSeconds - type: - scalar: numeric - - name: backoffLimit - type: - scalar: numeric - - name: backoffLimitPerIndex - type: - scalar: numeric - - name: completionMode - type: - scalar: string - - name: completions - type: - scalar: numeric - - name: managedBy - type: - scalar: string - - name: manualSelector - type: - scalar: boolean - - name: maxFailedIndexes - type: - scalar: numeric - - name: parallelism - type: - scalar: numeric - - name: podFailurePolicy - type: - namedType: io.k8s.api.batch.v1.PodFailurePolicy - - name: podReplacementPolicy - type: - scalar: string - - name: selector - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector - - name: successPolicy - type: - namedType: io.k8s.api.batch.v1.SuccessPolicy - - name: suspend - type: - scalar: boolean - - name: template - type: - namedType: io.k8s.api.core.v1.PodTemplateSpec - default: {} - - name: ttlSecondsAfterFinished - type: - scalar: numeric -- name: io.k8s.api.batch.v1.JobStatus - map: - fields: - - name: active - type: - scalar: numeric - - name: completedIndexes - type: - scalar: string - - name: completionTime - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time - - name: conditions + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: conditions type: list: elementType: @@ -4643,6 +4089,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" + - name: stubPKCS10Request + type: + scalar: string - name: unverifiedUserAnnotations type: map: @@ -6292,6 +5741,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: reference type: scalar: string +- name: io.k8s.api.core.v1.ImageVolumeStatus + map: + fields: + - name: imageRef + type: + scalar: string - name: io.k8s.api.core.v1.KeyToPath map: fields: @@ -6585,6 +6040,24 @@ var schemaYAML = typed.YAMLObject(`types: - name: requiredDuringSchedulingIgnoredDuringExecution type: namedType: io.k8s.api.core.v1.NodeSelector +- name: io.k8s.api.core.v1.NodeAllocatableResourceClaimStatus + map: + fields: + - name: containers + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: resourceClaimName + type: + scalar: string + default: "" + - name: resources + type: + map: + elementType: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - name: io.k8s.api.core.v1.NodeCondition map: fields: @@ -7418,6 +6891,16 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" +- name: io.k8s.api.core.v1.PodSchedulingGroup + map: + fields: + - name: podGroupName + type: + scalar: string + unions: + - fields: + - fieldName: podGroupName + discriminatorValue: PodGroupName - name: io.k8s.api.core.v1.PodSecurityContext map: fields: @@ -7605,6 +7088,9 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name + - name: schedulingGroup + type: + namedType: io.k8s.api.core.v1.PodSchedulingGroup - name: securityContext type: namedType: io.k8s.api.core.v1.PodSecurityContext @@ -7649,9 +7135,6 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - name - - name: workloadRef - type: - namedType: io.k8s.api.core.v1.WorkloadReference - name: io.k8s.api.core.v1.PodStatus map: fields: @@ -7701,6 +7184,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: message type: scalar: string + - name: nodeAllocatableResourceClaimStatuses + type: + list: + elementType: + namedType: io.k8s.api.core.v1.NodeAllocatableResourceClaimStatus + elementRelationship: atomic - name: nominatedNodeName type: scalar: string @@ -8064,6 +7553,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: health type: scalar: string + - name: message + type: + scalar: string - name: resourceID type: scalar: string @@ -8952,6 +8444,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: recursiveReadOnly type: scalar: string + - name: volumeStatus + type: + namedType: io.k8s.api.core.v1.VolumeStatus - name: io.k8s.api.core.v1.VolumeNodeAffinity map: fields: @@ -8992,6 +8487,12 @@ var schemaYAML = typed.YAMLObject(`types: map: elementType: namedType: io.k8s.apimachinery.pkg.api.resource.Quantity +- name: io.k8s.api.core.v1.VolumeStatus + map: + fields: + - name: image + type: + namedType: io.k8s.api.core.v1.ImageVolumeStatus - name: io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource map: fields: @@ -9034,20 +8535,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: runAsUserName type: scalar: string -- name: io.k8s.api.core.v1.WorkloadReference - map: - fields: - - name: name - type: - scalar: string - default: "" - - name: podGroup - type: - scalar: string - default: "" - - name: podGroupReplicaKey - type: - scalar: string - name: io.k8s.api.discovery.v1.Endpoint map: fields: @@ -12989,6 +12476,11 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" + - name: nodeAllocatableResourceMappings + type: + map: + elementType: + namedType: io.k8s.api.resource.v1.NodeAllocatableResourceMapping - name: nodeName type: scalar: string @@ -13038,15 +12530,39 @@ var schemaYAML = typed.YAMLObject(`types: - name: bool type: scalar: boolean + - name: bools + type: + list: + elementType: + scalar: boolean + elementRelationship: atomic - name: int type: scalar: numeric + - name: ints + type: + list: + elementType: + scalar: numeric + elementRelationship: atomic - name: string type: scalar: string + - name: strings + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: version type: scalar: string + - name: versions + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: io.k8s.api.resource.v1.DeviceCapacity map: fields: @@ -13341,6 +12857,15 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic +- name: io.k8s.api.resource.v1.NodeAllocatableResourceMapping + map: + fields: + - name: allocationMultiplier + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: capacityKey + type: + scalar: string - name: io.k8s.api.resource.v1.OpaqueDeviceConfiguration map: fields: @@ -13534,7 +13059,95 @@ var schemaYAML = typed.YAMLObject(`types: - name: value type: scalar: string -- name: io.k8s.api.resource.v1alpha3.DeviceTaintRule +- name: io.k8s.api.resource.v1alpha3.DeviceTaintRule + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1alpha3.DeviceTaintRuleSpec + default: {} + - name: status + type: + namedType: io.k8s.api.resource.v1alpha3.DeviceTaintRuleStatus + default: {} +- name: io.k8s.api.resource.v1alpha3.DeviceTaintRuleSpec + map: + fields: + - name: deviceSelector + type: + namedType: io.k8s.api.resource.v1alpha3.DeviceTaintSelector + - name: taint + type: + namedType: io.k8s.api.resource.v1alpha3.DeviceTaint + default: {} +- name: io.k8s.api.resource.v1alpha3.DeviceTaintRuleStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type +- name: io.k8s.api.resource.v1alpha3.DeviceTaintSelector + map: + fields: + - name: device + type: + scalar: string + - name: driver + type: + scalar: string + - name: pool + type: + scalar: string +- name: io.k8s.api.resource.v1alpha3.PoolStatus + map: + fields: + - name: allocatedDevices + type: + scalar: numeric + - name: availableDevices + type: + scalar: numeric + - name: driver + type: + scalar: string + - name: generation + type: + scalar: numeric + default: 0 + - name: nodeName + type: + scalar: string + - name: poolName + type: + scalar: string + - name: resourceSliceCount + type: + scalar: numeric + - name: totalDevices + type: + scalar: numeric + - name: unavailableDevices + type: + scalar: numeric + - name: validationError + type: + scalar: string +- name: io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequest map: fields: - name: apiVersion @@ -13549,23 +13162,26 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha3.DeviceTaintRuleSpec + namedType: io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestSpec default: {} - name: status type: - namedType: io.k8s.api.resource.v1alpha3.DeviceTaintRuleStatus - default: {} -- name: io.k8s.api.resource.v1alpha3.DeviceTaintRuleSpec + namedType: io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestStatus +- name: io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestSpec map: fields: - - name: deviceSelector + - name: driver type: - namedType: io.k8s.api.resource.v1alpha3.DeviceTaintSelector - - name: taint + scalar: string + default: "" + - name: limit type: - namedType: io.k8s.api.resource.v1alpha3.DeviceTaint - default: {} -- name: io.k8s.api.resource.v1alpha3.DeviceTaintRuleStatus + scalar: numeric + default: 100 + - name: poolName + type: + scalar: string +- name: io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequestStatus map: fields: - name: conditions @@ -13576,18 +13192,15 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type -- name: io.k8s.api.resource.v1alpha3.DeviceTaintSelector - map: - fields: - - name: device - type: - scalar: string - - name: driver + - name: poolCount type: - scalar: string - - name: pool + scalar: numeric + - name: pools type: - scalar: string + list: + elementType: + namedType: io.k8s.api.resource.v1alpha3.PoolStatus + elementRelationship: atomic - name: io.k8s.api.resource.v1beta1.AllocatedDeviceStatus map: fields: @@ -13673,6 +13286,11 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.resource.v1beta1.DeviceCounterConsumption elementRelationship: atomic + - name: nodeAllocatableResourceMappings + type: + map: + elementType: + namedType: io.k8s.api.resource.v1beta1.NodeAllocatableResourceMapping - name: nodeName type: scalar: string @@ -13792,15 +13410,39 @@ var schemaYAML = typed.YAMLObject(`types: - name: bool type: scalar: boolean + - name: bools + type: + list: + elementType: + scalar: boolean + elementRelationship: atomic - name: int type: scalar: numeric + - name: ints + type: + list: + elementType: + scalar: numeric + elementRelationship: atomic - name: string type: scalar: string + - name: strings + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: version type: scalar: string + - name: versions + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: io.k8s.api.resource.v1beta1.DeviceCapacity map: fields: @@ -14089,6 +13731,15 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic +- name: io.k8s.api.resource.v1beta1.NodeAllocatableResourceMapping + map: + fields: + - name: allocationMultiplier + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: capacityKey + type: + scalar: string - name: io.k8s.api.resource.v1beta1.OpaqueDeviceConfiguration map: fields: @@ -14414,6 +14065,11 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" + - name: nodeAllocatableResourceMappings + type: + map: + elementType: + namedType: io.k8s.api.resource.v1beta2.NodeAllocatableResourceMapping - name: nodeName type: scalar: string @@ -14463,15 +14119,39 @@ var schemaYAML = typed.YAMLObject(`types: - name: bool type: scalar: boolean + - name: bools + type: + list: + elementType: + scalar: boolean + elementRelationship: atomic - name: int type: scalar: numeric + - name: ints + type: + list: + elementType: + scalar: numeric + elementRelationship: atomic - name: string type: scalar: string + - name: strings + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: version type: scalar: string + - name: versions + type: + list: + elementType: + scalar: string + elementRelationship: atomic - name: io.k8s.api.resource.v1beta2.DeviceCapacity map: fields: @@ -14701,6 +14381,60 @@ var schemaYAML = typed.YAMLObject(`types: - name: value type: scalar: string +- name: io.k8s.api.resource.v1beta2.DeviceTaintRule + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.resource.v1beta2.DeviceTaintRuleSpec + default: {} + - name: status + type: + namedType: io.k8s.api.resource.v1beta2.DeviceTaintRuleStatus + default: {} +- name: io.k8s.api.resource.v1beta2.DeviceTaintRuleSpec + map: + fields: + - name: deviceSelector + type: + namedType: io.k8s.api.resource.v1beta2.DeviceTaintSelector + - name: taint + type: + namedType: io.k8s.api.resource.v1beta2.DeviceTaint + default: {} +- name: io.k8s.api.resource.v1beta2.DeviceTaintRuleStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type +- name: io.k8s.api.resource.v1beta2.DeviceTaintSelector + map: + fields: + - name: device + type: + scalar: string + - name: driver + type: + scalar: string + - name: pool + type: + scalar: string - name: io.k8s.api.resource.v1beta2.DeviceToleration map: fields: @@ -14766,6 +14500,15 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: atomic +- name: io.k8s.api.resource.v1beta2.NodeAllocatableResourceMapping + map: + fields: + - name: allocationMultiplier + type: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity + - name: capacityKey + type: + scalar: string - name: io.k8s.api.resource.v1beta2.OpaqueDeviceConfiguration map: fields: @@ -14968,7 +14711,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 -- name: io.k8s.api.scheduling.v1alpha1.BasicSchedulingPolicy +- name: io.k8s.api.scheduling.v1alpha2.BasicSchedulingPolicy map: elementType: scalar: untyped @@ -14980,60 +14723,180 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: __untyped_deduced_ elementRelationship: separable -- name: io.k8s.api.scheduling.v1alpha1.GangSchedulingPolicy +- name: io.k8s.api.scheduling.v1alpha2.GangSchedulingPolicy map: fields: - name: minCount type: scalar: numeric default: 0 -- name: io.k8s.api.scheduling.v1alpha1.PodGroup +- name: io.k8s.api.scheduling.v1alpha2.PodGroup + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupSpec + default: {} + - name: status + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupStatus + default: {} +- name: io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaim map: fields: - name: name type: scalar: string default: "" - - name: policy + - name: resourceClaimName type: - namedType: io.k8s.api.scheduling.v1alpha1.PodGroupPolicy - default: {} -- name: io.k8s.api.scheduling.v1alpha1.PodGroupPolicy + scalar: string + - name: resourceClaimTemplateName + type: + scalar: string +- name: io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaimStatus + map: + fields: + - name: name + type: + scalar: string + default: "" + - name: resourceClaimName + type: + scalar: string +- name: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingConstraints + map: + fields: + - name: topology + type: + list: + elementType: + namedType: io.k8s.api.scheduling.v1alpha2.TopologyConstraint + elementRelationship: atomic +- name: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingPolicy map: fields: - name: basic type: - namedType: io.k8s.api.scheduling.v1alpha1.BasicSchedulingPolicy + namedType: io.k8s.api.scheduling.v1alpha2.BasicSchedulingPolicy - name: gang type: - namedType: io.k8s.api.scheduling.v1alpha1.GangSchedulingPolicy -- name: io.k8s.api.scheduling.v1alpha1.PriorityClass + namedType: io.k8s.api.scheduling.v1alpha2.GangSchedulingPolicy + unions: + - fields: + - fieldName: basic + discriminatorValue: Basic + - fieldName: gang + discriminatorValue: Gang +- name: io.k8s.api.scheduling.v1alpha2.PodGroupSpec map: fields: - - name: apiVersion + - name: disruptionMode type: scalar: string - - name: description + default: Pod + - name: podGroupTemplateRef type: - scalar: string - - name: globalDefault + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupTemplateReference + - name: priority type: - scalar: boolean - - name: kind + scalar: numeric + - name: priorityClassName type: scalar: string - - name: metadata + - name: resourceClaims type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + list: + elementType: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaim + elementRelationship: associative + keys: + - name + - name: schedulingConstraints + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingConstraints + - name: schedulingPolicy + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingPolicy default: {} - - name: preemptionPolicy +- name: io.k8s.api.scheduling.v1alpha2.PodGroupStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: resourceClaimStatuses + type: + list: + elementType: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaimStatus + elementRelationship: associative + keys: + - name +- name: io.k8s.api.scheduling.v1alpha2.PodGroupTemplate + map: + fields: + - name: disruptionMode type: scalar: string - - name: value + - name: name + type: + scalar: string + default: "" + - name: priority type: scalar: numeric - default: 0 -- name: io.k8s.api.scheduling.v1alpha1.TypedLocalObjectReference + - name: priorityClassName + type: + scalar: string + - name: resourceClaims + type: + list: + elementType: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupResourceClaim + elementRelationship: associative + keys: + - name + - name: schedulingConstraints + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingConstraints + - name: schedulingPolicy + type: + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupSchedulingPolicy + default: {} +- name: io.k8s.api.scheduling.v1alpha2.PodGroupTemplateReference + map: + fields: + - name: workload + type: + namedType: io.k8s.api.scheduling.v1alpha2.WorkloadPodGroupTemplateReference + unions: + - fields: + - fieldName: workload + discriminatorValue: Workload +- name: io.k8s.api.scheduling.v1alpha2.TopologyConstraint + map: + fields: + - name: key + type: + scalar: string + default: "" +- name: io.k8s.api.scheduling.v1alpha2.TypedLocalObjectReference map: fields: - name: apiGroup @@ -15047,7 +14910,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.scheduling.v1alpha1.Workload +- name: io.k8s.api.scheduling.v1alpha2.Workload map: fields: - name: apiVersion @@ -15062,19 +14925,30 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.scheduling.v1alpha1.WorkloadSpec + namedType: io.k8s.api.scheduling.v1alpha2.WorkloadSpec default: {} -- name: io.k8s.api.scheduling.v1alpha1.WorkloadSpec +- name: io.k8s.api.scheduling.v1alpha2.WorkloadPodGroupTemplateReference + map: + fields: + - name: podGroupTemplateName + type: + scalar: string + default: "" + - name: workloadName + type: + scalar: string + default: "" +- name: io.k8s.api.scheduling.v1alpha2.WorkloadSpec map: fields: - name: controllerRef type: - namedType: io.k8s.api.scheduling.v1alpha1.TypedLocalObjectReference - - name: podGroups + namedType: io.k8s.api.scheduling.v1alpha2.TypedLocalObjectReference + - name: podGroupTemplates type: list: elementType: - namedType: io.k8s.api.scheduling.v1alpha1.PodGroup + namedType: io.k8s.api.scheduling.v1alpha2.PodGroupTemplate elementRelationship: associative keys: - name @@ -15136,6 +15010,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: podInfoOnMount type: scalar: boolean + - name: preventPodSchedulingIfMissing + type: + scalar: boolean - name: requiresRepublish type: scalar: boolean @@ -15545,6 +15422,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: podInfoOnMount type: scalar: boolean + - name: preventPodSchedulingIfMissing + type: + scalar: boolean - name: requiresRepublish type: scalar: boolean diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/allocationresult.go index 83f0b96895..6e380790ea 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/allocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/allocationresult.go @@ -36,7 +36,7 @@ type AllocationResultApplyConfiguration struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. AllocationTimestamp *metav1.Time `json:"allocationTimestamp,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/celdeviceselector.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/celdeviceselector.go index 5a77aac95f..15ec20da40 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/celdeviceselector.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/celdeviceselector.go @@ -72,6 +72,14 @@ type CELDeviceSelectorApplyConfiguration struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/device.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/device.go index ca50f6024a..f19b9000cd 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/device.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/device.go @@ -19,6 +19,7 @@ limitations under the License. package v1 import ( + apicorev1 "k8s.io/api/core/v1" resourcev1 "k8s.io/api/resource/v1" corev1 "k8s.io/client-go/applyconfigurations/core/v1" ) @@ -74,7 +75,7 @@ type DeviceApplyConfiguration struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Taints []DeviceTaintApplyConfiguration `json:"taints,omitempty"` // BindsToNode indicates if the usage of an allocation involving this device @@ -82,7 +83,7 @@ type DeviceApplyConfiguration struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindsToNode *bool `json:"bindsToNode,omitempty"` // BindingConditions defines the conditions for proceeding with binding. @@ -94,7 +95,7 @@ type DeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions defines the conditions for binding failure. @@ -105,7 +106,7 @@ type DeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -113,6 +114,18 @@ type DeviceApplyConfiguration struct { // If AllowMultipleAllocations is set to true, the device can be allocated more than once, // and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not. AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty"` + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + NodeAllocatableResourceMappings map[apicorev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration `json:"nodeAllocatableResourceMappings,omitempty"` } // DeviceApplyConfiguration constructs a declarative configuration of the Device type for use with @@ -242,3 +255,17 @@ func (b *DeviceApplyConfiguration) WithAllowMultipleAllocations(value bool) *Dev b.AllowMultipleAllocations = &value return b } + +// WithNodeAllocatableResourceMappings puts the entries into the NodeAllocatableResourceMappings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeAllocatableResourceMappings field, +// overwriting an existing map entries in NodeAllocatableResourceMappings field with the same key. +func (b *DeviceApplyConfiguration) WithNodeAllocatableResourceMappings(entries map[apicorev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration) *DeviceApplyConfiguration { + if b.NodeAllocatableResourceMappings == nil && len(entries) > 0 { + b.NodeAllocatableResourceMappings = make(map[apicorev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration, len(entries)) + } + for k, v := range entries { + b.NodeAllocatableResourceMappings[k] = v + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceattribute.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceattribute.go index e41696ab88..9d5b16f271 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceattribute.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceattribute.go @@ -32,6 +32,22 @@ type DeviceAttributeApplyConfiguration struct { // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. VersionValue *string `json:"version,omitempty"` + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + IntValues []int64 `json:"ints,omitempty"` + // BoolValues is a non-empty list of true/false values. + BoolValues []bool `json:"bools,omitempty"` + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + StringValues []string `json:"strings,omitempty"` + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + VersionValues []string `json:"versions,omitempty"` } // DeviceAttributeApplyConfiguration constructs a declarative configuration of the DeviceAttribute type for use with @@ -71,3 +87,43 @@ func (b *DeviceAttributeApplyConfiguration) WithVersionValue(value string) *Devi b.VersionValue = &value return b } + +// WithIntValues adds the given value to the IntValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the IntValues field. +func (b *DeviceAttributeApplyConfiguration) WithIntValues(values ...int64) *DeviceAttributeApplyConfiguration { + for i := range values { + b.IntValues = append(b.IntValues, values[i]) + } + return b +} + +// WithBoolValues adds the given value to the BoolValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the BoolValues field. +func (b *DeviceAttributeApplyConfiguration) WithBoolValues(values ...bool) *DeviceAttributeApplyConfiguration { + for i := range values { + b.BoolValues = append(b.BoolValues, values[i]) + } + return b +} + +// WithStringValues adds the given value to the StringValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the StringValues field. +func (b *DeviceAttributeApplyConfiguration) WithStringValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.StringValues = append(b.StringValues, values[i]) + } + return b +} + +// WithVersionValues adds the given value to the VersionValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the VersionValues field. +func (b *DeviceAttributeApplyConfiguration) WithVersionValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.VersionValues = append(b.VersionValues, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclass.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclass.go index 6d3bc7e76d..478f90bb04 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclass.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclass.go @@ -34,9 +34,6 @@ import ( // device configuration and selectors. It can be referenced in // the device requests of a claim to apply these presets. // Cluster scoped. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type DeviceClassApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` // Standard object metadata diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclassspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclassspec.go index a304c7d8d2..a6a3992c92 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclassspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceclassspec.go @@ -41,7 +41,7 @@ type DeviceClassSpecApplyConfiguration struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. ExtendedResourceName *string `json:"extendedResourceName,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceconstraint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceconstraint.go index cd2467e694..ba13edbb84 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceconstraint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/deviceconstraint.go @@ -48,11 +48,21 @@ type DeviceConstraintApplyConfiguration struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as single-element lists for backward compatibility. + // // Must include the domain qualifier. MatchAttribute *resourcev1.FullyQualifiedName `json:"matchAttribute,omitempty"` // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go index 8b38fd2887..592a641756 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go @@ -57,8 +57,7 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // administrative access. See the corresponding request field // for a definition of mode. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. AdminAccess *bool `json:"adminAccess,omitempty"` // A copy of all tolerations specified in the request at the time @@ -66,19 +65,19 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // ShareID uniquely identifies an individual allocation share of the device, diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicesubrequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicesubrequest.go index f3ee27af3c..d554522fa1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicesubrequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicesubrequest.go @@ -93,7 +93,7 @@ type DeviceSubRequestApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicetaint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicetaint.go index db98da8b87..c65c88e05b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicetaint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/devicetaint.go @@ -43,8 +43,17 @@ type DeviceTaintApplyConfiguration struct { // nodes is not valid here. More effects may get added in the future. // Consumers must treat unknown effects like None. Effect *resourcev1.DeviceTaintEffect `json:"effect,omitempty"` - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. + // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). TimeAdded *metav1.Time `json:"timeAdded,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/exactdevicerequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/exactdevicerequest.go index 130893c6d6..8eb0fd3526 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/exactdevicerequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/exactdevicerequest.go @@ -72,8 +72,7 @@ type ExactDeviceRequestApplyConfiguration struct { // all ordinary claims to the device with respect to access modes and // any resource allocations. // - // This is an alpha field and requires enabling the DRAAdminAccess - // feature gate. Admin access is disabled if this field is unset or + // Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. AdminAccess *bool `json:"adminAccess,omitempty"` // If specified, the request's tolerations. @@ -91,7 +90,7 @@ type ExactDeviceRequestApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/networkdevicedata.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/networkdevicedata.go index 5d0ee8fc50..9cb1b4dea5 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/networkdevicedata.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/networkdevicedata.go @@ -29,7 +29,7 @@ type NetworkDeviceDataApplyConfiguration struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. InterfaceName *string `json:"interfaceName,omitempty"` // IPs lists the network addresses assigned to the device's network interface. // This can include both IPv4 and IPv6 addresses. @@ -39,7 +39,7 @@ type NetworkDeviceDataApplyConfiguration struct { IPs []string `json:"ips,omitempty"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. HardwareAddress *string `json:"hardwareAddress,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/nodeallocatableresourcemapping.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/nodeallocatableresourcemapping.go new file mode 100644 index 0000000000..600d96af89 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/nodeallocatableresourcemapping.go @@ -0,0 +1,84 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + resourcev1 "k8s.io/api/resource/v1" + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NodeAllocatableResourceMappingApplyConfiguration represents a declarative configuration of the NodeAllocatableResourceMapping type for use +// with apply. +// +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMappingApplyConfiguration struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + CapacityKey *resourcev1.QualifiedName `json:"capacityKey,omitempty"` + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty"` +} + +// NodeAllocatableResourceMappingApplyConfiguration constructs a declarative configuration of the NodeAllocatableResourceMapping type for use with +// apply. +func NodeAllocatableResourceMapping() *NodeAllocatableResourceMappingApplyConfiguration { + return &NodeAllocatableResourceMappingApplyConfiguration{} +} + +// WithCapacityKey sets the CapacityKey field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CapacityKey field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithCapacityKey(value resourcev1.QualifiedName) *NodeAllocatableResourceMappingApplyConfiguration { + b.CapacityKey = &value + return b +} + +// WithAllocationMultiplier sets the AllocationMultiplier field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocationMultiplier field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithAllocationMultiplier(value resource.Quantity) *NodeAllocatableResourceMappingApplyConfiguration { + b.AllocationMultiplier = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaim.go index 240e181846..5a87ea3cbc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaim.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaim.go @@ -35,9 +35,6 @@ import ( // with specific properties, this is how that request is expressed. The status // stanza tracks whether this claim has been satisfied and what specific // resources have been allocated. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceClaimApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` // Standard object metadata diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaimtemplate.go index 7bbadb7009..cee18f3797 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceclaimtemplate.go @@ -31,9 +31,6 @@ import ( // with apply. // // ResourceClaimTemplate is used to produce ResourceClaim objects. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceClaimTemplateApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` // Standard object metadata diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceslice.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceslice.go index 6c7ddf41e3..7a3eec9d5c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceslice.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1/resourceslice.go @@ -51,9 +51,6 @@ import ( // // For resources that are not local to a node, the node name is not set. Instead, // the driver may use a node selector to specify where the devices are available. -// -// This is an alpha type and requires enabling the DynamicResourceAllocation -// feature gate. type ResourceSliceApplyConfiguration struct { metav1.TypeMetaApplyConfiguration `json:",inline"` // Standard object metadata diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaint.go index d9c2c6f48d..719168dbee 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaint.go @@ -43,8 +43,17 @@ type DeviceTaintApplyConfiguration struct { // nodes is not valid here. More effects may get added in the future. // Consumers must treat unknown effects like None. Effect *resourcev1alpha3.DeviceTaintEffect `json:"effect,omitempty"` - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. + // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). TimeAdded *v1.Time `json:"timeAdded,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/poolstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/poolstatus.go new file mode 100644 index 0000000000..343fe8247d --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/poolstatus.go @@ -0,0 +1,152 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha3 + +// PoolStatusApplyConfiguration represents a declarative configuration of the PoolStatus type for use +// with apply. +// +// PoolStatus contains status information for a single resource pool. +type PoolStatusApplyConfiguration struct { + // Driver is the DRA driver name for this pool. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + Driver *string `json:"driver,omitempty"` + // PoolName is the name of the pool. + // Must be a valid resource pool name (DNS subdomains separated by "/"). + PoolName *string `json:"poolName,omitempty"` + // Generation is the pool generation observed across all ResourceSlices + // in this pool. Only the latest generation is reported. During a generation + // rollout, if not all slices at the latest generation have been published, + // the pool is included with a validationError and device counts unset. + Generation *int64 `json:"generation,omitempty"` + // ResourceSliceCount is the number of ResourceSlices that make up this pool. + // May be unset when validationError is set. + ResourceSliceCount *int32 `json:"resourceSliceCount,omitempty"` + // TotalDevices is the total number of devices in the pool across all slices. + // A value of 0 means the pool has no devices. + // May be unset when validationError is set. + TotalDevices *int32 `json:"totalDevices,omitempty"` + // AllocatedDevices is the number of devices currently allocated to claims. + // A value of 0 means no devices are allocated. + // May be unset when validationError is set. + AllocatedDevices *int32 `json:"allocatedDevices,omitempty"` + // AvailableDevices is the number of devices available for allocation. + // This equals TotalDevices - AllocatedDevices - UnavailableDevices. + // A value of 0 means no devices are currently available. + // May be unset when validationError is set. + AvailableDevices *int32 `json:"availableDevices,omitempty"` + // UnavailableDevices is the number of devices that are not available + // due to taints or other conditions, but are not allocated. + // A value of 0 means all unallocated devices are available. + // May be unset when validationError is set. + UnavailableDevices *int32 `json:"unavailableDevices,omitempty"` + // NodeName is the node this pool is associated with. + // When omitted, the pool is not associated with a specific node. + // Must be a valid DNS subdomain name (RFC1123). + NodeName *string `json:"nodeName,omitempty"` + // ValidationError is set when the pool's data could not be fully + // validated (e.g., incomplete slice publication). When set, device + // count fields and ResourceSliceCount may be unset. + ValidationError *string `json:"validationError,omitempty"` +} + +// PoolStatusApplyConfiguration constructs a declarative configuration of the PoolStatus type for use with +// apply. +func PoolStatus() *PoolStatusApplyConfiguration { + return &PoolStatusApplyConfiguration{} +} + +// WithDriver sets the Driver field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Driver field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithDriver(value string) *PoolStatusApplyConfiguration { + b.Driver = &value + return b +} + +// WithPoolName sets the PoolName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PoolName field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithPoolName(value string) *PoolStatusApplyConfiguration { + b.PoolName = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithGeneration(value int64) *PoolStatusApplyConfiguration { + b.Generation = &value + return b +} + +// WithResourceSliceCount sets the ResourceSliceCount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceSliceCount field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithResourceSliceCount(value int32) *PoolStatusApplyConfiguration { + b.ResourceSliceCount = &value + return b +} + +// WithTotalDevices sets the TotalDevices field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TotalDevices field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithTotalDevices(value int32) *PoolStatusApplyConfiguration { + b.TotalDevices = &value + return b +} + +// WithAllocatedDevices sets the AllocatedDevices field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocatedDevices field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithAllocatedDevices(value int32) *PoolStatusApplyConfiguration { + b.AllocatedDevices = &value + return b +} + +// WithAvailableDevices sets the AvailableDevices field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AvailableDevices field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithAvailableDevices(value int32) *PoolStatusApplyConfiguration { + b.AvailableDevices = &value + return b +} + +// WithUnavailableDevices sets the UnavailableDevices field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UnavailableDevices field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithUnavailableDevices(value int32) *PoolStatusApplyConfiguration { + b.UnavailableDevices = &value + return b +} + +// WithNodeName sets the NodeName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the NodeName field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithNodeName(value string) *PoolStatusApplyConfiguration { + b.NodeName = &value + return b +} + +// WithValidationError sets the ValidationError field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ValidationError field is set to the value of the last call. +func (b *PoolStatusApplyConfiguration) WithValidationError(value string) *PoolStatusApplyConfiguration { + b.ValidationError = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequest.go similarity index 57% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/priorityclass.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequest.go index 1735a6deae..aee4d0ed90 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/priorityclass.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequest.go @@ -16,11 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha3 import ( - corev1 "k8s.io/api/core/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + resourcev1alpha3 "k8s.io/api/resource/v1alpha3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -28,85 +27,81 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// PriorityClassApplyConfiguration represents a declarative configuration of the PriorityClass type for use +// ResourcePoolStatusRequestApplyConfiguration represents a declarative configuration of the ResourcePoolStatusRequest type for use // with apply. // -// DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. -// PriorityClass defines mapping from a priority class name to the priority -// integer value. The value can be any valid integer. -type PriorityClassApplyConfiguration struct { +// ResourcePoolStatusRequest triggers a one-time calculation of resource pool status +// based on the provided filters. Once status is set, the request is considered complete and will not be reprocessed. +// Users should delete and recreate requests to get updated information. +type ResourcePoolStatusRequestApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // Standard object metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // value represents the integer value of this priority class. This is the actual priority that pods - // receive when they have the name of this class in their pod spec. - Value *int32 `json:"value,omitempty"` - // globalDefault specifies whether this PriorityClass should be considered as - // the default priority for pods that do not have any priority class. - // Only one PriorityClass can be marked as `globalDefault`. However, if more than - // one PriorityClasses exists with their `globalDefault` field set to true, - // the smallest value of such global default PriorityClasses will be used as the default priority. - GlobalDefault *bool `json:"globalDefault,omitempty"` - // description is an arbitrary string that usually provides guidelines on - // when this priority class should be used. - Description *string `json:"description,omitempty"` - // preemptionPolicy is the Policy for preempting pods with lower priority. - // One of Never, PreemptLowerPriority. - // Defaults to PreemptLowerPriority if unset. - PreemptionPolicy *corev1.PreemptionPolicy `json:"preemptionPolicy,omitempty"` + // Spec defines the filters for which pools to include in the status. + // The spec is immutable once created. + Spec *ResourcePoolStatusRequestSpecApplyConfiguration `json:"spec,omitempty"` + // Status is populated by the controller with the calculated pool status. + // When status is non-nil, the request is considered complete and the + // entire object becomes immutable. + Status *ResourcePoolStatusRequestStatusApplyConfiguration `json:"status,omitempty"` } -// PriorityClass constructs a declarative configuration of the PriorityClass type for use with +// ResourcePoolStatusRequest constructs a declarative configuration of the ResourcePoolStatusRequest type for use with // apply. -func PriorityClass(name string) *PriorityClassApplyConfiguration { - b := &PriorityClassApplyConfiguration{} +func ResourcePoolStatusRequest(name string) *ResourcePoolStatusRequestApplyConfiguration { + b := &ResourcePoolStatusRequestApplyConfiguration{} b.WithName(name) - b.WithKind("PriorityClass") - b.WithAPIVersion("scheduling.k8s.io/v1alpha1") + b.WithKind("ResourcePoolStatusRequest") + b.WithAPIVersion("resource.k8s.io/v1alpha3") return b } -// ExtractPriorityClassFrom extracts the applied configuration owned by fieldManager from -// priorityClass for the specified subresource. Pass an empty string for subresource to extract +// ExtractResourcePoolStatusRequestFrom extracts the applied configuration owned by fieldManager from +// resourcePoolStatusRequest for the specified subresource. Pass an empty string for subresource to extract // the main resource. Common subresources include "status", "scale", etc. -// priorityClass must be a unmodified PriorityClass API object that was retrieved from the Kubernetes API. -// ExtractPriorityClassFrom provides a way to perform a extract/modify-in-place/apply workflow. +// resourcePoolStatusRequest must be a unmodified ResourcePoolStatusRequest API object that was retrieved from the Kubernetes API. +// ExtractResourcePoolStatusRequestFrom provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractPriorityClassFrom(priorityClass *schedulingv1alpha1.PriorityClass, fieldManager string, subresource string) (*PriorityClassApplyConfiguration, error) { - b := &PriorityClassApplyConfiguration{} - err := managedfields.ExtractInto(priorityClass, internal.Parser().Type("io.k8s.api.scheduling.v1alpha1.PriorityClass"), fieldManager, b, subresource) +func ExtractResourcePoolStatusRequestFrom(resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, fieldManager string, subresource string) (*ResourcePoolStatusRequestApplyConfiguration, error) { + b := &ResourcePoolStatusRequestApplyConfiguration{} + err := managedfields.ExtractInto(resourcePoolStatusRequest, internal.Parser().Type("io.k8s.api.resource.v1alpha3.ResourcePoolStatusRequest"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(priorityClass.Name) + b.WithName(resourcePoolStatusRequest.Name) - b.WithKind("PriorityClass") - b.WithAPIVersion("scheduling.k8s.io/v1alpha1") + b.WithKind("ResourcePoolStatusRequest") + b.WithAPIVersion("resource.k8s.io/v1alpha3") return b, nil } -// ExtractPriorityClass extracts the applied configuration owned by fieldManager from -// priorityClass. If no managedFields are found in priorityClass for fieldManager, a -// PriorityClassApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractResourcePoolStatusRequest extracts the applied configuration owned by fieldManager from +// resourcePoolStatusRequest. If no managedFields are found in resourcePoolStatusRequest for fieldManager, a +// ResourcePoolStatusRequestApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// priorityClass must be a unmodified PriorityClass API object that was retrieved from the Kubernetes API. -// ExtractPriorityClass provides a way to perform a extract/modify-in-place/apply workflow. +// resourcePoolStatusRequest must be a unmodified ResourcePoolStatusRequest API object that was retrieved from the Kubernetes API. +// ExtractResourcePoolStatusRequest provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractPriorityClass(priorityClass *schedulingv1alpha1.PriorityClass, fieldManager string) (*PriorityClassApplyConfiguration, error) { - return ExtractPriorityClassFrom(priorityClass, fieldManager, "") +func ExtractResourcePoolStatusRequest(resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, fieldManager string) (*ResourcePoolStatusRequestApplyConfiguration, error) { + return ExtractResourcePoolStatusRequestFrom(resourcePoolStatusRequest, fieldManager, "") } -func (b PriorityClassApplyConfiguration) IsApplyConfiguration() {} +// ExtractResourcePoolStatusRequestStatus extracts the applied configuration owned by fieldManager from +// resourcePoolStatusRequest for the status subresource. +func ExtractResourcePoolStatusRequestStatus(resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, fieldManager string) (*ResourcePoolStatusRequestApplyConfiguration, error) { + return ExtractResourcePoolStatusRequestFrom(resourcePoolStatusRequest, fieldManager, "status") +} + +func (b ResourcePoolStatusRequestApplyConfiguration) IsApplyConfiguration() {} // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithKind(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithKind(value string) *ResourcePoolStatusRequestApplyConfiguration { b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -114,7 +109,7 @@ func (b *PriorityClassApplyConfiguration) WithKind(value string) *PriorityClassA // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithAPIVersion(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithAPIVersion(value string) *ResourcePoolStatusRequestApplyConfiguration { b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -122,7 +117,7 @@ func (b *PriorityClassApplyConfiguration) WithAPIVersion(value string) *Priority // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithName(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithName(value string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Name = &value return b @@ -131,7 +126,7 @@ func (b *PriorityClassApplyConfiguration) WithName(value string) *PriorityClassA // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithGenerateName(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithGenerateName(value string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.GenerateName = &value return b @@ -140,7 +135,7 @@ func (b *PriorityClassApplyConfiguration) WithGenerateName(value string) *Priori // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithNamespace(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithNamespace(value string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Namespace = &value return b @@ -149,7 +144,7 @@ func (b *PriorityClassApplyConfiguration) WithNamespace(value string) *PriorityC // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithUID(value types.UID) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithUID(value types.UID) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.UID = &value return b @@ -158,7 +153,7 @@ func (b *PriorityClassApplyConfiguration) WithUID(value types.UID) *PriorityClas // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithResourceVersion(value string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithResourceVersion(value string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b @@ -167,7 +162,7 @@ func (b *PriorityClassApplyConfiguration) WithResourceVersion(value string) *Pri // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithGeneration(value int64) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithGeneration(value int64) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Generation = &value return b @@ -176,7 +171,7 @@ func (b *PriorityClassApplyConfiguration) WithGeneration(value int64) *PriorityC // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b @@ -185,7 +180,7 @@ func (b *PriorityClassApplyConfiguration) WithCreationTimestamp(value metav1.Tim // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b @@ -194,7 +189,7 @@ func (b *PriorityClassApplyConfiguration) WithDeletionTimestamp(value metav1.Tim // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b @@ -204,7 +199,7 @@ func (b *PriorityClassApplyConfiguration) WithDeletionGracePeriodSeconds(value i // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *PriorityClassApplyConfiguration) WithLabels(entries map[string]string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithLabels(entries map[string]string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) @@ -219,7 +214,7 @@ func (b *PriorityClassApplyConfiguration) WithLabels(entries map[string]string) // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *PriorityClassApplyConfiguration) WithAnnotations(entries map[string]string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithAnnotations(entries map[string]string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) @@ -233,7 +228,7 @@ func (b *PriorityClassApplyConfiguration) WithAnnotations(entries map[string]str // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PriorityClassApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -247,7 +242,7 @@ func (b *PriorityClassApplyConfiguration) WithOwnerReferences(values ...*v1.Owne // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PriorityClassApplyConfiguration) WithFinalizers(values ...string) *PriorityClassApplyConfiguration { +func (b *ResourcePoolStatusRequestApplyConfiguration) WithFinalizers(values ...string) *ResourcePoolStatusRequestApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) @@ -255,62 +250,46 @@ func (b *PriorityClassApplyConfiguration) WithFinalizers(values ...string) *Prio return b } -func (b *PriorityClassApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *ResourcePoolStatusRequestApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } } -// WithValue sets the Value field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Value field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithValue(value int32) *PriorityClassApplyConfiguration { - b.Value = &value - return b -} - -// WithGlobalDefault sets the GlobalDefault field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the GlobalDefault field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithGlobalDefault(value bool) *PriorityClassApplyConfiguration { - b.GlobalDefault = &value - return b -} - -// WithDescription sets the Description field in the declarative configuration to the given value +// WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Description field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithDescription(value string) *PriorityClassApplyConfiguration { - b.Description = &value +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ResourcePoolStatusRequestApplyConfiguration) WithSpec(value *ResourcePoolStatusRequestSpecApplyConfiguration) *ResourcePoolStatusRequestApplyConfiguration { + b.Spec = value return b } -// WithPreemptionPolicy sets the PreemptionPolicy field in the declarative configuration to the given value +// WithStatus sets the Status field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PreemptionPolicy field is set to the value of the last call. -func (b *PriorityClassApplyConfiguration) WithPreemptionPolicy(value corev1.PreemptionPolicy) *PriorityClassApplyConfiguration { - b.PreemptionPolicy = &value +// If called multiple times, the Status field is set to the value of the last call. +func (b *ResourcePoolStatusRequestApplyConfiguration) WithStatus(value *ResourcePoolStatusRequestStatusApplyConfiguration) *ResourcePoolStatusRequestApplyConfiguration { + b.Status = value return b } // GetKind retrieves the value of the Kind field in the declarative configuration. -func (b *PriorityClassApplyConfiguration) GetKind() *string { +func (b *ResourcePoolStatusRequestApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind } // GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. -func (b *PriorityClassApplyConfiguration) GetAPIVersion() *string { +func (b *ResourcePoolStatusRequestApplyConfiguration) GetAPIVersion() *string { return b.TypeMetaApplyConfiguration.APIVersion } // GetName retrieves the value of the Name field in the declarative configuration. -func (b *PriorityClassApplyConfiguration) GetName() *string { +func (b *ResourcePoolStatusRequestApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Name } // GetNamespace retrieves the value of the Namespace field in the declarative configuration. -func (b *PriorityClassApplyConfiguration) GetNamespace() *string { +func (b *ResourcePoolStatusRequestApplyConfiguration) GetNamespace() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Namespace } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequestspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequestspec.go new file mode 100644 index 0000000000..bb86727321 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequestspec.go @@ -0,0 +1,73 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha3 + +// ResourcePoolStatusRequestSpecApplyConfiguration represents a declarative configuration of the ResourcePoolStatusRequestSpec type for use +// with apply. +// +// ResourcePoolStatusRequestSpec defines the filters for the pool status request. +type ResourcePoolStatusRequestSpecApplyConfiguration struct { + // Driver specifies the DRA driver name to filter pools. + // Only pools from ResourceSlices with this driver will be included. + // Must be a DNS subdomain (e.g., "gpu.example.com"). + Driver *string `json:"driver,omitempty"` + // PoolName optionally filters to a specific pool name. + // If not specified, all pools from the specified driver are included. + // When specified, must be a non-empty valid resource pool name + // (DNS subdomains separated by "/"). + PoolName *string `json:"poolName,omitempty"` + // Limit optionally specifies the maximum number of pools to return in the status. + // If more pools match the filter criteria, the response will be truncated + // (i.e., len(status.pools) < status.poolCount). + // + // Default: 100 + // Minimum: 1 + // Maximum: 1000 + Limit *int32 `json:"limit,omitempty"` +} + +// ResourcePoolStatusRequestSpecApplyConfiguration constructs a declarative configuration of the ResourcePoolStatusRequestSpec type for use with +// apply. +func ResourcePoolStatusRequestSpec() *ResourcePoolStatusRequestSpecApplyConfiguration { + return &ResourcePoolStatusRequestSpecApplyConfiguration{} +} + +// WithDriver sets the Driver field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Driver field is set to the value of the last call. +func (b *ResourcePoolStatusRequestSpecApplyConfiguration) WithDriver(value string) *ResourcePoolStatusRequestSpecApplyConfiguration { + b.Driver = &value + return b +} + +// WithPoolName sets the PoolName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PoolName field is set to the value of the last call. +func (b *ResourcePoolStatusRequestSpecApplyConfiguration) WithPoolName(value string) *ResourcePoolStatusRequestSpecApplyConfiguration { + b.PoolName = &value + return b +} + +// WithLimit sets the Limit field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Limit field is set to the value of the last call. +func (b *ResourcePoolStatusRequestSpecApplyConfiguration) WithLimit(value int32) *ResourcePoolStatusRequestSpecApplyConfiguration { + b.Limit = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequeststatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequeststatus.go new file mode 100644 index 0000000000..124c702900 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/resourcepoolstatusrequeststatus.go @@ -0,0 +1,87 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ResourcePoolStatusRequestStatusApplyConfiguration represents a declarative configuration of the ResourcePoolStatusRequestStatus type for use +// with apply. +// +// ResourcePoolStatusRequestStatus contains the calculated pool status information. +type ResourcePoolStatusRequestStatusApplyConfiguration struct { + // PoolCount is the total number of pools that matched the filter criteria, + // regardless of truncation. This helps users understand how many pools exist + // even when the response is truncated. A value of 0 means no pools matched + // the filter criteria. + PoolCount *int32 `json:"poolCount,omitempty"` + // Pools contains the first `spec.limit` matching pools, sorted by driver + // then pool name. If `len(pools) < poolCount`, the list was truncated. + // When omitted, no pools matched the request filters. + Pools []PoolStatusApplyConfiguration `json:"pools,omitempty"` + // Conditions provide information about the state of the request. + // A condition with type=Complete or type=Failed will always be set + // when the status is populated. + // + // Known condition types: + // - "Complete": True when the request has been processed successfully + // - "Failed": True when the request could not be processed + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ResourcePoolStatusRequestStatusApplyConfiguration constructs a declarative configuration of the ResourcePoolStatusRequestStatus type for use with +// apply. +func ResourcePoolStatusRequestStatus() *ResourcePoolStatusRequestStatusApplyConfiguration { + return &ResourcePoolStatusRequestStatusApplyConfiguration{} +} + +// WithPoolCount sets the PoolCount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PoolCount field is set to the value of the last call. +func (b *ResourcePoolStatusRequestStatusApplyConfiguration) WithPoolCount(value int32) *ResourcePoolStatusRequestStatusApplyConfiguration { + b.PoolCount = &value + return b +} + +// WithPools adds the given value to the Pools field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Pools field. +func (b *ResourcePoolStatusRequestStatusApplyConfiguration) WithPools(values ...*PoolStatusApplyConfiguration) *ResourcePoolStatusRequestStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPools") + } + b.Pools = append(b.Pools, *values[i]) + } + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ResourcePoolStatusRequestStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ResourcePoolStatusRequestStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocationresult.go index f6fd7e2034..594dc364bc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocationresult.go @@ -36,7 +36,7 @@ type AllocationResultApplyConfiguration struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. AllocationTimestamp *metav1.Time `json:"allocationTimestamp,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/basicdevice.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/basicdevice.go index 8a0241a2f3..64527b2938 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/basicdevice.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/basicdevice.go @@ -19,6 +19,7 @@ limitations under the License. package v1beta1 import ( + corev1 "k8s.io/api/core/v1" resourcev1beta1 "k8s.io/api/resource/v1beta1" v1 "k8s.io/client-go/applyconfigurations/core/v1" ) @@ -70,7 +71,7 @@ type BasicDeviceApplyConfiguration struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Taints []DeviceTaintApplyConfiguration `json:"taints,omitempty"` // BindsToNode indicates if the usage of an allocation involving this device @@ -78,7 +79,7 @@ type BasicDeviceApplyConfiguration struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindsToNode *bool `json:"bindsToNode,omitempty"` // BindingConditions defines the conditions for proceeding with binding. @@ -90,7 +91,7 @@ type BasicDeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions defines the conditions for binding failure. @@ -101,7 +102,7 @@ type BasicDeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -109,6 +110,18 @@ type BasicDeviceApplyConfiguration struct { // If AllowMultipleAllocations is set to true, the device can be allocated more than once, // and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not. AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty"` + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + NodeAllocatableResourceMappings map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration `json:"nodeAllocatableResourceMappings,omitempty"` } // BasicDeviceApplyConfiguration constructs a declarative configuration of the BasicDevice type for use with @@ -230,3 +243,17 @@ func (b *BasicDeviceApplyConfiguration) WithAllowMultipleAllocations(value bool) b.AllowMultipleAllocations = &value return b } + +// WithNodeAllocatableResourceMappings puts the entries into the NodeAllocatableResourceMappings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeAllocatableResourceMappings field, +// overwriting an existing map entries in NodeAllocatableResourceMappings field with the same key. +func (b *BasicDeviceApplyConfiguration) WithNodeAllocatableResourceMappings(entries map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration) *BasicDeviceApplyConfiguration { + if b.NodeAllocatableResourceMappings == nil && len(entries) > 0 { + b.NodeAllocatableResourceMappings = make(map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration, len(entries)) + } + for k, v := range entries { + b.NodeAllocatableResourceMappings[k] = v + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/celdeviceselector.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/celdeviceselector.go index 42708c5c9f..ba65467ae5 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/celdeviceselector.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/celdeviceselector.go @@ -72,6 +72,14 @@ type CELDeviceSelectorApplyConfiguration struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceattribute.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceattribute.go index a4e9fe8504..178f70fb76 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceattribute.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceattribute.go @@ -32,6 +32,22 @@ type DeviceAttributeApplyConfiguration struct { // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. VersionValue *string `json:"version,omitempty"` + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + IntValues []int64 `json:"ints,omitempty"` + // BoolValues is a non-empty list of true/false values. + BoolValues []bool `json:"bools,omitempty"` + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + StringValues []string `json:"strings,omitempty"` + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + VersionValues []string `json:"versions,omitempty"` } // DeviceAttributeApplyConfiguration constructs a declarative configuration of the DeviceAttribute type for use with @@ -71,3 +87,43 @@ func (b *DeviceAttributeApplyConfiguration) WithVersionValue(value string) *Devi b.VersionValue = &value return b } + +// WithIntValues adds the given value to the IntValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the IntValues field. +func (b *DeviceAttributeApplyConfiguration) WithIntValues(values ...int64) *DeviceAttributeApplyConfiguration { + for i := range values { + b.IntValues = append(b.IntValues, values[i]) + } + return b +} + +// WithBoolValues adds the given value to the BoolValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the BoolValues field. +func (b *DeviceAttributeApplyConfiguration) WithBoolValues(values ...bool) *DeviceAttributeApplyConfiguration { + for i := range values { + b.BoolValues = append(b.BoolValues, values[i]) + } + return b +} + +// WithStringValues adds the given value to the StringValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the StringValues field. +func (b *DeviceAttributeApplyConfiguration) WithStringValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.StringValues = append(b.StringValues, values[i]) + } + return b +} + +// WithVersionValues adds the given value to the VersionValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the VersionValues field. +func (b *DeviceAttributeApplyConfiguration) WithVersionValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.VersionValues = append(b.VersionValues, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceclassspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceclassspec.go index 942da3efed..c234bdd732 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceclassspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceclassspec.go @@ -41,7 +41,7 @@ type DeviceClassSpecApplyConfiguration struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. ExtendedResourceName *string `json:"extendedResourceName,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceconstraint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceconstraint.go index 1716c92331..8cbdee16d9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceconstraint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/deviceconstraint.go @@ -48,11 +48,21 @@ type DeviceConstraintApplyConfiguration struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. MatchAttribute *resourcev1beta1.FullyQualifiedName `json:"matchAttribute,omitempty"` // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequest.go index eab54ba01c..fdcb928a57 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequest.go @@ -133,7 +133,7 @@ type DeviceRequestApplyConfiguration struct { // This field can only be set when deviceClassName is set and no subrequests // are specified in the firstAvailable list. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go index 2171522a35..3a47b9c1f6 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go @@ -66,19 +66,19 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // ShareID uniquely identifies an individual allocation share of the device, diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicesubrequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicesubrequest.go index 2701074e90..ae7bf65a04 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicesubrequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicesubrequest.go @@ -94,7 +94,7 @@ type DeviceSubRequestApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetaint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetaint.go index 55c7d58a68..32b37402c5 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetaint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetaint.go @@ -43,8 +43,17 @@ type DeviceTaintApplyConfiguration struct { // nodes is not valid here. More effects may get added in the future. // Consumers must treat unknown effects like None. Effect *resourcev1beta1.DeviceTaintEffect `json:"effect,omitempty"` - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. + // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). TimeAdded *v1.Time `json:"timeAdded,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/networkdevicedata.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/networkdevicedata.go index 5c3edcfe88..f112f01454 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/networkdevicedata.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/networkdevicedata.go @@ -29,7 +29,7 @@ type NetworkDeviceDataApplyConfiguration struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. InterfaceName *string `json:"interfaceName,omitempty"` // IPs lists the network addresses assigned to the device's network interface. // This can include both IPv4 and IPv6 addresses. @@ -41,7 +41,7 @@ type NetworkDeviceDataApplyConfiguration struct { IPs []string `json:"ips,omitempty"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. HardwareAddress *string `json:"hardwareAddress,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/nodeallocatableresourcemapping.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/nodeallocatableresourcemapping.go new file mode 100644 index 0000000000..5cdc2c7512 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/nodeallocatableresourcemapping.go @@ -0,0 +1,84 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +import ( + resourcev1beta1 "k8s.io/api/resource/v1beta1" + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NodeAllocatableResourceMappingApplyConfiguration represents a declarative configuration of the NodeAllocatableResourceMapping type for use +// with apply. +// +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMappingApplyConfiguration struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + CapacityKey *resourcev1beta1.QualifiedName `json:"capacityKey,omitempty"` + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty"` +} + +// NodeAllocatableResourceMappingApplyConfiguration constructs a declarative configuration of the NodeAllocatableResourceMapping type for use with +// apply. +func NodeAllocatableResourceMapping() *NodeAllocatableResourceMappingApplyConfiguration { + return &NodeAllocatableResourceMappingApplyConfiguration{} +} + +// WithCapacityKey sets the CapacityKey field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CapacityKey field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithCapacityKey(value resourcev1beta1.QualifiedName) *NodeAllocatableResourceMappingApplyConfiguration { + b.CapacityKey = &value + return b +} + +// WithAllocationMultiplier sets the AllocationMultiplier field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocationMultiplier field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithAllocationMultiplier(value resource.Quantity) *NodeAllocatableResourceMappingApplyConfiguration { + b.AllocationMultiplier = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocationresult.go index 91db54f92e..540b37ed59 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocationresult.go @@ -36,7 +36,7 @@ type AllocationResultApplyConfiguration struct { // AllocationTimestamp stores the time when the resources were allocated. // This field is not guaranteed to be set, in which case that time is unknown. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gate. AllocationTimestamp *metav1.Time `json:"allocationTimestamp,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/celdeviceselector.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/celdeviceselector.go index 861168b9e7..a184590ebe 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/celdeviceselector.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/celdeviceselector.go @@ -72,6 +72,14 @@ type CELDeviceSelectorApplyConfiguration struct { // // cel.bind(dra, device.attributes["dra.example.com"], dra.someBool && dra.anotherBool) // + // When the DRAListTypeAttributes feature gate is enabled, + // the includes() helper is available and it can work for both scalar + // and list-type attributes. It was introduced to support smooth migration + // from scalar attributes to list-type attributes while keeping + // CEL expressions simple. For example: + // + // device.attributes["dra.example.com"].models.includes("some-model") + // // The length of the expression must be smaller or equal to 10 Ki. The // cost of evaluating it is also limited based on the estimated number // of logical steps. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/device.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/device.go index 607c9f5eb7..b3985b0ca5 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/device.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/device.go @@ -19,6 +19,7 @@ limitations under the License. package v1beta2 import ( + corev1 "k8s.io/api/core/v1" resourcev1beta2 "k8s.io/api/resource/v1beta2" v1 "k8s.io/client-go/applyconfigurations/core/v1" ) @@ -74,7 +75,7 @@ type DeviceApplyConfiguration struct { // any device in a ResourceSlice, then the maximum number of // allowed devices per ResourceSlice is 64 instead of 128. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Taints []DeviceTaintApplyConfiguration `json:"taints,omitempty"` // BindsToNode indicates if the usage of an allocation involving this device @@ -82,7 +83,7 @@ type DeviceApplyConfiguration struct { // If set to true, the scheduler will set the ResourceClaim.Status.Allocation.NodeSelector // to match the node where the allocation was made. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindsToNode *bool `json:"bindsToNode,omitempty"` // BindingConditions defines the conditions for proceeding with binding. @@ -94,7 +95,7 @@ type DeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions defines the conditions for binding failure. @@ -105,7 +106,7 @@ type DeviceApplyConfiguration struct { // // The conditions must be a valid condition type string. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // AllowMultipleAllocations marks whether the device is allowed to be allocated to multiple DeviceRequests. @@ -113,6 +114,18 @@ type DeviceApplyConfiguration struct { // If AllowMultipleAllocations is set to true, the device can be allocated more than once, // and all of its capacity is consumable, regardless of whether the requestPolicy is defined or not. AllowMultipleAllocations *bool `json:"allowMultipleAllocations,omitempty"` + // NodeAllocatableResourceMappings defines the mapping of node resources + // that are managed by the DRA driver exposing this device. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // In addition to standard requests made through the Pod `spec`, these resources + // can also be requested through claims and allocated by the DRA driver. + // For example, a CPU DRA driver might allocate exclusive CPUs or auxiliary node memory + // dependencies of an accelerator device. + // The keys of this map are the node-allocatable resource names (e.g., "cpu", "memory"). + // Extended resource names are not permitted as keys. + NodeAllocatableResourceMappings map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration `json:"nodeAllocatableResourceMappings,omitempty"` } // DeviceApplyConfiguration constructs a declarative configuration of the Device type for use with @@ -242,3 +255,17 @@ func (b *DeviceApplyConfiguration) WithAllowMultipleAllocations(value bool) *Dev b.AllowMultipleAllocations = &value return b } + +// WithNodeAllocatableResourceMappings puts the entries into the NodeAllocatableResourceMappings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the NodeAllocatableResourceMappings field, +// overwriting an existing map entries in NodeAllocatableResourceMappings field with the same key. +func (b *DeviceApplyConfiguration) WithNodeAllocatableResourceMappings(entries map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration) *DeviceApplyConfiguration { + if b.NodeAllocatableResourceMappings == nil && len(entries) > 0 { + b.NodeAllocatableResourceMappings = make(map[corev1.ResourceName]NodeAllocatableResourceMappingApplyConfiguration, len(entries)) + } + for k, v := range entries { + b.NodeAllocatableResourceMappings[k] = v + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceattribute.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceattribute.go index 63c7f20510..9929e54121 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceattribute.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceattribute.go @@ -32,6 +32,22 @@ type DeviceAttributeApplyConfiguration struct { // VersionValue is a semantic version according to semver.org spec 2.0.0. // Must not be longer than 64 characters. VersionValue *string `json:"version,omitempty"` + // IntValues is a non-empty list of numbers. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + IntValues []int64 `json:"ints,omitempty"` + // BoolValues is a non-empty list of true/false values. + BoolValues []bool `json:"bools,omitempty"` + // StringValues is a non-empty list of strings. + // Each string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + StringValues []string `json:"strings,omitempty"` + // VersionValues is a non-empty list of semantic versions according to semver.org spec 2.0.0. + // Each version string must not be longer than 64 characters. + // + // This is an alpha field and requires enabling the DRAListTypeAttributes feature gate. + VersionValues []string `json:"versions,omitempty"` } // DeviceAttributeApplyConfiguration constructs a declarative configuration of the DeviceAttribute type for use with @@ -71,3 +87,43 @@ func (b *DeviceAttributeApplyConfiguration) WithVersionValue(value string) *Devi b.VersionValue = &value return b } + +// WithIntValues adds the given value to the IntValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the IntValues field. +func (b *DeviceAttributeApplyConfiguration) WithIntValues(values ...int64) *DeviceAttributeApplyConfiguration { + for i := range values { + b.IntValues = append(b.IntValues, values[i]) + } + return b +} + +// WithBoolValues adds the given value to the BoolValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the BoolValues field. +func (b *DeviceAttributeApplyConfiguration) WithBoolValues(values ...bool) *DeviceAttributeApplyConfiguration { + for i := range values { + b.BoolValues = append(b.BoolValues, values[i]) + } + return b +} + +// WithStringValues adds the given value to the StringValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the StringValues field. +func (b *DeviceAttributeApplyConfiguration) WithStringValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.StringValues = append(b.StringValues, values[i]) + } + return b +} + +// WithVersionValues adds the given value to the VersionValues field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the VersionValues field. +func (b *DeviceAttributeApplyConfiguration) WithVersionValues(values ...string) *DeviceAttributeApplyConfiguration { + for i := range values { + b.VersionValues = append(b.VersionValues, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassspec.go index e270c5908b..4ae2eaa29f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassspec.go @@ -41,7 +41,7 @@ type DeviceClassSpecApplyConfiguration struct { // If two classes are created at the same time, then the name of the class // lexicographically sorted first is picked. // - // This is an alpha field. + // This is a beta field. ExtendedResourceName *string `json:"extendedResourceName,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconstraint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconstraint.go index 81a682c82b..05d914af41 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconstraint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconstraint.go @@ -48,11 +48,21 @@ type DeviceConstraintApplyConfiguration struct { // its specification, but if one device doesn't, then it also will not be // chosen. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics(i.e., element order and duplicates are ignored): list-valued attributes + // match when the intersection across all devices is non-empty. + // Scalar values are treated as singleton sets for backward compatibility. + // // Must include the domain qualifier. MatchAttribute *resourcev1beta2.FullyQualifiedName `json:"matchAttribute,omitempty"` // DistinctAttribute requires that all devices in question have this // attribute and that its type and value are unique across those devices. // + // When the DRAListTypeAttributes feature gate is enabled, comparison uses + // set semantics (i.e., element order and duplicates are ignored): + // list-valued attributes must be pairwise disjoint across devices. + // Scalar values are treated as singleton sets for backward compatibility. + // // This acts as the inverse of MatchAttribute. // // This constraint is used to avoid allocating multiple requests to the same device diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go index c1fd0266f5..a274e5706c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go @@ -66,19 +66,19 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // BindingConditions contains a copy of the BindingConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingConditions []string `json:"bindingConditions,omitempty"` // BindingFailureConditions contains a copy of the BindingFailureConditions // from the corresponding ResourceSlice at the time of allocation. // - // This is an alpha field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus + // This is a beta field and requires enabling the DRADeviceBindingConditions and DRAResourceClaimDeviceStatus // feature gates. BindingFailureConditions []string `json:"bindingFailureConditions,omitempty"` // ShareID uniquely identifies an individual allocation share of the device, diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicesubrequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicesubrequest.go index 79345cf6c5..d9f4a5cb57 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicesubrequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicesubrequest.go @@ -93,7 +93,7 @@ type DeviceSubRequestApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaint.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaint.go index 8049f52cc0..91abce3bb3 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaint.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaint.go @@ -43,8 +43,17 @@ type DeviceTaintApplyConfiguration struct { // nodes is not valid here. More effects may get added in the future. // Consumers must treat unknown effects like None. Effect *resourcev1beta2.DeviceTaintEffect `json:"effect,omitempty"` - // TimeAdded represents the time at which the taint was added. + // TimeAdded represents the time at which the taint was added or + // (only in a DeviceTaintRule) the effect was modified. // Added automatically during create or update if not set. + // + // In addition, in a DeviceTaintRule a value provided during + // an update gets replaced with the current time if the provided + // value is the same as the old one and the new effect is different. + // Changing the key and/or value while keeping the effect unchanged + // is possible and does not update the time stamp because the eviction + // which uses it is either already started (NoExecute) or + // not started yet (NoEffect, NoSchedule). TimeAdded *v1.Time `json:"timeAdded,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrule.go similarity index 60% rename from vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscaler.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrule.go index 9a4588bc8c..18b2aca188 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrule.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v2beta2 +package v1beta2 import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" + resourcev1beta2 "k8s.io/api/resource/v1beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,82 +27,80 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// HorizontalPodAutoscalerApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscaler type for use +// DeviceTaintRuleApplyConfiguration represents a declarative configuration of the DeviceTaintRule type for use // with apply. // -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -type HorizontalPodAutoscalerApplyConfiguration struct { +// DeviceTaintRule adds one taint to all devices which match the selector. +// This has the same effect as if the taint was specified directly +// in the ResourceSlice by the DRA driver. +type DeviceTaintRuleApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // metadata is the standard object metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // Standard object metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - Spec *HorizontalPodAutoscalerSpecApplyConfiguration `json:"spec,omitempty"` - // status is the current information about the autoscaler. - Status *HorizontalPodAutoscalerStatusApplyConfiguration `json:"status,omitempty"` + // Spec specifies the selector and one taint. + // + // Changing the spec automatically increments the metadata.generation number. + Spec *DeviceTaintRuleSpecApplyConfiguration `json:"spec,omitempty"` + // Status provides information about what was requested in the spec. + Status *DeviceTaintRuleStatusApplyConfiguration `json:"status,omitempty"` } -// HorizontalPodAutoscaler constructs a declarative configuration of the HorizontalPodAutoscaler type for use with +// DeviceTaintRule constructs a declarative configuration of the DeviceTaintRule type for use with // apply. -func HorizontalPodAutoscaler(name, namespace string) *HorizontalPodAutoscalerApplyConfiguration { - b := &HorizontalPodAutoscalerApplyConfiguration{} +func DeviceTaintRule(name string) *DeviceTaintRuleApplyConfiguration { + b := &DeviceTaintRuleApplyConfiguration{} b.WithName(name) - b.WithNamespace(namespace) - b.WithKind("HorizontalPodAutoscaler") - b.WithAPIVersion("autoscaling/v2beta2") + b.WithKind("DeviceTaintRule") + b.WithAPIVersion("resource.k8s.io/v1beta2") return b } -// ExtractHorizontalPodAutoscalerFrom extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler for the specified subresource. Pass an empty string for subresource to extract +// ExtractDeviceTaintRuleFrom extracts the applied configuration owned by fieldManager from +// deviceTaintRule for the specified subresource. Pass an empty string for subresource to extract // the main resource. Common subresources include "status", "scale", etc. -// horizontalPodAutoscaler must be a unmodified HorizontalPodAutoscaler API object that was retrieved from the Kubernetes API. -// ExtractHorizontalPodAutoscalerFrom provides a way to perform a extract/modify-in-place/apply workflow. +// deviceTaintRule must be a unmodified DeviceTaintRule API object that was retrieved from the Kubernetes API. +// ExtractDeviceTaintRuleFrom provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, fieldManager string, subresource string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - b := &HorizontalPodAutoscalerApplyConfiguration{} - err := managedfields.ExtractInto(horizontalPodAutoscaler, internal.Parser().Type("io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscaler"), fieldManager, b, subresource) +func ExtractDeviceTaintRuleFrom(deviceTaintRule *resourcev1beta2.DeviceTaintRule, fieldManager string, subresource string) (*DeviceTaintRuleApplyConfiguration, error) { + b := &DeviceTaintRuleApplyConfiguration{} + err := managedfields.ExtractInto(deviceTaintRule, internal.Parser().Type("io.k8s.api.resource.v1beta2.DeviceTaintRule"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(horizontalPodAutoscaler.Name) - b.WithNamespace(horizontalPodAutoscaler.Namespace) + b.WithName(deviceTaintRule.Name) - b.WithKind("HorizontalPodAutoscaler") - b.WithAPIVersion("autoscaling/v2beta2") + b.WithKind("DeviceTaintRule") + b.WithAPIVersion("resource.k8s.io/v1beta2") return b, nil } -// ExtractHorizontalPodAutoscaler extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler. If no managedFields are found in horizontalPodAutoscaler for fieldManager, a -// HorizontalPodAutoscalerApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractDeviceTaintRule extracts the applied configuration owned by fieldManager from +// deviceTaintRule. If no managedFields are found in deviceTaintRule for fieldManager, a +// DeviceTaintRuleApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// horizontalPodAutoscaler must be a unmodified HorizontalPodAutoscaler API object that was retrieved from the Kubernetes API. -// ExtractHorizontalPodAutoscaler provides a way to perform a extract/modify-in-place/apply workflow. +// deviceTaintRule must be a unmodified DeviceTaintRule API object that was retrieved from the Kubernetes API. +// ExtractDeviceTaintRule provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractHorizontalPodAutoscaler(horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, fieldManager string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - return ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler, fieldManager, "") +func ExtractDeviceTaintRule(deviceTaintRule *resourcev1beta2.DeviceTaintRule, fieldManager string) (*DeviceTaintRuleApplyConfiguration, error) { + return ExtractDeviceTaintRuleFrom(deviceTaintRule, fieldManager, "") } -// ExtractHorizontalPodAutoscalerStatus extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler for the status subresource. -func ExtractHorizontalPodAutoscalerStatus(horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, fieldManager string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - return ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler, fieldManager, "status") +// ExtractDeviceTaintRuleStatus extracts the applied configuration owned by fieldManager from +// deviceTaintRule for the status subresource. +func ExtractDeviceTaintRuleStatus(deviceTaintRule *resourcev1beta2.DeviceTaintRule, fieldManager string) (*DeviceTaintRuleApplyConfiguration, error) { + return ExtractDeviceTaintRuleFrom(deviceTaintRule, fieldManager, "status") } -func (b HorizontalPodAutoscalerApplyConfiguration) IsApplyConfiguration() {} +func (b DeviceTaintRuleApplyConfiguration) IsApplyConfiguration() {} // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithKind(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithKind(value string) *DeviceTaintRuleApplyConfiguration { b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -110,7 +108,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithKind(value string) *Hori // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithAPIVersion(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithAPIVersion(value string) *DeviceTaintRuleApplyConfiguration { b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -118,7 +116,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithAPIVersion(value string) // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithName(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithName(value string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Name = &value return b @@ -127,7 +125,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithName(value string) *Hori // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithGenerateName(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithGenerateName(value string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.GenerateName = &value return b @@ -136,7 +134,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithGenerateName(value strin // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithNamespace(value string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Namespace = &value return b @@ -145,7 +143,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string) // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithUID(value types.UID) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithUID(value types.UID) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.UID = &value return b @@ -154,7 +152,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithUID(value types.UID) *Ho // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithResourceVersion(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithResourceVersion(value string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b @@ -163,7 +161,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithResourceVersion(value st // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithGeneration(value int64) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithGeneration(value int64) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Generation = &value return b @@ -172,7 +170,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithGeneration(value int64) // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithCreationTimestamp(value metav1.Time) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithCreationTimestamp(value metav1.Time) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b @@ -181,7 +179,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithCreationTimestamp(value // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b @@ -190,7 +188,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionTimestamp(value // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b @@ -200,7 +198,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionGracePeriodSecon // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithLabels(entries map[string]string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithLabels(entries map[string]string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) @@ -215,7 +213,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithLabels(entries map[strin // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithAnnotations(entries map[string]string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithAnnotations(entries map[string]string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) @@ -229,7 +227,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithAnnotations(entries map[ // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -243,7 +241,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithOwnerReferences(values . // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithFinalizers(values ...string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithFinalizers(values ...string) *DeviceTaintRuleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) @@ -251,7 +249,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithFinalizers(values ...str return b } -func (b *HorizontalPodAutoscalerApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *DeviceTaintRuleApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -260,7 +258,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) ensureObjectMetaApplyConfigu // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithSpec(value *HorizontalPodAutoscalerSpecApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithSpec(value *DeviceTaintRuleSpecApplyConfiguration) *DeviceTaintRuleApplyConfiguration { b.Spec = value return b } @@ -268,29 +266,29 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithSpec(value *HorizontalPo // WithStatus sets the Status field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Status field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithStatus(value *HorizontalPodAutoscalerStatusApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *DeviceTaintRuleApplyConfiguration) WithStatus(value *DeviceTaintRuleStatusApplyConfiguration) *DeviceTaintRuleApplyConfiguration { b.Status = value return b } // GetKind retrieves the value of the Kind field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetKind() *string { +func (b *DeviceTaintRuleApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind } // GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetAPIVersion() *string { +func (b *DeviceTaintRuleApplyConfiguration) GetAPIVersion() *string { return b.TypeMetaApplyConfiguration.APIVersion } // GetName retrieves the value of the Name field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetName() *string { +func (b *DeviceTaintRuleApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Name } // GetNamespace retrieves the value of the Namespace field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetNamespace() *string { +func (b *DeviceTaintRuleApplyConfiguration) GetNamespace() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Namespace } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulespec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulespec.go new file mode 100644 index 0000000000..7328296e7c --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulespec.go @@ -0,0 +1,55 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +// DeviceTaintRuleSpecApplyConfiguration represents a declarative configuration of the DeviceTaintRuleSpec type for use +// with apply. +// +// DeviceTaintRuleSpec specifies the selector and one taint. +type DeviceTaintRuleSpecApplyConfiguration struct { + // DeviceSelector defines which device(s) the taint is applied to. + // All selector criteria must be satisfied for a device to + // match. The empty selector matches all devices. Without + // a selector, no devices are matches. + DeviceSelector *DeviceTaintSelectorApplyConfiguration `json:"deviceSelector,omitempty"` + // The taint that gets applied to matching devices. + Taint *DeviceTaintApplyConfiguration `json:"taint,omitempty"` +} + +// DeviceTaintRuleSpecApplyConfiguration constructs a declarative configuration of the DeviceTaintRuleSpec type for use with +// apply. +func DeviceTaintRuleSpec() *DeviceTaintRuleSpecApplyConfiguration { + return &DeviceTaintRuleSpecApplyConfiguration{} +} + +// WithDeviceSelector sets the DeviceSelector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeviceSelector field is set to the value of the last call. +func (b *DeviceTaintRuleSpecApplyConfiguration) WithDeviceSelector(value *DeviceTaintSelectorApplyConfiguration) *DeviceTaintRuleSpecApplyConfiguration { + b.DeviceSelector = value + return b +} + +// WithTaint sets the Taint field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Taint field is set to the value of the last call. +func (b *DeviceTaintRuleSpecApplyConfiguration) WithTaint(value *DeviceTaintApplyConfiguration) *DeviceTaintRuleSpecApplyConfiguration { + b.Taint = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulestatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulestatus.go new file mode 100644 index 0000000000..7b92c5e8e0 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintrulestatus.go @@ -0,0 +1,70 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// DeviceTaintRuleStatusApplyConfiguration represents a declarative configuration of the DeviceTaintRuleStatus type for use +// with apply. +// +// DeviceTaintRuleStatus provides information about an on-going pod eviction. +type DeviceTaintRuleStatusApplyConfiguration struct { + // Conditions provide information about the state of the DeviceTaintRule + // and the cluster at some point in time, + // in a machine-readable and human-readable format. + // + // The following condition is currently defined as part of this API, more may + // get added: + // - Type: EvictionInProgress + // - Status: True if there are currently pods which need to be evicted, False otherwise + // (includes the effects which don't cause eviction). + // - Reason: not specified, may change + // - Message: includes information about number of pending pods and already evicted pods + // in a human-readable format, updated periodically, may change + // + // For `effect: None`, the condition above gets set once for each change to + // the spec, with the message containing information about what would happen + // if the effect was `NoExecute`. This feedback can be used to decide whether + // changing the effect to `NoExecute` will work as intended. It only gets + // set once to avoid having to constantly update the status. + // + // Must have 8 or fewer entries. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// DeviceTaintRuleStatusApplyConfiguration constructs a declarative configuration of the DeviceTaintRuleStatus type for use with +// apply. +func DeviceTaintRuleStatus() *DeviceTaintRuleStatusApplyConfiguration { + return &DeviceTaintRuleStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *DeviceTaintRuleStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *DeviceTaintRuleStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintselector.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintselector.go new file mode 100644 index 0000000000..1aeaed7204 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaintselector.go @@ -0,0 +1,76 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +// DeviceTaintSelectorApplyConfiguration represents a declarative configuration of the DeviceTaintSelector type for use +// with apply. +// +// DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. +// The empty selector matches all devices. Without a selector, no devices +// are matched. +type DeviceTaintSelectorApplyConfiguration struct { + // If driver is set, only devices from that driver are selected. + // This fields corresponds to slice.spec.driver. + Driver *string `json:"driver,omitempty"` + // If pool is set, only devices in that pool are selected. + // + // Also setting the driver name may be useful to avoid + // ambiguity when different drivers use the same pool name, + // but this is not required because selecting pools from + // different drivers may also be useful, for example when + // drivers with node-local devices use the node name as + // their pool name. + Pool *string `json:"pool,omitempty"` + // If device is set, only devices with that name are selected. + // This field corresponds to slice.spec.devices[].name. + // + // Setting also driver and pool may be required to avoid ambiguity, + // but is not required. + Device *string `json:"device,omitempty"` +} + +// DeviceTaintSelectorApplyConfiguration constructs a declarative configuration of the DeviceTaintSelector type for use with +// apply. +func DeviceTaintSelector() *DeviceTaintSelectorApplyConfiguration { + return &DeviceTaintSelectorApplyConfiguration{} +} + +// WithDriver sets the Driver field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Driver field is set to the value of the last call. +func (b *DeviceTaintSelectorApplyConfiguration) WithDriver(value string) *DeviceTaintSelectorApplyConfiguration { + b.Driver = &value + return b +} + +// WithPool sets the Pool field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Pool field is set to the value of the last call. +func (b *DeviceTaintSelectorApplyConfiguration) WithPool(value string) *DeviceTaintSelectorApplyConfiguration { + b.Pool = &value + return b +} + +// WithDevice sets the Device field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Device field is set to the value of the last call. +func (b *DeviceTaintSelectorApplyConfiguration) WithDevice(value string) *DeviceTaintSelectorApplyConfiguration { + b.Device = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/exactdevicerequest.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/exactdevicerequest.go index e4c5d59963..bda1152701 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/exactdevicerequest.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/exactdevicerequest.go @@ -91,7 +91,7 @@ type ExactDeviceRequestApplyConfiguration struct { // // The maximum number of tolerations is 16. // - // This is an alpha field and requires enabling the DRADeviceTaints + // This is a beta field and requires enabling the DRADeviceTaints // feature gate. Tolerations []DeviceTolerationApplyConfiguration `json:"tolerations,omitempty"` // Capacity define resource requirements against each capacity. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/networkdevicedata.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/networkdevicedata.go index 9621703268..238e5412f1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/networkdevicedata.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/networkdevicedata.go @@ -29,7 +29,7 @@ type NetworkDeviceDataApplyConfiguration struct { // the allocated device. This might be the name of a physical or virtual // network interface being configured in the pod. // - // Must not be longer than 256 characters. + // Must not be longer than 256 bytes. InterfaceName *string `json:"interfaceName,omitempty"` // IPs lists the network addresses assigned to the device's network interface. // This can include both IPv4 and IPv6 addresses. @@ -39,7 +39,7 @@ type NetworkDeviceDataApplyConfiguration struct { IPs []string `json:"ips,omitempty"` // HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // - // Must not be longer than 128 characters. + // Must not be longer than 128 bytes. HardwareAddress *string `json:"hardwareAddress,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/nodeallocatableresourcemapping.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/nodeallocatableresourcemapping.go new file mode 100644 index 0000000000..b1490b5e75 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/nodeallocatableresourcemapping.go @@ -0,0 +1,84 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta2 + +import ( + resourcev1beta2 "k8s.io/api/resource/v1beta2" + resource "k8s.io/apimachinery/pkg/api/resource" +) + +// NodeAllocatableResourceMappingApplyConfiguration represents a declarative configuration of the NodeAllocatableResourceMapping type for use +// with apply. +// +// NodeAllocatableResourceMapping defines the translation between the DRA device/capacity +// units requested to the corresponding quantity of the node allocatable resource. +type NodeAllocatableResourceMappingApplyConfiguration struct { + // CapacityKey references a capacity name defined as a key in the + // `spec.devices[*].capacity` map. When this field is set, the value associated with + // this key in the `status.allocation.devices.results[*].consumedCapacity` map + // (for a specific claim allocation) determines the base quantity for + // the node allocatable resource. If `allocationMultiplier` is also set, it is + // multiplied with the base quantity. + // For example, if `spec.devices[*].capacity` has an entry "dra.example.com/memory": "128Gi", + // and this field is set to "dra.example.com/memory", then for a claim allocation + // that consumes { "dra.example.com/memory": "4Gi" } the base quantity for the + // node allocatable resource mapping will be "4Gi", and `allocationMultiplier` should + // be omitted or set to "1". + CapacityKey *resourcev1beta2.QualifiedName `json:"capacityKey,omitempty"` + // AllocationMultiplier is used as a multiplier for the allocated device count or the allocated capacity in the claim. + // It defaults to 1 if not specified. How the field is used also depends on whether `capacityKey` is set. + // 1. If `capacityKey` is NOT set: `allocationMultiplier` multiplies the device count allocated to the claim. + // a. A DRA driver representing each CPU core as a device would have + // {ResourceName: "cpu", allocationMultiplier: "2"} in its + // `nodeAllocatableResourceMappings`. If 4 devices are allocated to the claim, + // 4 * 2 CPUs would be considered as allocated and subtracted from the node's capacity. + // b. A GPU device that needs additional node memory per GPU allocation would + // have {ResourceName: "memory", allocationMultiplier: "2Gi"}. Each allocated + // GPU device instance of this type will account for 2Gi of memory. + // + // 2. If `capacityKey` IS set: `allocationMultiplier` is multiplied by the amount of that capacity consumed. + // The final node allocatable resource amount is `consumedCapacity[capacityKey]` * `allocationMultiplier`. + // For example, if a Device's capacity "dra.example.com/cores" is consumed, + // and each "core" provides 2 "cpu"s, the mapping would be: + // {ResourceName: "cpu", capacityKey: "dra.example.com/cores", allocationMultiplier: "2"}. + // If a claim consumes 8 "dra.example.com/cores", the CPU footprint is 8 * 2 = 16. + AllocationMultiplier *resource.Quantity `json:"allocationMultiplier,omitempty"` +} + +// NodeAllocatableResourceMappingApplyConfiguration constructs a declarative configuration of the NodeAllocatableResourceMapping type for use with +// apply. +func NodeAllocatableResourceMapping() *NodeAllocatableResourceMappingApplyConfiguration { + return &NodeAllocatableResourceMappingApplyConfiguration{} +} + +// WithCapacityKey sets the CapacityKey field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CapacityKey field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithCapacityKey(value resourcev1beta2.QualifiedName) *NodeAllocatableResourceMappingApplyConfiguration { + b.CapacityKey = &value + return b +} + +// WithAllocationMultiplier sets the AllocationMultiplier field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocationMultiplier field is set to the value of the last call. +func (b *NodeAllocatableResourceMappingApplyConfiguration) WithAllocationMultiplier(value resource.Quantity) *NodeAllocatableResourceMappingApplyConfiguration { + b.AllocationMultiplier = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgroup.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgroup.go deleted file mode 100644 index b1ce26179a..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgroup.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -// PodGroupApplyConfiguration represents a declarative configuration of the PodGroup type for use -// with apply. -// -// PodGroup represents a set of pods with a common scheduling policy. -type PodGroupApplyConfiguration struct { - // Name is a unique identifier for the PodGroup within the Workload. - // It must be a DNS label. This field is immutable. - Name *string `json:"name,omitempty"` - // Policy defines the scheduling policy for this PodGroup. - Policy *PodGroupPolicyApplyConfiguration `json:"policy,omitempty"` -} - -// PodGroupApplyConfiguration constructs a declarative configuration of the PodGroup type for use with -// apply. -func PodGroup() *PodGroupApplyConfiguration { - return &PodGroupApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *PodGroupApplyConfiguration) WithName(value string) *PodGroupApplyConfiguration { - b.Name = &value - return b -} - -// WithPolicy sets the Policy field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Policy field is set to the value of the last call. -func (b *PodGroupApplyConfiguration) WithPolicy(value *PodGroupPolicyApplyConfiguration) *PodGroupApplyConfiguration { - b.Policy = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/gangschedulingpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/gangschedulingpolicy.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/gangschedulingpolicy.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/gangschedulingpolicy.go index 6bf41585cf..987a89013b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/gangschedulingpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/gangschedulingpolicy.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // GangSchedulingPolicyApplyConfiguration represents a declarative configuration of the GangSchedulingPolicy type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroup.go similarity index 61% rename from vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscaler.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroup.go index 8a89398f9c..ee28510624 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta1/horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroup.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v2beta1 +package v1alpha2 import ( - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,82 +27,82 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// HorizontalPodAutoscalerApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscaler type for use +// PodGroupApplyConfiguration represents a declarative configuration of the PodGroup type for use // with apply. // -// HorizontalPodAutoscaler is the configuration for a horizontal pod -// autoscaler, which automatically manages the replica count of any resource -// implementing the scale subresource based on the metrics specified. -type HorizontalPodAutoscalerApplyConfiguration struct { +// PodGroup represents a runtime instance of pods grouped together. +// PodGroups are created by workload controllers (Job, LWS, JobSet, etc...) from +// Workload.podGroupTemplates. +// PodGroup API enablement is toggled by the GenericWorkload feature gate. +type PodGroupApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` - // metadata is the standard object metadata. + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - // spec is the specification for the behaviour of the autoscaler. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. - Spec *HorizontalPodAutoscalerSpecApplyConfiguration `json:"spec,omitempty"` - // status is the current information about the autoscaler. - Status *HorizontalPodAutoscalerStatusApplyConfiguration `json:"status,omitempty"` + // Spec defines the desired state of the PodGroup. + Spec *PodGroupSpecApplyConfiguration `json:"spec,omitempty"` + // Status represents the current observed state of the PodGroup. + Status *PodGroupStatusApplyConfiguration `json:"status,omitempty"` } -// HorizontalPodAutoscaler constructs a declarative configuration of the HorizontalPodAutoscaler type for use with +// PodGroup constructs a declarative configuration of the PodGroup type for use with // apply. -func HorizontalPodAutoscaler(name, namespace string) *HorizontalPodAutoscalerApplyConfiguration { - b := &HorizontalPodAutoscalerApplyConfiguration{} +func PodGroup(name, namespace string) *PodGroupApplyConfiguration { + b := &PodGroupApplyConfiguration{} b.WithName(name) b.WithNamespace(namespace) - b.WithKind("HorizontalPodAutoscaler") - b.WithAPIVersion("autoscaling/v2beta1") + b.WithKind("PodGroup") + b.WithAPIVersion("scheduling.k8s.io/v1alpha2") return b } -// ExtractHorizontalPodAutoscalerFrom extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler for the specified subresource. Pass an empty string for subresource to extract +// ExtractPodGroupFrom extracts the applied configuration owned by fieldManager from +// podGroup for the specified subresource. Pass an empty string for subresource to extract // the main resource. Common subresources include "status", "scale", etc. -// horizontalPodAutoscaler must be a unmodified HorizontalPodAutoscaler API object that was retrieved from the Kubernetes API. -// ExtractHorizontalPodAutoscalerFrom provides a way to perform a extract/modify-in-place/apply workflow. +// podGroup must be a unmodified PodGroup API object that was retrieved from the Kubernetes API. +// ExtractPodGroupFrom provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, fieldManager string, subresource string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - b := &HorizontalPodAutoscalerApplyConfiguration{} - err := managedfields.ExtractInto(horizontalPodAutoscaler, internal.Parser().Type("io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler"), fieldManager, b, subresource) +func ExtractPodGroupFrom(podGroup *schedulingv1alpha2.PodGroup, fieldManager string, subresource string) (*PodGroupApplyConfiguration, error) { + b := &PodGroupApplyConfiguration{} + err := managedfields.ExtractInto(podGroup, internal.Parser().Type("io.k8s.api.scheduling.v1alpha2.PodGroup"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(horizontalPodAutoscaler.Name) - b.WithNamespace(horizontalPodAutoscaler.Namespace) + b.WithName(podGroup.Name) + b.WithNamespace(podGroup.Namespace) - b.WithKind("HorizontalPodAutoscaler") - b.WithAPIVersion("autoscaling/v2beta1") + b.WithKind("PodGroup") + b.WithAPIVersion("scheduling.k8s.io/v1alpha2") return b, nil } -// ExtractHorizontalPodAutoscaler extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler. If no managedFields are found in horizontalPodAutoscaler for fieldManager, a -// HorizontalPodAutoscalerApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractPodGroup extracts the applied configuration owned by fieldManager from +// podGroup. If no managedFields are found in podGroup for fieldManager, a +// PodGroupApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// horizontalPodAutoscaler must be a unmodified HorizontalPodAutoscaler API object that was retrieved from the Kubernetes API. -// ExtractHorizontalPodAutoscaler provides a way to perform a extract/modify-in-place/apply workflow. +// podGroup must be a unmodified PodGroup API object that was retrieved from the Kubernetes API. +// ExtractPodGroup provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractHorizontalPodAutoscaler(horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, fieldManager string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - return ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler, fieldManager, "") +func ExtractPodGroup(podGroup *schedulingv1alpha2.PodGroup, fieldManager string) (*PodGroupApplyConfiguration, error) { + return ExtractPodGroupFrom(podGroup, fieldManager, "") } -// ExtractHorizontalPodAutoscalerStatus extracts the applied configuration owned by fieldManager from -// horizontalPodAutoscaler for the status subresource. -func ExtractHorizontalPodAutoscalerStatus(horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, fieldManager string) (*HorizontalPodAutoscalerApplyConfiguration, error) { - return ExtractHorizontalPodAutoscalerFrom(horizontalPodAutoscaler, fieldManager, "status") +// ExtractPodGroupStatus extracts the applied configuration owned by fieldManager from +// podGroup for the status subresource. +func ExtractPodGroupStatus(podGroup *schedulingv1alpha2.PodGroup, fieldManager string) (*PodGroupApplyConfiguration, error) { + return ExtractPodGroupFrom(podGroup, fieldManager, "status") } -func (b HorizontalPodAutoscalerApplyConfiguration) IsApplyConfiguration() {} +func (b PodGroupApplyConfiguration) IsApplyConfiguration() {} // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithKind(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithKind(value string) *PodGroupApplyConfiguration { b.TypeMetaApplyConfiguration.Kind = &value return b } @@ -110,7 +110,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithKind(value string) *Hori // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithAPIVersion(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithAPIVersion(value string) *PodGroupApplyConfiguration { b.TypeMetaApplyConfiguration.APIVersion = &value return b } @@ -118,7 +118,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithAPIVersion(value string) // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithName(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithName(value string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Name = &value return b @@ -127,7 +127,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithName(value string) *Hori // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithGenerateName(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithGenerateName(value string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.GenerateName = &value return b @@ -136,7 +136,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithGenerateName(value strin // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithNamespace(value string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Namespace = &value return b @@ -145,7 +145,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string) // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithUID(value types.UID) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithUID(value types.UID) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.UID = &value return b @@ -154,7 +154,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithUID(value types.UID) *Ho // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithResourceVersion(value string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithResourceVersion(value string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.ResourceVersion = &value return b @@ -163,7 +163,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithResourceVersion(value st // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithGeneration(value int64) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithGeneration(value int64) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.Generation = &value return b @@ -172,7 +172,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithGeneration(value int64) // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithCreationTimestamp(value metav1.Time) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.CreationTimestamp = &value return b @@ -181,7 +181,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithCreationTimestamp(value // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value return b @@ -190,7 +190,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionTimestamp(value // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value return b @@ -200,7 +200,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithDeletionGracePeriodSecon // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithLabels(entries map[string]string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithLabels(entries map[string]string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) @@ -215,7 +215,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithLabels(entries map[strin // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithAnnotations(entries map[string]string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithAnnotations(entries map[string]string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) @@ -229,7 +229,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithAnnotations(entries map[ // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -243,7 +243,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithOwnerReferences(values . // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithFinalizers(values ...string) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithFinalizers(values ...string) *PodGroupApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) @@ -251,7 +251,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithFinalizers(values ...str return b } -func (b *HorizontalPodAutoscalerApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *PodGroupApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -260,7 +260,7 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) ensureObjectMetaApplyConfigu // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithSpec(value *HorizontalPodAutoscalerSpecApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithSpec(value *PodGroupSpecApplyConfiguration) *PodGroupApplyConfiguration { b.Spec = value return b } @@ -268,29 +268,29 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithSpec(value *HorizontalPo // WithStatus sets the Status field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Status field is set to the value of the last call. -func (b *HorizontalPodAutoscalerApplyConfiguration) WithStatus(value *HorizontalPodAutoscalerStatusApplyConfiguration) *HorizontalPodAutoscalerApplyConfiguration { +func (b *PodGroupApplyConfiguration) WithStatus(value *PodGroupStatusApplyConfiguration) *PodGroupApplyConfiguration { b.Status = value return b } // GetKind retrieves the value of the Kind field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetKind() *string { +func (b *PodGroupApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind } // GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetAPIVersion() *string { +func (b *PodGroupApplyConfiguration) GetAPIVersion() *string { return b.TypeMetaApplyConfiguration.APIVersion } // GetName retrieves the value of the Name field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetName() *string { +func (b *PodGroupApplyConfiguration) GetName() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Name } // GetNamespace retrieves the value of the Namespace field in the declarative configuration. -func (b *HorizontalPodAutoscalerApplyConfiguration) GetNamespace() *string { +func (b *PodGroupApplyConfiguration) GetNamespace() *string { b.ensureObjectMetaApplyConfigurationExists() return b.ObjectMetaApplyConfiguration.Namespace } diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaim.go new file mode 100644 index 0000000000..a7b21b530b --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaim.go @@ -0,0 +1,89 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodGroupResourceClaimApplyConfiguration represents a declarative configuration of the PodGroupResourceClaim type for use +// with apply. +// +// PodGroupResourceClaim references exactly one ResourceClaim, either directly +// or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim +// for the PodGroup. +// +// It adds a name to it that uniquely identifies the ResourceClaim inside the PodGroup. +// Pods that need access to the ResourceClaim define a matching reference in its +// own Spec.ResourceClaims. The Pod's claim must match all fields of the +// PodGroup's claim exactly. +type PodGroupResourceClaimApplyConfiguration struct { + // Name uniquely identifies this resource claim inside the PodGroup. + // This must be a DNS_LABEL. + Name *string `json:"name,omitempty"` + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this PodGroup. The ResourceClaim will be reserved for the + // PodGroup instead of its individual pods. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + ResourceClaimName *string `json:"resourceClaimName,omitempty"` + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this PodGroup. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this PodGroup. When this PodGroup is deleted, the ResourceClaim + // will also be deleted. The PodGroup name and resource name, along with a + // generated component, will be used to form a unique name for the + // ResourceClaim, which will be recorded in podgroup.status.resourceClaimStatuses. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + ResourceClaimTemplateName *string `json:"resourceClaimTemplateName,omitempty"` +} + +// PodGroupResourceClaimApplyConfiguration constructs a declarative configuration of the PodGroupResourceClaim type for use with +// apply. +func PodGroupResourceClaim() *PodGroupResourceClaimApplyConfiguration { + return &PodGroupResourceClaimApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodGroupResourceClaimApplyConfiguration) WithName(value string) *PodGroupResourceClaimApplyConfiguration { + b.Name = &value + return b +} + +// WithResourceClaimName sets the ResourceClaimName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimName field is set to the value of the last call. +func (b *PodGroupResourceClaimApplyConfiguration) WithResourceClaimName(value string) *PodGroupResourceClaimApplyConfiguration { + b.ResourceClaimName = &value + return b +} + +// WithResourceClaimTemplateName sets the ResourceClaimTemplateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimTemplateName field is set to the value of the last call. +func (b *PodGroupResourceClaimApplyConfiguration) WithResourceClaimTemplateName(value string) *PodGroupResourceClaimApplyConfiguration { + b.ResourceClaimTemplateName = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaimstatus.go new file mode 100644 index 0000000000..5f8498b13e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupresourceclaimstatus.go @@ -0,0 +1,59 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodGroupResourceClaimStatusApplyConfiguration represents a declarative configuration of the PodGroupResourceClaimStatus type for use +// with apply. +// +// PodGroupResourceClaimStatus is stored in the PodGroupStatus for each +// PodGroupResourceClaim which references a ResourceClaimTemplate. It stores the +// generated name for the corresponding ResourceClaim. +type PodGroupResourceClaimStatusApplyConfiguration struct { + // Name uniquely identifies this resource claim inside the PodGroup. This + // must match the name of an entry in podgroup.spec.resourceClaims, which + // implies that the string must be a DNS_LABEL. + Name *string `json:"name,omitempty"` + // ResourceClaimName is the name of the ResourceClaim that was generated for + // the PodGroup in the namespace of the PodGroup. If this is unset, then + // generating a ResourceClaim was not necessary. The + // podgroup.spec.resourceClaims entry can be ignored in this case. + ResourceClaimName *string `json:"resourceClaimName,omitempty"` +} + +// PodGroupResourceClaimStatusApplyConfiguration constructs a declarative configuration of the PodGroupResourceClaimStatus type for use with +// apply. +func PodGroupResourceClaimStatus() *PodGroupResourceClaimStatusApplyConfiguration { + return &PodGroupResourceClaimStatusApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodGroupResourceClaimStatusApplyConfiguration) WithName(value string) *PodGroupResourceClaimStatusApplyConfiguration { + b.Name = &value + return b +} + +// WithResourceClaimName sets the ResourceClaimName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceClaimName field is set to the value of the last call. +func (b *PodGroupResourceClaimStatusApplyConfiguration) WithResourceClaimName(value string) *PodGroupResourceClaimStatusApplyConfiguration { + b.ResourceClaimName = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingconstraints.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingconstraints.go new file mode 100644 index 0000000000..eda72ea50e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingconstraints.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodGroupSchedulingConstraintsApplyConfiguration represents a declarative configuration of the PodGroupSchedulingConstraints type for use +// with apply. +// +// PodGroupSchedulingConstraints defines scheduling constraints (e.g. topology) for a PodGroup. +type PodGroupSchedulingConstraintsApplyConfiguration struct { + // Topology defines the topology constraints for the pod group. + // Currently only a single topology constraint can be specified. This may change in the future. + Topology []TopologyConstraintApplyConfiguration `json:"topology,omitempty"` +} + +// PodGroupSchedulingConstraintsApplyConfiguration constructs a declarative configuration of the PodGroupSchedulingConstraints type for use with +// apply. +func PodGroupSchedulingConstraints() *PodGroupSchedulingConstraintsApplyConfiguration { + return &PodGroupSchedulingConstraintsApplyConfiguration{} +} + +// WithTopology adds the given value to the Topology field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Topology field. +func (b *PodGroupSchedulingConstraintsApplyConfiguration) WithTopology(values ...*TopologyConstraintApplyConfiguration) *PodGroupSchedulingConstraintsApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithTopology") + } + b.Topology = append(b.Topology, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgrouppolicy.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingpolicy.go similarity index 60% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgrouppolicy.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingpolicy.go index d73c5e4409..02be5f27eb 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/podgrouppolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupschedulingpolicy.go @@ -16,35 +16,36 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" ) -// PodGroupPolicyApplyConfiguration represents a declarative configuration of the PodGroupPolicy type for use +// PodGroupSchedulingPolicyApplyConfiguration represents a declarative configuration of the PodGroupSchedulingPolicy type for use // with apply. // -// PodGroupPolicy defines the scheduling configuration for a PodGroup. -type PodGroupPolicyApplyConfiguration struct { +// PodGroupSchedulingPolicy defines the scheduling configuration for a PodGroup. +// Exactly one policy must be set. +type PodGroupSchedulingPolicyApplyConfiguration struct { // Basic specifies that the pods in this group should be scheduled using // standard Kubernetes scheduling behavior. - Basic *schedulingv1alpha1.BasicSchedulingPolicy `json:"basic,omitempty"` + Basic *schedulingv1alpha2.BasicSchedulingPolicy `json:"basic,omitempty"` // Gang specifies that the pods in this group should be scheduled using // all-or-nothing semantics. Gang *GangSchedulingPolicyApplyConfiguration `json:"gang,omitempty"` } -// PodGroupPolicyApplyConfiguration constructs a declarative configuration of the PodGroupPolicy type for use with +// PodGroupSchedulingPolicyApplyConfiguration constructs a declarative configuration of the PodGroupSchedulingPolicy type for use with // apply. -func PodGroupPolicy() *PodGroupPolicyApplyConfiguration { - return &PodGroupPolicyApplyConfiguration{} +func PodGroupSchedulingPolicy() *PodGroupSchedulingPolicyApplyConfiguration { + return &PodGroupSchedulingPolicyApplyConfiguration{} } // WithBasic sets the Basic field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Basic field is set to the value of the last call. -func (b *PodGroupPolicyApplyConfiguration) WithBasic(value schedulingv1alpha1.BasicSchedulingPolicy) *PodGroupPolicyApplyConfiguration { +func (b *PodGroupSchedulingPolicyApplyConfiguration) WithBasic(value schedulingv1alpha2.BasicSchedulingPolicy) *PodGroupSchedulingPolicyApplyConfiguration { b.Basic = &value return b } @@ -52,7 +53,7 @@ func (b *PodGroupPolicyApplyConfiguration) WithBasic(value schedulingv1alpha1.Ba // WithGang sets the Gang field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Gang field is set to the value of the last call. -func (b *PodGroupPolicyApplyConfiguration) WithGang(value *GangSchedulingPolicyApplyConfiguration) *PodGroupPolicyApplyConfiguration { +func (b *PodGroupSchedulingPolicyApplyConfiguration) WithGang(value *GangSchedulingPolicyApplyConfiguration) *PodGroupSchedulingPolicyApplyConfiguration { b.Gang = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupspec.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupspec.go new file mode 100644 index 0000000000..76538c6221 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupspec.go @@ -0,0 +1,145 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" +) + +// PodGroupSpecApplyConfiguration represents a declarative configuration of the PodGroupSpec type for use +// with apply. +// +// PodGroupSpec defines the desired state of a PodGroup. +type PodGroupSpecApplyConfiguration struct { + // PodGroupTemplateRef references an optional PodGroup template within other object + // (e.g. Workload) that was used to create the PodGroup. This field is immutable. + PodGroupTemplateRef *PodGroupTemplateReferenceApplyConfiguration `json:"podGroupTemplateRef,omitempty"` + // SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + SchedulingPolicy *PodGroupSchedulingPolicyApplyConfiguration `json:"schedulingPolicy,omitempty"` + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + SchedulingConstraints *PodGroupSchedulingConstraintsApplyConfiguration `json:"schedulingConstraints,omitempty"` + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + ResourceClaims []PodGroupResourceClaimApplyConfiguration `json:"resourceClaims,omitempty"` + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // One of Pod, PodGroup. Defaults to Pod if unset. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + DisruptionMode *schedulingv1alpha2.DisruptionMode `json:"disruptionMode,omitempty"` + // PriorityClassName defines the priority that should be considered when scheduling this pod group. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate + // (i.e. if no priority class is specified, admission control can set this to the global default + // priority class if it exists. Otherwise, the pod group's priority will be zero). + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + PriorityClassName *string `json:"priorityClassName,omitempty"` + // Priority is the value of priority of this pod group. Various system components + // use this field to find the priority of the pod group. When Priority Admission + // Controller is enabled, it prevents users from setting this field. The admission + // controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + Priority *int32 `json:"priority,omitempty"` +} + +// PodGroupSpecApplyConfiguration constructs a declarative configuration of the PodGroupSpec type for use with +// apply. +func PodGroupSpec() *PodGroupSpecApplyConfiguration { + return &PodGroupSpecApplyConfiguration{} +} + +// WithPodGroupTemplateRef sets the PodGroupTemplateRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PodGroupTemplateRef field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithPodGroupTemplateRef(value *PodGroupTemplateReferenceApplyConfiguration) *PodGroupSpecApplyConfiguration { + b.PodGroupTemplateRef = value + return b +} + +// WithSchedulingPolicy sets the SchedulingPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SchedulingPolicy field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithSchedulingPolicy(value *PodGroupSchedulingPolicyApplyConfiguration) *PodGroupSpecApplyConfiguration { + b.SchedulingPolicy = value + return b +} + +// WithSchedulingConstraints sets the SchedulingConstraints field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SchedulingConstraints field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithSchedulingConstraints(value *PodGroupSchedulingConstraintsApplyConfiguration) *PodGroupSpecApplyConfiguration { + b.SchedulingConstraints = value + return b +} + +// WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceClaims field. +func (b *PodGroupSpecApplyConfiguration) WithResourceClaims(values ...*PodGroupResourceClaimApplyConfiguration) *PodGroupSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceClaims") + } + b.ResourceClaims = append(b.ResourceClaims, *values[i]) + } + return b +} + +// WithDisruptionMode sets the DisruptionMode field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DisruptionMode field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithDisruptionMode(value schedulingv1alpha2.DisruptionMode) *PodGroupSpecApplyConfiguration { + b.DisruptionMode = &value + return b +} + +// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityClassName field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithPriorityClassName(value string) *PodGroupSpecApplyConfiguration { + b.PriorityClassName = &value + return b +} + +// WithPriority sets the Priority field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Priority field is set to the value of the last call. +func (b *PodGroupSpecApplyConfiguration) WithPriority(value int32) *PodGroupSpecApplyConfiguration { + b.Priority = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupstatus.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupstatus.go new file mode 100644 index 0000000000..c8c4b30da9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgroupstatus.go @@ -0,0 +1,81 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// PodGroupStatusApplyConfiguration represents a declarative configuration of the PodGroupStatus type for use +// with apply. +// +// PodGroupStatus represents information about the status of a pod group. +type PodGroupStatusApplyConfiguration struct { + // Conditions represent the latest observations of the PodGroup's state. + // + // Known condition types: + // - "PodGroupScheduled": Indicates whether the scheduling requirement has been satisfied. + // - "DisruptionTarget": Indicates whether the PodGroup is about to be terminated + // due to disruption such as preemption. + // + // Known reasons for the PodGroupScheduled condition: + // - "Unschedulable": The PodGroup cannot be scheduled due to resource constraints, + // affinity/anti-affinity rules, or insufficient capacity for the gang. + // - "SchedulerError": The PodGroup cannot be scheduled due to some internal error + // that happened during scheduling, for example due to nodeAffinity parsing errors. + // + // Known reasons for the DisruptionTarget condition: + // - "PreemptionByScheduler": The PodGroup was preempted by the scheduler to make room for + // higher-priority PodGroups or Pods. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` + // Status of resource claims. + ResourceClaimStatuses []PodGroupResourceClaimStatusApplyConfiguration `json:"resourceClaimStatuses,omitempty"` +} + +// PodGroupStatusApplyConfiguration constructs a declarative configuration of the PodGroupStatus type for use with +// apply. +func PodGroupStatus() *PodGroupStatusApplyConfiguration { + return &PodGroupStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *PodGroupStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *PodGroupStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} + +// WithResourceClaimStatuses adds the given value to the ResourceClaimStatuses field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceClaimStatuses field. +func (b *PodGroupStatusApplyConfiguration) WithResourceClaimStatuses(values ...*PodGroupResourceClaimStatusApplyConfiguration) *PodGroupStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceClaimStatuses") + } + b.ResourceClaimStatuses = append(b.ResourceClaimStatuses, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplate.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplate.go new file mode 100644 index 0000000000..695caf2997 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplate.go @@ -0,0 +1,136 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" +) + +// PodGroupTemplateApplyConfiguration represents a declarative configuration of the PodGroupTemplate type for use +// with apply. +// +// PodGroupTemplate represents a template for a set of pods with a scheduling policy. +type PodGroupTemplateApplyConfiguration struct { + // Name is a unique identifier for the PodGroupTemplate within the Workload. + // It must be a DNS label. This field is immutable. + Name *string `json:"name,omitempty"` + // SchedulingPolicy defines the scheduling policy for this PodGroupTemplate. + SchedulingPolicy *PodGroupSchedulingPolicyApplyConfiguration `json:"schedulingPolicy,omitempty"` + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + SchedulingConstraints *PodGroupSchedulingConstraintsApplyConfiguration `json:"schedulingConstraints,omitempty"` + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + ResourceClaims []PodGroupResourceClaimApplyConfiguration `json:"resourceClaims,omitempty"` + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // One of Pod, PodGroup. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + DisruptionMode *schedulingv1alpha2.DisruptionMode `json:"disruptionMode,omitempty"` + // PriorityClassName indicates the priority that should be considered when scheduling + // a pod group created from this template. If no priority class is specified, admission + // control can set this to the global default priority class if it exists. Otherwise, + // pod groups created from this template will have the priority set to zero. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + PriorityClassName *string `json:"priorityClassName,omitempty"` + // Priority is the value of priority of pod groups created from this template. Various + // system components use this field to find the priority of the pod group. When + // Priority Admission Controller is enabled, it prevents users from setting this field. + // The admission controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + Priority *int32 `json:"priority,omitempty"` +} + +// PodGroupTemplateApplyConfiguration constructs a declarative configuration of the PodGroupTemplate type for use with +// apply. +func PodGroupTemplate() *PodGroupTemplateApplyConfiguration { + return &PodGroupTemplateApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithName(value string) *PodGroupTemplateApplyConfiguration { + b.Name = &value + return b +} + +// WithSchedulingPolicy sets the SchedulingPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SchedulingPolicy field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithSchedulingPolicy(value *PodGroupSchedulingPolicyApplyConfiguration) *PodGroupTemplateApplyConfiguration { + b.SchedulingPolicy = value + return b +} + +// WithSchedulingConstraints sets the SchedulingConstraints field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SchedulingConstraints field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithSchedulingConstraints(value *PodGroupSchedulingConstraintsApplyConfiguration) *PodGroupTemplateApplyConfiguration { + b.SchedulingConstraints = value + return b +} + +// WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceClaims field. +func (b *PodGroupTemplateApplyConfiguration) WithResourceClaims(values ...*PodGroupResourceClaimApplyConfiguration) *PodGroupTemplateApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceClaims") + } + b.ResourceClaims = append(b.ResourceClaims, *values[i]) + } + return b +} + +// WithDisruptionMode sets the DisruptionMode field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DisruptionMode field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithDisruptionMode(value schedulingv1alpha2.DisruptionMode) *PodGroupTemplateApplyConfiguration { + b.DisruptionMode = &value + return b +} + +// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PriorityClassName field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithPriorityClassName(value string) *PodGroupTemplateApplyConfiguration { + b.PriorityClassName = &value + return b +} + +// WithPriority sets the Priority field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Priority field is set to the value of the last call. +func (b *PodGroupTemplateApplyConfiguration) WithPriority(value int32) *PodGroupTemplateApplyConfiguration { + b.Priority = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplatereference.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplatereference.go new file mode 100644 index 0000000000..f8b1f61ffc --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/podgrouptemplatereference.go @@ -0,0 +1,44 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// PodGroupTemplateReferenceApplyConfiguration represents a declarative configuration of the PodGroupTemplateReference type for use +// with apply. +// +// PodGroupTemplateReference references a PodGroup template defined in some object (e.g. Workload). +// Exactly one reference must be set. +type PodGroupTemplateReferenceApplyConfiguration struct { + // Workload references the PodGroupTemplate within the Workload object that was used to create + // the PodGroup. + Workload *WorkloadPodGroupTemplateReferenceApplyConfiguration `json:"workload,omitempty"` +} + +// PodGroupTemplateReferenceApplyConfiguration constructs a declarative configuration of the PodGroupTemplateReference type for use with +// apply. +func PodGroupTemplateReference() *PodGroupTemplateReferenceApplyConfiguration { + return &PodGroupTemplateReferenceApplyConfiguration{} +} + +// WithWorkload sets the Workload field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Workload field is set to the value of the last call. +func (b *PodGroupTemplateReferenceApplyConfiguration) WithWorkload(value *WorkloadPodGroupTemplateReferenceApplyConfiguration) *PodGroupTemplateReferenceApplyConfiguration { + b.Workload = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/topologyconstraint.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/topologyconstraint.go new file mode 100644 index 0000000000..92727eb2bb --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/topologyconstraint.go @@ -0,0 +1,45 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// TopologyConstraintApplyConfiguration represents a declarative configuration of the TopologyConstraint type for use +// with apply. +// +// TopologyConstraint defines a topology constraint for a PodGroup. +type TopologyConstraintApplyConfiguration struct { + // Key specifies the key of the node label representing the topology domain. + // All pods within the PodGroup must be colocated within the same domain instance. + // Different PodGroups can land on different domain instances even if they derive from the same PodGroupTemplate. + // Examples: "topology.kubernetes.io/rack" + Key *string `json:"key,omitempty"` +} + +// TopologyConstraintApplyConfiguration constructs a declarative configuration of the TopologyConstraint type for use with +// apply. +func TopologyConstraint() *TopologyConstraintApplyConfiguration { + return &TopologyConstraintApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *TopologyConstraintApplyConfiguration) WithKey(value string) *TopologyConstraintApplyConfiguration { + b.Key = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/typedlocalobjectreference.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/typedlocalobjectreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/typedlocalobjectreference.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/typedlocalobjectreference.go index 73c11c884e..cfbbc48e07 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/typedlocalobjectreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/typedlocalobjectreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // TypedLocalObjectReferenceApplyConfiguration represents a declarative configuration of the TypedLocalObjectReference type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workload.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workload.go similarity index 95% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workload.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workload.go index 6530899aee..787095d238 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workload.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workload.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -31,12 +31,13 @@ import ( // with apply. // // Workload allows for expressing scheduling constraints that should be used -// when managing lifecycle of workloads from scheduling perspective, +// when managing the lifecycle of workloads from the scheduling perspective, // including scheduling, preemption, eviction and other phases. +// Workload API enablement is toggled by the GenericWorkload feature gate. type WorkloadApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` // Standard object's metadata. - // Name must be a DNS subdomain. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` // Spec defines the desired behavior of a Workload. Spec *WorkloadSpecApplyConfiguration `json:"spec,omitempty"` @@ -49,7 +50,7 @@ func Workload(name, namespace string) *WorkloadApplyConfiguration { b.WithName(name) b.WithNamespace(namespace) b.WithKind("Workload") - b.WithAPIVersion("scheduling.k8s.io/v1alpha1") + b.WithAPIVersion("scheduling.k8s.io/v1alpha2") return b } @@ -60,9 +61,9 @@ func Workload(name, namespace string) *WorkloadApplyConfiguration { // ExtractWorkloadFrom provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractWorkloadFrom(workload *schedulingv1alpha1.Workload, fieldManager string, subresource string) (*WorkloadApplyConfiguration, error) { +func ExtractWorkloadFrom(workload *schedulingv1alpha2.Workload, fieldManager string, subresource string) (*WorkloadApplyConfiguration, error) { b := &WorkloadApplyConfiguration{} - err := managedfields.ExtractInto(workload, internal.Parser().Type("io.k8s.api.scheduling.v1alpha1.Workload"), fieldManager, b, subresource) + err := managedfields.ExtractInto(workload, internal.Parser().Type("io.k8s.api.scheduling.v1alpha2.Workload"), fieldManager, b, subresource) if err != nil { return nil, err } @@ -70,7 +71,7 @@ func ExtractWorkloadFrom(workload *schedulingv1alpha1.Workload, fieldManager str b.WithNamespace(workload.Namespace) b.WithKind("Workload") - b.WithAPIVersion("scheduling.k8s.io/v1alpha1") + b.WithAPIVersion("scheduling.k8s.io/v1alpha2") return b, nil } @@ -84,7 +85,7 @@ func ExtractWorkloadFrom(workload *schedulingv1alpha1.Workload, fieldManager str // ExtractWorkload provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. -func ExtractWorkload(workload *schedulingv1alpha1.Workload, fieldManager string) (*WorkloadApplyConfiguration, error) { +func ExtractWorkload(workload *schedulingv1alpha2.Workload, fieldManager string) (*WorkloadApplyConfiguration, error) { return ExtractWorkloadFrom(workload, fieldManager, "") } diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadpodgrouptemplatereference.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadpodgrouptemplatereference.go new file mode 100644 index 0000000000..ff3ab06c8d --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadpodgrouptemplatereference.go @@ -0,0 +1,52 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// WorkloadPodGroupTemplateReferenceApplyConfiguration represents a declarative configuration of the WorkloadPodGroupTemplateReference type for use +// with apply. +// +// WorkloadPodGroupTemplateReference references the PodGroupTemplate within the Workload object. +type WorkloadPodGroupTemplateReferenceApplyConfiguration struct { + // WorkloadName defines the name of the Workload object. + WorkloadName *string `json:"workloadName,omitempty"` + // PodGroupTemplateName defines the PodGroupTemplate name within the Workload object. + PodGroupTemplateName *string `json:"podGroupTemplateName,omitempty"` +} + +// WorkloadPodGroupTemplateReferenceApplyConfiguration constructs a declarative configuration of the WorkloadPodGroupTemplateReference type for use with +// apply. +func WorkloadPodGroupTemplateReference() *WorkloadPodGroupTemplateReferenceApplyConfiguration { + return &WorkloadPodGroupTemplateReferenceApplyConfiguration{} +} + +// WithWorkloadName sets the WorkloadName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the WorkloadName field is set to the value of the last call. +func (b *WorkloadPodGroupTemplateReferenceApplyConfiguration) WithWorkloadName(value string) *WorkloadPodGroupTemplateReferenceApplyConfiguration { + b.WorkloadName = &value + return b +} + +// WithPodGroupTemplateName sets the PodGroupTemplateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PodGroupTemplateName field is set to the value of the last call. +func (b *WorkloadPodGroupTemplateReferenceApplyConfiguration) WithPodGroupTemplateName(value string) *WorkloadPodGroupTemplateReferenceApplyConfiguration { + b.PodGroupTemplateName = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workloadspec.go b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadspec.go similarity index 75% rename from vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workloadspec.go rename to vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadspec.go index 1ceb9210db..33eb8a5c09 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha1/workloadspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/scheduling/v1alpha2/workloadspec.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // WorkloadSpecApplyConfiguration represents a declarative configuration of the WorkloadSpec type for use // with apply. @@ -26,11 +26,11 @@ type WorkloadSpecApplyConfiguration struct { // ControllerRef is an optional reference to the controlling object, such as a // Deployment or Job. This field is intended for use by tools like CLIs // to provide a link back to the original workload definition. - // When set, it cannot be changed. + // This field is immutable. ControllerRef *TypedLocalObjectReferenceApplyConfiguration `json:"controllerRef,omitempty"` - // PodGroups is the list of pod groups that make up the Workload. - // The maximum number of pod groups is 8. This field is immutable. - PodGroups []PodGroupApplyConfiguration `json:"podGroups,omitempty"` + // PodGroupTemplates is the list of templates that make up the Workload. + // The maximum number of templates is 8. This field is immutable. + PodGroupTemplates []PodGroupTemplateApplyConfiguration `json:"podGroupTemplates,omitempty"` } // WorkloadSpecApplyConfiguration constructs a declarative configuration of the WorkloadSpec type for use with @@ -47,15 +47,15 @@ func (b *WorkloadSpecApplyConfiguration) WithControllerRef(value *TypedLocalObje return b } -// WithPodGroups adds the given value to the PodGroups field in the declarative configuration +// WithPodGroupTemplates adds the given value to the PodGroupTemplates field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the PodGroups field. -func (b *WorkloadSpecApplyConfiguration) WithPodGroups(values ...*PodGroupApplyConfiguration) *WorkloadSpecApplyConfiguration { +// If called multiple times, values provided by each call will be appended to the PodGroupTemplates field. +func (b *WorkloadSpecApplyConfiguration) WithPodGroupTemplates(values ...*PodGroupTemplateApplyConfiguration) *WorkloadSpecApplyConfiguration { for i := range values { if values[i] == nil { - panic("nil value passed to WithPodGroups") + panic("nil value passed to WithPodGroupTemplates") } - b.PodGroups = append(b.PodGroups, *values[i]) + b.PodGroupTemplates = append(b.PodGroupTemplates, *values[i]) } return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go index 653329ecec..4a715c141b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/csidriverspec.go @@ -154,7 +154,7 @@ type CSIDriverSpecApplyConfiguration struct { // occur (neither periodic nor upon detecting capacity-related failures), and the // allocatable.count remains static. The minimum allowed value for this field is 10 seconds. // - // This is a beta feature and requires the MutableCSINodeAllocatableCount feature gate to be enabled. + // This feature requires the MutableCSINodeAllocatableCount feature gate to be enabled. // // This field is mutable. NodeAllocatableUpdatePeriodSeconds *int64 `json:"nodeAllocatableUpdatePeriodSeconds,omitempty"` @@ -178,6 +178,24 @@ type CSIDriverSpecApplyConfiguration struct { // // Default behavior if unset is to pass tokens in the VolumeContext field. ServiceAccountTokenInSecrets *bool `json:"serviceAccountTokenInSecrets,omitempty"` + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty"` } // CSIDriverSpecApplyConfiguration constructs a declarative configuration of the CSIDriverSpec type for use with @@ -272,3 +290,11 @@ func (b *CSIDriverSpecApplyConfiguration) WithServiceAccountTokenInSecrets(value b.ServiceAccountTokenInSecrets = &value return b } + +// WithPreventPodSchedulingIfMissing sets the PreventPodSchedulingIfMissing field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PreventPodSchedulingIfMissing field is set to the value of the last call. +func (b *CSIDriverSpecApplyConfiguration) WithPreventPodSchedulingIfMissing(value bool) *CSIDriverSpecApplyConfiguration { + b.PreventPodSchedulingIfMissing = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/volumeerror.go b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/volumeerror.go index b1a572f4eb..607a39ea11 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/storage/v1/volumeerror.go +++ b/vendor/k8s.io/client-go/applyconfigurations/storage/v1/volumeerror.go @@ -35,7 +35,7 @@ type VolumeErrorApplyConfiguration struct { Message *string `json:"message,omitempty"` // errorCode is a numeric gRPC code representing the error encountered during Attach or Detach operations. // - // This is an optional, beta field that requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. + // This field requires the MutableCSINodeAllocatableCount feature gate being enabled to be set. ErrorCode *int32 `json:"errorCode,omitempty"` } diff --git a/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go b/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go index 323065d2a4..cec76d9fd8 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/storage/v1beta1/csidriverspec.go @@ -178,6 +178,24 @@ type CSIDriverSpecApplyConfiguration struct { // // Default behavior if unset is to pass tokens in the VolumeContext field. ServiceAccountTokenInSecrets *bool `json:"serviceAccountTokenInSecrets,omitempty"` + // PreventPodSchedulingIfMissing indicates that the CSI driver wants to prevent pod + // scheduling if the CSI driver on the node is missing. + // + // Enabling this option will prevent the scheduler (or any other + // component which embeds default scheduler such as cluster-autoscaler) from + // scheduling pods to nodes where CSI driver is not installed. + // + // For components(such as cluster-autoscaler) that embed the scheduler and run + // pod placement simulations using scheduler plugins, they MUST be aware of + // CSI driver registration information via CSINode object. They must create simulated + // CSINode objects in addition to Node objects during scheduling simulation, otherwise + // if PreventPodSchedulingIfMissing is enabled globally for CSIDriver object, any + // newly created node may be rejected by the scheduler because of missing CSI driver + // information from the node. + // + // This is an alpha feature and requires the VolumeLimitScaling feature gate to be enabled. + // Default is "false". + PreventPodSchedulingIfMissing *bool `json:"preventPodSchedulingIfMissing,omitempty"` } // CSIDriverSpecApplyConfiguration constructs a declarative configuration of the CSIDriverSpec type for use with @@ -272,3 +290,11 @@ func (b *CSIDriverSpecApplyConfiguration) WithServiceAccountTokenInSecrets(value b.ServiceAccountTokenInSecrets = &value return b } + +// WithPreventPodSchedulingIfMissing sets the PreventPodSchedulingIfMissing field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PreventPodSchedulingIfMissing field is set to the value of the last call. +func (b *CSIDriverSpecApplyConfiguration) WithPreventPodSchedulingIfMissing(value bool) *CSIDriverSpecApplyConfiguration { + b.PreventPodSchedulingIfMissing = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/utils.go b/vendor/k8s.io/client-go/applyconfigurations/utils.go index ef6f16e83b..355051fc8d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/utils.go +++ b/vendor/k8s.io/client-go/applyconfigurations/utils.go @@ -28,8 +28,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" autoscalingv1 "k8s.io/api/autoscaling/v1" v2 "k8s.io/api/autoscaling/v2" - v2beta1 "k8s.io/api/autoscaling/v2beta1" - v2beta2 "k8s.io/api/autoscaling/v2beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" @@ -64,7 +62,7 @@ import ( resourcev1beta1 "k8s.io/api/resource/v1beta1" resourcev1beta2 "k8s.io/api/resource/v1beta2" schedulingv1 "k8s.io/api/scheduling/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" storagev1 "k8s.io/api/storage/v1" storagev1alpha1 "k8s.io/api/storage/v1alpha1" @@ -83,8 +81,6 @@ import ( appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" applyconfigurationsautoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" autoscalingv2 "k8s.io/client-go/applyconfigurations/autoscaling/v2" - autoscalingv2beta1 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1" - autoscalingv2beta2 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2" applyconfigurationsbatchv1 "k8s.io/client-go/applyconfigurations/batch/v1" applyconfigurationsbatchv1beta1 "k8s.io/client-go/applyconfigurations/batch/v1beta1" applyconfigurationscertificatesv1 "k8s.io/client-go/applyconfigurations/certificates/v1" @@ -121,7 +117,7 @@ import ( applyconfigurationsresourcev1beta1 "k8s.io/client-go/applyconfigurations/resource/v1beta1" applyconfigurationsresourcev1beta2 "k8s.io/client-go/applyconfigurations/resource/v1beta2" applyconfigurationsschedulingv1 "k8s.io/client-go/applyconfigurations/scheduling/v1" - applyconfigurationsschedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" + applyconfigurationsschedulingv1alpha2 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha2" applyconfigurationsschedulingv1beta1 "k8s.io/client-go/applyconfigurations/scheduling/v1beta1" applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" applyconfigurationsstoragev1alpha1 "k8s.io/client-go/applyconfigurations/storage/v1alpha1" @@ -134,18 +130,32 @@ import ( func ForKind(kind schema.GroupVersionKind) interface{} { switch kind { // Group=admissionregistration.k8s.io, Version=v1 + case v1.SchemeGroupVersion.WithKind("ApplyConfiguration"): + return &admissionregistrationv1.ApplyConfigurationApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("AuditAnnotation"): return &admissionregistrationv1.AuditAnnotationApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("ExpressionWarning"): return &admissionregistrationv1.ExpressionWarningApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("JSONPatch"): + return &admissionregistrationv1.JSONPatchApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("MatchCondition"): return &admissionregistrationv1.MatchConditionApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("MatchResources"): return &admissionregistrationv1.MatchResourcesApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicy"): + return &admissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicyBinding"): + return &admissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicyBindingSpec"): + return &admissionregistrationv1.MutatingAdmissionPolicyBindingSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicySpec"): + return &admissionregistrationv1.MutatingAdmissionPolicySpecApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("MutatingWebhook"): return &admissionregistrationv1.MutatingWebhookApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("MutatingWebhookConfiguration"): return &admissionregistrationv1.MutatingWebhookConfigurationApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("Mutation"): + return &admissionregistrationv1.MutationApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("NamedRuleWithOperations"): return &admissionregistrationv1.NamedRuleWithOperationsApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("ParamKind"): @@ -489,90 +499,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} { case v2.SchemeGroupVersion.WithKind("ResourceMetricStatus"): return &autoscalingv2.ResourceMetricStatusApplyConfiguration{} - // Group=autoscaling, Version=v2beta1 - case v2beta1.SchemeGroupVersion.WithKind("ContainerResourceMetricSource"): - return &autoscalingv2beta1.ContainerResourceMetricSourceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ContainerResourceMetricStatus"): - return &autoscalingv2beta1.ContainerResourceMetricStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("CrossVersionObjectReference"): - return &autoscalingv2beta1.CrossVersionObjectReferenceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ExternalMetricSource"): - return &autoscalingv2beta1.ExternalMetricSourceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ExternalMetricStatus"): - return &autoscalingv2beta1.ExternalMetricStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler"): - return &autoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerCondition"): - return &autoscalingv2beta1.HorizontalPodAutoscalerConditionApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerSpec"): - return &autoscalingv2beta1.HorizontalPodAutoscalerSpecApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerStatus"): - return &autoscalingv2beta1.HorizontalPodAutoscalerStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("MetricSpec"): - return &autoscalingv2beta1.MetricSpecApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("MetricStatus"): - return &autoscalingv2beta1.MetricStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ObjectMetricSource"): - return &autoscalingv2beta1.ObjectMetricSourceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ObjectMetricStatus"): - return &autoscalingv2beta1.ObjectMetricStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("PodsMetricSource"): - return &autoscalingv2beta1.PodsMetricSourceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("PodsMetricStatus"): - return &autoscalingv2beta1.PodsMetricStatusApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ResourceMetricSource"): - return &autoscalingv2beta1.ResourceMetricSourceApplyConfiguration{} - case v2beta1.SchemeGroupVersion.WithKind("ResourceMetricStatus"): - return &autoscalingv2beta1.ResourceMetricStatusApplyConfiguration{} - - // Group=autoscaling, Version=v2beta2 - case v2beta2.SchemeGroupVersion.WithKind("ContainerResourceMetricSource"): - return &autoscalingv2beta2.ContainerResourceMetricSourceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ContainerResourceMetricStatus"): - return &autoscalingv2beta2.ContainerResourceMetricStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("CrossVersionObjectReference"): - return &autoscalingv2beta2.CrossVersionObjectReferenceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ExternalMetricSource"): - return &autoscalingv2beta2.ExternalMetricSourceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ExternalMetricStatus"): - return &autoscalingv2beta2.ExternalMetricStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler"): - return &autoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerBehavior"): - return &autoscalingv2beta2.HorizontalPodAutoscalerBehaviorApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerCondition"): - return &autoscalingv2beta2.HorizontalPodAutoscalerConditionApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerSpec"): - return &autoscalingv2beta2.HorizontalPodAutoscalerSpecApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerStatus"): - return &autoscalingv2beta2.HorizontalPodAutoscalerStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HPAScalingPolicy"): - return &autoscalingv2beta2.HPAScalingPolicyApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("HPAScalingRules"): - return &autoscalingv2beta2.HPAScalingRulesApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("MetricIdentifier"): - return &autoscalingv2beta2.MetricIdentifierApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("MetricSpec"): - return &autoscalingv2beta2.MetricSpecApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("MetricStatus"): - return &autoscalingv2beta2.MetricStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("MetricTarget"): - return &autoscalingv2beta2.MetricTargetApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("MetricValueStatus"): - return &autoscalingv2beta2.MetricValueStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ObjectMetricSource"): - return &autoscalingv2beta2.ObjectMetricSourceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ObjectMetricStatus"): - return &autoscalingv2beta2.ObjectMetricStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("PodsMetricSource"): - return &autoscalingv2beta2.PodsMetricSourceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("PodsMetricStatus"): - return &autoscalingv2beta2.PodsMetricStatusApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ResourceMetricSource"): - return &autoscalingv2beta2.ResourceMetricSourceApplyConfiguration{} - case v2beta2.SchemeGroupVersion.WithKind("ResourceMetricStatus"): - return &autoscalingv2beta2.ResourceMetricStatusApplyConfiguration{} - // Group=batch, Version=v1 case batchv1.SchemeGroupVersion.WithKind("CronJob"): return &applyconfigurationsbatchv1.CronJobApplyConfiguration{} @@ -818,6 +744,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationscorev1.HTTPHeaderApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("ImageVolumeSource"): return &applyconfigurationscorev1.ImageVolumeSourceApplyConfiguration{} + case corev1.SchemeGroupVersion.WithKind("ImageVolumeStatus"): + return &applyconfigurationscorev1.ImageVolumeStatusApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("ISCSIPersistentVolumeSource"): return &applyconfigurationscorev1.ISCSIPersistentVolumeSourceApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("ISCSIVolumeSource"): @@ -862,6 +790,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationscorev1.NodeAddressApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("NodeAffinity"): return &applyconfigurationscorev1.NodeAffinityApplyConfiguration{} + case corev1.SchemeGroupVersion.WithKind("NodeAllocatableResourceClaimStatus"): + return &applyconfigurationscorev1.NodeAllocatableResourceClaimStatusApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("NodeCondition"): return &applyconfigurationscorev1.NodeConditionApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("NodeConfigSource"): @@ -946,6 +876,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationscorev1.PodResourceClaimStatusApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("PodSchedulingGate"): return &applyconfigurationscorev1.PodSchedulingGateApplyConfiguration{} + case corev1.SchemeGroupVersion.WithKind("PodSchedulingGroup"): + return &applyconfigurationscorev1.PodSchedulingGroupApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("PodSecurityContext"): return &applyconfigurationscorev1.PodSecurityContextApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("PodSpec"): @@ -1078,14 +1010,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationscorev1.VolumeResourceRequirementsApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("VolumeSource"): return &applyconfigurationscorev1.VolumeSourceApplyConfiguration{} + case corev1.SchemeGroupVersion.WithKind("VolumeStatus"): + return &applyconfigurationscorev1.VolumeStatusApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("VsphereVirtualDiskVolumeSource"): return &applyconfigurationscorev1.VsphereVirtualDiskVolumeSourceApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("WeightedPodAffinityTerm"): return &applyconfigurationscorev1.WeightedPodAffinityTermApplyConfiguration{} case corev1.SchemeGroupVersion.WithKind("WindowsSecurityContextOptions"): return &applyconfigurationscorev1.WindowsSecurityContextOptionsApplyConfiguration{} - case corev1.SchemeGroupVersion.WithKind("WorkloadReference"): - return &applyconfigurationscorev1.WorkloadReferenceApplyConfiguration{} // Group=discovery.k8s.io, Version=v1 case discoveryv1.SchemeGroupVersion.WithKind("Endpoint"): @@ -1690,6 +1622,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationsresourcev1.ExactDeviceRequestApplyConfiguration{} case resourcev1.SchemeGroupVersion.WithKind("NetworkDeviceData"): return &applyconfigurationsresourcev1.NetworkDeviceDataApplyConfiguration{} + case resourcev1.SchemeGroupVersion.WithKind("NodeAllocatableResourceMapping"): + return &applyconfigurationsresourcev1.NodeAllocatableResourceMappingApplyConfiguration{} case resourcev1.SchemeGroupVersion.WithKind("OpaqueDeviceConfiguration"): return &applyconfigurationsresourcev1.OpaqueDeviceConfigurationApplyConfiguration{} case resourcev1.SchemeGroupVersion.WithKind("ResourceClaim"): @@ -1722,6 +1656,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &resourcev1alpha3.DeviceTaintRuleStatusApplyConfiguration{} case v1alpha3.SchemeGroupVersion.WithKind("DeviceTaintSelector"): return &resourcev1alpha3.DeviceTaintSelectorApplyConfiguration{} + case v1alpha3.SchemeGroupVersion.WithKind("PoolStatus"): + return &resourcev1alpha3.PoolStatusApplyConfiguration{} + case v1alpha3.SchemeGroupVersion.WithKind("ResourcePoolStatusRequest"): + return &resourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration{} + case v1alpha3.SchemeGroupVersion.WithKind("ResourcePoolStatusRequestSpec"): + return &resourcev1alpha3.ResourcePoolStatusRequestSpecApplyConfiguration{} + case v1alpha3.SchemeGroupVersion.WithKind("ResourcePoolStatusRequestStatus"): + return &resourcev1alpha3.ResourcePoolStatusRequestStatusApplyConfiguration{} // Group=resource.k8s.io, Version=v1beta1 case resourcev1beta1.SchemeGroupVersion.WithKind("AllocatedDeviceStatus"): @@ -1782,6 +1724,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationsresourcev1beta1.DeviceTolerationApplyConfiguration{} case resourcev1beta1.SchemeGroupVersion.WithKind("NetworkDeviceData"): return &applyconfigurationsresourcev1beta1.NetworkDeviceDataApplyConfiguration{} + case resourcev1beta1.SchemeGroupVersion.WithKind("NodeAllocatableResourceMapping"): + return &applyconfigurationsresourcev1beta1.NodeAllocatableResourceMappingApplyConfiguration{} case resourcev1beta1.SchemeGroupVersion.WithKind("OpaqueDeviceConfiguration"): return &applyconfigurationsresourcev1beta1.OpaqueDeviceConfigurationApplyConfiguration{} case resourcev1beta1.SchemeGroupVersion.WithKind("ResourceClaim"): @@ -1856,12 +1800,22 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationsresourcev1beta2.DeviceSubRequestApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceTaint"): return &applyconfigurationsresourcev1beta2.DeviceTaintApplyConfiguration{} + case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceTaintRule"): + return &applyconfigurationsresourcev1beta2.DeviceTaintRuleApplyConfiguration{} + case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceTaintRuleSpec"): + return &applyconfigurationsresourcev1beta2.DeviceTaintRuleSpecApplyConfiguration{} + case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceTaintRuleStatus"): + return &applyconfigurationsresourcev1beta2.DeviceTaintRuleStatusApplyConfiguration{} + case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceTaintSelector"): + return &applyconfigurationsresourcev1beta2.DeviceTaintSelectorApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("DeviceToleration"): return &applyconfigurationsresourcev1beta2.DeviceTolerationApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("ExactDeviceRequest"): return &applyconfigurationsresourcev1beta2.ExactDeviceRequestApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("NetworkDeviceData"): return &applyconfigurationsresourcev1beta2.NetworkDeviceDataApplyConfiguration{} + case resourcev1beta2.SchemeGroupVersion.WithKind("NodeAllocatableResourceMapping"): + return &applyconfigurationsresourcev1beta2.NodeAllocatableResourceMappingApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("OpaqueDeviceConfiguration"): return &applyconfigurationsresourcev1beta2.OpaqueDeviceConfigurationApplyConfiguration{} case resourcev1beta2.SchemeGroupVersion.WithKind("ResourceClaim"): @@ -1887,21 +1841,37 @@ func ForKind(kind schema.GroupVersionKind) interface{} { case schedulingv1.SchemeGroupVersion.WithKind("PriorityClass"): return &applyconfigurationsschedulingv1.PriorityClassApplyConfiguration{} - // Group=scheduling.k8s.io, Version=v1alpha1 - case schedulingv1alpha1.SchemeGroupVersion.WithKind("GangSchedulingPolicy"): - return &applyconfigurationsschedulingv1alpha1.GangSchedulingPolicyApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("PodGroup"): - return &applyconfigurationsschedulingv1alpha1.PodGroupApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("PodGroupPolicy"): - return &applyconfigurationsschedulingv1alpha1.PodGroupPolicyApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("PriorityClass"): - return &applyconfigurationsschedulingv1alpha1.PriorityClassApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("TypedLocalObjectReference"): - return &applyconfigurationsschedulingv1alpha1.TypedLocalObjectReferenceApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("Workload"): - return &applyconfigurationsschedulingv1alpha1.WorkloadApplyConfiguration{} - case schedulingv1alpha1.SchemeGroupVersion.WithKind("WorkloadSpec"): - return &applyconfigurationsschedulingv1alpha1.WorkloadSpecApplyConfiguration{} + // Group=scheduling.k8s.io, Version=v1alpha2 + case schedulingv1alpha2.SchemeGroupVersion.WithKind("GangSchedulingPolicy"): + return &applyconfigurationsschedulingv1alpha2.GangSchedulingPolicyApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroup"): + return &applyconfigurationsschedulingv1alpha2.PodGroupApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupResourceClaim"): + return &applyconfigurationsschedulingv1alpha2.PodGroupResourceClaimApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupResourceClaimStatus"): + return &applyconfigurationsschedulingv1alpha2.PodGroupResourceClaimStatusApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupSchedulingConstraints"): + return &applyconfigurationsschedulingv1alpha2.PodGroupSchedulingConstraintsApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupSchedulingPolicy"): + return &applyconfigurationsschedulingv1alpha2.PodGroupSchedulingPolicyApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupSpec"): + return &applyconfigurationsschedulingv1alpha2.PodGroupSpecApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupStatus"): + return &applyconfigurationsschedulingv1alpha2.PodGroupStatusApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupTemplate"): + return &applyconfigurationsschedulingv1alpha2.PodGroupTemplateApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("PodGroupTemplateReference"): + return &applyconfigurationsschedulingv1alpha2.PodGroupTemplateReferenceApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("TopologyConstraint"): + return &applyconfigurationsschedulingv1alpha2.TopologyConstraintApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("TypedLocalObjectReference"): + return &applyconfigurationsschedulingv1alpha2.TypedLocalObjectReferenceApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("Workload"): + return &applyconfigurationsschedulingv1alpha2.WorkloadApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("WorkloadPodGroupTemplateReference"): + return &applyconfigurationsschedulingv1alpha2.WorkloadPodGroupTemplateReferenceApplyConfiguration{} + case schedulingv1alpha2.SchemeGroupVersion.WithKind("WorkloadSpec"): + return &applyconfigurationsschedulingv1alpha2.WorkloadSpecApplyConfiguration{} // Group=scheduling.k8s.io, Version=v1beta1 case schedulingv1beta1.SchemeGroupVersion.WithKind("PriorityClass"): diff --git a/vendor/k8s.io/client-go/discovery/cached/disk/round_tripper.go b/vendor/k8s.io/client-go/discovery/cached/disk/round_tripper.go index f3a4b2947f..b978a2bed9 100644 --- a/vendor/k8s.io/client-go/discovery/cached/disk/round_tripper.go +++ b/vendor/k8s.io/client-go/discovery/cached/disk/round_tripper.go @@ -24,8 +24,8 @@ import ( "os" "path/filepath" - "github.com/gregjones/httpcache" "github.com/peterbourgon/diskv" + "k8s.io/client-go/third_party/forked/httpcache" "k8s.io/klog/v2" ) @@ -66,7 +66,7 @@ func (rt *cacheRoundTripper) CancelRequest(req *http.Request) { func (rt *cacheRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt.Transport } -// A sumDiskCache is a cache backend for github.com/gregjones/httpcache. It is +// A sumDiskCache is a cache backend for httpcache. It is // similar to httpcache's diskcache package, but uses SHA256 sums to ensure // cache integrity at read time rather than fsyncing each cache entry to // increase the likelihood they will be persisted at write time. This avoids diff --git a/vendor/k8s.io/client-go/dynamic/fake/simple.go b/vendor/k8s.io/client-go/dynamic/fake/simple.go index 06ef859425..39b3b64600 100644 --- a/vendor/k8s.io/client-go/dynamic/fake/simple.go +++ b/vendor/k8s.io/client-go/dynamic/fake/simple.go @@ -114,9 +114,13 @@ func NewSimpleDynamicClientWithCustomListKinds(scheme *runtime.Scheme, gvrToList cs := &FakeDynamicClient{scheme: scheme, gvrToListKind: completeGVRToListKind, tracker: o} cs.AddReactor("*", "*", testing.ObjectReaction(o)) cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + var opts metav1.ListOptions + if watchAction, ok := action.(testing.WatchActionImpl); ok { + opts = watchAction.ListOptions + } gvr := action.GetResource() ns := action.GetNamespace() - watch, err := o.Watch(gvr, ns) + watch, err := o.Watch(gvr, ns, opts) if err != nil { return false, nil, err } diff --git a/vendor/k8s.io/client-go/features/envvar.go b/vendor/k8s.io/client-go/features/envvar.go index 8c3f887dc4..93aa21fa71 100644 --- a/vendor/k8s.io/client-go/features/envvar.go +++ b/vendor/k8s.io/client-go/features/envvar.go @@ -121,12 +121,28 @@ func (f *envVarFeatureGates) Enabled(key Feature) bool { // Features set via this method take precedence over // the features set via environment variables. func (f *envVarFeatureGates) Set(featureName Feature, featureValue bool) error { + return f.set(featureName, featureValue, false) +} + +// SetForTesting sets the given feature to the given value. This method +// bypasses the check for locked features and should only be used for +// testing purposes. +// +// Features set via this method take precedence over +// the features set via environment variables. +func (f *envVarFeatureGates) SetForTesting(featureName Feature, featureValue bool) error { + return f.set(featureName, featureValue, true) +} + +func (f *envVarFeatureGates) set(featureName Feature, featureValue bool, allowChangingLockedFeatures bool) error { feature, ok := f.known[featureName] if !ok { return fmt.Errorf("feature %q is not registered in FeatureGates %q", featureName, f.callSiteName) } - if feature.LockToDefault && feature.Default != featureValue { - return fmt.Errorf("cannot set feature gate %q to %v, feature is locked to %v", featureName, featureValue, feature.Default) + if !allowChangingLockedFeatures { + if feature.LockToDefault && feature.Default != featureValue { + return fmt.Errorf("cannot set feature gate %q to %v, feature is locked to %v", featureName, featureValue, feature.Default) + } } f.lockEnabledViaSetMethod.Lock() @@ -141,6 +157,13 @@ func (f *envVarFeatureGates) Set(featureName Feature, featureValue bool) error { // read from the corresponding environmental variable. func (f *envVarFeatureGates) getEnabledMapFromEnvVar() map[Feature]bool { f.readEnvVarsOnce.Do(func() { + // This code does not really support contextual logging. Making it do so has huge + // implications for several call chains because the Enabled call then needs + // a `*WithLogger` variant. This does not matter in Kubernetes itself because + // all Kubernetes components replace the feature gate implementation used + // by client-go, but it might matter elsewhere. + logger := klog.Background() + featureGatesState := map[Feature]bool{} for feature, featureSpec := range f.known { featureState, featureStateSet := os.LookupEnv(fmt.Sprintf("KUBE_FEATURE_%s", feature)) @@ -150,10 +173,10 @@ func (f *envVarFeatureGates) getEnabledMapFromEnvVar() map[Feature]bool { boolVal, boolErr := strconv.ParseBool(featureState) switch { case boolErr != nil: - utilruntime.HandleError(fmt.Errorf("cannot set feature gate %q to %q, due to %v", feature, featureState, boolErr)) + utilruntime.HandleErrorWithLogger(logger, boolErr, "Could not set feature gate", "feature", feature, "desiredState", featureState) case featureSpec.LockToDefault: if boolVal != featureSpec.Default { - utilruntime.HandleError(fmt.Errorf("cannot set feature gate %q to %q, feature is locked to %v", feature, featureState, featureSpec.Default)) + utilruntime.HandleErrorWithLogger(logger, nil, "Could not set feature gate, feature is locked", "feature", feature, "desiredState", featureState, "lockedState", featureSpec.Default) break } featureGatesState[feature] = featureSpec.Default @@ -166,10 +189,10 @@ func (f *envVarFeatureGates) getEnabledMapFromEnvVar() map[Feature]bool { for feature, featureSpec := range f.known { if featureState, ok := featureGatesState[feature]; ok { - klog.V(1).InfoS("Feature gate updated state", "feature", feature, "enabled", featureState) + logger.V(1).Info("Feature gate updated state", "feature", feature, "enabled", featureState) continue } - klog.V(1).InfoS("Feature gate default state", "feature", feature, "enabled", featureSpec.Default) + logger.V(1).Info("Feature gate default state", "feature", feature, "enabled", featureSpec.Default) } }) return f.enabledViaEnvVar.Load().(map[Feature]bool) diff --git a/vendor/k8s.io/client-go/features/features.go b/vendor/k8s.io/client-go/features/features.go index cabb7468d6..f21511dca2 100644 --- a/vendor/k8s.io/client-go/features/features.go +++ b/vendor/k8s.io/client-go/features/features.go @@ -17,7 +17,7 @@ limitations under the License. package features import ( - "errors" + "context" "sync/atomic" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -127,7 +127,9 @@ func AddVersionedFeaturesToExistingFeatureGates(registry VersionedRegistry) erro // clientgofeaturegate.ReplaceFeatureGates(utilfeature.DefaultMutableFeatureGate) func ReplaceFeatureGates(newFeatureGates Gates) { if replaceFeatureGatesWithWarningIndicator(newFeatureGates) { - utilruntime.HandleError(errors.New("the default feature gates implementation has already been used and now it's being overwritten. This might lead to unexpected behaviour. Check your initialization order")) + // TODO (?): A new API would be needed where callers pass in a context or logger. + // Probably not worth it. + utilruntime.HandleErrorWithContext(context.TODO(), nil, "The default feature gates implementation has already been used and now it's being overwritten. This might lead to unexpected behaviour. Check your initialization order.") } } diff --git a/vendor/k8s.io/client-go/features/known_features.go b/vendor/k8s.io/client-go/features/known_features.go index 4b022c4b4f..250188dbc2 100644 --- a/vendor/k8s.io/client-go/features/known_features.go +++ b/vendor/k8s.io/client-go/features/known_features.go @@ -31,6 +31,20 @@ import ( // of code conflicts because changes are more likely to be scattered // across the file. const ( + // owner: @michaelasp + // beta: v1.36 + // + // Allow the client to process events atomically rather than a stream of + // events for items popped off the FIFO. + AtomicFIFO Feature = "AtomicFIFO" + + // owner: @yt2985 + // beta: 1.36 + // + // If enabled, allows clients to gracefully handle Certificate Authority (CA) + // rotations without dropping connections or requiring a restart. + ClientsAllowCARotation Feature = "ClientsAllowCARotation" + // owner: @benluddy // kep: https://kep.k8s.io/4222 // alpha: 1.32 @@ -41,6 +55,13 @@ const ( // "application/json" or "application/apply-patch+yaml", respectively. ClientsAllowCBOR Feature = "ClientsAllowCBOR" + // owner: @enj + // beta: v1.36 + // + // If enabled, the client-go TLS transport cache uses weak pointers to allow + // garbage collection of unused transports, preventing unbounded cache growth. + ClientsAllowTLSCacheGC Feature = "ClientsAllowTLSCacheGC" + // owner: @benluddy // kep: https://kep.k8s.io/4222 // alpha: 1.32 @@ -69,6 +90,12 @@ const ( // GA: v1.35 InformerResourceVersion Feature = "InformerResourceVersion" + // owner: @michaelasp + // beta: v1.36 + // + // Allow the FIFO to unlock while processing items to allow other goroutines to add items to the queue. + UnlockWhileProcessingFIFO Feature = "UnlockWhileProcessingFIFO" + // owner: @p0lyn0mial // beta: v1.30 // @@ -82,14 +109,24 @@ const ( // After registering with the binary, the features are, by default, controllable using environment variables. // For more details, please see envVarFeatureGates implementation. var defaultVersionedKubernetesFeatureGates = map[Feature]VersionedSpecs{ + AtomicFIFO: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: Beta}, + }, + ClientsAllowCARotation: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: Beta}, + }, ClientsAllowCBOR: { {Version: version.MustParse("1.32"), Default: false, PreRelease: Alpha}, }, + ClientsAllowTLSCacheGC: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: Beta}, + }, ClientsPreferCBOR: { {Version: version.MustParse("1.32"), Default: false, PreRelease: Alpha}, }, InOrderInformers: { {Version: version.MustParse("1.33"), Default: true, PreRelease: Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: GA, LockToDefault: true}, }, InOrderInformersBatchProcess: { {Version: version.MustParse("1.35"), Default: true, PreRelease: Beta}, @@ -98,6 +135,9 @@ var defaultVersionedKubernetesFeatureGates = map[Feature]VersionedSpecs{ {Version: version.MustParse("1.30"), Default: false, PreRelease: Alpha}, {Version: version.MustParse("1.35"), Default: true, PreRelease: GA}, }, + UnlockWhileProcessingFIFO: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: Beta}, + }, WatchListClient: { {Version: version.MustParse("1.30"), Default: false, PreRelease: Beta}, {Version: version.MustParse("1.35"), Default: true, PreRelease: Beta}, diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go index 08769d3cca..4bfe9c4c6e 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/interface.go @@ -24,6 +24,10 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { + // MutatingAdmissionPolicies returns a MutatingAdmissionPolicyInformer. + MutatingAdmissionPolicies() MutatingAdmissionPolicyInformer + // MutatingAdmissionPolicyBindings returns a MutatingAdmissionPolicyBindingInformer. + MutatingAdmissionPolicyBindings() MutatingAdmissionPolicyBindingInformer // MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer // ValidatingAdmissionPolicies returns a ValidatingAdmissionPolicyInformer. @@ -45,6 +49,16 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// MutatingAdmissionPolicies returns a MutatingAdmissionPolicyInformer. +func (v *version) MutatingAdmissionPolicies() MutatingAdmissionPolicyInformer { + return &mutatingAdmissionPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// MutatingAdmissionPolicyBindings returns a MutatingAdmissionPolicyBindingInformer. +func (v *version) MutatingAdmissionPolicyBindings() MutatingAdmissionPolicyBindingInformer { + return &mutatingAdmissionPolicyBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // MutatingWebhookConfigurations returns a MutatingWebhookConfigurationInformer. func (v *version) MutatingWebhookConfigurations() MutatingWebhookConfigurationInformer { return &mutatingWebhookConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicy.go new file mode 100644 index 0000000000..65df1905a5 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicy.go @@ -0,0 +1,115 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + context "context" + time "time" + + apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + admissionregistrationv1 "k8s.io/client-go/listers/admissionregistration/v1" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingAdmissionPolicyInformer provides access to a shared informer and lister for +// MutatingAdmissionPolicies. +type MutatingAdmissionPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() admissionregistrationv1.MutatingAdmissionPolicyLister +} + +type mutatingAdmissionPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewMutatingAdmissionPolicyInformer constructs a new informer for MutatingAdmissionPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredMutatingAdmissionPolicyInformer constructs a new informer for MutatingAdmissionPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyInformerWithOptions constructs a new informer for MutatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "mutatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicies().List(context.Background(), opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicies().Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicies().List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicies().Watch(ctx, opts) + }, + }, client), + &apiadmissionregistrationv1.MutatingAdmissionPolicy{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *mutatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *mutatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiadmissionregistrationv1.MutatingAdmissionPolicy{}, f.defaultInformer) +} + +func (f *mutatingAdmissionPolicyInformer) Lister() admissionregistrationv1.MutatingAdmissionPolicyLister { + return admissionregistrationv1.NewMutatingAdmissionPolicyLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicybinding.go new file mode 100644 index 0000000000..d06ca0b4e1 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingadmissionpolicybinding.go @@ -0,0 +1,115 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + context "context" + time "time" + + apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + admissionregistrationv1 "k8s.io/client-go/listers/admissionregistration/v1" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingAdmissionPolicyBindingInformer provides access to a shared informer and lister for +// MutatingAdmissionPolicyBindings. +type MutatingAdmissionPolicyBindingInformer interface { + Informer() cache.SharedIndexInformer + Lister() admissionregistrationv1.MutatingAdmissionPolicyBindingLister +} + +type mutatingAdmissionPolicyBindingInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewMutatingAdmissionPolicyBindingInformer constructs a new informer for MutatingAdmissionPolicyBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredMutatingAdmissionPolicyBindingInformer constructs a new informer for MutatingAdmissionPolicyBinding type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for MutatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "mutatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicyBindings().List(context.Background(), opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicyBindings().Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicyBindings().List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.AdmissionregistrationV1().MutatingAdmissionPolicyBindings().Watch(ctx, opts) + }, + }, client), + &apiadmissionregistrationv1.MutatingAdmissionPolicyBinding{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *mutatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *mutatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiadmissionregistrationv1.MutatingAdmissionPolicyBinding{}, f.defaultInformer) +} + +func (f *mutatingAdmissionPolicyBindingInformer) Lister() admissionregistrationv1.MutatingAdmissionPolicyBindingLister { + return admissionregistrationv1.NewMutatingAdmissionPolicyBindingLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go index 77439c4bc7..d7c48e78a6 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/mutatingwebhookconfiguration.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingWebhookConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingWebhookConfigurationInformerWithOptions constructs a new informer for MutatingWebhookConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingWebhookConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "mutatingwebhookconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.Background(), options) + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(context.Background(), options) + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().MutatingWebhookConfigurations().List(ctx, options) + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(ctx, options) + return client.AdmissionregistrationV1().MutatingWebhookConfigurations().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1.MutatingWebhookConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicy.go index 89b86c09e1..bdc5c0b28a 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicy.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyInformer constructs a new informer for ValidatingAdmissionPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyInformerWithOptions constructs a new informer for ValidatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "validatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().List(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Watch(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().List(ctx, options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Watch(ctx, options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicies().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1.ValidatingAdmissionPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicybinding.go index b318ed445b..1ecf9703a9 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingadmissionpolicybinding.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyBindingInformer constructs a new informer for ValidatingAdmissionPolicyBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for ValidatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "validatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().List(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().List(ctx, options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().Watch(ctx, options) + return client.AdmissionregistrationV1().ValidatingAdmissionPolicyBindings().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1.ValidatingAdmissionPolicyBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go index d1d3840795..07653c35ce 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1/validatingwebhookconfiguration.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingWebhookConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingWebhookConfigurationInformerWithOptions constructs a new informer for ValidatingWebhookConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingWebhookConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "validatingwebhookconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(context.Background(), options) + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().List(ctx, options) + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(ctx, options) + return client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1.ValidatingWebhookConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicy.go index 2a0cb2cfde..3441d6df44 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicy.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingAdmissionPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingAdmissionPolicyInformer constructs a new informer for MutatingAdmissionPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyInformerWithOptions constructs a new informer for MutatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "mutatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().List(context.Background(), options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().Watch(context.Background(), options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().List(ctx, options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().Watch(ctx, options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicies().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1alpha1.MutatingAdmissionPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go index 23ef580fef..568c911159 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/mutatingadmissionpolicybinding.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingAdmissionPolicyBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingAdmissionPolicyBindingInformer constructs a new informer for MutatingAdmissionPolicyBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for MutatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "mutatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().List(context.Background(), options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().Watch(context.Background(), options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().List(ctx, options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().Watch(ctx, options) + return client.AdmissionregistrationV1alpha1().MutatingAdmissionPolicyBindings().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1alpha1.MutatingAdmissionPolicyBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go index 9a896b70dd..c86ca6da62 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyInformer constructs a new informer for ValidatingAdmissionPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyInformerWithOptions constructs a new informer for ValidatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "validatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().List(context.Background(), options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Watch(context.Background(), options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().List(ctx, options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Watch(ctx, options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1alpha1.ValidatingAdmissionPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go index 630471e9e2..224049a254 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1alpha1/validatingadmissionpolicybinding.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyBindingInformer constructs a new informer for ValidatingAdmissionPolicyBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for ValidatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "validatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().List(context.Background(), options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().List(ctx, options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().Watch(ctx, options) + return client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicyBindings().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicy.go index bfd1e4245d..edfe94417b 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicy.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingAdmissionPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingAdmissionPolicyInformer constructs a new informer for MutatingAdmissionPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyInformerWithOptions constructs a new informer for MutatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "mutatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().List(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicies().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.MutatingAdmissionPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go index 416590c0b7..bb833f4447 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingadmissionpolicybinding.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingAdmissionPolicyBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingAdmissionPolicyBindingInformer constructs a new informer for MutatingAdmissionPolicyBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for MutatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "mutatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().List(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingAdmissionPolicyBindings().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.MutatingAdmissionPolicyBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go index 2f086798e2..bb077a1746 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/mutatingwebhookconfiguration.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type mutatingWebhookConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredMutatingWebhookConfigurationInformer constructs a new informer for MutatingWebhookConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredMutatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewMutatingWebhookConfigurationInformerWithOptions constructs a new informer for MutatingWebhookConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewMutatingWebhookConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "mutatingwebhookconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().List(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.MutatingWebhookConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *mutatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredMutatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewMutatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicy.go index 18960ff9f8..a88a254d6f 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicy.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyInformer constructs a new informer for ValidatingAdmissionPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyInformerWithOptions constructs a new informer for ValidatingAdmissionPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "validatingadmissionpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().List(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.ValidatingAdmissionPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicybinding.go index ab3febb15a..d1df5a3f2f 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingadmissionpolicybinding.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingAdmissionPolicyBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, indexers, nil) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingAdmissionPolicyBindingInformer constructs a new informer for ValidatingAdmissionPolicyBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingAdmissionPolicyBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingAdmissionPolicyBindingInformerWithOptions constructs a new informer for ValidatingAdmissionPolicyBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingAdmissionPolicyBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "validatingadmissionpolicybindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().List(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicyBindings().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingAdmissionPolicyBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingAdmissionPolicyBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingAdmissionPolicyBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingAdmissionPolicyBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go index ae88860543..41852cb03d 100644 --- a/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/informers/admissionregistration/v1beta1/validatingwebhookconfiguration.go @@ -25,6 +25,7 @@ import ( apiadmissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type validatingWebhookConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredValidatingWebhookConfigurationInformer constructs a new informer for ValidatingWebhookConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredValidatingWebhookConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewValidatingWebhookConfigurationInformerWithOptions constructs a new informer for ValidatingWebhookConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewValidatingWebhookConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "validatingwebhookconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().List(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(context.Background(), options) + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().List(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(ctx, options) + return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(ctx, opts) }, }, client), &apiadmissionregistrationv1beta1.ValidatingWebhookConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *validatingWebhookConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredValidatingWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewValidatingWebhookConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go index 1f1cfd503f..6d164a317c 100644 --- a/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go +++ b/vendor/k8s.io/client-go/informers/apiserverinternal/v1alpha1/storageversion.go @@ -25,6 +25,7 @@ import ( apiapiserverinternalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type storageVersionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStorageVersionInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageVersionInformer(client, resyncPeriod, indexers, nil) + return NewStorageVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStorageVersionInformer constructs a new informer for StorageVersion type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStorageVersionInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStorageVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStorageVersionInformerWithOptions constructs a new informer for StorageVersion type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageVersionInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "internal.apiserver.k8s.io", Version: "v1alpha1", Resource: "storageversions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.InternalV1alpha1().StorageVersions().List(context.Background(), options) + return client.InternalV1alpha1().StorageVersions().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.InternalV1alpha1().StorageVersions().Watch(context.Background(), options) + return client.InternalV1alpha1().StorageVersions().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.InternalV1alpha1().StorageVersions().List(ctx, options) + return client.InternalV1alpha1().StorageVersions().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.InternalV1alpha1().StorageVersions().Watch(ctx, options) + return client.InternalV1alpha1().StorageVersions().Watch(ctx, opts) }, }, client), &apiapiserverinternalv1alpha1.StorageVersion{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *storageVersionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageVersionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStorageVersionInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *storageVersionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go index 1d306123ca..f58da53f18 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go +++ b/vendor/k8s.io/client-go/informers/apps/v1/controllerrevision.go @@ -25,6 +25,7 @@ import ( apiappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type controllerRevisionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewControllerRevisionInformerWithOptions constructs a new informer for ControllerRevision type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "controllerrevisions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ControllerRevisions(namespace).List(context.Background(), options) + return client.AppsV1().ControllerRevisions(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ControllerRevisions(namespace).Watch(context.Background(), options) + return client.AppsV1().ControllerRevisions(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ControllerRevisions(namespace).List(ctx, options) + return client.AppsV1().ControllerRevisions(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ControllerRevisions(namespace).Watch(ctx, options) + return client.AppsV1().ControllerRevisions(namespace).Watch(ctx, opts) }, }, client), &apiappsv1.ControllerRevision{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewControllerRevisionInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go b/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go index 658d6b9ae0..dbdc401242 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1/daemonset.go @@ -25,6 +25,7 @@ import ( apiappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type daemonSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDaemonSetInformerWithOptions constructs a new informer for DaemonSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().DaemonSets(namespace).List(context.Background(), options) + return client.AppsV1().DaemonSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().DaemonSets(namespace).Watch(context.Background(), options) + return client.AppsV1().DaemonSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().DaemonSets(namespace).List(ctx, options) + return client.AppsV1().DaemonSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().DaemonSets(namespace).Watch(ctx, options) + return client.AppsV1().DaemonSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1.DaemonSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDaemonSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1/deployment.go index 4a8a29c246..dbf4df6a88 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1/deployment.go +++ b/vendor/k8s.io/client-go/informers/apps/v1/deployment.go @@ -25,6 +25,7 @@ import ( apiappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type deploymentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeploymentInformer constructs a new informer for Deployment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeploymentInformerWithOptions constructs a new informer for Deployment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().Deployments(namespace).List(context.Background(), options) + return client.AppsV1().Deployments(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().Deployments(namespace).Watch(context.Background(), options) + return client.AppsV1().Deployments(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().Deployments(namespace).List(ctx, options) + return client.AppsV1().Deployments(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().Deployments(namespace).Watch(ctx, options) + return client.AppsV1().Deployments(namespace).Watch(ctx, opts) }, }, client), &apiappsv1.Deployment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeploymentInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deploymentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go b/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go index d37292cb6d..1115e5adcc 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1/replicaset.go @@ -25,6 +25,7 @@ import ( apiappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type replicaSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewReplicaSetInformerWithOptions constructs a new informer for ReplicaSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "replicasets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ReplicaSets(namespace).List(context.Background(), options) + return client.AppsV1().ReplicaSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ReplicaSets(namespace).Watch(context.Background(), options) + return client.AppsV1().ReplicaSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ReplicaSets(namespace).List(ctx, options) + return client.AppsV1().ReplicaSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().ReplicaSets(namespace).Watch(ctx, options) + return client.AppsV1().ReplicaSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1.ReplicaSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewReplicaSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go index 70a5f9c0ba..998251edee 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1/statefulset.go @@ -25,6 +25,7 @@ import ( apiappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type statefulSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStatefulSetInformerWithOptions constructs a new informer for StatefulSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().StatefulSets(namespace).List(context.Background(), options) + return client.AppsV1().StatefulSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().StatefulSets(namespace).Watch(context.Background(), options) + return client.AppsV1().StatefulSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().StatefulSets(namespace).List(ctx, options) + return client.AppsV1().StatefulSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1().StatefulSets(namespace).Watch(ctx, options) + return client.AppsV1().StatefulSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1.StatefulSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStatefulSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go index deaaa24c6b..ee3b156e02 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/controllerrevision.go @@ -25,6 +25,7 @@ import ( apiappsv1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type controllerRevisionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewControllerRevisionInformerWithOptions constructs a new informer for ControllerRevision type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "controllerrevisions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().ControllerRevisions(namespace).List(context.Background(), options) + return client.AppsV1beta1().ControllerRevisions(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().ControllerRevisions(namespace).Watch(context.Background(), options) + return client.AppsV1beta1().ControllerRevisions(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().ControllerRevisions(namespace).List(ctx, options) + return client.AppsV1beta1().ControllerRevisions(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().ControllerRevisions(namespace).Watch(ctx, options) + return client.AppsV1beta1().ControllerRevisions(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta1.ControllerRevision{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewControllerRevisionInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go index 4dbad1e983..699375e3e1 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/deployment.go @@ -25,6 +25,7 @@ import ( apiappsv1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type deploymentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeploymentInformer constructs a new informer for Deployment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeploymentInformerWithOptions constructs a new informer for Deployment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "deployments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().Deployments(namespace).List(context.Background(), options) + return client.AppsV1beta1().Deployments(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().Deployments(namespace).Watch(context.Background(), options) + return client.AppsV1beta1().Deployments(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().Deployments(namespace).List(ctx, options) + return client.AppsV1beta1().Deployments(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().Deployments(namespace).Watch(ctx, options) + return client.AppsV1beta1().Deployments(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta1.Deployment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeploymentInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deploymentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go index 2c5aa846ec..480e68f9d1 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta1/statefulset.go @@ -25,6 +25,7 @@ import ( apiappsv1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type statefulSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStatefulSetInformerWithOptions constructs a new informer for StatefulSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "statefulsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().StatefulSets(namespace).List(context.Background(), options) + return client.AppsV1beta1().StatefulSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().StatefulSets(namespace).Watch(context.Background(), options) + return client.AppsV1beta1().StatefulSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().StatefulSets(namespace).List(ctx, options) + return client.AppsV1beta1().StatefulSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta1().StatefulSets(namespace).Watch(ctx, options) + return client.AppsV1beta1().StatefulSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta1.StatefulSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStatefulSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go index f6cca7d574..41e3bf1563 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/controllerrevision.go @@ -25,6 +25,7 @@ import ( apiappsv1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type controllerRevisionInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, namespace, resyncPeriod, indexers, nil) + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredControllerRevisionInformer constructs a new informer for ControllerRevision type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewControllerRevisionInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewControllerRevisionInformerWithOptions constructs a new informer for ControllerRevision type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewControllerRevisionInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "controllerrevisions"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ControllerRevisions(namespace).List(context.Background(), options) + return client.AppsV1beta2().ControllerRevisions(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ControllerRevisions(namespace).Watch(context.Background(), options) + return client.AppsV1beta2().ControllerRevisions(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ControllerRevisions(namespace).List(ctx, options) + return client.AppsV1beta2().ControllerRevisions(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ControllerRevisions(namespace).Watch(ctx, options) + return client.AppsV1beta2().ControllerRevisions(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta2.ControllerRevision{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredControllerRevisionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewControllerRevisionInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go index aaec4988c2..5c339a78a0 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/daemonset.go @@ -25,6 +25,7 @@ import ( apiappsv1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type daemonSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDaemonSetInformerWithOptions constructs a new informer for DaemonSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "daemonsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().DaemonSets(namespace).List(context.Background(), options) + return client.AppsV1beta2().DaemonSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().DaemonSets(namespace).Watch(context.Background(), options) + return client.AppsV1beta2().DaemonSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().DaemonSets(namespace).List(ctx, options) + return client.AppsV1beta2().DaemonSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().DaemonSets(namespace).Watch(ctx, options) + return client.AppsV1beta2().DaemonSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta2.DaemonSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDaemonSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go index 69f6e3fb8e..1e0b64cb28 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/deployment.go @@ -25,6 +25,7 @@ import ( apiappsv1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type deploymentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeploymentInformer constructs a new informer for Deployment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeploymentInformerWithOptions constructs a new informer for Deployment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "deployments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().Deployments(namespace).List(context.Background(), options) + return client.AppsV1beta2().Deployments(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().Deployments(namespace).Watch(context.Background(), options) + return client.AppsV1beta2().Deployments(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().Deployments(namespace).List(ctx, options) + return client.AppsV1beta2().Deployments(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().Deployments(namespace).Watch(ctx, options) + return client.AppsV1beta2().Deployments(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta2.Deployment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeploymentInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deploymentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go index a65d451616..425ad55333 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/replicaset.go @@ -25,6 +25,7 @@ import ( apiappsv1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type replicaSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewReplicaSetInformerWithOptions constructs a new informer for ReplicaSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "replicasets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ReplicaSets(namespace).List(context.Background(), options) + return client.AppsV1beta2().ReplicaSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ReplicaSets(namespace).Watch(context.Background(), options) + return client.AppsV1beta2().ReplicaSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ReplicaSets(namespace).List(ctx, options) + return client.AppsV1beta2().ReplicaSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().ReplicaSets(namespace).Watch(ctx, options) + return client.AppsV1beta2().ReplicaSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta2.ReplicaSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewReplicaSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go b/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go index 5e90c39c7b..0fb22661cf 100644 --- a/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go +++ b/vendor/k8s.io/client-go/informers/apps/v1beta2/statefulset.go @@ -25,6 +25,7 @@ import ( apiappsv1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type statefulSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStatefulSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStatefulSetInformerWithOptions constructs a new informer for StatefulSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStatefulSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "statefulsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().StatefulSets(namespace).List(context.Background(), options) + return client.AppsV1beta2().StatefulSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().StatefulSets(namespace).Watch(context.Background(), options) + return client.AppsV1beta2().StatefulSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().StatefulSets(namespace).List(ctx, options) + return client.AppsV1beta2().StatefulSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AppsV1beta2().StatefulSets(namespace).Watch(ctx, options) + return client.AppsV1beta2().StatefulSets(namespace).Watch(ctx, opts) }, }, client), &apiappsv1beta2.StatefulSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStatefulSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *statefulSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/autoscaling/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/interface.go index 2b3b2d0e50..439dd24beb 100644 --- a/vendor/k8s.io/client-go/informers/autoscaling/interface.go +++ b/vendor/k8s.io/client-go/informers/autoscaling/interface.go @@ -21,8 +21,6 @@ package autoscaling import ( v1 "k8s.io/client-go/informers/autoscaling/v1" v2 "k8s.io/client-go/informers/autoscaling/v2" - v2beta1 "k8s.io/client-go/informers/autoscaling/v2beta1" - v2beta2 "k8s.io/client-go/informers/autoscaling/v2beta2" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" ) @@ -32,10 +30,6 @@ type Interface interface { V1() v1.Interface // V2 provides access to shared informers for resources in V2. V2() v2.Interface - // V2beta1 provides access to shared informers for resources in V2beta1. - V2beta1() v2beta1.Interface - // V2beta2 provides access to shared informers for resources in V2beta2. - V2beta2() v2beta2.Interface } type group struct { @@ -58,13 +52,3 @@ func (g *group) V1() v1.Interface { func (g *group) V2() v2.Interface { return v2.New(g.factory, g.namespace, g.tweakListOptions) } - -// V2beta1 returns a new v2beta1.Interface. -func (g *group) V2beta1() v2beta1.Interface { - return v2beta1.New(g.factory, g.namespace, g.tweakListOptions) -} - -// V2beta2 returns a new v2beta2.Interface. -func (g *group) V2beta2() v2beta2.Interface { - return v2beta2.New(g.factory, g.namespace, g.tweakListOptions) -} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go index 98aacb1e3c..e49b035242 100644 --- a/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/informers/autoscaling/v1/horizontalpodautoscaler.go @@ -25,6 +25,7 @@ import ( apiautoscalingv1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type horizontalPodAutoscalerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) + return NewHorizontalPodAutoscalerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewHorizontalPodAutoscalerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewHorizontalPodAutoscalerInformerWithOptions constructs a new informer for HorizontalPodAutoscaler type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "autoscaling", Version: "v1", Resource: "horizontalpodautoscalers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(context.Background(), options) + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(context.Background(), options) + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(ctx, options) + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(ctx, options) + return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(ctx, opts) }, }, client), &apiautoscalingv1.HorizontalPodAutoscaler{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewHorizontalPodAutoscalerInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go index ce86ea8778..3605718d08 100644 --- a/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/informers/autoscaling/v2/horizontalpodautoscaler.go @@ -25,6 +25,7 @@ import ( apiautoscalingv2 "k8s.io/api/autoscaling/v2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type horizontalPodAutoscalerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) + return NewHorizontalPodAutoscalerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewHorizontalPodAutoscalerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewHorizontalPodAutoscalerInformerWithOptions constructs a new informer for HorizontalPodAutoscaler type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewHorizontalPodAutoscalerInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "autoscaling", Version: "v2", Resource: "horizontalpodautoscalers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).List(context.Background(), options) + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Watch(context.Background(), options) + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).List(ctx, options) + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Watch(ctx, options) + return client.AutoscalingV2().HorizontalPodAutoscalers(namespace).Watch(ctx, opts) }, }, client), &apiautoscalingv2.HorizontalPodAutoscaler{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewHorizontalPodAutoscalerInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go deleted file mode 100644 index 7136842006..0000000000 --- a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/horizontalpodautoscaler.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v2beta1 - -import ( - context "context" - time "time" - - apiautoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - kubernetes "k8s.io/client-go/kubernetes" - autoscalingv2beta1 "k8s.io/client-go/listers/autoscaling/v2beta1" - cache "k8s.io/client-go/tools/cache" -) - -// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for -// HorizontalPodAutoscalers. -type HorizontalPodAutoscalerInformer interface { - Informer() cache.SharedIndexInformer - Lister() autoscalingv2beta1.HorizontalPodAutoscalerLister -} - -type horizontalPodAutoscalerInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).List(context.Background(), options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).Watch(context.Background(), options) - }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).List(ctx, options) - }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).Watch(ctx, options) - }, - }, client), - &apiautoscalingv2beta1.HorizontalPodAutoscaler{}, - resyncPeriod, - indexers, - ) -} - -func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apiautoscalingv2beta1.HorizontalPodAutoscaler{}, f.defaultInformer) -} - -func (f *horizontalPodAutoscalerInformer) Lister() autoscalingv2beta1.HorizontalPodAutoscalerLister { - return autoscalingv2beta1.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) -} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go deleted file mode 100644 index ff5d44b09d..0000000000 --- a/vendor/k8s.io/client-go/informers/autoscaling/v2beta1/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v2beta1 - -import ( - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. - HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. -func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { - return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go deleted file mode 100644 index 4ff8b10331..0000000000 --- a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/horizontalpodautoscaler.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v2beta2 - -import ( - context "context" - time "time" - - apiautoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - kubernetes "k8s.io/client-go/kubernetes" - autoscalingv2beta2 "k8s.io/client-go/listers/autoscaling/v2beta2" - cache "k8s.io/client-go/tools/cache" -) - -// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for -// HorizontalPodAutoscalers. -type HorizontalPodAutoscalerInformer interface { - Informer() cache.SharedIndexInformer - Lister() autoscalingv2beta2.HorizontalPodAutoscalerLister -} - -type horizontalPodAutoscalerInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).List(context.Background(), options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Watch(context.Background(), options) - }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).List(ctx, options) - }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Watch(ctx, options) - }, - }, client), - &apiautoscalingv2beta2.HorizontalPodAutoscaler{}, - resyncPeriod, - indexers, - ) -} - -func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apiautoscalingv2beta2.HorizontalPodAutoscaler{}, f.defaultInformer) -} - -func (f *horizontalPodAutoscalerInformer) Lister() autoscalingv2beta2.HorizontalPodAutoscalerLister { - return autoscalingv2beta2.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer()) -} diff --git a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go b/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go deleted file mode 100644 index e482c57925..0000000000 --- a/vendor/k8s.io/client-go/informers/autoscaling/v2beta2/interface.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v2beta2 - -import ( - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" -) - -// Interface provides access to all the informers in this group version. -type Interface interface { - // HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. - HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer -} - -type version struct { - factory internalinterfaces.SharedInformerFactory - namespace string - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// New returns a new Interface. -func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer. -func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer { - return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} diff --git a/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go b/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go index 9875a88b5b..022710011b 100644 --- a/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go +++ b/vendor/k8s.io/client-go/informers/batch/v1/cronjob.go @@ -25,6 +25,7 @@ import ( apibatchv1 "k8s.io/api/batch/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type cronJobInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, namespace, resyncPeriod, indexers, nil) + return NewCronJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCronJobInformer constructs a new informer for CronJob type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCronJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCronJobInformerWithOptions constructs a new informer for CronJob type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCronJobInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "cronjobs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().CronJobs(namespace).List(context.Background(), options) + return client.BatchV1().CronJobs(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().CronJobs(namespace).Watch(context.Background(), options) + return client.BatchV1().CronJobs(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().CronJobs(namespace).List(ctx, options) + return client.BatchV1().CronJobs(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().CronJobs(namespace).Watch(ctx, options) + return client.BatchV1().CronJobs(namespace).Watch(ctx, opts) }, }, client), &apibatchv1.CronJob{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCronJobInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cronJobInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/batch/v1/job.go b/vendor/k8s.io/client-go/informers/batch/v1/job.go index a68178d639..97e88927bf 100644 --- a/vendor/k8s.io/client-go/informers/batch/v1/job.go +++ b/vendor/k8s.io/client-go/informers/batch/v1/job.go @@ -25,6 +25,7 @@ import ( apibatchv1 "k8s.io/api/batch/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type jobInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredJobInformer(client, namespace, resyncPeriod, indexers, nil) + return NewJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredJobInformer constructs a new informer for Job type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewJobInformerWithOptions constructs a new informer for Job type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewJobInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().Jobs(namespace).List(context.Background(), options) + return client.BatchV1().Jobs(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().Jobs(namespace).Watch(context.Background(), options) + return client.BatchV1().Jobs(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().Jobs(namespace).List(ctx, options) + return client.BatchV1().Jobs(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1().Jobs(namespace).Watch(ctx, options) + return client.BatchV1().Jobs(namespace).Watch(ctx, opts) }, }, client), &apibatchv1.Job{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *jobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewJobInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *jobInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go b/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go index 16644920c7..5d2129323b 100644 --- a/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go +++ b/vendor/k8s.io/client-go/informers/batch/v1beta1/cronjob.go @@ -25,6 +25,7 @@ import ( apibatchv1beta1 "k8s.io/api/batch/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type cronJobInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, namespace, resyncPeriod, indexers, nil) + return NewCronJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCronJobInformer constructs a new informer for CronJob type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCronJobInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCronJobInformerWithOptions constructs a new informer for CronJob type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCronJobInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "batch", Version: "v1beta1", Resource: "cronjobs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1beta1().CronJobs(namespace).List(context.Background(), options) + return client.BatchV1beta1().CronJobs(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1beta1().CronJobs(namespace).Watch(context.Background(), options) + return client.BatchV1beta1().CronJobs(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1beta1().CronJobs(namespace).List(ctx, options) + return client.BatchV1beta1().CronJobs(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.BatchV1beta1().CronJobs(namespace).Watch(ctx, options) + return client.BatchV1beta1().CronJobs(namespace).Watch(ctx, opts) }, }, client), &apibatchv1beta1.CronJob{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCronJobInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cronJobInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go b/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go index a16eb3f3b0..0e0706893c 100644 --- a/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1/certificatesigningrequest.go @@ -25,6 +25,7 @@ import ( apicertificatesv1 "k8s.io/api/certificates/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type certificateSigningRequestInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, indexers, nil) + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCertificateSigningRequestInformerWithOptions constructs a new informer for CertificateSigningRequest type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCertificateSigningRequestInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1", Resource: "certificatesigningrequests"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1().CertificateSigningRequests().List(context.Background(), options) + return client.CertificatesV1().CertificateSigningRequests().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1().CertificateSigningRequests().Watch(context.Background(), options) + return client.CertificatesV1().CertificateSigningRequests().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1().CertificateSigningRequests().List(ctx, options) + return client.CertificatesV1().CertificateSigningRequests().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1().CertificateSigningRequests().Watch(ctx, options) + return client.CertificatesV1().CertificateSigningRequests().Watch(ctx, opts) }, }, client), &apicertificatesv1.CertificateSigningRequest{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *certificateSigningRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go index 02d8800fb3..637cfd71da 100644 --- a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go @@ -25,6 +25,7 @@ import ( apicertificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterTrustBundleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil) + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterTrustBundleInformerWithOptions constructs a new informer for ClusterTrustBundle type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterTrustBundleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1alpha1", Resource: "clustertrustbundles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1alpha1().ClusterTrustBundles().List(context.Background(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(context.Background(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, options) + return client.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(ctx, options) + return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(ctx, opts) }, }, client), &apicertificatesv1alpha1.ClusterTrustBundle{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go b/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go index 57097b7a9b..4d4408d906 100644 --- a/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1beta1/certificatesigningrequest.go @@ -25,6 +25,7 @@ import ( apicertificatesv1beta1 "k8s.io/api/certificates/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type certificateSigningRequestInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, indexers, nil) + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCertificateSigningRequestInformer constructs a new informer for CertificateSigningRequest type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCertificateSigningRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCertificateSigningRequestInformerWithOptions constructs a new informer for CertificateSigningRequest type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCertificateSigningRequestInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "certificatesigningrequests"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().CertificateSigningRequests().List(context.Background(), options) + return client.CertificatesV1beta1().CertificateSigningRequests().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().CertificateSigningRequests().Watch(context.Background(), options) + return client.CertificatesV1beta1().CertificateSigningRequests().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().CertificateSigningRequests().List(ctx, options) + return client.CertificatesV1beta1().CertificateSigningRequests().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().CertificateSigningRequests().Watch(ctx, options) + return client.CertificatesV1beta1().CertificateSigningRequests().Watch(ctx, opts) }, }, client), &apicertificatesv1beta1.CertificateSigningRequest{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *certificateSigningRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCertificateSigningRequestInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCertificateSigningRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/certificates/v1beta1/clustertrustbundle.go b/vendor/k8s.io/client-go/informers/certificates/v1beta1/clustertrustbundle.go index 93b5d631db..f665d0b739 100644 --- a/vendor/k8s.io/client-go/informers/certificates/v1beta1/clustertrustbundle.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1beta1/clustertrustbundle.go @@ -25,6 +25,7 @@ import ( apicertificatesv1beta1 "k8s.io/api/certificates/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterTrustBundleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil) + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterTrustBundleInformerWithOptions constructs a new informer for ClusterTrustBundle type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterTrustBundleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "clustertrustbundles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().ClusterTrustBundles().List(context.Background(), options) + return client.CertificatesV1beta1().ClusterTrustBundles().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().ClusterTrustBundles().Watch(context.Background(), options) + return client.CertificatesV1beta1().ClusterTrustBundles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().ClusterTrustBundles().List(ctx, options) + return client.CertificatesV1beta1().ClusterTrustBundles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().ClusterTrustBundles().Watch(ctx, options) + return client.CertificatesV1beta1().ClusterTrustBundles().Watch(ctx, opts) }, }, client), &apicertificatesv1beta1.ClusterTrustBundle{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterTrustBundleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/certificates/v1beta1/podcertificaterequest.go b/vendor/k8s.io/client-go/informers/certificates/v1beta1/podcertificaterequest.go index 2d41c76e92..03f7816cfd 100644 --- a/vendor/k8s.io/client-go/informers/certificates/v1beta1/podcertificaterequest.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1beta1/podcertificaterequest.go @@ -25,6 +25,7 @@ import ( apicertificatesv1beta1 "k8s.io/api/certificates/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type podCertificateRequestInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPodCertificateRequestInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodCertificateRequestInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPodCertificateRequestInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPodCertificateRequestInformer constructs a new informer for PodCertificateRequest type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPodCertificateRequestInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPodCertificateRequestInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodCertificateRequestInformerWithOptions constructs a new informer for PodCertificateRequest type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodCertificateRequestInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "podcertificaterequests"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().PodCertificateRequests(namespace).List(context.Background(), options) + return client.CertificatesV1beta1().PodCertificateRequests(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().PodCertificateRequests(namespace).Watch(context.Background(), options) + return client.CertificatesV1beta1().PodCertificateRequests(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().PodCertificateRequests(namespace).List(ctx, options) + return client.CertificatesV1beta1().PodCertificateRequests(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CertificatesV1beta1().PodCertificateRequests(namespace).Watch(ctx, options) + return client.CertificatesV1beta1().PodCertificateRequests(namespace).Watch(ctx, opts) }, }, client), &apicertificatesv1beta1.PodCertificateRequest{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *podCertificateRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodCertificateRequestInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPodCertificateRequestInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *podCertificateRequestInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/coordination/v1/lease.go b/vendor/k8s.io/client-go/informers/coordination/v1/lease.go index 1a34bf73f3..cce8ab4d13 100644 --- a/vendor/k8s.io/client-go/informers/coordination/v1/lease.go +++ b/vendor/k8s.io/client-go/informers/coordination/v1/lease.go @@ -25,6 +25,7 @@ import ( apicoordinationv1 "k8s.io/api/coordination/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type leaseInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil) + return NewLeaseInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredLeaseInformer constructs a new informer for Lease type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewLeaseInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewLeaseInformerWithOptions constructs a new informer for Lease type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1", Resource: "leases"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1().Leases(namespace).List(context.Background(), options) + return client.CoordinationV1().Leases(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1().Leases(namespace).Watch(context.Background(), options) + return client.CoordinationV1().Leases(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1().Leases(namespace).List(ctx, options) + return client.CoordinationV1().Leases(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1().Leases(namespace).Watch(ctx, options) + return client.CoordinationV1().Leases(namespace).Watch(ctx, opts) }, }, client), &apicoordinationv1.Lease{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *leaseInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewLeaseInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *leaseInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/coordination/v1alpha2/leasecandidate.go b/vendor/k8s.io/client-go/informers/coordination/v1alpha2/leasecandidate.go index f029be068a..5aa0ff3ae2 100644 --- a/vendor/k8s.io/client-go/informers/coordination/v1alpha2/leasecandidate.go +++ b/vendor/k8s.io/client-go/informers/coordination/v1alpha2/leasecandidate.go @@ -25,6 +25,7 @@ import ( apicoordinationv1alpha2 "k8s.io/api/coordination/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type leaseCandidateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewLeaseCandidateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLeaseCandidateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewLeaseCandidateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredLeaseCandidateInformer constructs a new informer for LeaseCandidate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredLeaseCandidateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewLeaseCandidateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewLeaseCandidateInformerWithOptions constructs a new informer for LeaseCandidate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseCandidateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1alpha2", Resource: "leasecandidates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1alpha2().LeaseCandidates(namespace).List(context.Background(), options) + return client.CoordinationV1alpha2().LeaseCandidates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1alpha2().LeaseCandidates(namespace).Watch(context.Background(), options) + return client.CoordinationV1alpha2().LeaseCandidates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1alpha2().LeaseCandidates(namespace).List(ctx, options) + return client.CoordinationV1alpha2().LeaseCandidates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1alpha2().LeaseCandidates(namespace).Watch(ctx, options) + return client.CoordinationV1alpha2().LeaseCandidates(namespace).Watch(ctx, opts) }, }, client), &apicoordinationv1alpha2.LeaseCandidate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *leaseCandidateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLeaseCandidateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewLeaseCandidateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *leaseCandidateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go b/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go index f254e30da3..66802fd949 100644 --- a/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go +++ b/vendor/k8s.io/client-go/informers/coordination/v1beta1/lease.go @@ -25,6 +25,7 @@ import ( apicoordinationv1beta1 "k8s.io/api/coordination/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type leaseInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil) + return NewLeaseInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredLeaseInformer constructs a new informer for Lease type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewLeaseInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewLeaseInformerWithOptions constructs a new informer for Lease type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1beta1", Resource: "leases"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().Leases(namespace).List(context.Background(), options) + return client.CoordinationV1beta1().Leases(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().Leases(namespace).Watch(context.Background(), options) + return client.CoordinationV1beta1().Leases(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().Leases(namespace).List(ctx, options) + return client.CoordinationV1beta1().Leases(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().Leases(namespace).Watch(ctx, options) + return client.CoordinationV1beta1().Leases(namespace).Watch(ctx, opts) }, }, client), &apicoordinationv1beta1.Lease{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *leaseInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewLeaseInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *leaseInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/coordination/v1beta1/leasecandidate.go b/vendor/k8s.io/client-go/informers/coordination/v1beta1/leasecandidate.go index bdb3e1be13..ee83397f4c 100644 --- a/vendor/k8s.io/client-go/informers/coordination/v1beta1/leasecandidate.go +++ b/vendor/k8s.io/client-go/informers/coordination/v1beta1/leasecandidate.go @@ -25,6 +25,7 @@ import ( apicoordinationv1beta1 "k8s.io/api/coordination/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type leaseCandidateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewLeaseCandidateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLeaseCandidateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewLeaseCandidateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredLeaseCandidateInformer constructs a new informer for LeaseCandidate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredLeaseCandidateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewLeaseCandidateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewLeaseCandidateInformerWithOptions constructs a new informer for LeaseCandidate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLeaseCandidateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1beta1", Resource: "leasecandidates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().LeaseCandidates(namespace).List(context.Background(), options) + return client.CoordinationV1beta1().LeaseCandidates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().LeaseCandidates(namespace).Watch(context.Background(), options) + return client.CoordinationV1beta1().LeaseCandidates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().LeaseCandidates(namespace).List(ctx, options) + return client.CoordinationV1beta1().LeaseCandidates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoordinationV1beta1().LeaseCandidates(namespace).Watch(ctx, options) + return client.CoordinationV1beta1().LeaseCandidates(namespace).Watch(ctx, opts) }, }, client), &apicoordinationv1beta1.LeaseCandidate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *leaseCandidateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLeaseCandidateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewLeaseCandidateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *leaseCandidateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go b/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go index 9cf1a062aa..5b6f6556c3 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go +++ b/vendor/k8s.io/client-go/informers/core/v1/componentstatus.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type componentStatusInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredComponentStatusInformer(client, resyncPeriod, indexers, nil) + return NewComponentStatusInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredComponentStatusInformer constructs a new informer for ComponentStatus type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewComponentStatusInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewComponentStatusInformerWithOptions constructs a new informer for ComponentStatus type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewComponentStatusInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "componentstatuss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ComponentStatuses().List(context.Background(), options) + return client.CoreV1().ComponentStatuses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ComponentStatuses().Watch(context.Background(), options) + return client.CoreV1().ComponentStatuses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ComponentStatuses().List(ctx, options) + return client.CoreV1().ComponentStatuses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ComponentStatuses().Watch(ctx, options) + return client.CoreV1().ComponentStatuses().Watch(ctx, opts) }, }, client), &apicorev1.ComponentStatus{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *componentStatusInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredComponentStatusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewComponentStatusInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *componentStatusInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/configmap.go b/vendor/k8s.io/client-go/informers/core/v1/configmap.go index 5772678bfa..5b6389884b 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/configmap.go +++ b/vendor/k8s.io/client-go/informers/core/v1/configmap.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type configMapInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewConfigMapInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredConfigMapInformer(client, namespace, resyncPeriod, indexers, nil) + return NewConfigMapInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredConfigMapInformer constructs a new informer for ConfigMap type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredConfigMapInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewConfigMapInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewConfigMapInformerWithOptions constructs a new informer for ConfigMap type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConfigMapInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ConfigMaps(namespace).List(context.Background(), options) + return client.CoreV1().ConfigMaps(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ConfigMaps(namespace).Watch(context.Background(), options) + return client.CoreV1().ConfigMaps(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ConfigMaps(namespace).List(ctx, options) + return client.CoreV1().ConfigMaps(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ConfigMaps(namespace).Watch(ctx, options) + return client.CoreV1().ConfigMaps(namespace).Watch(ctx, opts) }, }, client), &apicorev1.ConfigMap{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *configMapInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredConfigMapInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewConfigMapInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *configMapInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/endpoints.go b/vendor/k8s.io/client-go/informers/core/v1/endpoints.go index 6c55df9887..1609ce7f7e 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/endpoints.go +++ b/vendor/k8s.io/client-go/informers/core/v1/endpoints.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type endpointsInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEndpointsInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEndpointsInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEndpointsInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEndpointsInformer constructs a new informer for Endpoints type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEndpointsInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEndpointsInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEndpointsInformerWithOptions constructs a new informer for Endpoints type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointsInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "endpointss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Endpoints(namespace).List(context.Background(), options) + return client.CoreV1().Endpoints(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Endpoints(namespace).Watch(context.Background(), options) + return client.CoreV1().Endpoints(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Endpoints(namespace).List(ctx, options) + return client.CoreV1().Endpoints(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Endpoints(namespace).Watch(ctx, options) + return client.CoreV1().Endpoints(namespace).Watch(ctx, opts) }, }, client), &apicorev1.Endpoints{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *endpointsInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEndpointsInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEndpointsInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *endpointsInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/event.go b/vendor/k8s.io/client-go/informers/core/v1/event.go index 63df621b66..ff9c3c5847 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/event.go +++ b/vendor/k8s.io/client-go/informers/core/v1/event.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type eventInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEventInformer constructs a new informer for Event type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEventInformerWithOptions constructs a new informer for Event type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "events"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Events(namespace).List(context.Background(), options) + return client.CoreV1().Events(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Events(namespace).Watch(context.Background(), options) + return client.CoreV1().Events(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Events(namespace).List(ctx, options) + return client.CoreV1().Events(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Events(namespace).Watch(ctx, options) + return client.CoreV1().Events(namespace).Watch(ctx, opts) }, }, client), &apicorev1.Event{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEventInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *eventInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/limitrange.go b/vendor/k8s.io/client-go/informers/core/v1/limitrange.go index 229adb2b8f..a3a01de6dc 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/limitrange.go +++ b/vendor/k8s.io/client-go/informers/core/v1/limitrange.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type limitRangeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewLimitRangeInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredLimitRangeInformer(client, namespace, resyncPeriod, indexers, nil) + return NewLimitRangeInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredLimitRangeInformer constructs a new informer for LimitRange type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredLimitRangeInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewLimitRangeInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewLimitRangeInformerWithOptions constructs a new informer for LimitRange type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewLimitRangeInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "limitranges"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().LimitRanges(namespace).List(context.Background(), options) + return client.CoreV1().LimitRanges(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().LimitRanges(namespace).Watch(context.Background(), options) + return client.CoreV1().LimitRanges(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().LimitRanges(namespace).List(ctx, options) + return client.CoreV1().LimitRanges(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().LimitRanges(namespace).Watch(ctx, options) + return client.CoreV1().LimitRanges(namespace).Watch(ctx, opts) }, }, client), &apicorev1.LimitRange{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *limitRangeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredLimitRangeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewLimitRangeInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *limitRangeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/namespace.go b/vendor/k8s.io/client-go/informers/core/v1/namespace.go index d45d2eee62..c2a9894417 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/namespace.go +++ b/vendor/k8s.io/client-go/informers/core/v1/namespace.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type namespaceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNamespaceInformer(client, resyncPeriod, indexers, nil) + return NewNamespaceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNamespaceInformer constructs a new informer for Namespace type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNamespaceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNamespaceInformerWithOptions constructs a new informer for Namespace type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNamespaceInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Namespaces().List(context.Background(), options) + return client.CoreV1().Namespaces().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Namespaces().Watch(context.Background(), options) + return client.CoreV1().Namespaces().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Namespaces().List(ctx, options) + return client.CoreV1().Namespaces().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Namespaces().Watch(ctx, options) + return client.CoreV1().Namespaces().Watch(ctx, opts) }, }, client), &apicorev1.Namespace{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *namespaceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNamespaceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNamespaceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *namespaceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/node.go b/vendor/k8s.io/client-go/informers/core/v1/node.go index a5224761f9..48e8d7d6aa 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/node.go +++ b/vendor/k8s.io/client-go/informers/core/v1/node.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type nodeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, indexers, nil) + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNodeInformer constructs a new informer for Node type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNodeInformerWithOptions constructs a new informer for Node type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNodeInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Nodes().List(context.Background(), options) + return client.CoreV1().Nodes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Nodes().Watch(context.Background(), options) + return client.CoreV1().Nodes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Nodes().List(ctx, options) + return client.CoreV1().Nodes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Nodes().Watch(ctx, options) + return client.CoreV1().Nodes().Watch(ctx, opts) }, }, client), &apicorev1.Node{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *nodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *nodeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go b/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go index 0458fc1956..aebe7ffa81 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go +++ b/vendor/k8s.io/client-go/informers/core/v1/persistentvolume.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type persistentVolumeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeInformer(client, resyncPeriod, indexers, nil) + return NewPersistentVolumeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPersistentVolumeInformer constructs a new informer for PersistentVolume type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPersistentVolumeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPersistentVolumeInformerWithOptions constructs a new informer for PersistentVolume type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPersistentVolumeInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumes().List(context.Background(), options) + return client.CoreV1().PersistentVolumes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumes().Watch(context.Background(), options) + return client.CoreV1().PersistentVolumes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumes().List(ctx, options) + return client.CoreV1().PersistentVolumes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumes().Watch(ctx, options) + return client.CoreV1().PersistentVolumes().Watch(ctx, opts) }, }, client), &apicorev1.PersistentVolume{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *persistentVolumeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPersistentVolumeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *persistentVolumeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go b/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go index dd75924def..973b5571ed 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go +++ b/vendor/k8s.io/client-go/informers/core/v1/persistentvolumeclaim.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type persistentVolumeClaimInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPersistentVolumeClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeClaimInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPersistentVolumeClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPersistentVolumeClaimInformer constructs a new informer for PersistentVolumeClaim type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPersistentVolumeClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPersistentVolumeClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPersistentVolumeClaimInformerWithOptions constructs a new informer for PersistentVolumeClaim type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPersistentVolumeClaimInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumeclaims"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumeClaims(namespace).List(context.Background(), options) + return client.CoreV1().PersistentVolumeClaims(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumeClaims(namespace).Watch(context.Background(), options) + return client.CoreV1().PersistentVolumeClaims(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumeClaims(namespace).List(ctx, options) + return client.CoreV1().PersistentVolumeClaims(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PersistentVolumeClaims(namespace).Watch(ctx, options) + return client.CoreV1().PersistentVolumeClaims(namespace).Watch(ctx, opts) }, }, client), &apicorev1.PersistentVolumeClaim{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *persistentVolumeClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPersistentVolumeClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPersistentVolumeClaimInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *persistentVolumeClaimInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/pod.go b/vendor/k8s.io/client-go/informers/core/v1/pod.go index b68ebc1dd5..f49dee3dee 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/pod.go +++ b/vendor/k8s.io/client-go/informers/core/v1/pod.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type podInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPodInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPodInformer constructs a new informer for Pod type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPodInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodInformerWithOptions constructs a new informer for Pod type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Pods(namespace).List(context.Background(), options) + return client.CoreV1().Pods(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Pods(namespace).Watch(context.Background(), options) + return client.CoreV1().Pods(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Pods(namespace).List(ctx, options) + return client.CoreV1().Pods(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Pods(namespace).Watch(ctx, options) + return client.CoreV1().Pods(namespace).Watch(ctx, opts) }, }, client), &apicorev1.Pod{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *podInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPodInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *podInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go b/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go index c4b4cd12be..940ae25999 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go +++ b/vendor/k8s.io/client-go/informers/core/v1/podtemplate.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type podTemplateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPodTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodTemplateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPodTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPodTemplateInformer constructs a new informer for PodTemplate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPodTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPodTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodTemplateInformerWithOptions constructs a new informer for PodTemplate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodTemplateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "podtemplates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PodTemplates(namespace).List(context.Background(), options) + return client.CoreV1().PodTemplates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PodTemplates(namespace).Watch(context.Background(), options) + return client.CoreV1().PodTemplates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PodTemplates(namespace).List(ctx, options) + return client.CoreV1().PodTemplates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().PodTemplates(namespace).Watch(ctx, options) + return client.CoreV1().PodTemplates(namespace).Watch(ctx, opts) }, }, client), &apicorev1.PodTemplate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *podTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPodTemplateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *podTemplateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go b/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go index 58b66c2bd5..ec323d3c63 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go +++ b/vendor/k8s.io/client-go/informers/core/v1/replicationcontroller.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type replicationControllerInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewReplicationControllerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicationControllerInformer(client, namespace, resyncPeriod, indexers, nil) + return NewReplicationControllerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredReplicationControllerInformer constructs a new informer for ReplicationController type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredReplicationControllerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewReplicationControllerInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewReplicationControllerInformerWithOptions constructs a new informer for ReplicationController type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicationControllerInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "replicationcontrollers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ReplicationControllers(namespace).List(context.Background(), options) + return client.CoreV1().ReplicationControllers(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ReplicationControllers(namespace).Watch(context.Background(), options) + return client.CoreV1().ReplicationControllers(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ReplicationControllers(namespace).List(ctx, options) + return client.CoreV1().ReplicationControllers(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ReplicationControllers(namespace).Watch(ctx, options) + return client.CoreV1().ReplicationControllers(namespace).Watch(ctx, opts) }, }, client), &apicorev1.ReplicationController{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *replicationControllerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicationControllerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewReplicationControllerInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *replicationControllerInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go b/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go index 408c024581..490a31212b 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go +++ b/vendor/k8s.io/client-go/informers/core/v1/resourcequota.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceQuotaInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceQuotaInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceQuotaInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceQuotaInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceQuotaInformer constructs a new informer for ResourceQuota type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceQuotaInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceQuotaInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceQuotaInformerWithOptions constructs a new informer for ResourceQuota type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceQuotaInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "resourcequotas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ResourceQuotas(namespace).List(context.Background(), options) + return client.CoreV1().ResourceQuotas(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ResourceQuotas(namespace).Watch(context.Background(), options) + return client.CoreV1().ResourceQuotas(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ResourceQuotas(namespace).List(ctx, options) + return client.CoreV1().ResourceQuotas(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ResourceQuotas(namespace).Watch(ctx, options) + return client.CoreV1().ResourceQuotas(namespace).Watch(ctx, opts) }, }, client), &apicorev1.ResourceQuota{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceQuotaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceQuotaInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceQuotaInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceQuotaInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/secret.go b/vendor/k8s.io/client-go/informers/core/v1/secret.go index 7f7338d063..86458285d9 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/secret.go +++ b/vendor/k8s.io/client-go/informers/core/v1/secret.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type secretInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewSecretInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredSecretInformer(client, namespace, resyncPeriod, indexers, nil) + return NewSecretInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredSecretInformer constructs a new informer for Secret type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredSecretInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewSecretInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewSecretInformerWithOptions constructs a new informer for Secret type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewSecretInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Secrets(namespace).List(context.Background(), options) + return client.CoreV1().Secrets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Secrets(namespace).Watch(context.Background(), options) + return client.CoreV1().Secrets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Secrets(namespace).List(ctx, options) + return client.CoreV1().Secrets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Secrets(namespace).Watch(ctx, options) + return client.CoreV1().Secrets(namespace).Watch(ctx, opts) }, }, client), &apicorev1.Secret{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *secretInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredSecretInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewSecretInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *secretInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/service.go b/vendor/k8s.io/client-go/informers/core/v1/service.go index b4dcb75d79..4ec10b3227 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/service.go +++ b/vendor/k8s.io/client-go/informers/core/v1/service.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type serviceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceInformer(client, namespace, resyncPeriod, indexers, nil) + return NewServiceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceInformer constructs a new informer for Service type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceInformerWithOptions constructs a new informer for Service type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Services(namespace).List(context.Background(), options) + return client.CoreV1().Services(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Services(namespace).Watch(context.Background(), options) + return client.CoreV1().Services(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Services(namespace).List(ctx, options) + return client.CoreV1().Services(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().Services(namespace).Watch(ctx, options) + return client.CoreV1().Services(namespace).Watch(ctx, opts) }, }, client), &apicorev1.Service{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go b/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go index 5ddc98b24e..32751b6a38 100644 --- a/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go +++ b/vendor/k8s.io/client-go/informers/core/v1/serviceaccount.go @@ -25,6 +25,7 @@ import ( apicorev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type serviceAccountInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceAccountInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceAccountInformer(client, namespace, resyncPeriod, indexers, nil) + return NewServiceAccountInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceAccountInformer constructs a new informer for ServiceAccount type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceAccountInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceAccountInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceAccountInformerWithOptions constructs a new informer for ServiceAccount type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceAccountInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ServiceAccounts(namespace).List(context.Background(), options) + return client.CoreV1().ServiceAccounts(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ServiceAccounts(namespace).Watch(context.Background(), options) + return client.CoreV1().ServiceAccounts(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ServiceAccounts(namespace).List(ctx, options) + return client.CoreV1().ServiceAccounts(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.CoreV1().ServiceAccounts(namespace).Watch(ctx, options) + return client.CoreV1().ServiceAccounts(namespace).Watch(ctx, opts) }, }, client), &apicorev1.ServiceAccount{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceAccountInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceAccountInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceAccountInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceAccountInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go b/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go index 1291912816..999d514598 100644 --- a/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go +++ b/vendor/k8s.io/client-go/informers/discovery/v1/endpointslice.go @@ -25,6 +25,7 @@ import ( apidiscoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type endpointSliceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEndpointSliceInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEndpointSliceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEndpointSliceInformer constructs a new informer for EndpointSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEndpointSliceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEndpointSliceInformerWithOptions constructs a new informer for EndpointSlice type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointSliceInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1", Resource: "endpointslices"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1().EndpointSlices(namespace).List(context.Background(), options) + return client.DiscoveryV1().EndpointSlices(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1().EndpointSlices(namespace).Watch(context.Background(), options) + return client.DiscoveryV1().EndpointSlices(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1().EndpointSlices(namespace).List(ctx, options) + return client.DiscoveryV1().EndpointSlices(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1().EndpointSlices(namespace).Watch(ctx, options) + return client.DiscoveryV1().EndpointSlices(namespace).Watch(ctx, opts) }, }, client), &apidiscoveryv1.EndpointSlice{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *endpointSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEndpointSliceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEndpointSliceInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *endpointSliceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go b/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go index 80147e2438..918e30485f 100644 --- a/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go +++ b/vendor/k8s.io/client-go/informers/discovery/v1beta1/endpointslice.go @@ -25,6 +25,7 @@ import ( apidiscoveryv1beta1 "k8s.io/api/discovery/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type endpointSliceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEndpointSliceInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEndpointSliceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEndpointSliceInformer constructs a new informer for EndpointSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEndpointSliceInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEndpointSliceInformerWithOptions constructs a new informer for EndpointSlice type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointSliceInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1beta1", Resource: "endpointslices"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1beta1().EndpointSlices(namespace).List(context.Background(), options) + return client.DiscoveryV1beta1().EndpointSlices(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(context.Background(), options) + return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1beta1().EndpointSlices(namespace).List(ctx, options) + return client.DiscoveryV1beta1().EndpointSlices(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(ctx, options) + return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(ctx, opts) }, }, client), &apidiscoveryv1beta1.EndpointSlice{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *endpointSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEndpointSliceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEndpointSliceInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *endpointSliceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/events/v1/event.go b/vendor/k8s.io/client-go/informers/events/v1/event.go index 68eafe312c..23aaa68479 100644 --- a/vendor/k8s.io/client-go/informers/events/v1/event.go +++ b/vendor/k8s.io/client-go/informers/events/v1/event.go @@ -25,6 +25,7 @@ import ( apieventsv1 "k8s.io/api/events/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type eventInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEventInformer constructs a new informer for Event type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEventInformerWithOptions constructs a new informer for Event type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "events.k8s.io", Version: "v1", Resource: "events"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1().Events(namespace).List(context.Background(), options) + return client.EventsV1().Events(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1().Events(namespace).Watch(context.Background(), options) + return client.EventsV1().Events(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1().Events(namespace).List(ctx, options) + return client.EventsV1().Events(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1().Events(namespace).Watch(ctx, options) + return client.EventsV1().Events(namespace).Watch(ctx, opts) }, }, client), &apieventsv1.Event{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEventInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *eventInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/events/v1beta1/event.go b/vendor/k8s.io/client-go/informers/events/v1beta1/event.go index b26c208938..ea0117eaca 100644 --- a/vendor/k8s.io/client-go/informers/events/v1beta1/event.go +++ b/vendor/k8s.io/client-go/informers/events/v1beta1/event.go @@ -25,6 +25,7 @@ import ( apieventsv1beta1 "k8s.io/api/events/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type eventInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, namespace, resyncPeriod, indexers, nil) + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredEventInformer constructs a new informer for Event type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewEventInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewEventInformerWithOptions constructs a new informer for Event type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "events.k8s.io", Version: "v1beta1", Resource: "events"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1beta1().Events(namespace).List(context.Background(), options) + return client.EventsV1beta1().Events(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1beta1().Events(namespace).Watch(context.Background(), options) + return client.EventsV1beta1().Events(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1beta1().Events(namespace).List(ctx, options) + return client.EventsV1beta1().Events(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.EventsV1beta1().Events(namespace).Watch(ctx, options) + return client.EventsV1beta1().Events(namespace).Watch(ctx, opts) }, }, client), &apieventsv1beta1.Event{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredEventInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewEventInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *eventInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go index fdfbb02306..ed8b023038 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/daemonset.go @@ -25,6 +25,7 @@ import ( apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type daemonSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDaemonSetInformer constructs a new informer for DaemonSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDaemonSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDaemonSetInformerWithOptions constructs a new informer for DaemonSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDaemonSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "daemonsets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().DaemonSets(namespace).List(context.Background(), options) + return client.ExtensionsV1beta1().DaemonSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().DaemonSets(namespace).Watch(context.Background(), options) + return client.ExtensionsV1beta1().DaemonSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().DaemonSets(namespace).List(ctx, options) + return client.ExtensionsV1beta1().DaemonSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().DaemonSets(namespace).Watch(ctx, options) + return client.ExtensionsV1beta1().DaemonSets(namespace).Watch(ctx, opts) }, }, client), &apiextensionsv1beta1.DaemonSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDaemonSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDaemonSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *daemonSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go index 6442266250..ee328bb517 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/deployment.go @@ -25,6 +25,7 @@ import ( apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type deploymentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeploymentInformer constructs a new informer for Deployment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeploymentInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeploymentInformerWithOptions constructs a new informer for Deployment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeploymentInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "deployments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Deployments(namespace).List(context.Background(), options) + return client.ExtensionsV1beta1().Deployments(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Deployments(namespace).Watch(context.Background(), options) + return client.ExtensionsV1beta1().Deployments(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Deployments(namespace).List(ctx, options) + return client.ExtensionsV1beta1().Deployments(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Deployments(namespace).Watch(ctx, options) + return client.ExtensionsV1beta1().Deployments(namespace).Watch(ctx, opts) }, }, client), &apiextensionsv1beta1.Deployment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeploymentInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deploymentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go index bbd7286843..852238a481 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/ingress.go @@ -25,6 +25,7 @@ import ( apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type ingressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressInformer constructs a new informer for Ingress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressInformerWithOptions constructs a new informer for Ingress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "ingresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Ingresses(namespace).List(context.Background(), options) + return client.ExtensionsV1beta1().Ingresses(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Ingresses(namespace).Watch(context.Background(), options) + return client.ExtensionsV1beta1().Ingresses(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Ingresses(namespace).List(ctx, options) + return client.ExtensionsV1beta1().Ingresses(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().Ingresses(namespace).Watch(ctx, options) + return client.ExtensionsV1beta1().Ingresses(namespace).Watch(ctx, opts) }, }, client), &apiextensionsv1beta1.Ingress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go index 45eb5e95bb..fda46c1d96 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/networkpolicy.go @@ -25,6 +25,7 @@ import ( apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type networkPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, namespace, resyncPeriod, indexers, nil) + return NewNetworkPolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNetworkPolicyInformer constructs a new informer for NetworkPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNetworkPolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNetworkPolicyInformerWithOptions constructs a new informer for NetworkPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkPolicyInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "networkpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().NetworkPolicies(namespace).List(context.Background(), options) + return client.ExtensionsV1beta1().NetworkPolicies(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().NetworkPolicies(namespace).Watch(context.Background(), options) + return client.ExtensionsV1beta1().NetworkPolicies(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().NetworkPolicies(namespace).List(ctx, options) + return client.ExtensionsV1beta1().NetworkPolicies(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().NetworkPolicies(namespace).Watch(ctx, options) + return client.ExtensionsV1beta1().NetworkPolicies(namespace).Watch(ctx, opts) }, }, client), &apiextensionsv1beta1.NetworkPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *networkPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNetworkPolicyInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *networkPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go index 82a183b3c7..eb0685147f 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/replicaset.go @@ -25,6 +25,7 @@ import ( apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type replicaSetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredReplicaSetInformer constructs a new informer for ReplicaSet type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewReplicaSetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewReplicaSetInformerWithOptions constructs a new informer for ReplicaSet type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewReplicaSetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicasets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().ReplicaSets(namespace).List(context.Background(), options) + return client.ExtensionsV1beta1().ReplicaSets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().ReplicaSets(namespace).Watch(context.Background(), options) + return client.ExtensionsV1beta1().ReplicaSets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().ReplicaSets(namespace).List(ctx, options) + return client.ExtensionsV1beta1().ReplicaSets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ExtensionsV1beta1().ReplicaSets(namespace).Watch(ctx, options) + return client.ExtensionsV1beta1().ReplicaSets(namespace).Watch(ctx, opts) }, }, client), &apiextensionsv1beta1.ReplicaSet{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredReplicaSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewReplicaSetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *replicaSetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/factory.go b/vendor/k8s.io/client-go/informers/factory.go index bd3d16c010..19901079f8 100644 --- a/vendor/k8s.io/client-go/informers/factory.go +++ b/vendor/k8s.io/client-go/informers/factory.go @@ -19,6 +19,7 @@ limitations under the License. package informers import ( + context "context" reflect "reflect" sync "sync" time "time" @@ -26,6 +27,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" + wait "k8s.io/apimachinery/pkg/util/wait" admissionregistration "k8s.io/client-go/informers/admissionregistration" apiserverinternal "k8s.io/client-go/informers/apiserverinternal" apps "k8s.io/client-go/informers/apps" @@ -62,6 +64,7 @@ type sharedInformerFactory struct { defaultResync time.Duration customResync map[reflect.Type]time.Duration transform cache.TransformFunc + informerName *cache.InformerName informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -108,6 +111,21 @@ func WithTransform(transform cache.TransformFunc) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *cache.InformerName) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *cache.InformerName { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client kubernetes.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -142,6 +160,10 @@ func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultRes } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext(wait.ContextForChannel(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx context.Context) { f.lock.Lock() defer f.lock.Unlock() @@ -151,15 +173,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -172,9 +188,15 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() @@ -188,10 +210,31 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return informers }() - res := map[reflect.Type]bool{} + // Wait for informers to sync, without polling. + cacheSyncs := make([]cache.DoneChecker, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + cache.WaitFor(ctx, "" /* no logging */, cacheSyncs...) + + res := cache.SyncResult{ + Synced: make(map[reflect.Type]bool, len(informers)), + } + failed := false for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = context.Cause(ctx) + } + return res } @@ -213,7 +256,9 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -230,27 +275,46 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // defer factory.WaitForStop() // Returns immediately if nothing was started. // genericInformer := factory.ForResource(resource) // typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) // } // // // Creating informers can also be created after Start, but then // // Start must be called again: // anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -265,8 +329,14 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx context.Context) cache.SyncResult + // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1/flowschema.go index 734ee0ebf4..624c2f5d6d 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1/flowschema.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1/flowschema.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1 "k8s.io/api/flowcontrol/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type flowSchemaInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewFlowSchemaInformerWithOptions constructs a new informer for FlowSchema type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1", Resource: "flowschemas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().FlowSchemas().List(context.Background(), options) + return client.FlowcontrolV1().FlowSchemas().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().FlowSchemas().Watch(context.Background(), options) + return client.FlowcontrolV1().FlowSchemas().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().FlowSchemas().List(ctx, options) + return client.FlowcontrolV1().FlowSchemas().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().FlowSchemas().Watch(ctx, options) + return client.FlowcontrolV1().FlowSchemas().Watch(ctx, opts) }, }, client), &apiflowcontrolv1.FlowSchema{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1/prioritylevelconfiguration.go index a5f23218ef..5a42509553 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1/prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1/prioritylevelconfiguration.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1 "k8s.io/api/flowcontrol/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityLevelConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityLevelConfigurationInformerWithOptions constructs a new informer for PriorityLevelConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1", Resource: "prioritylevelconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().PriorityLevelConfigurations().List(context.Background(), options) + return client.FlowcontrolV1().PriorityLevelConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().PriorityLevelConfigurations().Watch(context.Background(), options) + return client.FlowcontrolV1().PriorityLevelConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().PriorityLevelConfigurations().List(ctx, options) + return client.FlowcontrolV1().PriorityLevelConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1().PriorityLevelConfigurations().Watch(ctx, options) + return client.FlowcontrolV1().PriorityLevelConfigurations().Watch(ctx, opts) }, }, client), &apiflowcontrolv1.PriorityLevelConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go index 5e88fe8cb9..2e0098e664 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/flowschema.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type flowSchemaInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewFlowSchemaInformerWithOptions constructs a new informer for FlowSchema type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Resource: "flowschemas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().FlowSchemas().List(context.Background(), options) + return client.FlowcontrolV1beta1().FlowSchemas().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().FlowSchemas().Watch(context.Background(), options) + return client.FlowcontrolV1beta1().FlowSchemas().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().FlowSchemas().List(ctx, options) + return client.FlowcontrolV1beta1().FlowSchemas().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().FlowSchemas().Watch(ctx, options) + return client.FlowcontrolV1beta1().FlowSchemas().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta1.FlowSchema{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go index f86a96e38c..9c94839a1a 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta1/prioritylevelconfiguration.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta1 "k8s.io/api/flowcontrol/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityLevelConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityLevelConfigurationInformerWithOptions constructs a new informer for PriorityLevelConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Resource: "prioritylevelconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().PriorityLevelConfigurations().List(context.Background(), options) + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().PriorityLevelConfigurations().Watch(context.Background(), options) + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().PriorityLevelConfigurations().List(ctx, options) + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta1().PriorityLevelConfigurations().Watch(ctx, options) + return client.FlowcontrolV1beta1().PriorityLevelConfigurations().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta1.PriorityLevelConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go index e17e4c9fa2..aba4d712af 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/flowschema.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type flowSchemaInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewFlowSchemaInformerWithOptions constructs a new informer for FlowSchema type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Resource: "flowschemas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().FlowSchemas().List(context.Background(), options) + return client.FlowcontrolV1beta2().FlowSchemas().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().FlowSchemas().Watch(context.Background(), options) + return client.FlowcontrolV1beta2().FlowSchemas().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().FlowSchemas().List(ctx, options) + return client.FlowcontrolV1beta2().FlowSchemas().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().FlowSchemas().Watch(ctx, options) + return client.FlowcontrolV1beta2().FlowSchemas().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta2.FlowSchema{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go index 1db6efa6fe..0ce811759a 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta2/prioritylevelconfiguration.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityLevelConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityLevelConfigurationInformerWithOptions constructs a new informer for PriorityLevelConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Resource: "prioritylevelconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().PriorityLevelConfigurations().List(context.Background(), options) + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().PriorityLevelConfigurations().Watch(context.Background(), options) + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().PriorityLevelConfigurations().List(ctx, options) + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta2().PriorityLevelConfigurations().Watch(ctx, options) + return client.FlowcontrolV1beta2().PriorityLevelConfigurations().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta2.PriorityLevelConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go index 626a20d620..16ce2ba23c 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/flowschema.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type flowSchemaInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewFlowSchemaInformerWithOptions constructs a new informer for FlowSchema type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFlowSchemaInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Resource: "flowschemas"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().FlowSchemas().List(context.Background(), options) + return client.FlowcontrolV1beta3().FlowSchemas().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().FlowSchemas().Watch(context.Background(), options) + return client.FlowcontrolV1beta3().FlowSchemas().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().FlowSchemas().List(ctx, options) + return client.FlowcontrolV1beta3().FlowSchemas().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().FlowSchemas().Watch(ctx, options) + return client.FlowcontrolV1beta3().FlowSchemas().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta3.FlowSchema{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFlowSchemaInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go index 43f6974234..ab63c8e62b 100644 --- a/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/informers/flowcontrol/v1beta3/prioritylevelconfiguration.go @@ -25,6 +25,7 @@ import ( apiflowcontrolv1beta3 "k8s.io/api/flowcontrol/v1beta3" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityLevelConfigurationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityLevelConfigurationInformerWithOptions constructs a new informer for PriorityLevelConfiguration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityLevelConfigurationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Resource: "prioritylevelconfigurations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().PriorityLevelConfigurations().List(context.Background(), options) + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().PriorityLevelConfigurations().Watch(context.Background(), options) + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().PriorityLevelConfigurations().List(ctx, options) + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.FlowcontrolV1beta3().PriorityLevelConfigurations().Watch(ctx, options) + return client.FlowcontrolV1beta3().PriorityLevelConfigurations().Watch(ctx, opts) }, }, client), &apiflowcontrolv1beta3.PriorityLevelConfiguration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityLevelConfigurationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/generic.go b/vendor/k8s.io/client-go/informers/generic.go index 2b7efe7f4a..03c45c71cf 100644 --- a/vendor/k8s.io/client-go/informers/generic.go +++ b/vendor/k8s.io/client-go/informers/generic.go @@ -30,8 +30,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" autoscalingv1 "k8s.io/api/autoscaling/v1" v2 "k8s.io/api/autoscaling/v2" - v2beta1 "k8s.io/api/autoscaling/v2beta1" - v2beta2 "k8s.io/api/autoscaling/v2beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" @@ -65,7 +63,7 @@ import ( resourcev1beta1 "k8s.io/api/resource/v1beta1" resourcev1beta2 "k8s.io/api/resource/v1beta2" schedulingv1 "k8s.io/api/scheduling/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" storagev1 "k8s.io/api/storage/v1" storagev1alpha1 "k8s.io/api/storage/v1alpha1" @@ -102,6 +100,10 @@ func (f *genericInformer) Lister() cache.GenericLister { func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { // Group=admissionregistration.k8s.io, Version=v1 + case v1.SchemeGroupVersion.WithResource("mutatingadmissionpolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1().MutatingAdmissionPolicies().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("mutatingadmissionpolicybindings"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1().MutatingAdmissionPolicyBindings().Informer()}, nil case v1.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations"): return &genericInformer{resource: resource.GroupResource(), informer: f.Admissionregistration().V1().MutatingWebhookConfigurations().Informer()}, nil case v1.SchemeGroupVersion.WithResource("validatingadmissionpolicies"): @@ -175,14 +177,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2().HorizontalPodAutoscalers().Informer()}, nil - // Group=autoscaling, Version=v2beta1 - case v2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2beta1().HorizontalPodAutoscalers().Informer()}, nil - - // Group=autoscaling, Version=v2beta2 - case v2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V2beta2().HorizontalPodAutoscalers().Informer()}, nil - // Group=batch, Version=v1 case batchv1.SchemeGroupVersion.WithResource("cronjobs"): return &genericInformer{resource: resource.GroupResource(), informer: f.Batch().V1().CronJobs().Informer()}, nil @@ -398,6 +392,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=resource.k8s.io, Version=v1alpha3 case v1alpha3.SchemeGroupVersion.WithResource("devicetaintrules"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha3().DeviceTaintRules().Informer()}, nil + case v1alpha3.SchemeGroupVersion.WithResource("resourcepoolstatusrequests"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha3().ResourcePoolStatusRequests().Informer()}, nil // Group=resource.k8s.io, Version=v1beta1 case resourcev1beta1.SchemeGroupVersion.WithResource("deviceclasses"): @@ -412,6 +408,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=resource.k8s.io, Version=v1beta2 case resourcev1beta2.SchemeGroupVersion.WithResource("deviceclasses"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1beta2().DeviceClasses().Informer()}, nil + case resourcev1beta2.SchemeGroupVersion.WithResource("devicetaintrules"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1beta2().DeviceTaintRules().Informer()}, nil case resourcev1beta2.SchemeGroupVersion.WithResource("resourceclaims"): return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1beta2().ResourceClaims().Informer()}, nil case resourcev1beta2.SchemeGroupVersion.WithResource("resourceclaimtemplates"): @@ -423,11 +421,11 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1().PriorityClasses().Informer()}, nil - // Group=scheduling.k8s.io, Version=v1alpha1 - case schedulingv1alpha1.SchemeGroupVersion.WithResource("priorityclasses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1alpha1().PriorityClasses().Informer()}, nil - case schedulingv1alpha1.SchemeGroupVersion.WithResource("workloads"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1alpha1().Workloads().Informer()}, nil + // Group=scheduling.k8s.io, Version=v1alpha2 + case schedulingv1alpha2.SchemeGroupVersion.WithResource("podgroups"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1alpha2().PodGroups().Informer()}, nil + case schedulingv1alpha2.SchemeGroupVersion.WithResource("workloads"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduling().V1alpha2().Workloads().Informer()}, nil // Group=scheduling.k8s.io, Version=v1beta1 case schedulingv1beta1.SchemeGroupVersion.WithResource("priorityclasses"): diff --git a/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go b/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go index b00ed70cfd..8740840d73 100644 --- a/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go +++ b/vendor/k8s.io/client-go/informers/internalinterfaces/factory_interfaces.go @@ -34,7 +34,26 @@ type NewInformerFunc func(kubernetes.Interface, time.Duration) cache.SharedIndex type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer + InformerName() *cache.InformerName } // TweakListOptionsFunc is a function that transforms a v1.ListOptions. type TweakListOptionsFunc func(*v1.ListOptions) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod time.Duration + + // Indexers are the indexers for this informer. + Indexers cache.Indexers + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *cache.InformerName + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} diff --git a/vendor/k8s.io/client-go/informers/networking/v1/ingress.go b/vendor/k8s.io/client-go/informers/networking/v1/ingress.go index fa7252dfa7..65be7320d1 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1/ingress.go +++ b/vendor/k8s.io/client-go/informers/networking/v1/ingress.go @@ -25,6 +25,7 @@ import ( apinetworkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type ingressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressInformer constructs a new informer for Ingress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressInformerWithOptions constructs a new informer for Ingress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().Ingresses(namespace).List(context.Background(), options) + return client.NetworkingV1().Ingresses(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().Ingresses(namespace).Watch(context.Background(), options) + return client.NetworkingV1().Ingresses(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().Ingresses(namespace).List(ctx, options) + return client.NetworkingV1().Ingresses(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().Ingresses(namespace).Watch(ctx, options) + return client.NetworkingV1().Ingresses(namespace).Watch(ctx, opts) }, }, client), &apinetworkingv1.Ingress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go b/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go index bd6696a37f..bcb118f991 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go +++ b/vendor/k8s.io/client-go/informers/networking/v1/ingressclass.go @@ -25,6 +25,7 @@ import ( apinetworkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type ingressClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressClassInformer(client, resyncPeriod, indexers, nil) + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressClassInformer constructs a new informer for IngressClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressClassInformerWithOptions constructs a new informer for IngressClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingressclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IngressClasses().List(context.Background(), options) + return client.NetworkingV1().IngressClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IngressClasses().Watch(context.Background(), options) + return client.NetworkingV1().IngressClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IngressClasses().List(ctx, options) + return client.NetworkingV1().IngressClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IngressClasses().Watch(ctx, options) + return client.NetworkingV1().IngressClasses().Watch(ctx, opts) }, }, client), &apinetworkingv1.IngressClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1/ipaddress.go b/vendor/k8s.io/client-go/informers/networking/v1/ipaddress.go index 8ab3ac5d63..ea4bb280c8 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1/ipaddress.go +++ b/vendor/k8s.io/client-go/informers/networking/v1/ipaddress.go @@ -25,6 +25,7 @@ import ( apinetworkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type iPAddressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIPAddressInformer(client, resyncPeriod, indexers, nil) + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIPAddressInformer constructs a new informer for IPAddress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIPAddressInformerWithOptions constructs a new informer for IPAddress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIPAddressInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ipaddresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IPAddresses().List(context.Background(), options) + return client.NetworkingV1().IPAddresses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IPAddresses().Watch(context.Background(), options) + return client.NetworkingV1().IPAddresses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IPAddresses().List(ctx, options) + return client.NetworkingV1().IPAddresses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().IPAddresses().Watch(ctx, options) + return client.NetworkingV1().IPAddresses().Watch(ctx, opts) }, }, client), &apinetworkingv1.IPAddress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *iPAddressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIPAddressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *iPAddressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go b/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go index 1b39b0e6cf..237fe6266d 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go +++ b/vendor/k8s.io/client-go/informers/networking/v1/networkpolicy.go @@ -25,6 +25,7 @@ import ( apinetworkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type networkPolicyInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, namespace, resyncPeriod, indexers, nil) + return NewNetworkPolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredNetworkPolicyInformer constructs a new informer for NetworkPolicy type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredNetworkPolicyInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewNetworkPolicyInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewNetworkPolicyInformerWithOptions constructs a new informer for NetworkPolicy type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewNetworkPolicyInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().NetworkPolicies(namespace).List(context.Background(), options) + return client.NetworkingV1().NetworkPolicies(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().NetworkPolicies(namespace).Watch(context.Background(), options) + return client.NetworkingV1().NetworkPolicies(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().NetworkPolicies(namespace).List(ctx, options) + return client.NetworkingV1().NetworkPolicies(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().NetworkPolicies(namespace).Watch(ctx, options) + return client.NetworkingV1().NetworkPolicies(namespace).Watch(ctx, opts) }, }, client), &apinetworkingv1.NetworkPolicy{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *networkPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredNetworkPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewNetworkPolicyInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *networkPolicyInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1/servicecidr.go b/vendor/k8s.io/client-go/informers/networking/v1/servicecidr.go index 299e40611e..ee1810f817 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1/servicecidr.go +++ b/vendor/k8s.io/client-go/informers/networking/v1/servicecidr.go @@ -25,6 +25,7 @@ import ( apinetworkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type serviceCIDRInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceCIDRInformer(client, resyncPeriod, indexers, nil) + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceCIDRInformer constructs a new informer for ServiceCIDR type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceCIDRInformerWithOptions constructs a new informer for ServiceCIDR type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceCIDRInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "servicecidrs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().ServiceCIDRs().List(context.Background(), options) + return client.NetworkingV1().ServiceCIDRs().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().ServiceCIDRs().Watch(context.Background(), options) + return client.NetworkingV1().ServiceCIDRs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().ServiceCIDRs().List(ctx, options) + return client.NetworkingV1().ServiceCIDRs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1().ServiceCIDRs().Watch(ctx, options) + return client.NetworkingV1().ServiceCIDRs().Watch(ctx, opts) }, }, client), &apinetworkingv1.ServiceCIDR{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceCIDRInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceCIDRInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceCIDRInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go index 3e279cb544..ba35b8ac70 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingress.go @@ -25,6 +25,7 @@ import ( apinetworkingv1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type ingressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, namespace, resyncPeriod, indexers, nil) + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressInformer constructs a new informer for Ingress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressInformerWithOptions constructs a new informer for Ingress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "ingresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().Ingresses(namespace).List(context.Background(), options) + return client.NetworkingV1beta1().Ingresses(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().Ingresses(namespace).Watch(context.Background(), options) + return client.NetworkingV1beta1().Ingresses(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().Ingresses(namespace).List(ctx, options) + return client.NetworkingV1beta1().Ingresses(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().Ingresses(namespace).Watch(ctx, options) + return client.NetworkingV1beta1().Ingresses(namespace).Watch(ctx, opts) }, }, client), &apinetworkingv1beta1.Ingress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go index 296abfa8c4..97d761a633 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/ingressclass.go @@ -25,6 +25,7 @@ import ( apinetworkingv1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type ingressClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIngressClassInformer(client, resyncPeriod, indexers, nil) + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIngressClassInformer constructs a new informer for IngressClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIngressClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIngressClassInformerWithOptions constructs a new informer for IngressClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIngressClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "ingressclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IngressClasses().List(context.Background(), options) + return client.NetworkingV1beta1().IngressClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IngressClasses().Watch(context.Background(), options) + return client.NetworkingV1beta1().IngressClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IngressClasses().List(ctx, options) + return client.NetworkingV1beta1().IngressClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IngressClasses().Watch(ctx, options) + return client.NetworkingV1beta1().IngressClasses().Watch(ctx, opts) }, }, client), &apinetworkingv1beta1.IngressClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *ingressClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIngressClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIngressClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *ingressClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/ipaddress.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/ipaddress.go index 94f785f10d..fd94392393 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1beta1/ipaddress.go +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/ipaddress.go @@ -25,6 +25,7 @@ import ( apinetworkingv1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type iPAddressInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredIPAddressInformer(client, resyncPeriod, indexers, nil) + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredIPAddressInformer constructs a new informer for IPAddress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewIPAddressInformerWithOptions constructs a new informer for IPAddress type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIPAddressInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "ipaddresss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IPAddresses().List(context.Background(), options) + return client.NetworkingV1beta1().IPAddresses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IPAddresses().Watch(context.Background(), options) + return client.NetworkingV1beta1().IPAddresses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IPAddresses().List(ctx, options) + return client.NetworkingV1beta1().IPAddresses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().IPAddresses().Watch(ctx, options) + return client.NetworkingV1beta1().IPAddresses().Watch(ctx, opts) }, }, client), &apinetworkingv1beta1.IPAddress{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *iPAddressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredIPAddressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewIPAddressInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *iPAddressInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/networking/v1beta1/servicecidr.go b/vendor/k8s.io/client-go/informers/networking/v1beta1/servicecidr.go index 6777646396..6fe8c3bd11 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1beta1/servicecidr.go +++ b/vendor/k8s.io/client-go/informers/networking/v1beta1/servicecidr.go @@ -25,6 +25,7 @@ import ( apinetworkingv1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type serviceCIDRInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewServiceCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredServiceCIDRInformer(client, resyncPeriod, indexers, nil) + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredServiceCIDRInformer constructs a new informer for ServiceCIDR type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredServiceCIDRInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewServiceCIDRInformerWithOptions constructs a new informer for ServiceCIDR type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceCIDRInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "servicecidrs"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().ServiceCIDRs().List(context.Background(), options) + return client.NetworkingV1beta1().ServiceCIDRs().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().ServiceCIDRs().Watch(context.Background(), options) + return client.NetworkingV1beta1().ServiceCIDRs().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().ServiceCIDRs().List(ctx, options) + return client.NetworkingV1beta1().ServiceCIDRs().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NetworkingV1beta1().ServiceCIDRs().Watch(ctx, options) + return client.NetworkingV1beta1().ServiceCIDRs().Watch(ctx, opts) }, }, client), &apinetworkingv1beta1.ServiceCIDR{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *serviceCIDRInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredServiceCIDRInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewServiceCIDRInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *serviceCIDRInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go index d794c56951..3b7d4a25d2 100644 --- a/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go +++ b/vendor/k8s.io/client-go/informers/node/v1/runtimeclass.go @@ -25,6 +25,7 @@ import ( apinodev1 "k8s.io/api/node/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type runtimeClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRuntimeClassInformerWithOptions constructs a new informer for RuntimeClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1", Resource: "runtimeclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1().RuntimeClasses().List(context.Background(), options) + return client.NodeV1().RuntimeClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1().RuntimeClasses().Watch(context.Background(), options) + return client.NodeV1().RuntimeClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1().RuntimeClasses().List(ctx, options) + return client.NodeV1().RuntimeClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1().RuntimeClasses().Watch(ctx, options) + return client.NodeV1().RuntimeClasses().Watch(ctx, opts) }, }, client), &apinodev1.RuntimeClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go index 01718ac102..1907a122d2 100644 --- a/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go +++ b/vendor/k8s.io/client-go/informers/node/v1alpha1/runtimeclass.go @@ -25,6 +25,7 @@ import ( apinodev1alpha1 "k8s.io/api/node/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type runtimeClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRuntimeClassInformerWithOptions constructs a new informer for RuntimeClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1alpha1", Resource: "runtimeclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1alpha1().RuntimeClasses().List(context.Background(), options) + return client.NodeV1alpha1().RuntimeClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1alpha1().RuntimeClasses().Watch(context.Background(), options) + return client.NodeV1alpha1().RuntimeClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1alpha1().RuntimeClasses().List(ctx, options) + return client.NodeV1alpha1().RuntimeClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1alpha1().RuntimeClasses().Watch(ctx, options) + return client.NodeV1alpha1().RuntimeClasses().Watch(ctx, opts) }, }, client), &apinodev1alpha1.RuntimeClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go b/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go index 09390f58b4..ca7e9307ac 100644 --- a/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go +++ b/vendor/k8s.io/client-go/informers/node/v1beta1/runtimeclass.go @@ -25,6 +25,7 @@ import ( apinodev1beta1 "k8s.io/api/node/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type runtimeClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, indexers, nil) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRuntimeClassInformer constructs a new informer for RuntimeClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRuntimeClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRuntimeClassInformerWithOptions constructs a new informer for RuntimeClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuntimeClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1beta1", Resource: "runtimeclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1beta1().RuntimeClasses().List(context.Background(), options) + return client.NodeV1beta1().RuntimeClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1beta1().RuntimeClasses().Watch(context.Background(), options) + return client.NodeV1beta1().RuntimeClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1beta1().RuntimeClasses().List(ctx, options) + return client.NodeV1beta1().RuntimeClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.NodeV1beta1().RuntimeClasses().Watch(ctx, options) + return client.NodeV1beta1().RuntimeClasses().Watch(ctx, opts) }, }, client), &apinodev1beta1.RuntimeClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *runtimeClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRuntimeClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRuntimeClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *runtimeClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go b/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go index 10e45d851e..2945e543d7 100644 --- a/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go +++ b/vendor/k8s.io/client-go/informers/policy/v1/poddisruptionbudget.go @@ -25,6 +25,7 @@ import ( apipolicyv1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type podDisruptionBudgetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPodDisruptionBudgetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPodDisruptionBudgetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodDisruptionBudgetInformerWithOptions constructs a new informer for PodDisruptionBudget type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodDisruptionBudgetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "policy", Version: "v1", Resource: "poddisruptionbudgets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1().PodDisruptionBudgets(namespace).List(context.Background(), options) + return client.PolicyV1().PodDisruptionBudgets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1().PodDisruptionBudgets(namespace).Watch(context.Background(), options) + return client.PolicyV1().PodDisruptionBudgets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1().PodDisruptionBudgets(namespace).List(ctx, options) + return client.PolicyV1().PodDisruptionBudgets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1().PodDisruptionBudgets(namespace).Watch(ctx, options) + return client.PolicyV1().PodDisruptionBudgets(namespace).Watch(ctx, opts) }, }, client), &apipolicyv1.PodDisruptionBudget{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *podDisruptionBudgetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPodDisruptionBudgetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *podDisruptionBudgetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go b/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go index a45d753eb6..70c79683fe 100644 --- a/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go +++ b/vendor/k8s.io/client-go/informers/policy/v1beta1/poddisruptionbudget.go @@ -25,6 +25,7 @@ import ( apipolicyv1beta1 "k8s.io/api/policy/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type podDisruptionBudgetInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, namespace, resyncPeriod, indexers, nil) + return NewPodDisruptionBudgetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPodDisruptionBudgetInformer constructs a new informer for PodDisruptionBudget type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPodDisruptionBudgetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPodDisruptionBudgetInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodDisruptionBudgetInformerWithOptions constructs a new informer for PodDisruptionBudget type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodDisruptionBudgetInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "policy", Version: "v1beta1", Resource: "poddisruptionbudgets"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1beta1().PodDisruptionBudgets(namespace).List(context.Background(), options) + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1beta1().PodDisruptionBudgets(namespace).Watch(context.Background(), options) + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1beta1().PodDisruptionBudgets(namespace).List(ctx, options) + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.PolicyV1beta1().PodDisruptionBudgets(namespace).Watch(ctx, options) + return client.PolicyV1beta1().PodDisruptionBudgets(namespace).Watch(ctx, opts) }, }, client), &apipolicyv1beta1.PodDisruptionBudget{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *podDisruptionBudgetInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodDisruptionBudgetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPodDisruptionBudgetInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *podDisruptionBudgetInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go index 02dab4f9a6..d938be79ee 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrole.go @@ -25,6 +25,7 @@ import ( apirbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleInformerWithOptions constructs a new informer for ClusterRole type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoles().List(context.Background(), options) + return client.RbacV1().ClusterRoles().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoles().Watch(context.Background(), options) + return client.RbacV1().ClusterRoles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoles().List(ctx, options) + return client.RbacV1().ClusterRoles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoles().Watch(ctx, options) + return client.RbacV1().ClusterRoles().Watch(ctx, opts) }, }, client), &apirbacv1.ClusterRole{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go index 182009da85..72fe655da8 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1/clusterrolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleBindingInformerWithOptions constructs a new informer for ClusterRoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoleBindings().List(context.Background(), options) + return client.RbacV1().ClusterRoleBindings().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoleBindings().Watch(context.Background(), options) + return client.RbacV1().ClusterRoleBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoleBindings().List(ctx, options) + return client.RbacV1().ClusterRoleBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().ClusterRoleBindings().Watch(ctx, options) + return client.RbacV1().ClusterRoleBindings().Watch(ctx, opts) }, }, client), &apirbacv1.ClusterRoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1/role.go index 5a0a1f8003..f66decf040 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1/role.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1/role.go @@ -25,6 +25,7 @@ import ( apirbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleInformer constructs a new informer for Role type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleInformerWithOptions constructs a new informer for Role type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().Roles(namespace).List(context.Background(), options) + return client.RbacV1().Roles(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().Roles(namespace).Watch(context.Background(), options) + return client.RbacV1().Roles(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().Roles(namespace).List(ctx, options) + return client.RbacV1().Roles(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().Roles(namespace).Watch(ctx, options) + return client.RbacV1().Roles(namespace).Watch(ctx, opts) }, }, client), &apirbacv1.Role{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go index 0f0eec60f8..c17b1c474f 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1/rolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleBindingInformerWithOptions constructs a new informer for RoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().RoleBindings(namespace).List(context.Background(), options) + return client.RbacV1().RoleBindings(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().RoleBindings(namespace).Watch(context.Background(), options) + return client.RbacV1().RoleBindings(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().RoleBindings(namespace).List(ctx, options) + return client.RbacV1().RoleBindings(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1().RoleBindings(namespace).Watch(ctx, options) + return client.RbacV1().RoleBindings(namespace).Watch(ctx, opts) }, }, client), &apirbacv1.RoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleBindingInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go index e1b25180b9..cac4ba05b9 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrole.go @@ -25,6 +25,7 @@ import ( apirbacv1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleInformerWithOptions constructs a new informer for ClusterRole type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "clusterroles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoles().List(context.Background(), options) + return client.RbacV1alpha1().ClusterRoles().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoles().Watch(context.Background(), options) + return client.RbacV1alpha1().ClusterRoles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoles().List(ctx, options) + return client.RbacV1alpha1().ClusterRoles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoles().Watch(ctx, options) + return client.RbacV1alpha1().ClusterRoles().Watch(ctx, opts) }, }, client), &apirbacv1alpha1.ClusterRole{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go index d61e8b2930..944e16cef6 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/clusterrolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleBindingInformerWithOptions constructs a new informer for ClusterRoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "clusterrolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoleBindings().List(context.Background(), options) + return client.RbacV1alpha1().ClusterRoleBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoleBindings().Watch(context.Background(), options) + return client.RbacV1alpha1().ClusterRoleBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoleBindings().List(ctx, options) + return client.RbacV1alpha1().ClusterRoleBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().ClusterRoleBindings().Watch(ctx, options) + return client.RbacV1alpha1().ClusterRoleBindings().Watch(ctx, opts) }, }, client), &apirbacv1alpha1.ClusterRoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go index 497bccbba1..c4e2a6cf6c 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/role.go @@ -25,6 +25,7 @@ import ( apirbacv1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleInformer constructs a new informer for Role type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleInformerWithOptions constructs a new informer for Role type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "roles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().Roles(namespace).List(context.Background(), options) + return client.RbacV1alpha1().Roles(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().Roles(namespace).Watch(context.Background(), options) + return client.RbacV1alpha1().Roles(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().Roles(namespace).List(ctx, options) + return client.RbacV1alpha1().Roles(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().Roles(namespace).Watch(ctx, options) + return client.RbacV1alpha1().Roles(namespace).Watch(ctx, opts) }, }, client), &apirbacv1alpha1.Role{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go index 0d8b390b30..ef1e246f5b 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1alpha1/rolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleBindingInformerWithOptions constructs a new informer for RoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "rolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().RoleBindings(namespace).List(context.Background(), options) + return client.RbacV1alpha1().RoleBindings(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().RoleBindings(namespace).Watch(context.Background(), options) + return client.RbacV1alpha1().RoleBindings(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().RoleBindings(namespace).List(ctx, options) + return client.RbacV1alpha1().RoleBindings(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1alpha1().RoleBindings(namespace).Watch(ctx, options) + return client.RbacV1alpha1().RoleBindings(namespace).Watch(ctx, opts) }, }, client), &apirbacv1alpha1.RoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleBindingInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go index 1cc1a0dd00..df87d468ca 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrole.go @@ -25,6 +25,7 @@ import ( apirbacv1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleInformer constructs a new informer for ClusterRole type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleInformerWithOptions constructs a new informer for ClusterRole type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "clusterroles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoles().List(context.Background(), options) + return client.RbacV1beta1().ClusterRoles().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoles().Watch(context.Background(), options) + return client.RbacV1beta1().ClusterRoles().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoles().List(ctx, options) + return client.RbacV1beta1().ClusterRoles().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoles().Watch(ctx, options) + return client.RbacV1beta1().ClusterRoles().Watch(ctx, opts) }, }, client), &apirbacv1beta1.ClusterRole{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go index a96ed0889a..9f14c10daf 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/clusterrolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type clusterRoleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, indexers, nil) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredClusterRoleBindingInformer constructs a new informer for ClusterRoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredClusterRoleBindingInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewClusterRoleBindingInformerWithOptions constructs a new informer for ClusterRoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterRoleBindingInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "clusterrolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoleBindings().List(context.Background(), options) + return client.RbacV1beta1().ClusterRoleBindings().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoleBindings().Watch(context.Background(), options) + return client.RbacV1beta1().ClusterRoleBindings().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoleBindings().List(ctx, options) + return client.RbacV1beta1().ClusterRoleBindings().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().ClusterRoleBindings().Watch(ctx, options) + return client.RbacV1beta1().ClusterRoleBindings().Watch(ctx, opts) }, }, client), &apirbacv1beta1.ClusterRoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *clusterRoleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredClusterRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewClusterRoleBindingInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go index 922ac5dc5c..4dd948f167 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/role.go @@ -25,6 +25,7 @@ import ( apirbacv1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleInformer constructs a new informer for Role type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleInformerWithOptions constructs a new informer for Role type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "roles"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().Roles(namespace).List(context.Background(), options) + return client.RbacV1beta1().Roles(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().Roles(namespace).Watch(context.Background(), options) + return client.RbacV1beta1().Roles(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().Roles(namespace).List(ctx, options) + return client.RbacV1beta1().Roles(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().Roles(namespace).Watch(ctx, options) + return client.RbacV1beta1().Roles(namespace).Watch(ctx, opts) }, }, client), &apirbacv1beta1.Role{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go b/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go index 5fcd488493..882d59471e 100644 --- a/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go +++ b/vendor/k8s.io/client-go/informers/rbac/v1beta1/rolebinding.go @@ -25,6 +25,7 @@ import ( apirbacv1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type roleBindingInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, namespace, resyncPeriod, indexers, nil) + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredRoleBindingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewRoleBindingInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewRoleBindingInformerWithOptions constructs a new informer for RoleBinding type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRoleBindingInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "rolebindings"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().RoleBindings(namespace).List(context.Background(), options) + return client.RbacV1beta1().RoleBindings(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().RoleBindings(namespace).Watch(context.Background(), options) + return client.RbacV1beta1().RoleBindings(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().RoleBindings(namespace).List(ctx, options) + return client.RbacV1beta1().RoleBindings(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.RbacV1beta1().RoleBindings(namespace).Watch(ctx, options) + return client.RbacV1beta1().RoleBindings(namespace).Watch(ctx, opts) }, }, client), &apirbacv1beta1.RoleBinding{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *roleBindingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredRoleBindingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewRoleBindingInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *roleBindingInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1/deviceclass.go b/vendor/k8s.io/client-go/informers/resource/v1/deviceclass.go index 867bb7b35e..bacc65a28f 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1/deviceclass.go +++ b/vendor/k8s.io/client-go/informers/resource/v1/deviceclass.go @@ -25,6 +25,7 @@ import ( apiresourcev1 "k8s.io/api/resource/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type deviceClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, indexers, nil) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeviceClassInformer constructs a new informer for DeviceClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeviceClassInformerWithOptions constructs a new informer for DeviceClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1", Resource: "deviceclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().DeviceClasses().List(context.Background(), options) + return client.ResourceV1().DeviceClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().DeviceClasses().Watch(context.Background(), options) + return client.ResourceV1().DeviceClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().DeviceClasses().List(ctx, options) + return client.ResourceV1().DeviceClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().DeviceClasses().Watch(ctx, options) + return client.ResourceV1().DeviceClasses().Watch(ctx, opts) }, }, client), &apiresourcev1.DeviceClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deviceClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deviceClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1/resourceclaim.go index 64deaed694..996cc77f61 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1/resourceclaim.go +++ b/vendor/k8s.io/client-go/informers/resource/v1/resourceclaim.go @@ -25,6 +25,7 @@ import ( apiresourcev1 "k8s.io/api/resource/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimInformer constructs a new informer for ResourceClaim type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimInformerWithOptions constructs a new informer for ResourceClaim type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1", Resource: "resourceclaims"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaims(namespace).List(context.Background(), options) + return client.ResourceV1().ResourceClaims(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaims(namespace).Watch(context.Background(), options) + return client.ResourceV1().ResourceClaims(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaims(namespace).List(ctx, options) + return client.ResourceV1().ResourceClaims(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaims(namespace).Watch(ctx, options) + return client.ResourceV1().ResourceClaims(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1.ResourceClaim{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1/resourceclaimtemplate.go index 131e159ef9..e562314dc1 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/informers/resource/v1/resourceclaimtemplate.go @@ -25,6 +25,7 @@ import ( apiresourcev1 "k8s.io/api/resource/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimTemplateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimTemplateInformer constructs a new informer for ResourceClaimTemplate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimTemplateInformerWithOptions constructs a new informer for ResourceClaimTemplate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimTemplateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1", Resource: "resourceclaimtemplates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaimTemplates(namespace).List(context.Background(), options) + return client.ResourceV1().ResourceClaimTemplates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaimTemplates(namespace).Watch(context.Background(), options) + return client.ResourceV1().ResourceClaimTemplates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaimTemplates(namespace).List(ctx, options) + return client.ResourceV1().ResourceClaimTemplates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceClaimTemplates(namespace).Watch(ctx, options) + return client.ResourceV1().ResourceClaimTemplates(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1.ResourceClaimTemplate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimTemplateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1/resourceslice.go b/vendor/k8s.io/client-go/informers/resource/v1/resourceslice.go index a01abf0739..85c877f803 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1/resourceslice.go +++ b/vendor/k8s.io/client-go/informers/resource/v1/resourceslice.go @@ -25,6 +25,7 @@ import ( apiresourcev1 "k8s.io/api/resource/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type resourceSliceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, indexers, nil) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceSliceInformer constructs a new informer for ResourceSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceSliceInformerWithOptions constructs a new informer for ResourceSlice type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceSliceInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1", Resource: "resourceslices"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceSlices().List(context.Background(), options) + return client.ResourceV1().ResourceSlices().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceSlices().Watch(context.Background(), options) + return client.ResourceV1().ResourceSlices().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceSlices().List(ctx, options) + return client.ResourceV1().ResourceSlices().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1().ResourceSlices().Watch(ctx, options) + return client.ResourceV1().ResourceSlices().Watch(ctx, opts) }, }, client), &apiresourcev1.ResourceSlice{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceSliceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha3/devicetaintrule.go b/vendor/k8s.io/client-go/informers/resource/v1alpha3/devicetaintrule.go index 0fdc88ac59..0b0029ab54 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha3/devicetaintrule.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha3/devicetaintrule.go @@ -25,6 +25,7 @@ import ( apiresourcev1alpha3 "k8s.io/api/resource/v1alpha3" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type deviceTaintRuleInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeviceTaintRuleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeviceTaintRuleInformer(client, resyncPeriod, indexers, nil) + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeviceTaintRuleInformer constructs a new informer for DeviceTaintRule type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeviceTaintRuleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeviceTaintRuleInformerWithOptions constructs a new informer for DeviceTaintRule type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceTaintRuleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha3", Resource: "devicetaintrules"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1alpha3().DeviceTaintRules().List(context.Background(), options) + return client.ResourceV1alpha3().DeviceTaintRules().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1alpha3().DeviceTaintRules().Watch(context.Background(), options) + return client.ResourceV1alpha3().DeviceTaintRules().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1alpha3().DeviceTaintRules().List(ctx, options) + return client.ResourceV1alpha3().DeviceTaintRules().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1alpha3().DeviceTaintRules().Watch(ctx, options) + return client.ResourceV1alpha3().DeviceTaintRules().Watch(ctx, opts) }, }, client), &apiresourcev1alpha3.DeviceTaintRule{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deviceTaintRuleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeviceTaintRuleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deviceTaintRuleInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha3/interface.go b/vendor/k8s.io/client-go/informers/resource/v1alpha3/interface.go index 1fbab52b6f..b305681236 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha3/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha3/interface.go @@ -26,6 +26,8 @@ import ( type Interface interface { // DeviceTaintRules returns a DeviceTaintRuleInformer. DeviceTaintRules() DeviceTaintRuleInformer + // ResourcePoolStatusRequests returns a ResourcePoolStatusRequestInformer. + ResourcePoolStatusRequests() ResourcePoolStatusRequestInformer } type version struct { @@ -43,3 +45,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (v *version) DeviceTaintRules() DeviceTaintRuleInformer { return &deviceTaintRuleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } + +// ResourcePoolStatusRequests returns a ResourcePoolStatusRequestInformer. +func (v *version) ResourcePoolStatusRequests() ResourcePoolStatusRequestInformer { + return &resourcePoolStatusRequestInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha3/resourcepoolstatusrequest.go b/vendor/k8s.io/client-go/informers/resource/v1alpha3/resourcepoolstatusrequest.go new file mode 100644 index 0000000000..f34d57e138 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha3/resourcepoolstatusrequest.go @@ -0,0 +1,115 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + context "context" + time "time" + + apiresourcev1alpha3 "k8s.io/api/resource/v1alpha3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + resourcev1alpha3 "k8s.io/client-go/listers/resource/v1alpha3" + cache "k8s.io/client-go/tools/cache" +) + +// ResourcePoolStatusRequestInformer provides access to a shared informer and lister for +// ResourcePoolStatusRequests. +type ResourcePoolStatusRequestInformer interface { + Informer() cache.SharedIndexInformer + Lister() resourcev1alpha3.ResourcePoolStatusRequestLister +} + +type resourcePoolStatusRequestInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewResourcePoolStatusRequestInformer constructs a new informer for ResourcePoolStatusRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourcePoolStatusRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewResourcePoolStatusRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredResourcePoolStatusRequestInformer constructs a new informer for ResourcePoolStatusRequest type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredResourcePoolStatusRequestInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewResourcePoolStatusRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourcePoolStatusRequestInformerWithOptions constructs a new informer for ResourcePoolStatusRequest type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourcePoolStatusRequestInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha3", Resource: "resourcepoolstatusrequests"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1alpha3().ResourcePoolStatusRequests().List(context.Background(), opts) + }, + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1alpha3().ResourcePoolStatusRequests().Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1alpha3().ResourcePoolStatusRequests().List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1alpha3().ResourcePoolStatusRequests().Watch(ctx, opts) + }, + }, client), + &apiresourcev1alpha3.ResourcePoolStatusRequest{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *resourcePoolStatusRequestInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewResourcePoolStatusRequestInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *resourcePoolStatusRequestInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiresourcev1alpha3.ResourcePoolStatusRequest{}, f.defaultInformer) +} + +func (f *resourcePoolStatusRequestInformer) Lister() resourcev1alpha3.ResourcePoolStatusRequestLister { + return resourcev1alpha3.NewResourcePoolStatusRequestLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta1/deviceclass.go b/vendor/k8s.io/client-go/informers/resource/v1beta1/deviceclass.go index cb15fbc08f..0a4d4bea64 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta1/deviceclass.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta1/deviceclass.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta1 "k8s.io/api/resource/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type deviceClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, indexers, nil) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeviceClassInformer constructs a new informer for DeviceClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeviceClassInformerWithOptions constructs a new informer for DeviceClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta1", Resource: "deviceclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().DeviceClasses().List(context.Background(), options) + return client.ResourceV1beta1().DeviceClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().DeviceClasses().Watch(context.Background(), options) + return client.ResourceV1beta1().DeviceClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().DeviceClasses().List(ctx, options) + return client.ResourceV1beta1().DeviceClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().DeviceClasses().Watch(ctx, options) + return client.ResourceV1beta1().DeviceClasses().Watch(ctx, opts) }, }, client), &apiresourcev1beta1.DeviceClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deviceClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deviceClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaim.go index 982c598515..9ec1ece317 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaim.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaim.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta1 "k8s.io/api/resource/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimInformer constructs a new informer for ResourceClaim type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimInformerWithOptions constructs a new informer for ResourceClaim type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta1", Resource: "resourceclaims"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaims(namespace).List(context.Background(), options) + return client.ResourceV1beta1().ResourceClaims(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaims(namespace).Watch(context.Background(), options) + return client.ResourceV1beta1().ResourceClaims(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaims(namespace).List(ctx, options) + return client.ResourceV1beta1().ResourceClaims(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaims(namespace).Watch(ctx, options) + return client.ResourceV1beta1().ResourceClaims(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1beta1.ResourceClaim{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaimtemplate.go index 51a6381af6..b6aa9cb919 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceclaimtemplate.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta1 "k8s.io/api/resource/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimTemplateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimTemplateInformer constructs a new informer for ResourceClaimTemplate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimTemplateInformerWithOptions constructs a new informer for ResourceClaimTemplate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimTemplateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta1", Resource: "resourceclaimtemplates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaimTemplates(namespace).List(context.Background(), options) + return client.ResourceV1beta1().ResourceClaimTemplates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaimTemplates(namespace).Watch(context.Background(), options) + return client.ResourceV1beta1().ResourceClaimTemplates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaimTemplates(namespace).List(ctx, options) + return client.ResourceV1beta1().ResourceClaimTemplates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceClaimTemplates(namespace).Watch(ctx, options) + return client.ResourceV1beta1().ResourceClaimTemplates(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1beta1.ResourceClaimTemplate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimTemplateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceslice.go b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceslice.go index b6b1cc1fdc..39e971aec2 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceslice.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta1/resourceslice.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta1 "k8s.io/api/resource/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type resourceSliceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, indexers, nil) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceSliceInformer constructs a new informer for ResourceSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceSliceInformerWithOptions constructs a new informer for ResourceSlice type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceSliceInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta1", Resource: "resourceslices"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceSlices().List(context.Background(), options) + return client.ResourceV1beta1().ResourceSlices().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceSlices().Watch(context.Background(), options) + return client.ResourceV1beta1().ResourceSlices().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceSlices().List(ctx, options) + return client.ResourceV1beta1().ResourceSlices().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta1().ResourceSlices().Watch(ctx, options) + return client.ResourceV1beta1().ResourceSlices().Watch(ctx, opts) }, }, client), &apiresourcev1beta1.ResourceSlice{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceSliceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/deviceclass.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/deviceclass.go index a940a214f4..d98b4d658e 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta2/deviceclass.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/deviceclass.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta2 "k8s.io/api/resource/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type deviceClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, indexers, nil) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredDeviceClassInformer constructs a new informer for DeviceClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredDeviceClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeviceClassInformerWithOptions constructs a new informer for DeviceClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta2", Resource: "deviceclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().DeviceClasses().List(context.Background(), options) + return client.ResourceV1beta2().DeviceClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().DeviceClasses().Watch(context.Background(), options) + return client.ResourceV1beta2().DeviceClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().DeviceClasses().List(ctx, options) + return client.ResourceV1beta2().DeviceClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().DeviceClasses().Watch(ctx, options) + return client.ResourceV1beta2().DeviceClasses().Watch(ctx, opts) }, }, client), &apiresourcev1beta2.DeviceClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *deviceClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredDeviceClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewDeviceClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *deviceClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/devicetaintrule.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/devicetaintrule.go new file mode 100644 index 0000000000..328a9c3939 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/devicetaintrule.go @@ -0,0 +1,115 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta2 + +import ( + context "context" + time "time" + + apiresourcev1beta2 "k8s.io/api/resource/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + resourcev1beta2 "k8s.io/client-go/listers/resource/v1beta2" + cache "k8s.io/client-go/tools/cache" +) + +// DeviceTaintRuleInformer provides access to a shared informer and lister for +// DeviceTaintRules. +type DeviceTaintRuleInformer interface { + Informer() cache.SharedIndexInformer + Lister() resourcev1beta2.DeviceTaintRuleLister +} + +type deviceTaintRuleInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewDeviceTaintRuleInformer constructs a new informer for DeviceTaintRule type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceTaintRuleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredDeviceTaintRuleInformer constructs a new informer for DeviceTaintRule type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredDeviceTaintRuleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewDeviceTaintRuleInformerWithOptions constructs a new informer for DeviceTaintRule type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewDeviceTaintRuleInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta2", Resource: "devicetaintrules"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1beta2().DeviceTaintRules().List(context.Background(), opts) + }, + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1beta2().DeviceTaintRules().Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1beta2().DeviceTaintRules().List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.ResourceV1beta2().DeviceTaintRules().Watch(ctx, opts) + }, + }, client), + &apiresourcev1beta2.DeviceTaintRule{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *deviceTaintRuleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewDeviceTaintRuleInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *deviceTaintRuleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiresourcev1beta2.DeviceTaintRule{}, f.defaultInformer) +} + +func (f *deviceTaintRuleInformer) Lister() resourcev1beta2.DeviceTaintRuleLister { + return resourcev1beta2.NewDeviceTaintRuleLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/interface.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/interface.go index 4627d6f3e2..a05e518e2e 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta2/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/interface.go @@ -26,6 +26,8 @@ import ( type Interface interface { // DeviceClasses returns a DeviceClassInformer. DeviceClasses() DeviceClassInformer + // DeviceTaintRules returns a DeviceTaintRuleInformer. + DeviceTaintRules() DeviceTaintRuleInformer // ResourceClaims returns a ResourceClaimInformer. ResourceClaims() ResourceClaimInformer // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. @@ -50,6 +52,11 @@ func (v *version) DeviceClasses() DeviceClassInformer { return &deviceClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// DeviceTaintRules returns a DeviceTaintRuleInformer. +func (v *version) DeviceTaintRules() DeviceTaintRuleInformer { + return &deviceTaintRuleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // ResourceClaims returns a ResourceClaimInformer. func (v *version) ResourceClaims() ResourceClaimInformer { return &resourceClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaim.go index a5c085c2f0..61dc6db17d 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaim.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaim.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta2 "k8s.io/api/resource/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimInformer constructs a new informer for ResourceClaim type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimInformerWithOptions constructs a new informer for ResourceClaim type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta2", Resource: "resourceclaims"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaims(namespace).List(context.Background(), options) + return client.ResourceV1beta2().ResourceClaims(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaims(namespace).Watch(context.Background(), options) + return client.ResourceV1beta2().ResourceClaims(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaims(namespace).List(ctx, options) + return client.ResourceV1beta2().ResourceClaims(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaims(namespace).Watch(ctx, options) + return client.ResourceV1beta2().ResourceClaims(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1beta2.ResourceClaim{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaimtemplate.go index 7df9f74dd5..ee22977a39 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaimtemplate.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta2 "k8s.io/api/resource/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type resourceClaimTemplateInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, namespace, resyncPeriod, indexers, nil) + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceClaimTemplateInformer constructs a new informer for ResourceClaimTemplate type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceClaimTemplateInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceClaimTemplateInformerWithOptions constructs a new informer for ResourceClaimTemplate type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceClaimTemplateInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta2", Resource: "resourceclaimtemplates"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaimTemplates(namespace).List(context.Background(), options) + return client.ResourceV1beta2().ResourceClaimTemplates(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaimTemplates(namespace).Watch(context.Background(), options) + return client.ResourceV1beta2().ResourceClaimTemplates(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaimTemplates(namespace).List(ctx, options) + return client.ResourceV1beta2().ResourceClaimTemplates(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceClaimTemplates(namespace).Watch(ctx, options) + return client.ResourceV1beta2().ResourceClaimTemplates(namespace).Watch(ctx, opts) }, }, client), &apiresourcev1beta2.ResourceClaimTemplate{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceClaimTemplateInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceClaimTemplateInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceslice.go b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceslice.go index 83e6cc037a..7a8027886e 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceslice.go +++ b/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceslice.go @@ -25,6 +25,7 @@ import ( apiresourcev1beta2 "k8s.io/api/resource/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type resourceSliceInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, indexers, nil) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredResourceSliceInformer constructs a new informer for ResourceSlice type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredResourceSliceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewResourceSliceInformerWithOptions constructs a new informer for ResourceSlice type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewResourceSliceInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1beta2", Resource: "resourceslices"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceSlices().List(context.Background(), options) + return client.ResourceV1beta2().ResourceSlices().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceSlices().Watch(context.Background(), options) + return client.ResourceV1beta2().ResourceSlices().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceSlices().List(ctx, options) + return client.ResourceV1beta2().ResourceSlices().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.ResourceV1beta2().ResourceSlices().Watch(ctx, options) + return client.ResourceV1beta2().ResourceSlices().Watch(ctx, opts) }, }, client), &apiresourcev1beta2.ResourceSlice{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *resourceSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredResourceSliceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewResourceSliceInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *resourceSliceInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/scheduling/interface.go b/vendor/k8s.io/client-go/informers/scheduling/interface.go index 659089b531..e55a8410d1 100644 --- a/vendor/k8s.io/client-go/informers/scheduling/interface.go +++ b/vendor/k8s.io/client-go/informers/scheduling/interface.go @@ -21,7 +21,7 @@ package scheduling import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" v1 "k8s.io/client-go/informers/scheduling/v1" - v1alpha1 "k8s.io/client-go/informers/scheduling/v1alpha1" + v1alpha2 "k8s.io/client-go/informers/scheduling/v1alpha2" v1beta1 "k8s.io/client-go/informers/scheduling/v1beta1" ) @@ -29,8 +29,8 @@ import ( type Interface interface { // V1 provides access to shared informers for resources in V1. V1() v1.Interface - // V1alpha1 provides access to shared informers for resources in V1alpha1. - V1alpha1() v1alpha1.Interface + // V1alpha2 provides access to shared informers for resources in V1alpha2. + V1alpha2() v1alpha2.Interface // V1beta1 provides access to shared informers for resources in V1beta1. V1beta1() v1beta1.Interface } @@ -51,9 +51,9 @@ func (g *group) V1() v1.Interface { return v1.New(g.factory, g.namespace, g.tweakListOptions) } -// V1alpha1 returns a new v1alpha1.Interface. -func (g *group) V1alpha1() v1alpha1.Interface { - return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +// V1alpha2 returns a new v1alpha2.Interface. +func (g *group) V1alpha2() v1alpha2.Interface { + return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) } // V1beta1 returns a new v1beta1.Interface. diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go index 8cce79ce23..f1d18f2a01 100644 --- a/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go +++ b/vendor/k8s.io/client-go/informers/scheduling/v1/priorityclass.go @@ -25,6 +25,7 @@ import ( apischedulingv1 "k8s.io/api/scheduling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityClassInformerWithOptions constructs a new informer for PriorityClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1", Resource: "priorityclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1().PriorityClasses().List(context.Background(), options) + return client.SchedulingV1().PriorityClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1().PriorityClasses().Watch(context.Background(), options) + return client.SchedulingV1().PriorityClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1().PriorityClasses().List(ctx, options) + return client.SchedulingV1().PriorityClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1().PriorityClasses().Watch(ctx, options) + return client.SchedulingV1().PriorityClasses().Watch(ctx, opts) }, }, client), &apischedulingv1.PriorityClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go deleted file mode 100644 index 88f99a7d00..0000000000 --- a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/priorityclass.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - context "context" - time "time" - - apischedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - kubernetes "k8s.io/client-go/kubernetes" - schedulingv1alpha1 "k8s.io/client-go/listers/scheduling/v1alpha1" - cache "k8s.io/client-go/tools/cache" -) - -// PriorityClassInformer provides access to a shared informer and lister for -// PriorityClasses. -type PriorityClassInformer interface { - Informer() cache.SharedIndexInformer - Lister() schedulingv1alpha1.PriorityClassLister -} - -type priorityClassInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewPriorityClassInformer constructs a new informer for PriorityClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().PriorityClasses().List(context.Background(), options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().PriorityClasses().Watch(context.Background(), options) - }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().PriorityClasses().List(ctx, options) - }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().PriorityClasses().Watch(ctx, options) - }, - }, client), - &apischedulingv1alpha1.PriorityClass{}, - resyncPeriod, - indexers, - ) -} - -func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apischedulingv1alpha1.PriorityClass{}, f.defaultInformer) -} - -func (f *priorityClassInformer) Lister() schedulingv1alpha1.PriorityClassLister { - return schedulingv1alpha1.NewPriorityClassLister(f.Informer().GetIndexer()) -} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/workload.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/workload.go deleted file mode 100644 index c58e788946..0000000000 --- a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/workload.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - context "context" - time "time" - - apischedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - kubernetes "k8s.io/client-go/kubernetes" - schedulingv1alpha1 "k8s.io/client-go/listers/scheduling/v1alpha1" - cache "k8s.io/client-go/tools/cache" -) - -// WorkloadInformer provides access to a shared informer and lister for -// Workloads. -type WorkloadInformer interface { - Informer() cache.SharedIndexInformer - Lister() schedulingv1alpha1.WorkloadLister -} - -type workloadInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewWorkloadInformer constructs a new informer for Workload type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewWorkloadInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredWorkloadInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredWorkloadInformer constructs a new informer for Workload type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredWorkloadInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().Workloads(namespace).List(context.Background(), options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().Workloads(namespace).Watch(context.Background(), options) - }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().Workloads(namespace).List(ctx, options) - }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.SchedulingV1alpha1().Workloads(namespace).Watch(ctx, options) - }, - }, client), - &apischedulingv1alpha1.Workload{}, - resyncPeriod, - indexers, - ) -} - -func (f *workloadInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredWorkloadInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *workloadInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&apischedulingv1alpha1.Workload{}, f.defaultInformer) -} - -func (f *workloadInformer) Lister() schedulingv1alpha1.WorkloadLister { - return schedulingv1alpha1.NewWorkloadLister(f.Informer().GetIndexer()) -} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/interface.go similarity index 82% rename from vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go rename to vendor/k8s.io/client-go/informers/scheduling/v1alpha2/interface.go index fdfc4e6af4..8edc498b67 100644 --- a/vendor/k8s.io/client-go/informers/scheduling/v1alpha1/interface.go +++ b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/interface.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" @@ -24,8 +24,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // PriorityClasses returns a PriorityClassInformer. - PriorityClasses() PriorityClassInformer + // PodGroups returns a PodGroupInformer. + PodGroups() PodGroupInformer // Workloads returns a WorkloadInformer. Workloads() WorkloadInformer } @@ -41,9 +41,9 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// PriorityClasses returns a PriorityClassInformer. -func (v *version) PriorityClasses() PriorityClassInformer { - return &priorityClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +// PodGroups returns a PodGroupInformer. +func (v *version) PodGroups() PodGroupInformer { + return &podGroupInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } // Workloads returns a WorkloadInformer. diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/podgroup.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/podgroup.go new file mode 100644 index 0000000000..5f39858c65 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/podgroup.go @@ -0,0 +1,116 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + context "context" + time "time" + + apischedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + schedulingv1alpha2 "k8s.io/client-go/listers/scheduling/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// PodGroupInformer provides access to a shared informer and lister for +// PodGroups. +type PodGroupInformer interface { + Informer() cache.SharedIndexInformer + Lister() schedulingv1alpha2.PodGroupLister +} + +type podGroupInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodGroupInformer constructs a new informer for PodGroup type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodGroupInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewPodGroupInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredPodGroupInformer constructs a new informer for PodGroup type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodGroupInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewPodGroupInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPodGroupInformerWithOptions constructs a new informer for PodGroup type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodGroupInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1alpha2", Resource: "podgroups"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().PodGroups(namespace).List(context.Background(), opts) + }, + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().PodGroups(namespace).Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().PodGroups(namespace).List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().PodGroups(namespace).Watch(ctx, opts) + }, + }, client), + &apischedulingv1alpha2.PodGroup{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *podGroupInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewPodGroupInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *podGroupInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apischedulingv1alpha2.PodGroup{}, f.defaultInformer) +} + +func (f *podGroupInformer) Lister() schedulingv1alpha2.PodGroupLister { + return schedulingv1alpha2.NewPodGroupLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/workload.go b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/workload.go new file mode 100644 index 0000000000..ffe2f4ece7 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/scheduling/v1alpha2/workload.go @@ -0,0 +1,116 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + context "context" + time "time" + + apischedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + schedulingv1alpha2 "k8s.io/client-go/listers/scheduling/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// WorkloadInformer provides access to a shared informer and lister for +// Workloads. +type WorkloadInformer interface { + Informer() cache.SharedIndexInformer + Lister() schedulingv1alpha2.WorkloadLister +} + +type workloadInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewWorkloadInformer constructs a new informer for Workload type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewWorkloadInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewWorkloadInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) +} + +// NewFilteredWorkloadInformer constructs a new informer for Workload type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredWorkloadInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return NewWorkloadInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewWorkloadInformerWithOptions constructs a new informer for Workload type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewWorkloadInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1alpha2", Resource: "workloads"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( + cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().Workloads(namespace).List(context.Background(), opts) + }, + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().Workloads(namespace).Watch(context.Background(), opts) + }, + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().Workloads(namespace).List(ctx, opts) + }, + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&opts) + } + return client.SchedulingV1alpha2().Workloads(namespace).Watch(ctx, opts) + }, + }, client), + &apischedulingv1alpha2.Workload{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, + ) +} + +func (f *workloadInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewWorkloadInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) +} + +func (f *workloadInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apischedulingv1alpha2.Workload{}, f.defaultInformer) +} + +func (f *workloadInformer) Lister() schedulingv1alpha2.WorkloadLister { + return schedulingv1alpha2.NewWorkloadLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go index e8057f921a..a5cae3ea56 100644 --- a/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go +++ b/vendor/k8s.io/client-go/informers/scheduling/v1beta1/priorityclass.go @@ -25,6 +25,7 @@ import ( apischedulingv1beta1 "k8s.io/api/scheduling/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type priorityClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, indexers, nil) + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredPriorityClassInformer constructs a new informer for PriorityClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredPriorityClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewPriorityClassInformerWithOptions constructs a new informer for PriorityClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPriorityClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1beta1", Resource: "priorityclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1beta1().PriorityClasses().List(context.Background(), options) + return client.SchedulingV1beta1().PriorityClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1beta1().PriorityClasses().Watch(context.Background(), options) + return client.SchedulingV1beta1().PriorityClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1beta1().PriorityClasses().List(ctx, options) + return client.SchedulingV1beta1().PriorityClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.SchedulingV1beta1().PriorityClasses().Watch(ctx, options) + return client.SchedulingV1beta1().PriorityClasses().Watch(ctx, opts) }, }, client), &apischedulingv1beta1.PriorityClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *priorityClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPriorityClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewPriorityClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *priorityClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go b/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go index 3a1922edaa..56ed349e26 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/csidriver.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type cSIDriverInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSIDriverInformer(client, resyncPeriod, indexers, nil) + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSIDriverInformer constructs a new informer for CSIDriver type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSIDriverInformerWithOptions constructs a new informer for CSIDriver type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIDriverInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csidrivers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIDrivers().List(context.Background(), options) + return client.StorageV1().CSIDrivers().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIDrivers().Watch(context.Background(), options) + return client.StorageV1().CSIDrivers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIDrivers().List(ctx, options) + return client.StorageV1().CSIDrivers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIDrivers().Watch(ctx, options) + return client.StorageV1().CSIDrivers().Watch(ctx, opts) }, }, client), &apistoragev1.CSIDriver{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSIDriverInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSIDriverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSIDriverInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csinode.go b/vendor/k8s.io/client-go/informers/storage/v1/csinode.go index 350ab61e57..c90686bf78 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/csinode.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/csinode.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type cSINodeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSINodeInformer(client, resyncPeriod, indexers, nil) + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSINodeInformer constructs a new informer for CSINode type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSINodeInformerWithOptions constructs a new informer for CSINode type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSINodeInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csinodes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSINodes().List(context.Background(), options) + return client.StorageV1().CSINodes().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSINodes().Watch(context.Background(), options) + return client.StorageV1().CSINodes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSINodes().List(ctx, options) + return client.StorageV1().CSINodes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSINodes().Watch(ctx, options) + return client.StorageV1().CSINodes().Watch(ctx, opts) }, }, client), &apistoragev1.CSINode{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSINodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSINodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSINodeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go index 7c88e6e07b..52c0e281ac 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/csistoragecapacity.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type cSIStorageCapacityInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSIStorageCapacityInformerWithOptions constructs a new informer for CSIStorageCapacity type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csistoragecapacitys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIStorageCapacities(namespace).List(context.Background(), options) + return client.StorageV1().CSIStorageCapacities(namespace).List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIStorageCapacities(namespace).Watch(context.Background(), options) + return client.StorageV1().CSIStorageCapacities(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIStorageCapacities(namespace).List(ctx, options) + return client.StorageV1().CSIStorageCapacities(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().CSIStorageCapacities(namespace).Watch(ctx, options) + return client.StorageV1().CSIStorageCapacities(namespace).Watch(ctx, opts) }, }, client), &apistoragev1.CSIStorageCapacity{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSIStorageCapacityInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go b/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go index 620c1d3489..533d02fc86 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/storageclass.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type storageClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, indexers, nil) + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStorageClassInformer constructs a new informer for StorageClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStorageClassInformerWithOptions constructs a new informer for StorageClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "storageclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().StorageClasses().List(context.Background(), options) + return client.StorageV1().StorageClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().StorageClasses().Watch(context.Background(), options) + return client.StorageV1().StorageClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().StorageClasses().List(ctx, options) + return client.StorageV1().StorageClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().StorageClasses().Watch(ctx, options) + return client.StorageV1().StorageClasses().Watch(ctx, opts) }, }, client), &apistoragev1.StorageClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *storageClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *storageClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go index 3b7c461144..49444340ad 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/volumeattachment.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttachmentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttachmentInformerWithOptions constructs a new informer for VolumeAttachment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "volumeattachments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttachments().List(context.Background(), options) + return client.StorageV1().VolumeAttachments().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttachments().Watch(context.Background(), options) + return client.StorageV1().VolumeAttachments().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttachments().List(ctx, options) + return client.StorageV1().VolumeAttachments().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttachments().Watch(ctx, options) + return client.StorageV1().VolumeAttachments().Watch(ctx, opts) }, }, client), &apistoragev1.VolumeAttachment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1/volumeattributesclass.go b/vendor/k8s.io/client-go/informers/storage/v1/volumeattributesclass.go index 34dc8b48d8..fa8acccfbd 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1/volumeattributesclass.go +++ b/vendor/k8s.io/client-go/informers/storage/v1/volumeattributesclass.go @@ -25,6 +25,7 @@ import ( apistoragev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttributesClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttributesClassInformer constructs a new informer for VolumeAttributesClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttributesClassInformerWithOptions constructs a new informer for VolumeAttributesClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttributesClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "volumeattributesclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttributesClasses().List(context.Background(), options) + return client.StorageV1().VolumeAttributesClasses().List(context.Background(), opts) }, - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttributesClasses().Watch(context.Background(), options) + return client.StorageV1().VolumeAttributesClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttributesClasses().List(ctx, options) + return client.StorageV1().VolumeAttributesClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1().VolumeAttributesClasses().Watch(ctx, options) + return client.StorageV1().VolumeAttributesClasses().Watch(ctx, opts) }, }, client), &apistoragev1.VolumeAttributesClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttributesClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttributesClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go index 3b2753200c..2f7accab3d 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/csistoragecapacity.go @@ -25,6 +25,7 @@ import ( apistoragev1alpha1 "k8s.io/api/storage/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type cSIStorageCapacityInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSIStorageCapacityInformerWithOptions constructs a new informer for CSIStorageCapacity type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1alpha1", Resource: "csistoragecapacitys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().CSIStorageCapacities(namespace).List(context.Background(), options) + return client.StorageV1alpha1().CSIStorageCapacities(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().CSIStorageCapacities(namespace).Watch(context.Background(), options) + return client.StorageV1alpha1().CSIStorageCapacities(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().CSIStorageCapacities(namespace).List(ctx, options) + return client.StorageV1alpha1().CSIStorageCapacities(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().CSIStorageCapacities(namespace).Watch(ctx, options) + return client.StorageV1alpha1().CSIStorageCapacities(namespace).Watch(ctx, opts) }, }, client), &apistoragev1alpha1.CSIStorageCapacity{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSIStorageCapacityInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go index 10ac7e55ed..1ab135906f 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattachment.go @@ -25,6 +25,7 @@ import ( apistoragev1alpha1 "k8s.io/api/storage/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttachmentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttachmentInformerWithOptions constructs a new informer for VolumeAttachment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1alpha1", Resource: "volumeattachments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttachments().List(context.Background(), options) + return client.StorageV1alpha1().VolumeAttachments().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttachments().Watch(context.Background(), options) + return client.StorageV1alpha1().VolumeAttachments().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttachments().List(ctx, options) + return client.StorageV1alpha1().VolumeAttachments().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttachments().Watch(ctx, options) + return client.StorageV1alpha1().VolumeAttachments().Watch(ctx, opts) }, }, client), &apistoragev1alpha1.VolumeAttachment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattributesclass.go b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattributesclass.go index 312a443e34..e649c665ee 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattributesclass.go +++ b/vendor/k8s.io/client-go/informers/storage/v1alpha1/volumeattributesclass.go @@ -25,6 +25,7 @@ import ( apistoragev1alpha1 "k8s.io/api/storage/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttributesClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttributesClassInformer constructs a new informer for VolumeAttributesClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttributesClassInformerWithOptions constructs a new informer for VolumeAttributesClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttributesClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1alpha1", Resource: "volumeattributesclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttributesClasses().List(context.Background(), options) + return client.StorageV1alpha1().VolumeAttributesClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttributesClasses().Watch(context.Background(), options) + return client.StorageV1alpha1().VolumeAttributesClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttributesClasses().List(ctx, options) + return client.StorageV1alpha1().VolumeAttributesClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1alpha1().VolumeAttributesClasses().Watch(ctx, options) + return client.StorageV1alpha1().VolumeAttributesClasses().Watch(ctx, opts) }, }, client), &apistoragev1alpha1.VolumeAttributesClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttributesClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttributesClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go index 007caaab54..283dc6b17c 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csidriver.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type cSIDriverInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSIDriverInformer(client, resyncPeriod, indexers, nil) + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSIDriverInformer constructs a new informer for CSIDriver type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSIDriverInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSIDriverInformerWithOptions constructs a new informer for CSIDriver type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIDriverInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csidrivers"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIDrivers().List(context.Background(), options) + return client.StorageV1beta1().CSIDrivers().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIDrivers().Watch(context.Background(), options) + return client.StorageV1beta1().CSIDrivers().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIDrivers().List(ctx, options) + return client.StorageV1beta1().CSIDrivers().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIDrivers().Watch(ctx, options) + return client.StorageV1beta1().CSIDrivers().Watch(ctx, opts) }, }, client), &apistoragev1beta1.CSIDriver{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSIDriverInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSIDriverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSIDriverInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSIDriverInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go index ce518f0b2e..f304906ce7 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csinode.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type cSINodeInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSINodeInformer(client, resyncPeriod, indexers, nil) + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSINodeInformer constructs a new informer for CSINode type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSINodeInformerWithOptions constructs a new informer for CSINode type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSINodeInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csinodes"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSINodes().List(context.Background(), options) + return client.StorageV1beta1().CSINodes().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSINodes().Watch(context.Background(), options) + return client.StorageV1beta1().CSINodes().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSINodes().List(ctx, options) + return client.StorageV1beta1().CSINodes().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSINodes().Watch(ctx, options) + return client.StorageV1beta1().CSINodes().Watch(ctx, opts) }, }, client), &apistoragev1beta1.CSINode{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSINodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSINodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSINodeInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSINodeInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go index 88446b7695..5b24a8c32b 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/csistoragecapacity.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -49,48 +50,61 @@ type cSIStorageCapacityInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, namespace, resyncPeriod, indexers, nil) + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredCSIStorageCapacityInformer constructs a new informer for CSIStorageCapacity type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredCSIStorageCapacityInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewCSIStorageCapacityInformerWithOptions(client, namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewCSIStorageCapacityInformerWithOptions constructs a new informer for CSIStorageCapacity type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCSIStorageCapacityInformerWithOptions(client kubernetes.Interface, namespace string, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csistoragecapacitys"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIStorageCapacities(namespace).List(context.Background(), options) + return client.StorageV1beta1().CSIStorageCapacities(namespace).List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIStorageCapacities(namespace).Watch(context.Background(), options) + return client.StorageV1beta1().CSIStorageCapacities(namespace).Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIStorageCapacities(namespace).List(ctx, options) + return client.StorageV1beta1().CSIStorageCapacities(namespace).List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().CSIStorageCapacities(namespace).Watch(ctx, options) + return client.StorageV1beta1().CSIStorageCapacities(namespace).Watch(ctx, opts) }, }, client), &apistoragev1beta1.CSIStorageCapacity{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *cSIStorageCapacityInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredCSIStorageCapacityInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewCSIStorageCapacityInformerWithOptions(client, f.namespace, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *cSIStorageCapacityInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go index 786d46d3a4..2052da70e9 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/storageclass.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type storageClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, indexers, nil) + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStorageClassInformer constructs a new informer for StorageClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStorageClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStorageClassInformerWithOptions constructs a new informer for StorageClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "storageclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().StorageClasses().List(context.Background(), options) + return client.StorageV1beta1().StorageClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().StorageClasses().Watch(context.Background(), options) + return client.StorageV1beta1().StorageClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().StorageClasses().List(ctx, options) + return client.StorageV1beta1().StorageClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().StorageClasses().Watch(ctx, options) + return client.StorageV1beta1().StorageClasses().Watch(ctx, opts) }, }, client), &apistoragev1beta1.StorageClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *storageClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStorageClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *storageClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go index 0f1bf21613..11f9840b04 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattachment.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttachmentInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttachmentInformer constructs a new informer for VolumeAttachment type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttachmentInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttachmentInformerWithOptions constructs a new informer for VolumeAttachment type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttachmentInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "volumeattachments"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttachments().List(context.Background(), options) + return client.StorageV1beta1().VolumeAttachments().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttachments().Watch(context.Background(), options) + return client.StorageV1beta1().VolumeAttachments().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttachments().List(ctx, options) + return client.StorageV1beta1().VolumeAttachments().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttachments().Watch(ctx, options) + return client.StorageV1beta1().VolumeAttachments().Watch(ctx, opts) }, }, client), &apistoragev1beta1.VolumeAttachment{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttachmentInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttachmentInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttachmentInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttachmentInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattributesclass.go b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattributesclass.go index 90e79cc710..c91dfff0d1 100644 --- a/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattributesclass.go +++ b/vendor/k8s.io/client-go/informers/storage/v1beta1/volumeattributesclass.go @@ -25,6 +25,7 @@ import ( apistoragev1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type volumeAttributesClassInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, indexers, nil) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredVolumeAttributesClassInformer constructs a new informer for VolumeAttributesClass type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredVolumeAttributesClassInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewVolumeAttributesClassInformerWithOptions constructs a new informer for VolumeAttributesClass type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewVolumeAttributesClassInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "volumeattributesclasss"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttributesClasses().List(context.Background(), options) + return client.StorageV1beta1().VolumeAttributesClasses().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttributesClasses().Watch(context.Background(), options) + return client.StorageV1beta1().VolumeAttributesClasses().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttributesClasses().List(ctx, options) + return client.StorageV1beta1().VolumeAttributesClasses().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StorageV1beta1().VolumeAttributesClasses().Watch(ctx, options) + return client.StorageV1beta1().VolumeAttributesClasses().Watch(ctx, opts) }, }, client), &apistoragev1beta1.VolumeAttributesClass{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *volumeAttributesClassInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredVolumeAttributesClassInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewVolumeAttributesClassInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *volumeAttributesClassInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/informers/storagemigration/v1beta1/storageversionmigration.go b/vendor/k8s.io/client-go/informers/storagemigration/v1beta1/storageversionmigration.go index 370d88f242..50e271e6fe 100644 --- a/vendor/k8s.io/client-go/informers/storagemigration/v1beta1/storageversionmigration.go +++ b/vendor/k8s.io/client-go/informers/storagemigration/v1beta1/storageversionmigration.go @@ -25,6 +25,7 @@ import ( apistoragemigrationv1beta1 "k8s.io/api/storagemigration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" @@ -48,48 +49,61 @@ type storageVersionMigrationInformer struct { // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewStorageVersionMigrationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredStorageVersionMigrationInformer(client, resyncPeriod, indexers, nil) + return NewStorageVersionMigrationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers}) } // NewFilteredStorageVersionMigrationInformer constructs a new informer for StorageVersionMigration type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFilteredStorageVersionMigrationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( + return NewStorageVersionMigrationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} + +// NewStorageVersionMigrationInformerWithOptions constructs a new informer for StorageVersionMigration type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStorageVersionMigrationInformerWithOptions(client kubernetes.Interface, options internalinterfaces.InformerOptions) cache.SharedIndexInformer { + gvr := schema.GroupVersionResource{Group: "storagemigration.k8s.io", Version: "v1beta1", Resource: "storageversionmigrations"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return cache.NewSharedIndexInformerWithOptions( cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + ListFunc: func(opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StoragemigrationV1beta1().StorageVersionMigrations().List(context.Background(), options) + return client.StoragemigrationV1beta1().StorageVersionMigrations().List(context.Background(), opts) }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + WatchFunc: func(opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StoragemigrationV1beta1().StorageVersionMigrations().Watch(context.Background(), options) + return client.StoragemigrationV1beta1().StorageVersionMigrations().Watch(context.Background(), opts) }, - ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + ListWithContextFunc: func(ctx context.Context, opts v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StoragemigrationV1beta1().StorageVersionMigrations().List(ctx, options) + return client.StoragemigrationV1beta1().StorageVersionMigrations().List(ctx, opts) }, - WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + WatchFuncWithContext: func(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.StoragemigrationV1beta1().StorageVersionMigrations().Watch(ctx, options) + return client.StoragemigrationV1beta1().StorageVersionMigrations().Watch(ctx, opts) }, }, client), &apistoragemigrationv1beta1.StorageVersionMigration{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } func (f *storageVersionMigrationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredStorageVersionMigrationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewStorageVersionMigrationInformerWithOptions(client, internalinterfaces.InformerOptions{ResyncPeriod: resyncPeriod, Indexers: cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } func (f *storageVersionMigrationInformer) Informer() cache.SharedIndexInformer { diff --git a/vendor/k8s.io/client-go/kubernetes/clientset.go b/vendor/k8s.io/client-go/kubernetes/clientset.go index 1ef0ff4b2c..537609b718 100644 --- a/vendor/k8s.io/client-go/kubernetes/clientset.go +++ b/vendor/k8s.io/client-go/kubernetes/clientset.go @@ -37,8 +37,6 @@ import ( authorizationv1beta1 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1" autoscalingv1 "k8s.io/client-go/kubernetes/typed/autoscaling/v1" autoscalingv2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2" - autoscalingv2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" - autoscalingv2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" batchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" batchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" certificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1" @@ -72,7 +70,7 @@ import ( resourcev1beta1 "k8s.io/client-go/kubernetes/typed/resource/v1beta1" resourcev1beta2 "k8s.io/client-go/kubernetes/typed/resource/v1beta2" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" - schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2" schedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" storagev1 "k8s.io/client-go/kubernetes/typed/storage/v1" storagev1alpha1 "k8s.io/client-go/kubernetes/typed/storage/v1alpha1" @@ -98,8 +96,6 @@ type Interface interface { AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface AutoscalingV1() autoscalingv1.AutoscalingV1Interface AutoscalingV2() autoscalingv2.AutoscalingV2Interface - AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface - AutoscalingV2beta2() autoscalingv2beta2.AutoscalingV2beta2Interface BatchV1() batchv1.BatchV1Interface BatchV1beta1() batchv1beta1.BatchV1beta1Interface CertificatesV1() certificatesv1.CertificatesV1Interface @@ -132,7 +128,7 @@ type Interface interface { ResourceV1beta2() resourcev1beta2.ResourceV1beta2Interface ResourceV1beta1() resourcev1beta1.ResourceV1beta1Interface ResourceV1alpha3() resourcev1alpha3.ResourceV1alpha3Interface - SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface + SchedulingV1alpha2() schedulingv1alpha2.SchedulingV1alpha2Interface SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface SchedulingV1() schedulingv1.SchedulingV1Interface StorageV1beta1() storagev1beta1.StorageV1beta1Interface @@ -158,8 +154,6 @@ type Clientset struct { authorizationV1beta1 *authorizationv1beta1.AuthorizationV1beta1Client autoscalingV1 *autoscalingv1.AutoscalingV1Client autoscalingV2 *autoscalingv2.AutoscalingV2Client - autoscalingV2beta1 *autoscalingv2beta1.AutoscalingV2beta1Client - autoscalingV2beta2 *autoscalingv2beta2.AutoscalingV2beta2Client batchV1 *batchv1.BatchV1Client batchV1beta1 *batchv1beta1.BatchV1beta1Client certificatesV1 *certificatesv1.CertificatesV1Client @@ -192,7 +186,7 @@ type Clientset struct { resourceV1beta2 *resourcev1beta2.ResourceV1beta2Client resourceV1beta1 *resourcev1beta1.ResourceV1beta1Client resourceV1alpha3 *resourcev1alpha3.ResourceV1alpha3Client - schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client + schedulingV1alpha2 *schedulingv1alpha2.SchedulingV1alpha2Client schedulingV1beta1 *schedulingv1beta1.SchedulingV1beta1Client schedulingV1 *schedulingv1.SchedulingV1Client storageV1beta1 *storagev1beta1.StorageV1beta1Client @@ -271,16 +265,6 @@ func (c *Clientset) AutoscalingV2() autoscalingv2.AutoscalingV2Interface { return c.autoscalingV2 } -// AutoscalingV2beta1 retrieves the AutoscalingV2beta1Client -func (c *Clientset) AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface { - return c.autoscalingV2beta1 -} - -// AutoscalingV2beta2 retrieves the AutoscalingV2beta2Client -func (c *Clientset) AutoscalingV2beta2() autoscalingv2beta2.AutoscalingV2beta2Interface { - return c.autoscalingV2beta2 -} - // BatchV1 retrieves the BatchV1Client func (c *Clientset) BatchV1() batchv1.BatchV1Interface { return c.batchV1 @@ -441,9 +425,9 @@ func (c *Clientset) ResourceV1alpha3() resourcev1alpha3.ResourceV1alpha3Interfac return c.resourceV1alpha3 } -// SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client -func (c *Clientset) SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface { - return c.schedulingV1alpha1 +// SchedulingV1alpha2 retrieves the SchedulingV1alpha2Client +func (c *Clientset) SchedulingV1alpha2() schedulingv1alpha2.SchedulingV1alpha2Interface { + return c.schedulingV1alpha2 } // SchedulingV1beta1 retrieves the SchedulingV1beta1Client @@ -576,14 +560,6 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } - cs.autoscalingV2beta1, err = autoscalingv2beta1.NewForConfigAndClient(&configShallowCopy, httpClient) - if err != nil { - return nil, err - } - cs.autoscalingV2beta2, err = autoscalingv2beta2.NewForConfigAndClient(&configShallowCopy, httpClient) - if err != nil { - return nil, err - } cs.batchV1, err = batchv1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -712,7 +688,7 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } - cs.schedulingV1alpha1, err = schedulingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.schedulingV1alpha2, err = schedulingv1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } @@ -775,8 +751,6 @@ func New(c rest.Interface) *Clientset { cs.authorizationV1beta1 = authorizationv1beta1.New(c) cs.autoscalingV1 = autoscalingv1.New(c) cs.autoscalingV2 = autoscalingv2.New(c) - cs.autoscalingV2beta1 = autoscalingv2beta1.New(c) - cs.autoscalingV2beta2 = autoscalingv2beta2.New(c) cs.batchV1 = batchv1.New(c) cs.batchV1beta1 = batchv1beta1.New(c) cs.certificatesV1 = certificatesv1.New(c) @@ -809,7 +783,7 @@ func New(c rest.Interface) *Clientset { cs.resourceV1beta2 = resourcev1beta2.New(c) cs.resourceV1beta1 = resourcev1beta1.New(c) cs.resourceV1alpha3 = resourcev1alpha3.New(c) - cs.schedulingV1alpha1 = schedulingv1alpha1.New(c) + cs.schedulingV1alpha2 = schedulingv1alpha2.New(c) cs.schedulingV1beta1 = schedulingv1beta1.New(c) cs.schedulingV1 = schedulingv1.New(c) cs.storageV1beta1 = storagev1beta1.New(c) diff --git a/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go b/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go index f729718bfb..618dd57511 100644 --- a/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go +++ b/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go @@ -54,10 +54,6 @@ import ( fakeautoscalingv1 "k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake" autoscalingv2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2" fakeautoscalingv2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake" - autoscalingv2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" - fakeautoscalingv2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake" - autoscalingv2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" - fakeautoscalingv2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake" batchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" fakebatchv1 "k8s.io/client-go/kubernetes/typed/batch/v1/fake" batchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" @@ -124,8 +120,8 @@ import ( fakeresourcev1beta2 "k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" fakeschedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1/fake" - schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" - fakeschedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake" + schedulingv1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2" + fakeschedulingv1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake" schedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" fakeschedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake" storagev1 "k8s.io/client-go/kubernetes/typed/storage/v1" @@ -143,10 +139,6 @@ import ( // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -192,7 +184,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional @@ -207,6 +199,10 @@ func (c *Clientset) IsWatchListSemanticsUnSupported() bool { // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, @@ -314,16 +310,6 @@ func (c *Clientset) AutoscalingV2() autoscalingv2.AutoscalingV2Interface { return &fakeautoscalingv2.FakeAutoscalingV2{Fake: &c.Fake} } -// AutoscalingV2beta1 retrieves the AutoscalingV2beta1Client -func (c *Clientset) AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface { - return &fakeautoscalingv2beta1.FakeAutoscalingV2beta1{Fake: &c.Fake} -} - -// AutoscalingV2beta2 retrieves the AutoscalingV2beta2Client -func (c *Clientset) AutoscalingV2beta2() autoscalingv2beta2.AutoscalingV2beta2Interface { - return &fakeautoscalingv2beta2.FakeAutoscalingV2beta2{Fake: &c.Fake} -} - // BatchV1 retrieves the BatchV1Client func (c *Clientset) BatchV1() batchv1.BatchV1Interface { return &fakebatchv1.FakeBatchV1{Fake: &c.Fake} @@ -484,9 +470,9 @@ func (c *Clientset) ResourceV1alpha3() resourcev1alpha3.ResourceV1alpha3Interfac return &fakeresourcev1alpha3.FakeResourceV1alpha3{Fake: &c.Fake} } -// SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client -func (c *Clientset) SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface { - return &fakeschedulingv1alpha1.FakeSchedulingV1alpha1{Fake: &c.Fake} +// SchedulingV1alpha2 retrieves the SchedulingV1alpha2Client +func (c *Clientset) SchedulingV1alpha2() schedulingv1alpha2.SchedulingV1alpha2Interface { + return &fakeschedulingv1alpha2.FakeSchedulingV1alpha2{Fake: &c.Fake} } // SchedulingV1beta1 retrieves the SchedulingV1beta1Client diff --git a/vendor/k8s.io/client-go/kubernetes/fake/register.go b/vendor/k8s.io/client-go/kubernetes/fake/register.go index 7a2bacfb57..3b5d98c6a8 100644 --- a/vendor/k8s.io/client-go/kubernetes/fake/register.go +++ b/vendor/k8s.io/client-go/kubernetes/fake/register.go @@ -33,8 +33,6 @@ import ( authorizationv1beta1 "k8s.io/api/authorization/v1beta1" autoscalingv1 "k8s.io/api/autoscaling/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" @@ -68,7 +66,7 @@ import ( resourcev1beta1 "k8s.io/api/resource/v1beta1" resourcev1beta2 "k8s.io/api/resource/v1beta2" schedulingv1 "k8s.io/api/scheduling/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" storagev1 "k8s.io/api/storage/v1" storagev1alpha1 "k8s.io/api/storage/v1alpha1" @@ -99,8 +97,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{ authorizationv1beta1.AddToScheme, autoscalingv1.AddToScheme, autoscalingv2.AddToScheme, - autoscalingv2beta1.AddToScheme, - autoscalingv2beta2.AddToScheme, batchv1.AddToScheme, batchv1beta1.AddToScheme, certificatesv1.AddToScheme, @@ -133,7 +129,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ resourcev1beta2.AddToScheme, resourcev1beta1.AddToScheme, resourcev1alpha3.AddToScheme, - schedulingv1alpha1.AddToScheme, + schedulingv1alpha2.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, storagev1beta1.AddToScheme, diff --git a/vendor/k8s.io/client-go/kubernetes/scheme/register.go b/vendor/k8s.io/client-go/kubernetes/scheme/register.go index 9557cba2b4..c36fe7eda4 100644 --- a/vendor/k8s.io/client-go/kubernetes/scheme/register.go +++ b/vendor/k8s.io/client-go/kubernetes/scheme/register.go @@ -33,8 +33,6 @@ import ( authorizationv1beta1 "k8s.io/api/authorization/v1beta1" autoscalingv1 "k8s.io/api/autoscaling/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" @@ -68,7 +66,7 @@ import ( resourcev1beta1 "k8s.io/api/resource/v1beta1" resourcev1beta2 "k8s.io/api/resource/v1beta2" schedulingv1 "k8s.io/api/scheduling/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" storagev1 "k8s.io/api/storage/v1" storagev1alpha1 "k8s.io/api/storage/v1alpha1" @@ -99,8 +97,6 @@ var localSchemeBuilder = runtime.SchemeBuilder{ authorizationv1beta1.AddToScheme, autoscalingv1.AddToScheme, autoscalingv2.AddToScheme, - autoscalingv2beta1.AddToScheme, - autoscalingv2beta2.AddToScheme, batchv1.AddToScheme, batchv1beta1.AddToScheme, certificatesv1.AddToScheme, @@ -133,7 +129,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ resourcev1beta2.AddToScheme, resourcev1beta1.AddToScheme, resourcev1alpha3.AddToScheme, - schedulingv1alpha1.AddToScheme, + schedulingv1alpha2.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, storagev1beta1.AddToScheme, diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/admissionregistration_client.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/admissionregistration_client.go index 859ad913b9..e09930b7ce 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/admissionregistration_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/admissionregistration_client.go @@ -28,6 +28,8 @@ import ( type AdmissionregistrationV1Interface interface { RESTClient() rest.Interface + MutatingAdmissionPoliciesGetter + MutatingAdmissionPolicyBindingsGetter MutatingWebhookConfigurationsGetter ValidatingAdmissionPoliciesGetter ValidatingAdmissionPolicyBindingsGetter @@ -39,6 +41,14 @@ type AdmissionregistrationV1Client struct { restClient rest.Interface } +func (c *AdmissionregistrationV1Client) MutatingAdmissionPolicies() MutatingAdmissionPolicyInterface { + return newMutatingAdmissionPolicies(c) +} + +func (c *AdmissionregistrationV1Client) MutatingAdmissionPolicyBindings() MutatingAdmissionPolicyBindingInterface { + return newMutatingAdmissionPolicyBindings(c) +} + func (c *AdmissionregistrationV1Client) MutatingWebhookConfigurations() MutatingWebhookConfigurationInterface { return newMutatingWebhookConfigurations(c) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_admissionregistration_client.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_admissionregistration_client.go index 1a948ad93d..fbe72e9e54 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_admissionregistration_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_admissionregistration_client.go @@ -28,6 +28,14 @@ type FakeAdmissionregistrationV1 struct { *testing.Fake } +func (c *FakeAdmissionregistrationV1) MutatingAdmissionPolicies() v1.MutatingAdmissionPolicyInterface { + return newFakeMutatingAdmissionPolicies(c) +} + +func (c *FakeAdmissionregistrationV1) MutatingAdmissionPolicyBindings() v1.MutatingAdmissionPolicyBindingInterface { + return newFakeMutatingAdmissionPolicyBindings(c) +} + func (c *FakeAdmissionregistrationV1) MutatingWebhookConfigurations() v1.MutatingWebhookConfigurationInterface { return newFakeMutatingWebhookConfigurations(c) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicy.go new file mode 100644 index 0000000000..80e703b1cd --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicy.go @@ -0,0 +1,53 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/api/admissionregistration/v1" + admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + gentype "k8s.io/client-go/gentype" + typedadmissionregistrationv1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" +) + +// fakeMutatingAdmissionPolicies implements MutatingAdmissionPolicyInterface +type fakeMutatingAdmissionPolicies struct { + *gentype.FakeClientWithListAndApply[*v1.MutatingAdmissionPolicy, *v1.MutatingAdmissionPolicyList, *admissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration] + Fake *FakeAdmissionregistrationV1 +} + +func newFakeMutatingAdmissionPolicies(fake *FakeAdmissionregistrationV1) typedadmissionregistrationv1.MutatingAdmissionPolicyInterface { + return &fakeMutatingAdmissionPolicies{ + gentype.NewFakeClientWithListAndApply[*v1.MutatingAdmissionPolicy, *v1.MutatingAdmissionPolicyList, *admissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration]( + fake.Fake, + "", + v1.SchemeGroupVersion.WithResource("mutatingadmissionpolicies"), + v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicy"), + func() *v1.MutatingAdmissionPolicy { return &v1.MutatingAdmissionPolicy{} }, + func() *v1.MutatingAdmissionPolicyList { return &v1.MutatingAdmissionPolicyList{} }, + func(dst, src *v1.MutatingAdmissionPolicyList) { dst.ListMeta = src.ListMeta }, + func(list *v1.MutatingAdmissionPolicyList) []*v1.MutatingAdmissionPolicy { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1.MutatingAdmissionPolicyList, items []*v1.MutatingAdmissionPolicy) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicybinding.go new file mode 100644 index 0000000000..eba7c8406e --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingadmissionpolicybinding.go @@ -0,0 +1,53 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/api/admissionregistration/v1" + admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + gentype "k8s.io/client-go/gentype" + typedadmissionregistrationv1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" +) + +// fakeMutatingAdmissionPolicyBindings implements MutatingAdmissionPolicyBindingInterface +type fakeMutatingAdmissionPolicyBindings struct { + *gentype.FakeClientWithListAndApply[*v1.MutatingAdmissionPolicyBinding, *v1.MutatingAdmissionPolicyBindingList, *admissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration] + Fake *FakeAdmissionregistrationV1 +} + +func newFakeMutatingAdmissionPolicyBindings(fake *FakeAdmissionregistrationV1) typedadmissionregistrationv1.MutatingAdmissionPolicyBindingInterface { + return &fakeMutatingAdmissionPolicyBindings{ + gentype.NewFakeClientWithListAndApply[*v1.MutatingAdmissionPolicyBinding, *v1.MutatingAdmissionPolicyBindingList, *admissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration]( + fake.Fake, + "", + v1.SchemeGroupVersion.WithResource("mutatingadmissionpolicybindings"), + v1.SchemeGroupVersion.WithKind("MutatingAdmissionPolicyBinding"), + func() *v1.MutatingAdmissionPolicyBinding { return &v1.MutatingAdmissionPolicyBinding{} }, + func() *v1.MutatingAdmissionPolicyBindingList { return &v1.MutatingAdmissionPolicyBindingList{} }, + func(dst, src *v1.MutatingAdmissionPolicyBindingList) { dst.ListMeta = src.ListMeta }, + func(list *v1.MutatingAdmissionPolicyBindingList) []*v1.MutatingAdmissionPolicyBinding { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1.MutatingAdmissionPolicyBindingList, items []*v1.MutatingAdmissionPolicyBinding) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/generated_expansion.go index d81e1c87fc..c449e9b7d7 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/generated_expansion.go @@ -18,6 +18,10 @@ limitations under the License. package v1 +type MutatingAdmissionPolicyExpansion interface{} + +type MutatingAdmissionPolicyBindingExpansion interface{} + type MutatingWebhookConfigurationExpansion interface{} type ValidatingAdmissionPolicyExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicy.go new file mode 100644 index 0000000000..d0e85396cc --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicy.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + context "context" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsadmissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + gentype "k8s.io/client-go/gentype" + scheme "k8s.io/client-go/kubernetes/scheme" +) + +// MutatingAdmissionPoliciesGetter has a method to return a MutatingAdmissionPolicyInterface. +// A group's client should implement this interface. +type MutatingAdmissionPoliciesGetter interface { + MutatingAdmissionPolicies() MutatingAdmissionPolicyInterface +} + +// MutatingAdmissionPolicyInterface has methods to work with MutatingAdmissionPolicy resources. +type MutatingAdmissionPolicyInterface interface { + Create(ctx context.Context, mutatingAdmissionPolicy *admissionregistrationv1.MutatingAdmissionPolicy, opts metav1.CreateOptions) (*admissionregistrationv1.MutatingAdmissionPolicy, error) + Update(ctx context.Context, mutatingAdmissionPolicy *admissionregistrationv1.MutatingAdmissionPolicy, opts metav1.UpdateOptions) (*admissionregistrationv1.MutatingAdmissionPolicy, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*admissionregistrationv1.MutatingAdmissionPolicy, error) + List(ctx context.Context, opts metav1.ListOptions) (*admissionregistrationv1.MutatingAdmissionPolicyList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *admissionregistrationv1.MutatingAdmissionPolicy, err error) + Apply(ctx context.Context, mutatingAdmissionPolicy *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *admissionregistrationv1.MutatingAdmissionPolicy, err error) + MutatingAdmissionPolicyExpansion +} + +// mutatingAdmissionPolicies implements MutatingAdmissionPolicyInterface +type mutatingAdmissionPolicies struct { + *gentype.ClientWithListAndApply[*admissionregistrationv1.MutatingAdmissionPolicy, *admissionregistrationv1.MutatingAdmissionPolicyList, *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration] +} + +// newMutatingAdmissionPolicies returns a MutatingAdmissionPolicies +func newMutatingAdmissionPolicies(c *AdmissionregistrationV1Client) *mutatingAdmissionPolicies { + return &mutatingAdmissionPolicies{ + gentype.NewClientWithListAndApply[*admissionregistrationv1.MutatingAdmissionPolicy, *admissionregistrationv1.MutatingAdmissionPolicyList, *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyApplyConfiguration]( + "mutatingadmissionpolicies", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *admissionregistrationv1.MutatingAdmissionPolicy { + return &admissionregistrationv1.MutatingAdmissionPolicy{} + }, + func() *admissionregistrationv1.MutatingAdmissionPolicyList { + return &admissionregistrationv1.MutatingAdmissionPolicyList{} + }, + gentype.PrefersProtobuf[*admissionregistrationv1.MutatingAdmissionPolicy](), + ), + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicybinding.go new file mode 100644 index 0000000000..67b4aa9a6b --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/mutatingadmissionpolicybinding.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + context "context" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsadmissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + gentype "k8s.io/client-go/gentype" + scheme "k8s.io/client-go/kubernetes/scheme" +) + +// MutatingAdmissionPolicyBindingsGetter has a method to return a MutatingAdmissionPolicyBindingInterface. +// A group's client should implement this interface. +type MutatingAdmissionPolicyBindingsGetter interface { + MutatingAdmissionPolicyBindings() MutatingAdmissionPolicyBindingInterface +} + +// MutatingAdmissionPolicyBindingInterface has methods to work with MutatingAdmissionPolicyBinding resources. +type MutatingAdmissionPolicyBindingInterface interface { + Create(ctx context.Context, mutatingAdmissionPolicyBinding *admissionregistrationv1.MutatingAdmissionPolicyBinding, opts metav1.CreateOptions) (*admissionregistrationv1.MutatingAdmissionPolicyBinding, error) + Update(ctx context.Context, mutatingAdmissionPolicyBinding *admissionregistrationv1.MutatingAdmissionPolicyBinding, opts metav1.UpdateOptions) (*admissionregistrationv1.MutatingAdmissionPolicyBinding, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*admissionregistrationv1.MutatingAdmissionPolicyBinding, error) + List(ctx context.Context, opts metav1.ListOptions) (*admissionregistrationv1.MutatingAdmissionPolicyBindingList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *admissionregistrationv1.MutatingAdmissionPolicyBinding, err error) + Apply(ctx context.Context, mutatingAdmissionPolicyBinding *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration, opts metav1.ApplyOptions) (result *admissionregistrationv1.MutatingAdmissionPolicyBinding, err error) + MutatingAdmissionPolicyBindingExpansion +} + +// mutatingAdmissionPolicyBindings implements MutatingAdmissionPolicyBindingInterface +type mutatingAdmissionPolicyBindings struct { + *gentype.ClientWithListAndApply[*admissionregistrationv1.MutatingAdmissionPolicyBinding, *admissionregistrationv1.MutatingAdmissionPolicyBindingList, *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration] +} + +// newMutatingAdmissionPolicyBindings returns a MutatingAdmissionPolicyBindings +func newMutatingAdmissionPolicyBindings(c *AdmissionregistrationV1Client) *mutatingAdmissionPolicyBindings { + return &mutatingAdmissionPolicyBindings{ + gentype.NewClientWithListAndApply[*admissionregistrationv1.MutatingAdmissionPolicyBinding, *admissionregistrationv1.MutatingAdmissionPolicyBindingList, *applyconfigurationsadmissionregistrationv1.MutatingAdmissionPolicyBindingApplyConfiguration]( + "mutatingadmissionpolicybindings", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *admissionregistrationv1.MutatingAdmissionPolicyBinding { + return &admissionregistrationv1.MutatingAdmissionPolicyBinding{} + }, + func() *admissionregistrationv1.MutatingAdmissionPolicyBindingList { + return &admissionregistrationv1.MutatingAdmissionPolicyBindingList{} + }, + gentype.PrefersProtobuf[*admissionregistrationv1.MutatingAdmissionPolicyBinding](), + ), + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/autoscaling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/autoscaling_client.go deleted file mode 100644 index 25e38f371d..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/autoscaling_client.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v2beta1 - -import ( - http "net/http" - - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -type AutoscalingV2beta1Interface interface { - RESTClient() rest.Interface - HorizontalPodAutoscalersGetter -} - -// AutoscalingV2beta1Client is used to interact with features provided by the autoscaling group. -type AutoscalingV2beta1Client struct { - restClient rest.Interface -} - -func (c *AutoscalingV2beta1Client) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface { - return newHorizontalPodAutoscalers(c, namespace) -} - -// NewForConfig creates a new AutoscalingV2beta1Client for the given config. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*AutoscalingV2beta1Client, error) { - config := *c - setConfigDefaults(&config) - httpClient, err := rest.HTTPClientFor(&config) - if err != nil { - return nil, err - } - return NewForConfigAndClient(&config, httpClient) -} - -// NewForConfigAndClient creates a new AutoscalingV2beta1Client for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AutoscalingV2beta1Client, error) { - config := *c - setConfigDefaults(&config) - client, err := rest.RESTClientForConfigAndClient(&config, h) - if err != nil { - return nil, err - } - return &AutoscalingV2beta1Client{client}, nil -} - -// NewForConfigOrDie creates a new AutoscalingV2beta1Client for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *AutoscalingV2beta1Client { - client, err := NewForConfig(c) - if err != nil { - panic(err) - } - return client -} - -// New creates a new AutoscalingV2beta1Client for the given RESTClient. -func New(c rest.Interface) *AutoscalingV2beta1Client { - return &AutoscalingV2beta1Client{c} -} - -func setConfigDefaults(config *rest.Config) { - gv := autoscalingv2beta1.SchemeGroupVersion - config.GroupVersion = &gv - config.APIPath = "/apis" - config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() - - if config.UserAgent == "" { - config.UserAgent = rest.DefaultKubernetesUserAgent() - } -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *AutoscalingV2beta1Client) RESTClient() rest.Interface { - if c == nil { - return nil - } - return c.restClient -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_autoscaling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_autoscaling_client.go deleted file mode 100644 index ca4b461c2e..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_autoscaling_client.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" - rest "k8s.io/client-go/rest" - testing "k8s.io/client-go/testing" -) - -type FakeAutoscalingV2beta1 struct { - *testing.Fake -} - -func (c *FakeAutoscalingV2beta1) HorizontalPodAutoscalers(namespace string) v2beta1.HorizontalPodAutoscalerInterface { - return newFakeHorizontalPodAutoscalers(c, namespace) -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *FakeAutoscalingV2beta1) RESTClient() rest.Interface { - var ret *rest.RESTClient - return ret -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go deleted file mode 100644 index 8f28fb30c4..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v2beta1 "k8s.io/api/autoscaling/v2beta1" - autoscalingv2beta1 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1" - gentype "k8s.io/client-go/gentype" - typedautoscalingv2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" -) - -// fakeHorizontalPodAutoscalers implements HorizontalPodAutoscalerInterface -type fakeHorizontalPodAutoscalers struct { - *gentype.FakeClientWithListAndApply[*v2beta1.HorizontalPodAutoscaler, *v2beta1.HorizontalPodAutoscalerList, *autoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration] - Fake *FakeAutoscalingV2beta1 -} - -func newFakeHorizontalPodAutoscalers(fake *FakeAutoscalingV2beta1, namespace string) typedautoscalingv2beta1.HorizontalPodAutoscalerInterface { - return &fakeHorizontalPodAutoscalers{ - gentype.NewFakeClientWithListAndApply[*v2beta1.HorizontalPodAutoscaler, *v2beta1.HorizontalPodAutoscalerList, *autoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration]( - fake.Fake, - namespace, - v2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers"), - v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler"), - func() *v2beta1.HorizontalPodAutoscaler { return &v2beta1.HorizontalPodAutoscaler{} }, - func() *v2beta1.HorizontalPodAutoscalerList { return &v2beta1.HorizontalPodAutoscalerList{} }, - func(dst, src *v2beta1.HorizontalPodAutoscalerList) { dst.ListMeta = src.ListMeta }, - func(list *v2beta1.HorizontalPodAutoscalerList) []*v2beta1.HorizontalPodAutoscaler { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v2beta1.HorizontalPodAutoscalerList, items []*v2beta1.HorizontalPodAutoscaler) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/horizontalpodautoscaler.go deleted file mode 100644 index c1dc75ccc3..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/horizontalpodautoscaler.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v2beta1 - -import ( - context "context" - - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsautoscalingv2beta1 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1" - gentype "k8s.io/client-go/gentype" - scheme "k8s.io/client-go/kubernetes/scheme" -) - -// HorizontalPodAutoscalersGetter has a method to return a HorizontalPodAutoscalerInterface. -// A group's client should implement this interface. -type HorizontalPodAutoscalersGetter interface { - HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface -} - -// HorizontalPodAutoscalerInterface has methods to work with HorizontalPodAutoscaler resources. -type HorizontalPodAutoscalerInterface interface { - Create(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, opts v1.CreateOptions) (*autoscalingv2beta1.HorizontalPodAutoscaler, error) - Update(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, opts v1.UpdateOptions) (*autoscalingv2beta1.HorizontalPodAutoscaler, error) - // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta1.HorizontalPodAutoscaler, opts v1.UpdateOptions) (*autoscalingv2beta1.HorizontalPodAutoscaler, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*autoscalingv2beta1.HorizontalPodAutoscaler, error) - List(ctx context.Context, opts v1.ListOptions) (*autoscalingv2beta1.HorizontalPodAutoscalerList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *autoscalingv2beta1.HorizontalPodAutoscaler, err error) - Apply(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv2beta1.HorizontalPodAutoscaler, err error) - // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). - ApplyStatus(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv2beta1.HorizontalPodAutoscaler, err error) - HorizontalPodAutoscalerExpansion -} - -// horizontalPodAutoscalers implements HorizontalPodAutoscalerInterface -type horizontalPodAutoscalers struct { - *gentype.ClientWithListAndApply[*autoscalingv2beta1.HorizontalPodAutoscaler, *autoscalingv2beta1.HorizontalPodAutoscalerList, *applyconfigurationsautoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration] -} - -// newHorizontalPodAutoscalers returns a HorizontalPodAutoscalers -func newHorizontalPodAutoscalers(c *AutoscalingV2beta1Client, namespace string) *horizontalPodAutoscalers { - return &horizontalPodAutoscalers{ - gentype.NewClientWithListAndApply[*autoscalingv2beta1.HorizontalPodAutoscaler, *autoscalingv2beta1.HorizontalPodAutoscalerList, *applyconfigurationsautoscalingv2beta1.HorizontalPodAutoscalerApplyConfiguration]( - "horizontalpodautoscalers", - c.RESTClient(), - scheme.ParameterCodec, - namespace, - func() *autoscalingv2beta1.HorizontalPodAutoscaler { - return &autoscalingv2beta1.HorizontalPodAutoscaler{} - }, - func() *autoscalingv2beta1.HorizontalPodAutoscalerList { - return &autoscalingv2beta1.HorizontalPodAutoscalerList{} - }, - gentype.PrefersProtobuf[*autoscalingv2beta1.HorizontalPodAutoscaler](), - ), - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/autoscaling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/autoscaling_client.go deleted file mode 100644 index 21626e5ce7..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/autoscaling_client.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v2beta2 - -import ( - http "net/http" - - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -type AutoscalingV2beta2Interface interface { - RESTClient() rest.Interface - HorizontalPodAutoscalersGetter -} - -// AutoscalingV2beta2Client is used to interact with features provided by the autoscaling group. -type AutoscalingV2beta2Client struct { - restClient rest.Interface -} - -func (c *AutoscalingV2beta2Client) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface { - return newHorizontalPodAutoscalers(c, namespace) -} - -// NewForConfig creates a new AutoscalingV2beta2Client for the given config. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*AutoscalingV2beta2Client, error) { - config := *c - setConfigDefaults(&config) - httpClient, err := rest.HTTPClientFor(&config) - if err != nil { - return nil, err - } - return NewForConfigAndClient(&config, httpClient) -} - -// NewForConfigAndClient creates a new AutoscalingV2beta2Client for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AutoscalingV2beta2Client, error) { - config := *c - setConfigDefaults(&config) - client, err := rest.RESTClientForConfigAndClient(&config, h) - if err != nil { - return nil, err - } - return &AutoscalingV2beta2Client{client}, nil -} - -// NewForConfigOrDie creates a new AutoscalingV2beta2Client for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *AutoscalingV2beta2Client { - client, err := NewForConfig(c) - if err != nil { - panic(err) - } - return client -} - -// New creates a new AutoscalingV2beta2Client for the given RESTClient. -func New(c rest.Interface) *AutoscalingV2beta2Client { - return &AutoscalingV2beta2Client{c} -} - -func setConfigDefaults(config *rest.Config) { - gv := autoscalingv2beta2.SchemeGroupVersion - config.GroupVersion = &gv - config.APIPath = "/apis" - config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() - - if config.UserAgent == "" { - config.UserAgent = rest.DefaultKubernetesUserAgent() - } -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *AutoscalingV2beta2Client) RESTClient() rest.Interface { - if c == nil { - return nil - } - return c.restClient -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_autoscaling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_autoscaling_client.go deleted file mode 100644 index 99b5026bf7..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_autoscaling_client.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" - rest "k8s.io/client-go/rest" - testing "k8s.io/client-go/testing" -) - -type FakeAutoscalingV2beta2 struct { - *testing.Fake -} - -func (c *FakeAutoscalingV2beta2) HorizontalPodAutoscalers(namespace string) v2beta2.HorizontalPodAutoscalerInterface { - return newFakeHorizontalPodAutoscalers(c, namespace) -} - -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *FakeAutoscalingV2beta2) RESTClient() rest.Interface { - var ret *rest.RESTClient - return ret -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go deleted file mode 100644 index f747da9d0f..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v2beta2 "k8s.io/api/autoscaling/v2beta2" - autoscalingv2beta2 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2" - gentype "k8s.io/client-go/gentype" - typedautoscalingv2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" -) - -// fakeHorizontalPodAutoscalers implements HorizontalPodAutoscalerInterface -type fakeHorizontalPodAutoscalers struct { - *gentype.FakeClientWithListAndApply[*v2beta2.HorizontalPodAutoscaler, *v2beta2.HorizontalPodAutoscalerList, *autoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration] - Fake *FakeAutoscalingV2beta2 -} - -func newFakeHorizontalPodAutoscalers(fake *FakeAutoscalingV2beta2, namespace string) typedautoscalingv2beta2.HorizontalPodAutoscalerInterface { - return &fakeHorizontalPodAutoscalers{ - gentype.NewFakeClientWithListAndApply[*v2beta2.HorizontalPodAutoscaler, *v2beta2.HorizontalPodAutoscalerList, *autoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration]( - fake.Fake, - namespace, - v2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers"), - v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler"), - func() *v2beta2.HorizontalPodAutoscaler { return &v2beta2.HorizontalPodAutoscaler{} }, - func() *v2beta2.HorizontalPodAutoscalerList { return &v2beta2.HorizontalPodAutoscalerList{} }, - func(dst, src *v2beta2.HorizontalPodAutoscalerList) { dst.ListMeta = src.ListMeta }, - func(list *v2beta2.HorizontalPodAutoscalerList) []*v2beta2.HorizontalPodAutoscaler { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v2beta2.HorizontalPodAutoscalerList, items []*v2beta2.HorizontalPodAutoscaler) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/horizontalpodautoscaler.go deleted file mode 100644 index 017b3e1fc0..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/horizontalpodautoscaler.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v2beta2 - -import ( - context "context" - - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsautoscalingv2beta2 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2" - gentype "k8s.io/client-go/gentype" - scheme "k8s.io/client-go/kubernetes/scheme" -) - -// HorizontalPodAutoscalersGetter has a method to return a HorizontalPodAutoscalerInterface. -// A group's client should implement this interface. -type HorizontalPodAutoscalersGetter interface { - HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface -} - -// HorizontalPodAutoscalerInterface has methods to work with HorizontalPodAutoscaler resources. -type HorizontalPodAutoscalerInterface interface { - Create(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, opts v1.CreateOptions) (*autoscalingv2beta2.HorizontalPodAutoscaler, error) - Update(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, opts v1.UpdateOptions) (*autoscalingv2beta2.HorizontalPodAutoscaler, error) - // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, horizontalPodAutoscaler *autoscalingv2beta2.HorizontalPodAutoscaler, opts v1.UpdateOptions) (*autoscalingv2beta2.HorizontalPodAutoscaler, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*autoscalingv2beta2.HorizontalPodAutoscaler, error) - List(ctx context.Context, opts v1.ListOptions) (*autoscalingv2beta2.HorizontalPodAutoscalerList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *autoscalingv2beta2.HorizontalPodAutoscaler, err error) - Apply(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv2beta2.HorizontalPodAutoscaler, err error) - // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). - ApplyStatus(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv2beta2.HorizontalPodAutoscaler, err error) - HorizontalPodAutoscalerExpansion -} - -// horizontalPodAutoscalers implements HorizontalPodAutoscalerInterface -type horizontalPodAutoscalers struct { - *gentype.ClientWithListAndApply[*autoscalingv2beta2.HorizontalPodAutoscaler, *autoscalingv2beta2.HorizontalPodAutoscalerList, *applyconfigurationsautoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration] -} - -// newHorizontalPodAutoscalers returns a HorizontalPodAutoscalers -func newHorizontalPodAutoscalers(c *AutoscalingV2beta2Client, namespace string) *horizontalPodAutoscalers { - return &horizontalPodAutoscalers{ - gentype.NewClientWithListAndApply[*autoscalingv2beta2.HorizontalPodAutoscaler, *autoscalingv2beta2.HorizontalPodAutoscalerList, *applyconfigurationsautoscalingv2beta2.HorizontalPodAutoscalerApplyConfiguration]( - "horizontalpodautoscalers", - c.RESTClient(), - scheme.ParameterCodec, - namespace, - func() *autoscalingv2beta2.HorizontalPodAutoscaler { - return &autoscalingv2beta2.HorizontalPodAutoscaler{} - }, - func() *autoscalingv2beta2.HorizontalPodAutoscalerList { - return &autoscalingv2beta2.HorizontalPodAutoscalerList{} - }, - gentype.PrefersProtobuf[*autoscalingv2beta2.HorizontalPodAutoscaler](), - ), - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod_expansion.go index 3fbb89ad43..2b607298ca 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod_expansion.go @@ -17,16 +17,17 @@ limitations under the License. package fake import ( + "bytes" "context" "fmt" "io" "net/http" - "strings" v1 "k8s.io/api/core/v1" policyv1 "k8s.io/api/policy/v1" policyv1beta1 "k8s.io/api/policy/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" restclient "k8s.io/client-go/rest" fakerest "k8s.io/client-go/rest/fake" @@ -63,12 +64,26 @@ func (c *fakePods) GetLogs(name string, opts *v1.PodLogOptions) *restclient.Requ action.Subresource = "log" action.Value = opts - _, _ = c.Fake.Invokes(action, &v1.Pod{}) + defaultLogResponse := &runtime.Unknown{Raw: []byte("fake logs")} + obj, err := c.Fake.Invokes(action, defaultLogResponse) + logs := defaultLogResponse.Raw + if err == nil { + unknown, ok := obj.(*runtime.Unknown) + if !ok || unknown == nil { + err = fmt.Errorf("fake Pods.GetLogs expected reactor to return *runtime.Unknown, got %T", obj) + } else { + logs = unknown.Raw + } + } + fakeClient := &fakerest.RESTClient{ Client: fakerest.CreateHTTPClient(func(request *http.Request) (*http.Response, error) { + if err != nil { + return nil, err + } resp := &http.Response{ StatusCode: http.StatusOK, - Body: io.NopCloser(strings.NewReader("fake logs")), + Body: io.NopCloser(bytes.NewReader(logs)), } return resp, nil }), diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resource_client.go index 75bc9f9d33..99a5e8d877 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resource_client.go @@ -32,6 +32,10 @@ func (c *FakeResourceV1alpha3) DeviceTaintRules() v1alpha3.DeviceTaintRuleInterf return newFakeDeviceTaintRules(c) } +func (c *FakeResourceV1alpha3) ResourcePoolStatusRequests() v1alpha3.ResourcePoolStatusRequestInterface { + return newFakeResourcePoolStatusRequests(c) +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeResourceV1alpha3) RESTClient() rest.Interface { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resourcepoolstatusrequest.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resourcepoolstatusrequest.go new file mode 100644 index 0000000000..6196ddc1f6 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_resourcepoolstatusrequest.go @@ -0,0 +1,53 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha3 "k8s.io/api/resource/v1alpha3" + resourcev1alpha3 "k8s.io/client-go/applyconfigurations/resource/v1alpha3" + gentype "k8s.io/client-go/gentype" + typedresourcev1alpha3 "k8s.io/client-go/kubernetes/typed/resource/v1alpha3" +) + +// fakeResourcePoolStatusRequests implements ResourcePoolStatusRequestInterface +type fakeResourcePoolStatusRequests struct { + *gentype.FakeClientWithListAndApply[*v1alpha3.ResourcePoolStatusRequest, *v1alpha3.ResourcePoolStatusRequestList, *resourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration] + Fake *FakeResourceV1alpha3 +} + +func newFakeResourcePoolStatusRequests(fake *FakeResourceV1alpha3) typedresourcev1alpha3.ResourcePoolStatusRequestInterface { + return &fakeResourcePoolStatusRequests{ + gentype.NewFakeClientWithListAndApply[*v1alpha3.ResourcePoolStatusRequest, *v1alpha3.ResourcePoolStatusRequestList, *resourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration]( + fake.Fake, + "", + v1alpha3.SchemeGroupVersion.WithResource("resourcepoolstatusrequests"), + v1alpha3.SchemeGroupVersion.WithKind("ResourcePoolStatusRequest"), + func() *v1alpha3.ResourcePoolStatusRequest { return &v1alpha3.ResourcePoolStatusRequest{} }, + func() *v1alpha3.ResourcePoolStatusRequestList { return &v1alpha3.ResourcePoolStatusRequestList{} }, + func(dst, src *v1alpha3.ResourcePoolStatusRequestList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha3.ResourcePoolStatusRequestList) []*v1alpha3.ResourcePoolStatusRequest { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha3.ResourcePoolStatusRequestList, items []*v1alpha3.ResourcePoolStatusRequest) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/generated_expansion.go index 66e7c2b4b1..f5f9f8c840 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/generated_expansion.go @@ -19,3 +19,5 @@ limitations under the License. package v1alpha3 type DeviceTaintRuleExpansion interface{} + +type ResourcePoolStatusRequestExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resource_client.go index a7e2212fe7..ad36c69048 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resource_client.go @@ -29,6 +29,7 @@ import ( type ResourceV1alpha3Interface interface { RESTClient() rest.Interface DeviceTaintRulesGetter + ResourcePoolStatusRequestsGetter } // ResourceV1alpha3Client is used to interact with features provided by the resource.k8s.io group. @@ -40,6 +41,10 @@ func (c *ResourceV1alpha3Client) DeviceTaintRules() DeviceTaintRuleInterface { return newDeviceTaintRules(c) } +func (c *ResourceV1alpha3Client) ResourcePoolStatusRequests() ResourcePoolStatusRequestInterface { + return newResourcePoolStatusRequests(c) +} + // NewForConfig creates a new ResourceV1alpha3Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resourcepoolstatusrequest.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resourcepoolstatusrequest.go new file mode 100644 index 0000000000..964e488416 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/resourcepoolstatusrequest.go @@ -0,0 +1,79 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + context "context" + + resourcev1alpha3 "k8s.io/api/resource/v1alpha3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsresourcev1alpha3 "k8s.io/client-go/applyconfigurations/resource/v1alpha3" + gentype "k8s.io/client-go/gentype" + scheme "k8s.io/client-go/kubernetes/scheme" +) + +// ResourcePoolStatusRequestsGetter has a method to return a ResourcePoolStatusRequestInterface. +// A group's client should implement this interface. +type ResourcePoolStatusRequestsGetter interface { + ResourcePoolStatusRequests() ResourcePoolStatusRequestInterface +} + +// ResourcePoolStatusRequestInterface has methods to work with ResourcePoolStatusRequest resources. +type ResourcePoolStatusRequestInterface interface { + Create(ctx context.Context, resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, opts v1.CreateOptions) (*resourcev1alpha3.ResourcePoolStatusRequest, error) + Update(ctx context.Context, resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, opts v1.UpdateOptions) (*resourcev1alpha3.ResourcePoolStatusRequest, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, resourcePoolStatusRequest *resourcev1alpha3.ResourcePoolStatusRequest, opts v1.UpdateOptions) (*resourcev1alpha3.ResourcePoolStatusRequest, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*resourcev1alpha3.ResourcePoolStatusRequest, error) + List(ctx context.Context, opts v1.ListOptions) (*resourcev1alpha3.ResourcePoolStatusRequestList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *resourcev1alpha3.ResourcePoolStatusRequest, err error) + Apply(ctx context.Context, resourcePoolStatusRequest *applyconfigurationsresourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration, opts v1.ApplyOptions) (result *resourcev1alpha3.ResourcePoolStatusRequest, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, resourcePoolStatusRequest *applyconfigurationsresourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration, opts v1.ApplyOptions) (result *resourcev1alpha3.ResourcePoolStatusRequest, err error) + ResourcePoolStatusRequestExpansion +} + +// resourcePoolStatusRequests implements ResourcePoolStatusRequestInterface +type resourcePoolStatusRequests struct { + *gentype.ClientWithListAndApply[*resourcev1alpha3.ResourcePoolStatusRequest, *resourcev1alpha3.ResourcePoolStatusRequestList, *applyconfigurationsresourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration] +} + +// newResourcePoolStatusRequests returns a ResourcePoolStatusRequests +func newResourcePoolStatusRequests(c *ResourceV1alpha3Client) *resourcePoolStatusRequests { + return &resourcePoolStatusRequests{ + gentype.NewClientWithListAndApply[*resourcev1alpha3.ResourcePoolStatusRequest, *resourcev1alpha3.ResourcePoolStatusRequestList, *applyconfigurationsresourcev1alpha3.ResourcePoolStatusRequestApplyConfiguration]( + "resourcepoolstatusrequests", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *resourcev1alpha3.ResourcePoolStatusRequest { + return &resourcev1alpha3.ResourcePoolStatusRequest{} + }, + func() *resourcev1alpha3.ResourcePoolStatusRequestList { + return &resourcev1alpha3.ResourcePoolStatusRequestList{} + }, + gentype.PrefersProtobuf[*resourcev1alpha3.ResourcePoolStatusRequest](), + ), + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/devicetaintrule.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/devicetaintrule.go new file mode 100644 index 0000000000..da915c51f1 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/devicetaintrule.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta2 + +import ( + context "context" + + resourcev1beta2 "k8s.io/api/resource/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsresourcev1beta2 "k8s.io/client-go/applyconfigurations/resource/v1beta2" + gentype "k8s.io/client-go/gentype" + scheme "k8s.io/client-go/kubernetes/scheme" +) + +// DeviceTaintRulesGetter has a method to return a DeviceTaintRuleInterface. +// A group's client should implement this interface. +type DeviceTaintRulesGetter interface { + DeviceTaintRules() DeviceTaintRuleInterface +} + +// DeviceTaintRuleInterface has methods to work with DeviceTaintRule resources. +type DeviceTaintRuleInterface interface { + Create(ctx context.Context, deviceTaintRule *resourcev1beta2.DeviceTaintRule, opts v1.CreateOptions) (*resourcev1beta2.DeviceTaintRule, error) + Update(ctx context.Context, deviceTaintRule *resourcev1beta2.DeviceTaintRule, opts v1.UpdateOptions) (*resourcev1beta2.DeviceTaintRule, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, deviceTaintRule *resourcev1beta2.DeviceTaintRule, opts v1.UpdateOptions) (*resourcev1beta2.DeviceTaintRule, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*resourcev1beta2.DeviceTaintRule, error) + List(ctx context.Context, opts v1.ListOptions) (*resourcev1beta2.DeviceTaintRuleList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *resourcev1beta2.DeviceTaintRule, err error) + Apply(ctx context.Context, deviceTaintRule *applyconfigurationsresourcev1beta2.DeviceTaintRuleApplyConfiguration, opts v1.ApplyOptions) (result *resourcev1beta2.DeviceTaintRule, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, deviceTaintRule *applyconfigurationsresourcev1beta2.DeviceTaintRuleApplyConfiguration, opts v1.ApplyOptions) (result *resourcev1beta2.DeviceTaintRule, err error) + DeviceTaintRuleExpansion +} + +// deviceTaintRules implements DeviceTaintRuleInterface +type deviceTaintRules struct { + *gentype.ClientWithListAndApply[*resourcev1beta2.DeviceTaintRule, *resourcev1beta2.DeviceTaintRuleList, *applyconfigurationsresourcev1beta2.DeviceTaintRuleApplyConfiguration] +} + +// newDeviceTaintRules returns a DeviceTaintRules +func newDeviceTaintRules(c *ResourceV1beta2Client) *deviceTaintRules { + return &deviceTaintRules{ + gentype.NewClientWithListAndApply[*resourcev1beta2.DeviceTaintRule, *resourcev1beta2.DeviceTaintRuleList, *applyconfigurationsresourcev1beta2.DeviceTaintRuleApplyConfiguration]( + "devicetaintrules", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *resourcev1beta2.DeviceTaintRule { return &resourcev1beta2.DeviceTaintRule{} }, + func() *resourcev1beta2.DeviceTaintRuleList { return &resourcev1beta2.DeviceTaintRuleList{} }, + gentype.PrefersProtobuf[*resourcev1beta2.DeviceTaintRule](), + ), + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_devicetaintrule.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_devicetaintrule.go new file mode 100644 index 0000000000..13797c6cfd --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_devicetaintrule.go @@ -0,0 +1,53 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta2 "k8s.io/api/resource/v1beta2" + resourcev1beta2 "k8s.io/client-go/applyconfigurations/resource/v1beta2" + gentype "k8s.io/client-go/gentype" + typedresourcev1beta2 "k8s.io/client-go/kubernetes/typed/resource/v1beta2" +) + +// fakeDeviceTaintRules implements DeviceTaintRuleInterface +type fakeDeviceTaintRules struct { + *gentype.FakeClientWithListAndApply[*v1beta2.DeviceTaintRule, *v1beta2.DeviceTaintRuleList, *resourcev1beta2.DeviceTaintRuleApplyConfiguration] + Fake *FakeResourceV1beta2 +} + +func newFakeDeviceTaintRules(fake *FakeResourceV1beta2) typedresourcev1beta2.DeviceTaintRuleInterface { + return &fakeDeviceTaintRules{ + gentype.NewFakeClientWithListAndApply[*v1beta2.DeviceTaintRule, *v1beta2.DeviceTaintRuleList, *resourcev1beta2.DeviceTaintRuleApplyConfiguration]( + fake.Fake, + "", + v1beta2.SchemeGroupVersion.WithResource("devicetaintrules"), + v1beta2.SchemeGroupVersion.WithKind("DeviceTaintRule"), + func() *v1beta2.DeviceTaintRule { return &v1beta2.DeviceTaintRule{} }, + func() *v1beta2.DeviceTaintRuleList { return &v1beta2.DeviceTaintRuleList{} }, + func(dst, src *v1beta2.DeviceTaintRuleList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta2.DeviceTaintRuleList) []*v1beta2.DeviceTaintRule { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1beta2.DeviceTaintRuleList, items []*v1beta2.DeviceTaintRule) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resource_client.go index 10c5c0e337..718bdd9e0d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resource_client.go @@ -32,6 +32,10 @@ func (c *FakeResourceV1beta2) DeviceClasses() v1beta2.DeviceClassInterface { return newFakeDeviceClasses(c) } +func (c *FakeResourceV1beta2) DeviceTaintRules() v1beta2.DeviceTaintRuleInterface { + return newFakeDeviceTaintRules(c) +} + func (c *FakeResourceV1beta2) ResourceClaims(namespace string) v1beta2.ResourceClaimInterface { return newFakeResourceClaims(c, namespace) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/generated_expansion.go index 230ab8ccd3..06a1dc6e93 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/generated_expansion.go @@ -20,6 +20,8 @@ package v1beta2 type DeviceClassExpansion interface{} +type DeviceTaintRuleExpansion interface{} + type ResourceClaimExpansion interface{} type ResourceClaimTemplateExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resource_client.go index aadde5be95..45465a480d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resource_client.go @@ -29,6 +29,7 @@ import ( type ResourceV1beta2Interface interface { RESTClient() rest.Interface DeviceClassesGetter + DeviceTaintRulesGetter ResourceClaimsGetter ResourceClaimTemplatesGetter ResourceSlicesGetter @@ -43,6 +44,10 @@ func (c *ResourceV1beta2Client) DeviceClasses() DeviceClassInterface { return newDeviceClasses(c) } +func (c *ResourceV1beta2Client) DeviceTaintRules() DeviceTaintRuleInterface { + return newDeviceTaintRules(c) +} + func (c *ResourceV1beta2Client) ResourceClaims(namespace string) ResourceClaimInterface { return newResourceClaims(c, namespace) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go deleted file mode 100644 index 7d5a8e2630..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "k8s.io/api/scheduling/v1alpha1" - schedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" - gentype "k8s.io/client-go/gentype" - typedschedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" -) - -// fakePriorityClasses implements PriorityClassInterface -type fakePriorityClasses struct { - *gentype.FakeClientWithListAndApply[*v1alpha1.PriorityClass, *v1alpha1.PriorityClassList, *schedulingv1alpha1.PriorityClassApplyConfiguration] - Fake *FakeSchedulingV1alpha1 -} - -func newFakePriorityClasses(fake *FakeSchedulingV1alpha1) typedschedulingv1alpha1.PriorityClassInterface { - return &fakePriorityClasses{ - gentype.NewFakeClientWithListAndApply[*v1alpha1.PriorityClass, *v1alpha1.PriorityClassList, *schedulingv1alpha1.PriorityClassApplyConfiguration]( - fake.Fake, - "", - v1alpha1.SchemeGroupVersion.WithResource("priorityclasses"), - v1alpha1.SchemeGroupVersion.WithKind("PriorityClass"), - func() *v1alpha1.PriorityClass { return &v1alpha1.PriorityClass{} }, - func() *v1alpha1.PriorityClassList { return &v1alpha1.PriorityClassList{} }, - func(dst, src *v1alpha1.PriorityClassList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.PriorityClassList) []*v1alpha1.PriorityClass { - return gentype.ToPointerSlice(list.Items) - }, - func(list *v1alpha1.PriorityClassList, items []*v1alpha1.PriorityClass) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_workload.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_workload.go deleted file mode 100644 index 06a48d24e0..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_workload.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "k8s.io/api/scheduling/v1alpha1" - schedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" - gentype "k8s.io/client-go/gentype" - typedschedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" -) - -// fakeWorkloads implements WorkloadInterface -type fakeWorkloads struct { - *gentype.FakeClientWithListAndApply[*v1alpha1.Workload, *v1alpha1.WorkloadList, *schedulingv1alpha1.WorkloadApplyConfiguration] - Fake *FakeSchedulingV1alpha1 -} - -func newFakeWorkloads(fake *FakeSchedulingV1alpha1, namespace string) typedschedulingv1alpha1.WorkloadInterface { - return &fakeWorkloads{ - gentype.NewFakeClientWithListAndApply[*v1alpha1.Workload, *v1alpha1.WorkloadList, *schedulingv1alpha1.WorkloadApplyConfiguration]( - fake.Fake, - namespace, - v1alpha1.SchemeGroupVersion.WithResource("workloads"), - v1alpha1.SchemeGroupVersion.WithKind("Workload"), - func() *v1alpha1.Workload { return &v1alpha1.Workload{} }, - func() *v1alpha1.WorkloadList { return &v1alpha1.WorkloadList{} }, - func(dst, src *v1alpha1.WorkloadList) { dst.ListMeta = src.ListMeta }, - func(list *v1alpha1.WorkloadList) []*v1alpha1.Workload { return gentype.ToPointerSlice(list.Items) }, - func(list *v1alpha1.WorkloadList, items []*v1alpha1.Workload) { - list.Items = gentype.FromPointerSlice(items) - }, - ), - fake, - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/priorityclass.go deleted file mode 100644 index e7125f9fc3..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/priorityclass.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - context "context" - - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsschedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" - gentype "k8s.io/client-go/gentype" - scheme "k8s.io/client-go/kubernetes/scheme" -) - -// PriorityClassesGetter has a method to return a PriorityClassInterface. -// A group's client should implement this interface. -type PriorityClassesGetter interface { - PriorityClasses() PriorityClassInterface -} - -// PriorityClassInterface has methods to work with PriorityClass resources. -type PriorityClassInterface interface { - Create(ctx context.Context, priorityClass *schedulingv1alpha1.PriorityClass, opts v1.CreateOptions) (*schedulingv1alpha1.PriorityClass, error) - Update(ctx context.Context, priorityClass *schedulingv1alpha1.PriorityClass, opts v1.UpdateOptions) (*schedulingv1alpha1.PriorityClass, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*schedulingv1alpha1.PriorityClass, error) - List(ctx context.Context, opts v1.ListOptions) (*schedulingv1alpha1.PriorityClassList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *schedulingv1alpha1.PriorityClass, err error) - Apply(ctx context.Context, priorityClass *applyconfigurationsschedulingv1alpha1.PriorityClassApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1alpha1.PriorityClass, err error) - PriorityClassExpansion -} - -// priorityClasses implements PriorityClassInterface -type priorityClasses struct { - *gentype.ClientWithListAndApply[*schedulingv1alpha1.PriorityClass, *schedulingv1alpha1.PriorityClassList, *applyconfigurationsschedulingv1alpha1.PriorityClassApplyConfiguration] -} - -// newPriorityClasses returns a PriorityClasses -func newPriorityClasses(c *SchedulingV1alpha1Client) *priorityClasses { - return &priorityClasses{ - gentype.NewClientWithListAndApply[*schedulingv1alpha1.PriorityClass, *schedulingv1alpha1.PriorityClassList, *applyconfigurationsschedulingv1alpha1.PriorityClassApplyConfiguration]( - "priorityclasses", - c.RESTClient(), - scheme.ParameterCodec, - "", - func() *schedulingv1alpha1.PriorityClass { return &schedulingv1alpha1.PriorityClass{} }, - func() *schedulingv1alpha1.PriorityClassList { return &schedulingv1alpha1.PriorityClassList{} }, - gentype.PrefersProtobuf[*schedulingv1alpha1.PriorityClass](), - ), - } -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/doc.go similarity index 97% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/doc.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/doc.go index c600965946..baaf2d9853 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/doc.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/doc.go @@ -17,4 +17,4 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. // This package has the automatically generated typed clients. -package v2beta2 +package v1alpha2 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/doc.go similarity index 100% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/doc.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/doc.go diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_podgroup.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_podgroup.go new file mode 100644 index 0000000000..3709cf5214 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_podgroup.go @@ -0,0 +1,51 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha2 "k8s.io/api/scheduling/v1alpha2" + schedulingv1alpha2 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha2" + gentype "k8s.io/client-go/gentype" + typedschedulingv1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2" +) + +// fakePodGroups implements PodGroupInterface +type fakePodGroups struct { + *gentype.FakeClientWithListAndApply[*v1alpha2.PodGroup, *v1alpha2.PodGroupList, *schedulingv1alpha2.PodGroupApplyConfiguration] + Fake *FakeSchedulingV1alpha2 +} + +func newFakePodGroups(fake *FakeSchedulingV1alpha2, namespace string) typedschedulingv1alpha2.PodGroupInterface { + return &fakePodGroups{ + gentype.NewFakeClientWithListAndApply[*v1alpha2.PodGroup, *v1alpha2.PodGroupList, *schedulingv1alpha2.PodGroupApplyConfiguration]( + fake.Fake, + namespace, + v1alpha2.SchemeGroupVersion.WithResource("podgroups"), + v1alpha2.SchemeGroupVersion.WithKind("PodGroup"), + func() *v1alpha2.PodGroup { return &v1alpha2.PodGroup{} }, + func() *v1alpha2.PodGroupList { return &v1alpha2.PodGroupList{} }, + func(dst, src *v1alpha2.PodGroupList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha2.PodGroupList) []*v1alpha2.PodGroup { return gentype.ToPointerSlice(list.Items) }, + func(list *v1alpha2.PodGroupList, items []*v1alpha2.PodGroup) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_scheduling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_scheduling_client.go similarity index 70% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_scheduling_client.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_scheduling_client.go index 2be1412662..1d21b2d914 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_scheduling_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_scheduling_client.go @@ -19,26 +19,26 @@ limitations under the License. package fake import ( - v1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" + v1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) -type FakeSchedulingV1alpha1 struct { +type FakeSchedulingV1alpha2 struct { *testing.Fake } -func (c *FakeSchedulingV1alpha1) PriorityClasses() v1alpha1.PriorityClassInterface { - return newFakePriorityClasses(c) +func (c *FakeSchedulingV1alpha2) PodGroups(namespace string) v1alpha2.PodGroupInterface { + return newFakePodGroups(c, namespace) } -func (c *FakeSchedulingV1alpha1) Workloads(namespace string) v1alpha1.WorkloadInterface { +func (c *FakeSchedulingV1alpha2) Workloads(namespace string) v1alpha2.WorkloadInterface { return newFakeWorkloads(c, namespace) } // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *FakeSchedulingV1alpha1) RESTClient() rest.Interface { +func (c *FakeSchedulingV1alpha2) RESTClient() rest.Interface { var ret *rest.RESTClient return ret } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_workload.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_workload.go new file mode 100644 index 0000000000..29768874cf --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake/fake_workload.go @@ -0,0 +1,51 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha2 "k8s.io/api/scheduling/v1alpha2" + schedulingv1alpha2 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha2" + gentype "k8s.io/client-go/gentype" + typedschedulingv1alpha2 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2" +) + +// fakeWorkloads implements WorkloadInterface +type fakeWorkloads struct { + *gentype.FakeClientWithListAndApply[*v1alpha2.Workload, *v1alpha2.WorkloadList, *schedulingv1alpha2.WorkloadApplyConfiguration] + Fake *FakeSchedulingV1alpha2 +} + +func newFakeWorkloads(fake *FakeSchedulingV1alpha2, namespace string) typedschedulingv1alpha2.WorkloadInterface { + return &fakeWorkloads{ + gentype.NewFakeClientWithListAndApply[*v1alpha2.Workload, *v1alpha2.WorkloadList, *schedulingv1alpha2.WorkloadApplyConfiguration]( + fake.Fake, + namespace, + v1alpha2.SchemeGroupVersion.WithResource("workloads"), + v1alpha2.SchemeGroupVersion.WithKind("Workload"), + func() *v1alpha2.Workload { return &v1alpha2.Workload{} }, + func() *v1alpha2.WorkloadList { return &v1alpha2.WorkloadList{} }, + func(dst, src *v1alpha2.WorkloadList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha2.WorkloadList) []*v1alpha2.Workload { return gentype.ToPointerSlice(list.Items) }, + func(list *v1alpha2.WorkloadList, items []*v1alpha2.Workload) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/generated_expansion.go similarity index 91% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/generated_expansion.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/generated_expansion.go index 24946041af..60668af04d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/generated_expansion.go @@ -16,8 +16,8 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -type PriorityClassExpansion interface{} +type PodGroupExpansion interface{} type WorkloadExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/podgroup.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/podgroup.go new file mode 100644 index 0000000000..bbe91d35ab --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/podgroup.go @@ -0,0 +1,75 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + context "context" + + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + applyconfigurationsschedulingv1alpha2 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha2" + gentype "k8s.io/client-go/gentype" + scheme "k8s.io/client-go/kubernetes/scheme" +) + +// PodGroupsGetter has a method to return a PodGroupInterface. +// A group's client should implement this interface. +type PodGroupsGetter interface { + PodGroups(namespace string) PodGroupInterface +} + +// PodGroupInterface has methods to work with PodGroup resources. +type PodGroupInterface interface { + Create(ctx context.Context, podGroup *schedulingv1alpha2.PodGroup, opts v1.CreateOptions) (*schedulingv1alpha2.PodGroup, error) + Update(ctx context.Context, podGroup *schedulingv1alpha2.PodGroup, opts v1.UpdateOptions) (*schedulingv1alpha2.PodGroup, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, podGroup *schedulingv1alpha2.PodGroup, opts v1.UpdateOptions) (*schedulingv1alpha2.PodGroup, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*schedulingv1alpha2.PodGroup, error) + List(ctx context.Context, opts v1.ListOptions) (*schedulingv1alpha2.PodGroupList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *schedulingv1alpha2.PodGroup, err error) + Apply(ctx context.Context, podGroup *applyconfigurationsschedulingv1alpha2.PodGroupApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1alpha2.PodGroup, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, podGroup *applyconfigurationsschedulingv1alpha2.PodGroupApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1alpha2.PodGroup, err error) + PodGroupExpansion +} + +// podGroups implements PodGroupInterface +type podGroups struct { + *gentype.ClientWithListAndApply[*schedulingv1alpha2.PodGroup, *schedulingv1alpha2.PodGroupList, *applyconfigurationsschedulingv1alpha2.PodGroupApplyConfiguration] +} + +// newPodGroups returns a PodGroups +func newPodGroups(c *SchedulingV1alpha2Client, namespace string) *podGroups { + return &podGroups{ + gentype.NewClientWithListAndApply[*schedulingv1alpha2.PodGroup, *schedulingv1alpha2.PodGroupList, *applyconfigurationsschedulingv1alpha2.PodGroupApplyConfiguration]( + "podgroups", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *schedulingv1alpha2.PodGroup { return &schedulingv1alpha2.PodGroup{} }, + func() *schedulingv1alpha2.PodGroupList { return &schedulingv1alpha2.PodGroupList{} }, + gentype.PrefersProtobuf[*schedulingv1alpha2.PodGroup](), + ), + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/scheduling_client.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/scheduling_client.go similarity index 67% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/scheduling_client.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/scheduling_client.go index 0c53bc368a..8ccdc178b9 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/scheduling_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/scheduling_client.go @@ -16,39 +16,39 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( http "net/http" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) -type SchedulingV1alpha1Interface interface { +type SchedulingV1alpha2Interface interface { RESTClient() rest.Interface - PriorityClassesGetter + PodGroupsGetter WorkloadsGetter } -// SchedulingV1alpha1Client is used to interact with features provided by the scheduling.k8s.io group. -type SchedulingV1alpha1Client struct { +// SchedulingV1alpha2Client is used to interact with features provided by the scheduling.k8s.io group. +type SchedulingV1alpha2Client struct { restClient rest.Interface } -func (c *SchedulingV1alpha1Client) PriorityClasses() PriorityClassInterface { - return newPriorityClasses(c) +func (c *SchedulingV1alpha2Client) PodGroups(namespace string) PodGroupInterface { + return newPodGroups(c, namespace) } -func (c *SchedulingV1alpha1Client) Workloads(namespace string) WorkloadInterface { +func (c *SchedulingV1alpha2Client) Workloads(namespace string) WorkloadInterface { return newWorkloads(c, namespace) } -// NewForConfig creates a new SchedulingV1alpha1Client for the given config. +// NewForConfig creates a new SchedulingV1alpha2Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*SchedulingV1alpha1Client, error) { +func NewForConfig(c *rest.Config) (*SchedulingV1alpha2Client, error) { config := *c setConfigDefaults(&config) httpClient, err := rest.HTTPClientFor(&config) @@ -58,21 +58,21 @@ func NewForConfig(c *rest.Config) (*SchedulingV1alpha1Client, error) { return NewForConfigAndClient(&config, httpClient) } -// NewForConfigAndClient creates a new SchedulingV1alpha1Client for the given config and http client. +// NewForConfigAndClient creates a new SchedulingV1alpha2Client for the given config and http client. // Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*SchedulingV1alpha1Client, error) { +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*SchedulingV1alpha2Client, error) { config := *c setConfigDefaults(&config) client, err := rest.RESTClientForConfigAndClient(&config, h) if err != nil { return nil, err } - return &SchedulingV1alpha1Client{client}, nil + return &SchedulingV1alpha2Client{client}, nil } -// NewForConfigOrDie creates a new SchedulingV1alpha1Client for the given config and +// NewForConfigOrDie creates a new SchedulingV1alpha2Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *SchedulingV1alpha1Client { +func NewForConfigOrDie(c *rest.Config) *SchedulingV1alpha2Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -80,13 +80,13 @@ func NewForConfigOrDie(c *rest.Config) *SchedulingV1alpha1Client { return client } -// New creates a new SchedulingV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *SchedulingV1alpha1Client { - return &SchedulingV1alpha1Client{c} +// New creates a new SchedulingV1alpha2Client for the given RESTClient. +func New(c rest.Interface) *SchedulingV1alpha2Client { + return &SchedulingV1alpha2Client{c} } func setConfigDefaults(config *rest.Config) { - gv := schedulingv1alpha1.SchemeGroupVersion + gv := schedulingv1alpha2.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() @@ -98,7 +98,7 @@ func setConfigDefaults(config *rest.Config) { // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *SchedulingV1alpha1Client) RESTClient() rest.Interface { +func (c *SchedulingV1alpha2Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/workload.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/workload.go similarity index 60% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/workload.go rename to vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/workload.go index 9c906b5e89..89790940bc 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/workload.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/workload.go @@ -16,16 +16,16 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( context "context" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsschedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" + applyconfigurationsschedulingv1alpha2 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha2" gentype "k8s.io/client-go/gentype" scheme "k8s.io/client-go/kubernetes/scheme" ) @@ -38,34 +38,34 @@ type WorkloadsGetter interface { // WorkloadInterface has methods to work with Workload resources. type WorkloadInterface interface { - Create(ctx context.Context, workload *schedulingv1alpha1.Workload, opts v1.CreateOptions) (*schedulingv1alpha1.Workload, error) - Update(ctx context.Context, workload *schedulingv1alpha1.Workload, opts v1.UpdateOptions) (*schedulingv1alpha1.Workload, error) + Create(ctx context.Context, workload *schedulingv1alpha2.Workload, opts v1.CreateOptions) (*schedulingv1alpha2.Workload, error) + Update(ctx context.Context, workload *schedulingv1alpha2.Workload, opts v1.UpdateOptions) (*schedulingv1alpha2.Workload, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*schedulingv1alpha1.Workload, error) - List(ctx context.Context, opts v1.ListOptions) (*schedulingv1alpha1.WorkloadList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*schedulingv1alpha2.Workload, error) + List(ctx context.Context, opts v1.ListOptions) (*schedulingv1alpha2.WorkloadList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *schedulingv1alpha1.Workload, err error) - Apply(ctx context.Context, workload *applyconfigurationsschedulingv1alpha1.WorkloadApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1alpha1.Workload, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *schedulingv1alpha2.Workload, err error) + Apply(ctx context.Context, workload *applyconfigurationsschedulingv1alpha2.WorkloadApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1alpha2.Workload, err error) WorkloadExpansion } // workloads implements WorkloadInterface type workloads struct { - *gentype.ClientWithListAndApply[*schedulingv1alpha1.Workload, *schedulingv1alpha1.WorkloadList, *applyconfigurationsschedulingv1alpha1.WorkloadApplyConfiguration] + *gentype.ClientWithListAndApply[*schedulingv1alpha2.Workload, *schedulingv1alpha2.WorkloadList, *applyconfigurationsschedulingv1alpha2.WorkloadApplyConfiguration] } // newWorkloads returns a Workloads -func newWorkloads(c *SchedulingV1alpha1Client, namespace string) *workloads { +func newWorkloads(c *SchedulingV1alpha2Client, namespace string) *workloads { return &workloads{ - gentype.NewClientWithListAndApply[*schedulingv1alpha1.Workload, *schedulingv1alpha1.WorkloadList, *applyconfigurationsschedulingv1alpha1.WorkloadApplyConfiguration]( + gentype.NewClientWithListAndApply[*schedulingv1alpha2.Workload, *schedulingv1alpha2.WorkloadList, *applyconfigurationsschedulingv1alpha2.WorkloadApplyConfiguration]( "workloads", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *schedulingv1alpha1.Workload { return &schedulingv1alpha1.Workload{} }, - func() *schedulingv1alpha1.WorkloadList { return &schedulingv1alpha1.WorkloadList{} }, - gentype.PrefersProtobuf[*schedulingv1alpha1.Workload](), + func() *schedulingv1alpha2.Workload { return &schedulingv1alpha2.Workload{} }, + func() *schedulingv1alpha2.WorkloadList { return &schedulingv1alpha2.WorkloadList{} }, + gentype.PrefersProtobuf[*schedulingv1alpha2.Workload](), ), } } diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go index 9002ad6ea3..d3c96490fc 100644 --- a/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/expansion_generated.go @@ -18,6 +18,14 @@ limitations under the License. package v1 +// MutatingAdmissionPolicyListerExpansion allows custom methods to be added to +// MutatingAdmissionPolicyLister. +type MutatingAdmissionPolicyListerExpansion interface{} + +// MutatingAdmissionPolicyBindingListerExpansion allows custom methods to be added to +// MutatingAdmissionPolicyBindingLister. +type MutatingAdmissionPolicyBindingListerExpansion interface{} + // MutatingWebhookConfigurationListerExpansion allows custom methods to be added to // MutatingWebhookConfigurationLister. type MutatingWebhookConfigurationListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicy.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicy.go new file mode 100644 index 0000000000..3f5567f5cd --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicy.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingAdmissionPolicyLister helps list MutatingAdmissionPolicies. +// All objects returned here must be treated as read-only. +type MutatingAdmissionPolicyLister interface { + // List lists all MutatingAdmissionPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*admissionregistrationv1.MutatingAdmissionPolicy, err error) + // Get retrieves the MutatingAdmissionPolicy from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*admissionregistrationv1.MutatingAdmissionPolicy, error) + MutatingAdmissionPolicyListerExpansion +} + +// mutatingAdmissionPolicyLister implements the MutatingAdmissionPolicyLister interface. +type mutatingAdmissionPolicyLister struct { + listers.ResourceIndexer[*admissionregistrationv1.MutatingAdmissionPolicy] +} + +// NewMutatingAdmissionPolicyLister returns a new MutatingAdmissionPolicyLister. +func NewMutatingAdmissionPolicyLister(indexer cache.Indexer) MutatingAdmissionPolicyLister { + return &mutatingAdmissionPolicyLister{listers.New[*admissionregistrationv1.MutatingAdmissionPolicy](indexer, admissionregistrationv1.Resource("mutatingadmissionpolicy"))} +} diff --git a/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicybinding.go new file mode 100644 index 0000000000..686a9cc55c --- /dev/null +++ b/vendor/k8s.io/client-go/listers/admissionregistration/v1/mutatingadmissionpolicybinding.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// MutatingAdmissionPolicyBindingLister helps list MutatingAdmissionPolicyBindings. +// All objects returned here must be treated as read-only. +type MutatingAdmissionPolicyBindingLister interface { + // List lists all MutatingAdmissionPolicyBindings in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*admissionregistrationv1.MutatingAdmissionPolicyBinding, err error) + // Get retrieves the MutatingAdmissionPolicyBinding from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*admissionregistrationv1.MutatingAdmissionPolicyBinding, error) + MutatingAdmissionPolicyBindingListerExpansion +} + +// mutatingAdmissionPolicyBindingLister implements the MutatingAdmissionPolicyBindingLister interface. +type mutatingAdmissionPolicyBindingLister struct { + listers.ResourceIndexer[*admissionregistrationv1.MutatingAdmissionPolicyBinding] +} + +// NewMutatingAdmissionPolicyBindingLister returns a new MutatingAdmissionPolicyBindingLister. +func NewMutatingAdmissionPolicyBindingLister(indexer cache.Indexer) MutatingAdmissionPolicyBindingLister { + return &mutatingAdmissionPolicyBindingLister{listers.New[*admissionregistrationv1.MutatingAdmissionPolicyBinding](indexer, admissionregistrationv1.Resource("mutatingadmissionpolicybinding"))} +} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go deleted file mode 100644 index 8d46a4b6e3..0000000000 --- a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v2beta1 - -// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerLister. -type HorizontalPodAutoscalerListerExpansion interface{} - -// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerNamespaceLister. -type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go deleted file mode 100644 index b7ad8e79b5..0000000000 --- a/vendor/k8s.io/client-go/listers/autoscaling/v2beta1/horizontalpodautoscaler.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v2beta1 - -import ( - autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" - labels "k8s.io/apimachinery/pkg/labels" - listers "k8s.io/client-go/listers" - cache "k8s.io/client-go/tools/cache" -) - -// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. -// All objects returned here must be treated as read-only. -type HorizontalPodAutoscalerLister interface { - // List lists all HorizontalPodAutoscalers in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*autoscalingv2beta1.HorizontalPodAutoscaler, err error) - // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. - HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister - HorizontalPodAutoscalerListerExpansion -} - -// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. -type horizontalPodAutoscalerLister struct { - listers.ResourceIndexer[*autoscalingv2beta1.HorizontalPodAutoscaler] -} - -// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. -func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { - return &horizontalPodAutoscalerLister{listers.New[*autoscalingv2beta1.HorizontalPodAutoscaler](indexer, autoscalingv2beta1.Resource("horizontalpodautoscaler"))} -} - -// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. -func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { - return horizontalPodAutoscalerNamespaceLister{listers.NewNamespaced[*autoscalingv2beta1.HorizontalPodAutoscaler](s.ResourceIndexer, namespace)} -} - -// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. -// All objects returned here must be treated as read-only. -type HorizontalPodAutoscalerNamespaceLister interface { - // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*autoscalingv2beta1.HorizontalPodAutoscaler, err error) - // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*autoscalingv2beta1.HorizontalPodAutoscaler, error) - HorizontalPodAutoscalerNamespaceListerExpansion -} - -// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister -// interface. -type horizontalPodAutoscalerNamespaceLister struct { - listers.ResourceIndexer[*autoscalingv2beta1.HorizontalPodAutoscaler] -} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go deleted file mode 100644 index 5127945a9c..0000000000 --- a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/expansion_generated.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v2beta2 - -// HorizontalPodAutoscalerListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerLister. -type HorizontalPodAutoscalerListerExpansion interface{} - -// HorizontalPodAutoscalerNamespaceListerExpansion allows custom methods to be added to -// HorizontalPodAutoscalerNamespaceLister. -type HorizontalPodAutoscalerNamespaceListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go b/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go deleted file mode 100644 index 8d0fa6e798..0000000000 --- a/vendor/k8s.io/client-go/listers/autoscaling/v2beta2/horizontalpodautoscaler.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v2beta2 - -import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - labels "k8s.io/apimachinery/pkg/labels" - listers "k8s.io/client-go/listers" - cache "k8s.io/client-go/tools/cache" -) - -// HorizontalPodAutoscalerLister helps list HorizontalPodAutoscalers. -// All objects returned here must be treated as read-only. -type HorizontalPodAutoscalerLister interface { - // List lists all HorizontalPodAutoscalers in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*autoscalingv2beta2.HorizontalPodAutoscaler, err error) - // HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. - HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister - HorizontalPodAutoscalerListerExpansion -} - -// horizontalPodAutoscalerLister implements the HorizontalPodAutoscalerLister interface. -type horizontalPodAutoscalerLister struct { - listers.ResourceIndexer[*autoscalingv2beta2.HorizontalPodAutoscaler] -} - -// NewHorizontalPodAutoscalerLister returns a new HorizontalPodAutoscalerLister. -func NewHorizontalPodAutoscalerLister(indexer cache.Indexer) HorizontalPodAutoscalerLister { - return &horizontalPodAutoscalerLister{listers.New[*autoscalingv2beta2.HorizontalPodAutoscaler](indexer, autoscalingv2beta2.Resource("horizontalpodautoscaler"))} -} - -// HorizontalPodAutoscalers returns an object that can list and get HorizontalPodAutoscalers. -func (s *horizontalPodAutoscalerLister) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerNamespaceLister { - return horizontalPodAutoscalerNamespaceLister{listers.NewNamespaced[*autoscalingv2beta2.HorizontalPodAutoscaler](s.ResourceIndexer, namespace)} -} - -// HorizontalPodAutoscalerNamespaceLister helps list and get HorizontalPodAutoscalers. -// All objects returned here must be treated as read-only. -type HorizontalPodAutoscalerNamespaceLister interface { - // List lists all HorizontalPodAutoscalers in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*autoscalingv2beta2.HorizontalPodAutoscaler, err error) - // Get retrieves the HorizontalPodAutoscaler from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*autoscalingv2beta2.HorizontalPodAutoscaler, error) - HorizontalPodAutoscalerNamespaceListerExpansion -} - -// horizontalPodAutoscalerNamespaceLister implements the HorizontalPodAutoscalerNamespaceLister -// interface. -type horizontalPodAutoscalerNamespaceLister struct { - listers.ResourceIndexer[*autoscalingv2beta2.HorizontalPodAutoscaler] -} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha3/expansion_generated.go b/vendor/k8s.io/client-go/listers/resource/v1alpha3/expansion_generated.go index 8685199a24..0b9d51cd09 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha3/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha3/expansion_generated.go @@ -21,3 +21,7 @@ package v1alpha3 // DeviceTaintRuleListerExpansion allows custom methods to be added to // DeviceTaintRuleLister. type DeviceTaintRuleListerExpansion interface{} + +// ResourcePoolStatusRequestListerExpansion allows custom methods to be added to +// ResourcePoolStatusRequestLister. +type ResourcePoolStatusRequestListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha3/resourcepoolstatusrequest.go b/vendor/k8s.io/client-go/listers/resource/v1alpha3/resourcepoolstatusrequest.go new file mode 100644 index 0000000000..f12dccdd84 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha3/resourcepoolstatusrequest.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + resourcev1alpha3 "k8s.io/api/resource/v1alpha3" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// ResourcePoolStatusRequestLister helps list ResourcePoolStatusRequests. +// All objects returned here must be treated as read-only. +type ResourcePoolStatusRequestLister interface { + // List lists all ResourcePoolStatusRequests in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*resourcev1alpha3.ResourcePoolStatusRequest, err error) + // Get retrieves the ResourcePoolStatusRequest from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*resourcev1alpha3.ResourcePoolStatusRequest, error) + ResourcePoolStatusRequestListerExpansion +} + +// resourcePoolStatusRequestLister implements the ResourcePoolStatusRequestLister interface. +type resourcePoolStatusRequestLister struct { + listers.ResourceIndexer[*resourcev1alpha3.ResourcePoolStatusRequest] +} + +// NewResourcePoolStatusRequestLister returns a new ResourcePoolStatusRequestLister. +func NewResourcePoolStatusRequestLister(indexer cache.Indexer) ResourcePoolStatusRequestLister { + return &resourcePoolStatusRequestLister{listers.New[*resourcev1alpha3.ResourcePoolStatusRequest](indexer, resourcev1alpha3.Resource("resourcepoolstatusrequest"))} +} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go b/vendor/k8s.io/client-go/listers/resource/v1beta2/devicetaintrule.go similarity index 50% rename from vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go rename to vendor/k8s.io/client-go/listers/resource/v1beta2/devicetaintrule.go index 7beaf46322..a567777944 100644 --- a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go +++ b/vendor/k8s.io/client-go/listers/resource/v1beta2/devicetaintrule.go @@ -16,33 +16,33 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1beta2 import ( - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + resourcev1beta2 "k8s.io/api/resource/v1beta2" labels "k8s.io/apimachinery/pkg/labels" listers "k8s.io/client-go/listers" cache "k8s.io/client-go/tools/cache" ) -// PriorityClassLister helps list PriorityClasses. +// DeviceTaintRuleLister helps list DeviceTaintRules. // All objects returned here must be treated as read-only. -type PriorityClassLister interface { - // List lists all PriorityClasses in the indexer. +type DeviceTaintRuleLister interface { + // List lists all DeviceTaintRules in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*schedulingv1alpha1.PriorityClass, err error) - // Get retrieves the PriorityClass from the index for a given name. + List(selector labels.Selector) (ret []*resourcev1beta2.DeviceTaintRule, err error) + // Get retrieves the DeviceTaintRule from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*schedulingv1alpha1.PriorityClass, error) - PriorityClassListerExpansion + Get(name string) (*resourcev1beta2.DeviceTaintRule, error) + DeviceTaintRuleListerExpansion } -// priorityClassLister implements the PriorityClassLister interface. -type priorityClassLister struct { - listers.ResourceIndexer[*schedulingv1alpha1.PriorityClass] +// deviceTaintRuleLister implements the DeviceTaintRuleLister interface. +type deviceTaintRuleLister struct { + listers.ResourceIndexer[*resourcev1beta2.DeviceTaintRule] } -// NewPriorityClassLister returns a new PriorityClassLister. -func NewPriorityClassLister(indexer cache.Indexer) PriorityClassLister { - return &priorityClassLister{listers.New[*schedulingv1alpha1.PriorityClass](indexer, schedulingv1alpha1.Resource("priorityclass"))} +// NewDeviceTaintRuleLister returns a new DeviceTaintRuleLister. +func NewDeviceTaintRuleLister(indexer cache.Indexer) DeviceTaintRuleLister { + return &deviceTaintRuleLister{listers.New[*resourcev1beta2.DeviceTaintRule](indexer, resourcev1beta2.Resource("devicetaintrule"))} } diff --git a/vendor/k8s.io/client-go/listers/resource/v1beta2/expansion_generated.go b/vendor/k8s.io/client-go/listers/resource/v1beta2/expansion_generated.go index 590f26bd74..dcf80d2228 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1beta2/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/resource/v1beta2/expansion_generated.go @@ -22,6 +22,10 @@ package v1beta2 // DeviceClassLister. type DeviceClassListerExpansion interface{} +// DeviceTaintRuleListerExpansion allows custom methods to be added to +// DeviceTaintRuleLister. +type DeviceTaintRuleListerExpansion interface{} + // ResourceClaimListerExpansion allows custom methods to be added to // ResourceClaimLister. type ResourceClaimListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/expansion_generated.go similarity index 75% rename from vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go rename to vendor/k8s.io/client-go/listers/scheduling/v1alpha2/expansion_generated.go index 8617325d8b..3a63d7891c 100644 --- a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/expansion_generated.go @@ -16,11 +16,15 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PriorityClassListerExpansion allows custom methods to be added to -// PriorityClassLister. -type PriorityClassListerExpansion interface{} +// PodGroupListerExpansion allows custom methods to be added to +// PodGroupLister. +type PodGroupListerExpansion interface{} + +// PodGroupNamespaceListerExpansion allows custom methods to be added to +// PodGroupNamespaceLister. +type PodGroupNamespaceListerExpansion interface{} // WorkloadListerExpansion allows custom methods to be added to // WorkloadLister. diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/podgroup.go b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/podgroup.go new file mode 100644 index 0000000000..292e5d62be --- /dev/null +++ b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/podgroup.go @@ -0,0 +1,70 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// PodGroupLister helps list PodGroups. +// All objects returned here must be treated as read-only. +type PodGroupLister interface { + // List lists all PodGroups in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*schedulingv1alpha2.PodGroup, err error) + // PodGroups returns an object that can list and get PodGroups. + PodGroups(namespace string) PodGroupNamespaceLister + PodGroupListerExpansion +} + +// podGroupLister implements the PodGroupLister interface. +type podGroupLister struct { + listers.ResourceIndexer[*schedulingv1alpha2.PodGroup] +} + +// NewPodGroupLister returns a new PodGroupLister. +func NewPodGroupLister(indexer cache.Indexer) PodGroupLister { + return &podGroupLister{listers.New[*schedulingv1alpha2.PodGroup](indexer, schedulingv1alpha2.Resource("podgroup"))} +} + +// PodGroups returns an object that can list and get PodGroups. +func (s *podGroupLister) PodGroups(namespace string) PodGroupNamespaceLister { + return podGroupNamespaceLister{listers.NewNamespaced[*schedulingv1alpha2.PodGroup](s.ResourceIndexer, namespace)} +} + +// PodGroupNamespaceLister helps list and get PodGroups. +// All objects returned here must be treated as read-only. +type PodGroupNamespaceLister interface { + // List lists all PodGroups in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*schedulingv1alpha2.PodGroup, err error) + // Get retrieves the PodGroup from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*schedulingv1alpha2.PodGroup, error) + PodGroupNamespaceListerExpansion +} + +// podGroupNamespaceLister implements the PodGroupNamespaceLister +// interface. +type podGroupNamespaceLister struct { + listers.ResourceIndexer[*schedulingv1alpha2.PodGroup] +} diff --git a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/workload.go b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/workload.go similarity index 80% rename from vendor/k8s.io/client-go/listers/scheduling/v1alpha1/workload.go rename to vendor/k8s.io/client-go/listers/scheduling/v1alpha2/workload.go index 24f51a5ef3..9526da3b5a 100644 --- a/vendor/k8s.io/client-go/listers/scheduling/v1alpha1/workload.go +++ b/vendor/k8s.io/client-go/listers/scheduling/v1alpha2/workload.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" labels "k8s.io/apimachinery/pkg/labels" listers "k8s.io/client-go/listers" cache "k8s.io/client-go/tools/cache" @@ -30,7 +30,7 @@ import ( type WorkloadLister interface { // List lists all Workloads in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*schedulingv1alpha1.Workload, err error) + List(selector labels.Selector) (ret []*schedulingv1alpha2.Workload, err error) // Workloads returns an object that can list and get Workloads. Workloads(namespace string) WorkloadNamespaceLister WorkloadListerExpansion @@ -38,17 +38,17 @@ type WorkloadLister interface { // workloadLister implements the WorkloadLister interface. type workloadLister struct { - listers.ResourceIndexer[*schedulingv1alpha1.Workload] + listers.ResourceIndexer[*schedulingv1alpha2.Workload] } // NewWorkloadLister returns a new WorkloadLister. func NewWorkloadLister(indexer cache.Indexer) WorkloadLister { - return &workloadLister{listers.New[*schedulingv1alpha1.Workload](indexer, schedulingv1alpha1.Resource("workload"))} + return &workloadLister{listers.New[*schedulingv1alpha2.Workload](indexer, schedulingv1alpha2.Resource("workload"))} } // Workloads returns an object that can list and get Workloads. func (s *workloadLister) Workloads(namespace string) WorkloadNamespaceLister { - return workloadNamespaceLister{listers.NewNamespaced[*schedulingv1alpha1.Workload](s.ResourceIndexer, namespace)} + return workloadNamespaceLister{listers.NewNamespaced[*schedulingv1alpha2.Workload](s.ResourceIndexer, namespace)} } // WorkloadNamespaceLister helps list and get Workloads. @@ -56,15 +56,15 @@ func (s *workloadLister) Workloads(namespace string) WorkloadNamespaceLister { type WorkloadNamespaceLister interface { // List lists all Workloads in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*schedulingv1alpha1.Workload, err error) + List(selector labels.Selector) (ret []*schedulingv1alpha2.Workload, err error) // Get retrieves the Workload from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*schedulingv1alpha1.Workload, error) + Get(name string) (*schedulingv1alpha2.Workload, error) WorkloadNamespaceListerExpansion } // workloadNamespaceLister implements the WorkloadNamespaceLister // interface. type workloadNamespaceLister struct { - listers.ResourceIndexer[*schedulingv1alpha1.Workload] + listers.ResourceIndexer[*schedulingv1alpha2.Workload] } diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go index 1af2afdb91..b2393f4dd3 100644 --- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go +++ b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go @@ -38,7 +38,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/dump" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/pkg/apis/clientauthentication" @@ -51,6 +50,7 @@ import ( "k8s.io/client-go/util/connrotation" "k8s.io/klog/v2" "k8s.io/utils/clock" + "k8s.io/utils/dump" ) const execInfoEnv = "KUBERNETES_EXEC_INFO" @@ -185,8 +185,8 @@ func newAuthenticator(c *cache, isTerminalFunc func(int) bool, config *api.ExecC allowlistLookup := sets.New[string]() for _, entry := range config.PluginPolicy.Allowlist { - if entry.Name != "" { - allowlistLookup.Insert(entry.Name) + if entry.Command != "" { + allowlistLookup.Insert(entry.Command) } } @@ -641,14 +641,14 @@ func (a *Authenticator) checkAllowlistLocked(cmd *exec.Cmd) error { func (a *Authenticator) resolveAllowListEntriesLocked(commandHint string) { hintName := filepath.Base(commandHint) for _, entry := range a.execPluginPolicy.Allowlist { - entryBasename := filepath.Base(entry.Name) + entryBasename := filepath.Base(entry.Command) if hintName != "" && hintName != entryBasename { // we got a hint, and this allowlist entry does not match it continue } - entryResolvedPath, err := exec.LookPath(entry.Name) + entryResolvedPath, err := exec.LookPath(entry.Command) if err != nil { - klog.V(5).ErrorS(err, "resolving credential plugin allowlist", "name", entry.Name) + klog.V(5).ErrorS(err, "resolving credential plugin allowlist", "name", entry.Command) continue } if entryResolvedPath != "" { @@ -691,10 +691,10 @@ func validateAllowlist(list []api.AllowlistEntry) error { return fmt.Errorf("misconfigured credential plugin allowlist: empty allowlist entry #%d", i+1) } - if cleaned := filepath.Clean(item.Name); cleaned != item.Name { - return fmt.Errorf("non-normalized file path: %q vs %q", item.Name, cleaned) - } else if item.Name == "" { - return fmt.Errorf("empty file path: %q", item.Name) + if cleaned := filepath.Clean(item.Command); cleaned != item.Command { + return fmt.Errorf("non-normalized file path: %q vs %q", item.Command, cleaned) + } else if item.Command == "" { + return fmt.Errorf("empty file path: %q", item.Command) } } diff --git a/vendor/k8s.io/client-go/testing/doc.go b/vendor/k8s.io/client-go/testing/doc.go new file mode 100644 index 0000000000..991535703f --- /dev/null +++ b/vendor/k8s.io/client-go/testing/doc.go @@ -0,0 +1,70 @@ +/* +Copyright 2015 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 testing provides a fake Kubernetes client suitable for use in unit +// tests. The fake client simulates interactions with a kube-apiserver without +// requiring one to be running, making tests fast and self-contained. +// +// # Scope and Limitations +// +// This fake client is intentionally simplified. It does not, and will never, +// fully replicate the behavior of a real kube-apiserver. Many server-side +// behaviors such as field defaulting, validation, status management, +// strategic merge patch, server-side apply semantics, and advanced +// field selectors are not supported by this client and there are no plans +// to add them. +// +// This is by design. Maintaining a high-fidelity mock of the entire +// kube-apiserver API surface would introduce significant complexity that is +// difficult to justify for a test utility. +// +// # When to Use This Package +// +// The fake client works well for unit tests that need to verify how your code +// interacts with the Kubernetes API at a structural level, for example: +// +// - Verifying that the correct API calls are made. +// - Supplying canned responses to drive specific code paths. +// +// # When Not to Use This Package +// +// If your tests depend on the kube-apiserver behaving correctly (e.g., +// enforcing validation, persisting resources accurately, handling apply +// semantics, or producing realistic watch events), you should write +// integration tests against a real kube-apiserver instead. +// +// # Contributing +// +// Issues requesting that the fake client more closely match kube-apiserver +// behavior should be limiting to bugs in how the fake behaves for unit test +// scenarios it is clearly intended to support. Pull requests that improve the fake +// client will only be accepted when they meet all of the following criteria: +// +// - The change makes the fake client easier to use for common unit testing +// patterns. +// - The change does not introduce significant complexity to the fake client. +// - The use cases motivating the change are clearly better served by a fake +// client than by integration tests against a real kube-apiserver. +// +// We hold a high bar for these changes. If the test scenarios in question can +// be reasonably addressed through integration testing, we will prefer that +// path over expanding the fake client. +// +// We understand this stance may be inconvenient, and we appreciate your +// understanding. Our goal is to keep this package simple, maintainable, and +// honest about what it provides so that it remains a reliable tool for the +// cases it is designed to handle. +package testing diff --git a/vendor/k8s.io/client-go/testing/fixture.go b/vendor/k8s.io/client-go/testing/fixture.go index 152a5c1bac..4a91a99c70 100644 --- a/vendor/k8s.io/client-go/testing/fixture.go +++ b/vendor/k8s.io/client-go/testing/fixture.go @@ -20,6 +20,7 @@ import ( "fmt" "reflect" "sort" + "strconv" "strings" "sync" @@ -288,13 +289,46 @@ type tracker struct { scheme ObjectScheme decoder runtime.Decoder lock sync.RWMutex - objects map[schema.GroupVersionResource]map[types.NamespacedName]runtime.Object + objects map[schema.GroupVersionResource]map[types.NamespacedName]versionedObject // The value type of watchers is a map of which the key is either a namespace or // all/non namespace aka "" and its value is list of fake watchers. // Manipulations on resources will broadcast the notification events into the // watchers' channel. Note that too many unhandled events (currently 100, // see apimachinery/pkg/watch.DefaultChanSize) will cause a panic. watchers map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher + // resourceVersions is the highest resource version of any tracked object with + // a certain gvr. Conceptually it starts at 1 when no objects are stored (0 is + // special in queries) but the map contains no entries in that case. + // The resource version for that set of objects gets bumped before + // storing a new or modified object. + // + // Object content does not get changed to preserve the traditional behavior + // (hence also the versionedObject type instead of storing a runtime.Object + // with modified ResourceVersion). + // + // Resource version support (https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions) + // is very limited. It only supports one particular use case: + // List (no resource version check, returned ListMeta has ResourceVersion set) + + // Watch (Exact match for the ResourceVersion returned by List). + // + // This is sufficient for Reflector.ListAndWatch (https://github.com/kubernetes/kubernetes/blob/b53b9fb5573323484af9a19cf3f5bfe80760abba/staging/src/k8s.io/client-go/tools/cache/reflector.go#L401) + // when setting up informers in an informer factory. + // + // Strictly speaking, this should be by GroupVersion. But objects are + // also tracked by GroupVersionResource instead of GroupVersion, so the + // same is done here to match how List is implemented. + resourceVersions map[schema.GroupVersionResource]int64 +} + +// versionedObject stores an object together with the resource version that was +// assigned to it by the tracker. The version could be stored inline in the object, +// but this is not how fake client-go has traditionally worked and starting to do +// that now might break tests. +type versionedObject struct { + // resourceVersion is always > 1 for a stored object because 1 + // is the initial value for an empty set of objects. + resourceVersion int64 + runtime.Object } var _ ObjectTracker = &tracker{} @@ -303,10 +337,11 @@ var _ ObjectTracker = &tracker{} // of objects for the fake clientset. Mostly useful for unit tests. func NewObjectTracker(scheme ObjectScheme, decoder runtime.Decoder) ObjectTracker { return &tracker{ - scheme: scheme, - decoder: decoder, - objects: make(map[schema.GroupVersionResource]map[types.NamespacedName]runtime.Object), - watchers: make(map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher), + scheme: scheme, + decoder: decoder, + objects: make(map[schema.GroupVersionResource]map[types.NamespacedName]versionedObject), + watchers: make(map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher), + resourceVersions: make(map[schema.GroupVersionResource]int64), } } @@ -338,15 +373,27 @@ func (t *tracker) List(gvr schema.GroupVersionResource, gvk schema.GroupVersionK t.lock.RLock() defer t.lock.RUnlock() + if listMeta, err := meta.ListAccessor(list); err == nil { + resourceVersion, ok := t.resourceVersions[gvr] + if !ok { + resourceVersion = 1 + } + listMeta.SetResourceVersion(fmt.Sprintf("%d", resourceVersion)) + } + objs, ok := t.objects[gvr] if !ok { return list, nil } - matchingObjs, err := filterByNamespace(objs, ns) + matchingVersionedObjs, err := filterByNamespace(objs, ns) if err != nil { return nil, err } + matchingObjs := make([]runtime.Object, len(matchingVersionedObjs)) + for i, obj := range matchingVersionedObjs { + matchingObjs[i] = obj.Object + } if err := meta.SetList(list, matchingObjs); err != nil { return nil, err } @@ -359,6 +406,27 @@ func (t *tracker) Watch(gvr schema.GroupVersionResource, ns string, opts ...meta return nil, err } + // By default, emulate the traditional behavior of the tracker and don't deliver + // *any* existing objects unless list options are provided. + addExisting := false + addFromRV := int64(0) + if len(opts) > 0 { + // Providing options, as the generated client-go fake does, enables support + // for existing objects depending on the resource version. + // + // The default if ResourceVersion is empty is "start at most recent", + // which includes delivering all existing objects. addFromRV == 0 + // matches all objects below because all stored objects have addFromRV > 0. + addExisting = true + if opts[0].ResourceVersion != "" { + rv, err := strconv.ParseInt(opts[0].ResourceVersion, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid ResourceVersion %q in ListOptions, must be int64: %w", opts[0].ResourceVersion, err) + } + addFromRV = rv + } + } + t.lock.Lock() defer t.lock.Unlock() @@ -368,6 +436,22 @@ func (t *tracker) Watch(gvr schema.GroupVersionResource, ns string, opts ...meta t.watchers[gvr] = make(map[string][]*watch.RaceFreeFakeWatcher) } t.watchers[gvr][ns] = append(t.watchers[gvr][ns], fakewatcher) + + // Deliver all objects that match the list options, for example + // between the initial List and the following Watch. + if addExisting { + objs := t.objects[gvr] + matchingObjs, err := filterByNamespace(objs, ns) + if err != nil { + return nil, err + } + for _, obj := range matchingObjs { + if addFromRV < obj.resourceVersion { + fakewatcher.Add(obj.Object) + } + } + } + return fakewatcher, nil } @@ -565,17 +649,26 @@ func (t *tracker) add(gvr schema.GroupVersionResource, obj runtime.Object, ns st _, ok := t.objects[gvr] if !ok { - t.objects[gvr] = make(map[types.NamespacedName]runtime.Object) + t.objects[gvr] = make(map[types.NamespacedName]versionedObject) } + // Determine resource version for the new or updated object. + resourceVersion, ok := t.resourceVersions[gvr] + if !ok { + resourceVersion = 1 + } + resourceVersion++ + namespacedName := types.NamespacedName{Namespace: newMeta.GetNamespace(), Name: newMeta.GetName()} if _, ok = t.objects[gvr][namespacedName]; ok { if replaceExisting { + t.resourceVersions[gvr] = resourceVersion + t.objects[gvr][namespacedName] = versionedObject{resourceVersion, obj} + for _, w := range t.getWatches(gvr, ns) { // To avoid the object from being accidentally modified by watcher w.Modify(obj.DeepCopyObject()) } - t.objects[gvr][namespacedName] = obj return nil } return apierrors.NewAlreadyExists(gr, newMeta.GetName()) @@ -586,7 +679,8 @@ func (t *tracker) add(gvr schema.GroupVersionResource, obj runtime.Object, ns st return apierrors.NewNotFound(gr, newMeta.GetName()) } - t.objects[gvr][namespacedName] = obj + t.resourceVersions[gvr] = resourceVersion + t.objects[gvr][namespacedName] = versionedObject{resourceVersion, obj} for _, w := range t.getWatches(gvr, ns) { // To avoid the object from being accidentally modified by watcher @@ -841,11 +935,11 @@ func (d *objectDefaulter) Default(_ runtime.Object) {} // filterByNamespace returns all objects in the collection that // match provided namespace. Empty namespace matches // non-namespaced objects. -func filterByNamespace(objs map[types.NamespacedName]runtime.Object, ns string) ([]runtime.Object, error) { - var res []runtime.Object +func filterByNamespace(objs map[types.NamespacedName]versionedObject, ns string) ([]versionedObject, error) { + var res []versionedObject for _, obj := range objs { - acc, err := meta.Accessor(obj) + acc, err := meta.Accessor(obj.Object) if err != nil { return nil, err } @@ -857,8 +951,8 @@ func filterByNamespace(objs map[types.NamespacedName]runtime.Object, ns string) // Sort res to get deterministic order. sort.Slice(res, func(i, j int) bool { - acc1, _ := meta.Accessor(res[i]) - acc2, _ := meta.Accessor(res[j]) + acc1, _ := meta.Accessor(res[i].Object) + acc2, _ := meta.Accessor(res[j].Object) if acc1.GetNamespace() != acc2.GetNamespace() { return acc1.GetNamespace() < acc2.GetNamespace() } diff --git a/vendor/github.com/gregjones/httpcache/LICENSE.txt b/vendor/k8s.io/client-go/third_party/forked/httpcache/LICENSE similarity index 100% rename from vendor/github.com/gregjones/httpcache/LICENSE.txt rename to vendor/k8s.io/client-go/third_party/forked/httpcache/LICENSE diff --git a/vendor/github.com/gregjones/httpcache/httpcache.go b/vendor/k8s.io/client-go/third_party/forked/httpcache/httpcache.go similarity index 98% rename from vendor/github.com/gregjones/httpcache/httpcache.go rename to vendor/k8s.io/client-go/third_party/forked/httpcache/httpcache.go index b41a63d1ff..b92230e495 100644 --- a/vendor/github.com/gregjones/httpcache/httpcache.go +++ b/vendor/k8s.io/client-go/third_party/forked/httpcache/httpcache.go @@ -1,9 +1,13 @@ +// This package is copied from github.com/gregjones/httpcache +// with the following changes: +// - ioutil.NopCloser replaced with io.NopCloser (deprecated) +// - ioutil.ReadAll replaced with io.ReadAll (deprecated) + // Package httpcache provides a http.RoundTripper implementation that works as a // mostly RFC-compliant cache for http responses. // // It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client // and not for a shared proxy). -// package httpcache import ( @@ -11,7 +15,6 @@ import ( "bytes" "errors" "io" - "io/ioutil" "net/http" "net/http/httputil" "strings" @@ -234,7 +237,7 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error R: resp.Body, OnEOF: func(r io.Reader) { resp := *resp - resp.Body = ioutil.NopCloser(r) + resp.Body = io.NopCloser(r) respBytes, err := httputil.DumpResponse(&resp, true) if err == nil { t.Cache.Set(cacheKey, respBytes) diff --git a/vendor/k8s.io/client-go/tools/cache/OWNERS b/vendor/k8s.io/client-go/tools/cache/OWNERS index fc441e0efa..77d7e4d28a 100644 --- a/vendor/k8s.io/client-go/tools/cache/OWNERS +++ b/vendor/k8s.io/client-go/tools/cache/OWNERS @@ -22,6 +22,7 @@ reviewers: - jsafrane - dims - ingvagabund + - michaelasp emeritus_approvers: - lavalamp - ncdc diff --git a/vendor/k8s.io/client-go/tools/cache/controller.go b/vendor/k8s.io/client-go/tools/cache/controller.go index 51e0a4659f..b78ed522e2 100644 --- a/vendor/k8s.io/client-go/tools/cache/controller.go +++ b/vendor/k8s.io/client-go/tools/cache/controller.go @@ -27,6 +27,7 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" clientgofeaturegate "k8s.io/client-go/features" + "k8s.io/klog/v2" "k8s.io/utils/clock" ) @@ -141,6 +142,11 @@ type Controller interface { // HasSynced delegates to the Config's Queue HasSynced() bool + // HasSyncedChecker enables waiting for syncing without polling. + // The returned DoneChecker can be passed to WaitFor. + // It delegates to the Config's Queue. + HasSyncedChecker() DoneChecker + // LastSyncResourceVersion delegates to the Reflector when there // is one, otherwise returns the empty string LastSyncResourceVersion() string @@ -167,11 +173,13 @@ func (c *controller) RunWithContext(ctx context.Context) { <-ctx.Done() c.config.Queue.Close() }() + logger := klog.FromContext(ctx) r := NewReflectorWithOptions( c.config.ListerWatcher, c.config.ObjectType, c.config.Queue, ReflectorOptions{ + Logger: &logger, ResyncPeriod: c.config.FullResyncPeriod, MinWatchTimeout: c.config.MinWatchTimeout, TypeDescription: c.config.ObjectDescription, @@ -205,6 +213,13 @@ func (c *controller) HasSynced() bool { return c.config.Queue.HasSynced() } +// HasSyncedChecker enables waiting for syncing without polling. +// The returned DoneChecker can be passed to [WaitFor]. +// It delegates to the Config's Queue. +func (c *controller) HasSyncedChecker() DoneChecker { + return c.config.Queue.HasSyncedChecker() +} + func (c *controller) LastSyncResourceVersion() string { c.reflectorMutex.RLock() defer c.reflectorMutex.RUnlock() @@ -231,7 +246,7 @@ func (c *controller) processLoop(ctx context.Context) { default: var err error if useBatchProcess { - err = batchQueue.PopBatch(c.config.ProcessBatch) + err = batchQueue.PopBatch(c.config.ProcessBatch, PopProcessFunc(c.config.Process)) } else { // otherwise fallback to non-batch process behavior _, err = c.config.Pop(PopProcessFunc(c.config.Process)) @@ -395,6 +410,9 @@ func DeletionHandlingObjectToName(obj interface{}) (ObjectName, error) { // InformerOptions configure a Reflector. type InformerOptions struct { + // Logger, if not nil, is used instead of klog.Background() for logging. + Logger *klog.Logger + // ListerWatcher implements List and Watch functions for the source of the resource // the informer will be informing about. ListerWatcher ListerWatcher @@ -429,6 +447,14 @@ type InformerOptions struct { // for them. // Optional - if unset no additional transforming is happening. Transform TransformFunc + + // Identifier is used to identify the FIFO for metrics and logging purposes. + // If not set, metrics will not be published. + Identifier InformerNameAndResource + + // InformerMetricsProvider is the metrics provider for the informer. + // If not set, metrics will be no-ops. + InformerMetricsProvider InformerMetricsProvider } // NewInformerWithOptions returns a Store and a controller for populating the store @@ -438,11 +464,11 @@ type InformerOptions struct { func NewInformerWithOptions(options InformerOptions) (Store, Controller) { var clientState Store if options.Indexers == nil { - clientState = NewStore(DeletionHandlingMetaNamespaceKeyFunc) + clientState = NewStore(DeletionHandlingMetaNamespaceKeyFunc, WithStoreMetrics(options.Identifier, options.InformerMetricsProvider)) } else { - clientState = NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers) + clientState = NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers, WithStoreMetrics(options.Identifier, options.InformerMetricsProvider)) } - return clientState, newInformer(clientState, options) + return clientState, newInformer(clientState, options, DeletionHandlingMetaNamespaceKeyFunc) } // NewInformer returns a Store and a controller for populating the store @@ -476,7 +502,7 @@ func NewInformer( Handler: h, ResyncPeriod: resyncPeriod, } - return clientState, newInformer(clientState, options) + return clientState, newInformer(clientState, options, DeletionHandlingMetaNamespaceKeyFunc) } // NewIndexerInformer returns an Indexer and a Controller for populating the index @@ -513,7 +539,7 @@ func NewIndexerInformer( ResyncPeriod: resyncPeriod, Indexers: indexers, } - return clientState, newInformer(clientState, options) + return clientState, newInformer(clientState, options, DeletionHandlingMetaNamespaceKeyFunc) } // NewTransformingInformer returns a Store and a controller for populating @@ -542,7 +568,7 @@ func NewTransformingInformer( ResyncPeriod: resyncPeriod, Transform: transformer, } - return clientState, newInformer(clientState, options) + return clientState, newInformer(clientState, options, DeletionHandlingMetaNamespaceKeyFunc) } // NewTransformingIndexerInformer returns an Indexer and a controller for @@ -573,23 +599,43 @@ func NewTransformingIndexerInformer( Indexers: indexers, Transform: transformer, } - return clientState, newInformer(clientState, options) + return clientState, newInformer(clientState, options, DeletionHandlingMetaNamespaceKeyFunc) } // Multiplexes updates in the form of a list of Deltas into a Store, and informs // a given handler of events OnUpdate, OnAdd, OnDelete func processDeltas( + logger klog.Logger, // Object which receives event notifications from the given deltas handler ResourceEventHandler, clientState Store, deltas Deltas, isInInitialList bool, + keyFunc KeyFunc, ) error { // from oldest to newest for _, d := range deltas { obj := d.Object switch d.Type { + case ReplacedAll: + info, ok := obj.(ReplacedAllInfo) + if !ok { + return fmt.Errorf("ReplacedAll did not contain ReplacedAllInfo: %T", obj) + } + if err := processReplacedAllInfo(logger, handler, info, clientState, isInInitialList, keyFunc); err != nil { + return err + } + case SyncAll: + _, ok := obj.(SyncAllInfo) + if !ok { + return fmt.Errorf("SyncAll did not contain SyncAllInfo: %T", obj) + } + objs := clientState.List() + for _, obj := range objs { + handler.OnUpdate(obj, obj) + } + return nil case Sync, Replaced, Added, Updated: if old, exists, err := clientState.Get(obj); err == nil && exists { if err := clientState.Update(obj); err != nil { @@ -607,6 +653,12 @@ func processDeltas( return err } handler.OnDelete(obj) + case Bookmark: + info, ok := obj.(BookmarkInfo) + if !ok { + return fmt.Errorf("bookmark delta did not contain BookmarkInfo: %T", obj) + } + clientState.Bookmark(info.ResourceVersion) } } return nil @@ -622,10 +674,12 @@ func processDeltas( // Returns an error if any Delta or transaction fails. For TransactionError, // only successful operations trigger callbacks. func processDeltasInBatch( + logger klog.Logger, handler ResourceEventHandler, clientState Store, deltas []Delta, isInInitialList bool, + keyFunc KeyFunc, ) error { // from oldest to newest txns := make([]Transaction, 0) @@ -634,7 +688,7 @@ func processDeltasInBatch( if !txnSupported { var errs []error for _, delta := range deltas { - if err := processDeltas(handler, clientState, Deltas{delta}, isInInitialList); err != nil { + if err := processDeltas(logger, handler, clientState, Deltas{delta}, isInInitialList, keyFunc); err != nil { errs = append(errs, err) } } @@ -677,6 +731,8 @@ func processDeltasInBatch( callbacks = append(callbacks, func() { handler.OnDelete(obj) }) + default: + return fmt.Errorf("Delta type %s is not supported in batch processing", d.Type) } } @@ -697,18 +753,68 @@ func processDeltasInBatch( return nil } +func processReplacedAllInfo(logger klog.Logger, handler ResourceEventHandler, info ReplacedAllInfo, clientState Store, isInInitialList bool, keyFunc KeyFunc) error { + var deletions []DeletedFinalStateUnknown + type replacement struct { + oldObj interface{} + newObj interface{} + } + replacements := make([]replacement, 0, len(info.Objects)) + + err := reconcileReplacement(logger, nil, clientState, info.Objects, keyFunc, + func(obj DeletedFinalStateUnknown) error { + deletions = append(deletions, obj) + return nil + }, + func(obj interface{}) error { + // This behavior matches processDeltas handling of Replace deltas + if old, exists, err := clientState.Get(obj); err == nil && exists { + replacements = append(replacements, replacement{newObj: obj, oldObj: old}) + } else { + replacements = append(replacements, replacement{newObj: obj}) + } + return nil + }, + ) + if err != nil { + return err + } + + // Replace the client state first so the store reflects the events handlers are given + if err := clientState.Replace(info.Objects, info.ResourceVersion); err != nil { + return err + } + // Processing all deletions first matches behavior of RealFIFO#Replace + for _, objToDelete := range deletions { + handler.OnDelete(objToDelete) + } + // Processing adds/updates in order observed by reconcileReplacement matches behavior of RealFIFO#Replace + for _, r := range replacements { + if r.oldObj != nil { + handler.OnUpdate(r.oldObj, r.newObj) + } else { + handler.OnAdd(r.newObj, isInInitialList) + } + } + return nil +} + // newInformer returns a controller for populating the store while also // providing event notifications. // // Parameters // - clientState is the store you want to populate // - options contain the options to configure the controller -func newInformer(clientState Store, options InformerOptions) Controller { +func newInformer(clientState Store, options InformerOptions, keyFunc KeyFunc) Controller { // This will hold incoming changes. Note how we pass clientState in as a // KeyLister, that way resync operations will result in the correct set // of update/delete deltas. - fifo := newQueueFIFO(clientState, options.Transform) + logger := klog.Background() + if options.Logger != nil { + logger = *options.Logger + } + logger, fifo := newQueueFIFO(logger, options.ObjectType, clientState, options.Transform, options.Identifier, options.InformerMetricsProvider) cfg := &Config{ Queue: fifo, @@ -719,29 +825,54 @@ func newInformer(clientState Store, options InformerOptions) Controller { Process: func(obj interface{}, isInInitialList bool) error { if deltas, ok := obj.(Deltas); ok { - return processDeltas(options.Handler, clientState, deltas, isInInitialList) + // This must be the logger *of the fifo*. + return processDeltas(logger, options.Handler, clientState, deltas, isInInitialList, keyFunc) } return errors.New("object given as Process argument is not Deltas") }, ProcessBatch: func(deltaList []Delta, isInInitialList bool) error { - return processDeltasInBatch(options.Handler, clientState, deltaList, isInInitialList) + // Same here. + return processDeltasInBatch(logger, options.Handler, clientState, deltaList, isInInitialList, keyFunc) }, } return New(cfg) } -func newQueueFIFO(clientState Store, transform TransformFunc) Queue { +// newQueueFIFO constructs a new FIFO, choosing between real and delta FIFO +// depending on the InOrderInformers feature gate. +// +// It returns the FIFO and the logger used by the FIFO. +// That logger includes the name used for the FIFO, +// in contrast to the logger which was passed in. +func newQueueFIFO(logger klog.Logger, objectType any, clientState Store, transform TransformFunc, identifier InformerNameAndResource, metricsProvider InformerMetricsProvider) (klog.Logger, Queue) { if clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.InOrderInformers) { - return NewRealFIFOWithOptions(RealFIFOOptions{ - KeyFunction: MetaNamespaceKeyFunc, - KnownObjects: clientState, - Transformer: transform, - }) + options := RealFIFOOptions{ + Logger: &logger, + Name: fmt.Sprintf("RealFIFO %T", objectType), + KeyFunction: MetaNamespaceKeyFunc, + Transformer: transform, + Identifier: identifier, + MetricsProvider: metricsProvider, + } + // If atomic events are enabled, unset clientState in the case of atomic events as we cannot pass a + // store to an atomic fifo. + if clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.AtomicFIFO) { + options.AtomicEvents = true + options.UnlockWhileProcessing = clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.UnlockWhileProcessingFIFO) + options.EmitDeltaTypeBookmark = true + } else { + options.KnownObjects = clientState + } + f := NewRealFIFOWithOptions(options) + return f.logger, f } else { - return NewDeltaFIFOWithOptions(DeltaFIFOOptions{ + f := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ + Logger: &logger, + Name: fmt.Sprintf("DeltaFIFO %T", objectType), KnownObjects: clientState, EmitDeltaTypeReplaced: true, Transformer: transform, }) + return f.logger, f } } diff --git a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go index 217bcf8b7a..b2a191f78a 100644 --- a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go @@ -22,6 +22,7 @@ import ( "sync" "time" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" @@ -31,6 +32,12 @@ import ( // DeltaFIFOOptions is the configuration parameters for DeltaFIFO. All are // optional. type DeltaFIFOOptions struct { + // If set, log output will go to this logger instead of klog.Background(). + // The name of the fifo gets added automatically. + Logger *klog.Logger + + // Name can be used to override the default "DeltaFIFO" name for the new instance. + Name string // KeyFunction is used to figure out what key an object should have. (It's // exposed in the returned DeltaFIFO's KeyOf() method, with additional @@ -55,9 +62,6 @@ type DeltaFIFOOptions struct { // If set, will be called for objects before enqueueing them. Please // see the comment on TransformFunc for details. Transformer TransformFunc - - // If set, log output will go to this logger instead of klog.Background(). - Logger *klog.Logger } // DeltaFIFO is like FIFO, but differs in two ways. One is that the @@ -102,6 +106,13 @@ type DeltaFIFOOptions struct { // threads, you could end up with multiple threads processing slightly // different versions of the same object. type DeltaFIFO struct { + // logger is a per-instance logger. This gets chosen when constructing + // the instance, with klog.Background() as default. + logger klog.Logger + + // name is the name of the fifo. It is included in the logger. + name string + // lock/cond protects access to 'items' and 'queue'. lock sync.RWMutex cond sync.Cond @@ -115,6 +126,11 @@ type DeltaFIFO struct { // A key is in `queue` if and only if it is in `items`. queue []string + // synced is initially an open channel. It gets closed (once!) by checkSynced_locked + // as soon as the initial sync is considered complete. + synced chan struct{} + syncedClosed bool + // populated is true if the first batch of items inserted by Replace() has been populated // or Delete/Add/Update/AddIfNotPresent was called first. populated bool @@ -139,10 +155,6 @@ type DeltaFIFO struct { // Called with every object if non-nil. transformer TransformFunc - - // logger is a per-instance logger. This gets chosen when constructing - // the instance, with klog.Background() as default. - logger klog.Logger } // TransformFunc allows for transforming an object before it will be processed. @@ -172,14 +184,27 @@ const ( Updated DeltaType = "Updated" Deleted DeltaType = "Deleted" // Replaced is emitted when we encountered watch errors and had to do a - // relist. We don't know if the replaced object has changed. + // relist, or on initial listing of objects. We don't know if the replaced + // object has changed. // // NOTE: Previous versions of DeltaFIFO would use Sync for Replace events // as well. Hence, Replaced is only emitted when the option // EmitDeltaTypeReplaced is true. Replaced DeltaType = "Replaced" + // ReplacedAll is emitted when we encountered watch errors and had to do + // a relist, or on initial listing of objects. This is the same reason as + // Replaced but will be emitted instead when the FIFO supports atomic + // replacement. This event will return the full list of replaced items + // instead of a single object. + ReplacedAll DeltaType = "ReplacedAll" // Sync is for synthetic events during a periodic resync. Sync DeltaType = "Sync" + // SyncAll indicates all known objects should be reprocessed. + // This event contains an object of type SyncAllInfo. + SyncAll DeltaType = "SyncAll" + // Bookmark is emitted on Bookmark calls and Replace calls to pass resource + // version information to the consumer. + Bookmark DeltaType = "Bookmark" ) // Delta is a member of Deltas (a list of Delta objects) which @@ -253,6 +278,9 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { } f := &DeltaFIFO{ + logger: klog.Background(), + name: "DeltaFIFO", + synced: make(chan struct{}), items: map[string]Deltas{}, queue: []string{}, keyFunc: opts.KeyFunction, @@ -260,11 +288,14 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, transformer: opts.Transformer, - logger: klog.Background(), } if opts.Logger != nil { f.logger = *opts.Logger } + if name := opts.Name; name != "" { + f.name = name + } + f.logger = klog.LoggerWithName(f.logger, f.name) f.cond.L = &f.lock return f } @@ -272,6 +303,7 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { var ( _ = Queue(&DeltaFIFO{}) // DeltaFIFO is a Queue _ = TransformingStore(&DeltaFIFO{}) // DeltaFIFO implements TransformingStore to allow memory optimizations + _ = DoneChecker(&DeltaFIFO{}) // DeltaFIFO implements DoneChecker. ) var ( @@ -317,8 +349,36 @@ func (f *DeltaFIFO) HasSynced() bool { return f.hasSynced_locked() } +// HasSyncedChecker is done if an Add/Update/Delete/AddIfNotPresent are called first, +// or the first batch of items inserted by Replace() has been popped. +func (f *DeltaFIFO) HasSyncedChecker() DoneChecker { + return f +} + +// Name implements [DoneChecker.Name] +func (f *DeltaFIFO) Name() string { + return f.name +} + +// Done implements [DoneChecker.Done] +func (f *DeltaFIFO) Done() <-chan struct{} { + return f.synced +} + +// hasSynced_locked returns the result of a prior checkSynced_locked call. func (f *DeltaFIFO) hasSynced_locked() bool { - return f.populated && f.initialPopulationCount == 0 + return f.syncedClosed +} + +// checkSynced_locked checks whether the initial is completed. +// It must be called whenever populated or initialPopulationCount change. +func (f *DeltaFIFO) checkSynced_locked() { + synced := f.populated && f.initialPopulationCount == 0 + if synced && !f.syncedClosed { + // Initial sync is complete. + f.syncedClosed = true + close(f.synced) + } } // Add inserts an item, and puts it in the queue. The item is only enqueued @@ -327,6 +387,7 @@ func (f *DeltaFIFO) Add(obj interface{}) error { f.lock.Lock() defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() return f.queueActionLocked(Added, obj) } @@ -335,6 +396,7 @@ func (f *DeltaFIFO) Update(obj interface{}) error { f.lock.Lock() defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() return f.queueActionLocked(Updated, obj) } @@ -351,6 +413,7 @@ func (f *DeltaFIFO) Delete(obj interface{}) error { f.lock.Lock() defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() if f.knownObjects == nil { if _, exists := f.items[id]; !exists { // Presumably, this was deleted when a relist happened. @@ -467,10 +530,10 @@ func (f *DeltaFIFO) queueActionInternalLocked(actionType, internalActionType Del // when given a non-empty list (as it is here). // If somehow it happens anyway, deal with it but complain. if oldDeltas == nil { - f.logger.Error(nil, "Impossible dedupDeltas, ignoring", "id", id, "oldDeltas", oldDeltas, "obj", obj) + utilruntime.HandleErrorWithLogger(f.logger, nil, "Impossible dedupDeltas, ignoring", "id", id, "oldDeltas", oldDeltas, "obj", obj) return nil } - f.logger.Error(nil, "Impossible dedupDeltas, breaking invariant by storing empty Deltas", "id", id, "oldDeltas", oldDeltas, "obj", obj) + utilruntime.HandleErrorWithLogger(f.logger, nil, "Impossible dedupDeltas, breaking invariant by storing empty Deltas", "id", id, "oldDeltas", oldDeltas, "obj", obj) f.items[id] = newDeltas return fmt.Errorf("Impossible dedupDeltas for id=%q: oldDeltas=%#+v, obj=%#+v; broke DeltaFIFO invariant by storing empty Deltas", id, oldDeltas, obj) } @@ -516,11 +579,12 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { depth := len(f.queue) if f.initialPopulationCount > 0 { f.initialPopulationCount-- + f.checkSynced_locked() } item, ok := f.items[id] if !ok { // This should never happen - f.logger.Error(nil, "Inconceivable! Item was in f.queue but not f.items; ignoring", "id", id) + utilruntime.HandleErrorWithLogger(f.logger, nil, "Inconceivable! Item was in f.queue but not f.items; ignoring", "id", id) continue } delete(f.items, id) @@ -613,7 +677,7 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { deletedObj, exists, err := f.knownObjects.GetByKey(k) if err != nil { deletedObj = nil - f.logger.Error(err, "Unexpected error during lookup, placing DeleteFinalStateUnknown marker without object", "key", k) + utilruntime.HandleErrorWithLogger(f.logger, err, "Unexpected error during lookup, placing DeleteFinalStateUnknown marker without object", "key", k) } else if !exists { deletedObj = nil f.logger.Info("Key does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", "key", k) @@ -628,6 +692,7 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { if !f.populated { f.populated = true f.initialPopulationCount = keys.Len() + queuedDeletions + f.checkSynced_locked() } return nil @@ -656,7 +721,7 @@ func (f *DeltaFIFO) Resync() error { func (f *DeltaFIFO) syncKeyLocked(key string) error { obj, exists, err := f.knownObjects.GetByKey(key) if err != nil { - f.logger.Error(err, "Unexpected error during lookup, unable to queue object for sync", "key", key) + utilruntime.HandleErrorWithLogger(f.logger, err, "Unexpected error during lookup, unable to queue object for sync", "key", key) return nil } else if !exists { f.logger.Info("Key does not exist in known objects store, unable to queue object for sync", "key", key) diff --git a/vendor/k8s.io/client-go/tools/cache/event_handler_name.go b/vendor/k8s.io/client-go/tools/cache/event_handler_name.go new file mode 100644 index 0000000000..d466fc6e2d --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/event_handler_name.go @@ -0,0 +1,121 @@ +/* +Copyright 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 cache + +import ( + "fmt" + "reflect" + "runtime" + "strings" +) + +func nameForHandler(handler ResourceEventHandler) (name string) { + defer func() { + // Last resort: let Sprintf handle it. + if name == "" { + name = fmt.Sprintf("%T", handler) + } + }() + + if handler == nil { + return "" + } + switch handler := handler.(type) { + case *ResourceEventHandlerFuncs: + return nameForHandlerFuncs(*handler) + case ResourceEventHandlerFuncs: + return nameForHandlerFuncs(handler) + default: + // We can use the fully qualified name of whatever + // provides the interface. We don't care whether + // it contains fields or methods which provide + // the interface methods. + value := reflect.ValueOf(handler) + if value.Type().Kind() == reflect.Interface { + // Probably not needed, but let's play it safe. + value = value.Elem() + } + if value.Type().Kind() == reflect.Pointer { + if !value.IsNil() { + value = value.Elem() + } + } + name := value.Type().PkgPath() + if name != "" { + name += "." + } + if typeName := value.Type().Name(); typeName != "" { + name += typeName + } + return name + } +} + +func nameForHandlerFuncs(funcs ResourceEventHandlerFuncs) string { + return nameForFunctions(funcs.AddFunc, funcs.UpdateFunc, funcs.DeleteFunc) +} + +func nameForFunctions(fs ...any) string { + // If all functions are defined in the same place, then we + // don't care about the actual function name in + // e.g. "main.FuncName" or "main.(*Foo).FuncName-fm", instead + // we use the common qualifier. + // + // But we don't know that yet, so we also collect all names. + var qualifier string + singleQualifier := true + var names []string + for _, f := range fs { + if f == nil { + continue + } + name := nameForFunction(f) + if name == "" { + continue + } + names = append(names, name) + + newQualifier := name + index := strings.LastIndexByte(newQualifier, '.') + if index > 0 { + newQualifier = newQualifier[:index] + } + switch qualifier { + case "": + qualifier = newQualifier + case newQualifier: + // So far, so good... + default: + // Nope, different. + singleQualifier = false + } + } + + if singleQualifier { + return qualifier + } + + return strings.Join(names, "+") +} + +func nameForFunction(f any) string { + fn := runtime.FuncForPC(reflect.ValueOf(f).Pointer()) + if fn == nil { + return "" + } + return fn.Name() +} diff --git a/vendor/k8s.io/client-go/tools/cache/expiration_cache.go b/vendor/k8s.io/client-go/tools/cache/expiration_cache.go index 813916ebf0..19c2226b94 100644 --- a/vendor/k8s.io/client-go/tools/cache/expiration_cache.go +++ b/vendor/k8s.io/client-go/tools/cache/expiration_cache.go @@ -137,6 +137,16 @@ func (c *ExpirationCache) List() []interface{} { return list } +// LastStoreSyncResourceVersion returns the latest resource version that the cache has seen. +func (c *ExpirationCache) LastStoreSyncResourceVersion() string { + return c.cacheStorage.LastStoreSyncResourceVersion() +} + +// Bookmark observes a new resource version in the cache. +func (c *ExpirationCache) Bookmark(rv string) { + c.cacheStorage.Bookmark(rv) +} + // ListKeys returns a list of all keys in the expiration cache. func (c *ExpirationCache) ListKeys() []string { return c.cacheStorage.ListKeys() @@ -170,7 +180,7 @@ func (c *ExpirationCache) Delete(obj interface{}) error { } c.expirationLock.Lock() defer c.expirationLock.Unlock() - c.cacheStorage.Delete(key) + c.cacheStorage.DeleteWithObject(key, obj) return nil } diff --git a/vendor/k8s.io/client-go/tools/cache/fifo.go b/vendor/k8s.io/client-go/tools/cache/fifo.go index eb3ef589bd..e31e2d2703 100644 --- a/vendor/k8s.io/client-go/tools/cache/fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/fifo.go @@ -47,7 +47,9 @@ type Queue interface { // may return an ErrRequeue{inner} and in this case Pop will (a) // return that (key, accumulator) association to the Queue as part // of the atomic processing and (b) return the inner error from - // Pop. + // Pop. It is expected that the caller of Pop will be a single + // threaded consumer since otherwise it is possible for multiple + // PopProcessFuncs to be running simultaneously. Pop(PopProcessFunc) (interface{}, error) // HasSynced returns true if the first batch of keys have all been @@ -56,6 +58,12 @@ type Queue interface { // Update, or Delete; otherwise the first batch is empty. HasSynced() bool + // HasSyncedChecker is done once the first batch of keys have all been + // popped. The first batch of keys are those of the first Replace + // operation if that happened before any Add, AddIfNotPresent, + // Update, or Delete; otherwise the first batch is empty. + HasSyncedChecker() DoneChecker + // Close the queue Close() } @@ -73,23 +81,14 @@ type QueueWithBatch interface { // PopBatch behaves similarly to Queue#Pop, but processes multiple keys // as a batch. The implementation determines the batching strategy, - // such as the number of keys to include per batch. - PopBatch(ProcessBatchFunc) error -} - -// Pop is helper function for popping from Queue. -// WARNING: Do NOT use this function in non-test code to avoid races -// unless you really really really really know what you are doing. -// -// NOTE: This function is deprecated and may be removed in the future without -// additional warning. -func Pop(queue Queue) interface{} { - var result interface{} - queue.Pop(func(obj interface{}, isInInitialList bool) error { - result = obj - return nil - }) - return result + // such as the number of keys to include per batch. The ProcessBatchFunc + // is called when a batch is ready to be processed. The PopProcessFunc + // is called when a singleton item is ready to be processed. The + // ProcessBatchFunc and PopProcessFunc must do the same processing to + // ensure consistent behavior. It is expected that the caller of PopBatch + // will be a single threaded consumer since otherwise it is possible for + // multiple ProcessBatchFuncs/PopProcessFuncs to be running simultaneously. + PopBatch(processBatch ProcessBatchFunc, processSingle PopProcessFunc) error } // FIFO is a Queue in which (a) each accumulator is simply the most @@ -117,6 +116,11 @@ type FIFO struct { items map[string]interface{} queue []string + // synced is initially an open channel. It gets closed (once!) by checkSynced + // as soon as the initial sync is considered complete. + synced chan struct{} + syncedClosed bool + // populated is true if the first batch of items inserted by Replace() has been populated // or Delete/Add/Update was called first. populated bool @@ -134,7 +138,8 @@ type FIFO struct { } var ( - _ = Queue(&FIFO{}) // FIFO is a Queue + _ = Queue(&FIFO{}) // FIFO is a Queue + _ = DoneChecker(&FIFO{}) // ... and implements DoneChecker. ) // Close the queue. @@ -153,8 +158,36 @@ func (f *FIFO) HasSynced() bool { return f.hasSynced_locked() } +// HasSyncedChecker is done if an Add/Update/Delete/AddIfNotPresent are called first, +// or the first batch of items inserted by Replace() has been popped. +func (f *FIFO) HasSyncedChecker() DoneChecker { + return f +} + +// Name implements [DoneChecker.Name] +func (f *FIFO) Name() string { + return "FIFO" // FIFO doesn't seem to be used outside of a few tests, so changing the NewFIFO API to pass in a name doesn't seem worth it. +} + +// Done implements [DoneChecker.Done] +func (f *FIFO) Done() <-chan struct{} { + return f.synced +} + +// hasSynced_locked returns the result of a prior checkSynced call. func (f *FIFO) hasSynced_locked() bool { - return f.populated && f.initialPopulationCount == 0 + return f.syncedClosed +} + +// checkSynced checks whether the initial sync is completed. +// It must be called whenever populated or initialPopulationCount change +// while the mutex is still locked. +func (f *FIFO) checkSynced() { + synced := f.populated && f.initialPopulationCount == 0 + if synced && !f.syncedClosed { + f.syncedClosed = true + close(f.synced) + } } // Add inserts an item, and puts it in the queue. The item is only enqueued @@ -167,6 +200,7 @@ func (f *FIFO) Add(obj interface{}) error { f.lock.Lock() defer f.lock.Unlock() f.populated = true + f.checkSynced() if _, exists := f.items[id]; !exists { f.queue = append(f.queue, id) } @@ -191,6 +225,7 @@ func (f *FIFO) Delete(obj interface{}) error { f.lock.Lock() defer f.lock.Unlock() f.populated = true + f.checkSynced() delete(f.items, id) return err } @@ -227,6 +262,8 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { f.queue = f.queue[1:] if f.initialPopulationCount > 0 { f.initialPopulationCount-- + // Must be done *after* process has completed. + defer f.checkSynced() } item, ok := f.items[id] if !ok { @@ -259,6 +296,7 @@ func (f *FIFO) Replace(list []interface{}, resourceVersion string) error { if !f.populated { f.populated = true f.initialPopulationCount = len(items) + f.checkSynced() } f.items = items @@ -297,6 +335,7 @@ func (f *FIFO) Resync() error { // process. func NewFIFO(keyFunc KeyFunc) *FIFO { f := &FIFO{ + synced: make(chan struct{}), items: map[string]interface{}{}, queue: []string{}, keyFunc: keyFunc, diff --git a/vendor/k8s.io/client-go/tools/cache/fifo_metrics.go b/vendor/k8s.io/client-go/tools/cache/fifo_metrics.go new file mode 100644 index 0000000000..7a67817240 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/fifo_metrics.go @@ -0,0 +1,122 @@ +/* +Copyright 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 cache is a client-side caching mechanism. It is useful for +// reducing the number of server calls you'd otherwise need to make. +// Reflector watches a server and updates a Store. Two stores are provided; +// one that simply caches objects (for example, to allow a scheduler to +// list currently available nodes), and one that additionally acts as +// a FIFO queue (for example, to allow a scheduler to process incoming +// pods). +package cache + +import ( + "sync" +) + +var ( + globalInformerMetricsProvider InformerMetricsProvider = noopInformerMetricsProvider{} + setInformerMetricsProviderOnce sync.Once +) + +type noopInformerMetricsProvider struct{} + +// InformerMetricsProvider defines an interface for creating metrics that track informer operations. +type InformerMetricsProvider interface { + // NewQueuedItemMetric returns a gauge metric for tracking the total number of items + // currently queued and waiting to be processed. + // The returned metric should check id.Reserved() before updating to support + // dynamic informers that may shut down while the process is still running. + // + // For DeltaFIFO: Represents len(f.items) - the number of unique keys with pending deltas + // For RealFIFO: Represents len(f.items) - the total number of individual delta events queued + NewQueuedItemMetric(id InformerNameAndResource) GaugeMetric + + // NewProcessingLatencyMetric returns a histogram metric for tracking the time taken + // to process events (execute handlers) after they are popped from the queue. + // The latency is measured in seconds. + // The returned metric should check id.Reserved() before updating to support + // dynamic informers that may shut down while the process is still running. + NewProcessingLatencyMetric(id InformerNameAndResource) HistogramMetric + + // NewStoreResourceVersionMetric returns a gauge metric for tracking the resource version of the store. + // The returned metric should check id.Reserved() before updating to support + // dynamic informers that may shut down while the process is still running. + NewStoreResourceVersionMetric(id InformerNameAndResource) GaugeMetric +} + +// fifoMetrics holds all metrics for a FIFO. +type fifoMetrics struct { + numberOfQueuedItem GaugeMetric + processingLatency HistogramMetric +} + +// storeMetrics holds all metrics for a store. +type storeMetrics struct { + storeResourceVersion GaugeMetric +} + +// SetInformerMetricsProvider sets the metrics provider for all subsequently created +// FIFOs. Only the first call has an effect. +func SetInformerMetricsProvider(metricsProvider InformerMetricsProvider) { + setInformerMetricsProviderOnce.Do(func() { + globalInformerMetricsProvider = metricsProvider + }) +} + +func newFIFOMetrics(id InformerNameAndResource, metricsProvider InformerMetricsProvider) *fifoMetrics { + if metricsProvider == nil { + metricsProvider = globalInformerMetricsProvider + } + metrics := &fifoMetrics{ + numberOfQueuedItem: noopMetric{}, + processingLatency: noopMetric{}, + } + + if id.Reserved() { + metrics.numberOfQueuedItem = metricsProvider.NewQueuedItemMetric(id) + metrics.processingLatency = metricsProvider.NewProcessingLatencyMetric(id) + } + + return metrics +} + +func newStoreMetrics(id InformerNameAndResource, metricsProvider InformerMetricsProvider) *storeMetrics { + if metricsProvider == nil { + metricsProvider = globalInformerMetricsProvider + } + metrics := &storeMetrics{ + storeResourceVersion: noopMetric{}, + } + + if id.Reserved() { + metrics.storeResourceVersion = metricsProvider.NewStoreResourceVersionMetric(id) + } + + return metrics +} + +func (noopInformerMetricsProvider) NewQueuedItemMetric(InformerNameAndResource) GaugeMetric { + return noopMetric{} +} + +func (noopInformerMetricsProvider) NewProcessingLatencyMetric(InformerNameAndResource) HistogramMetric { + return noopMetric{} +} + +func (noopInformerMetricsProvider) NewStoreResourceVersionMetric(InformerNameAndResource) GaugeMetric { + return noopMetric{} +} diff --git a/vendor/k8s.io/client-go/tools/cache/identity.go b/vendor/k8s.io/client-go/tools/cache/identity.go new file mode 100644 index 0000000000..eed278dc06 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/identity.go @@ -0,0 +1,217 @@ +/* +Copyright 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 cache is a client-side caching mechanism. It is useful for +// reducing the number of server calls you'd otherwise need to make. +// Reflector watches a server and updates a Store. Two stores are provided; +// one that simply caches objects (for example, to allow a scheduler to +// list currently available nodes), and one that additionally acts as +// a FIFO queue (for example, to allow a scheduler to process incoming +// pods). +package cache + +import ( + "fmt" + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" +) + +// informerNameRegistry tracks all registered InformerName instances to detect collisions. +// Names must be globally unique across a process. +var informerNameRegistry = struct { + sync.Mutex + names map[string]*InformerName +}{ + names: make(map[string]*InformerName), +} + +// InformerName represents a named informer identity used for metrics. +// It is created once at startup (e.g., in cmd/kube-controller-manager) and passed to +// the SharedInformerFactory. The name must be globally unique within a process. +// +// InformerName tracks which GVRs have been registered under +// this name. When an informer requests a name+GVR combination, the first one wins +// and gets metrics enabled. Subsequent requests for the same GVR silently get +// metrics disabled. +type InformerName struct { + name string + // lock protects gvrs map modifications + lock sync.Mutex + // reserved is flipped to false when Release() is called + reserved *atomic.Bool + // gvrs maps each registered GVR to its atomic bool for lock-free Reserved() checks + gvrs map[schema.GroupVersionResource]*atomic.Bool +} + +// NewInformerName creates a new InformerName with the given name. +// The name must be globally unique within the process. If a name collision +// is detected, an error is returned. +// +// The caller should call Release() when the informer name is no longer needed +// (eg. at shutdown) to allow the name to be reused. +func NewInformerName(name string) (*InformerName, error) { + if name == "" { + return nil, fmt.Errorf("informer name cannot be empty") + } + + informerNameRegistry.Lock() + defer informerNameRegistry.Unlock() + + if existing, ok := informerNameRegistry.names[name]; ok { + // Check if the existing one is still reserved + if existing.reserved.Load() { + return nil, fmt.Errorf("informer name %q is already registered", name) + } + // Previous one was released, we can reuse the name + delete(informerNameRegistry.names, name) + } + + reserved := &atomic.Bool{} + reserved.Store(true) + + n := &InformerName{ + name: name, + reserved: reserved, + gvrs: make(map[schema.GroupVersionResource]*atomic.Bool), + } + + informerNameRegistry.names[name] = n + return n, nil +} + +// WithResource registers a GVR under this InformerName and returns an +// InformerNameAndResource that can be passed to FIFO/SharedIndexInformer. +// +// If this is the first time this GVR is registered under this name, the +// returned InformerNameAndResource will have Reserved() return true. +// If the GVR was already registered, the returned InformerNameAndResource +// will have Reserved() return false to prevent duplicate metrics. +func (n *InformerName) WithResource(gvr schema.GroupVersionResource) InformerNameAndResource { + if n == nil { + return InformerNameAndResource{gvr: gvr} + } + + n.lock.Lock() + defer n.lock.Unlock() + + retval := InformerNameAndResource{name: n.name, gvr: gvr, reserved: &atomic.Bool{}} + if n.reserved.Load() { + if _, gvrExists := n.gvrs[gvr]; !gvrExists { + retval.reserved.Store(true) + n.gvrs[gvr] = retval.reserved + } else { + // WithResource is called by generated informer code and probably + // not worth converting to contextual logging, which would require + // changing all those generated APIs. + klog.TODO().Error(nil, "Duplicate informer registration - metrics will not be published", "informerName", n.name, "group", gvr.Group, "version", gvr.Version, "resource", gvr.Resource) + } + } + return retval +} + +// Release marks this InformerName as no longer in use. +// All InformerNameAndResource instances created from this InformerName +// will have their Reserved() return false after this call. +// The name can be reused by a subsequent NewInformerName call. +func (n *InformerName) Release() { + if n == nil { + return + } + + n.lock.Lock() + defer n.lock.Unlock() + + // Flip all GVR-specific flags so that any InformerNameAndResource + // instances that were returned from WithResource() will have + // Reserved() return false. These instances hold pointers to the + // same atomic bools, so we must flip them before clearing the map. + for _, reserved := range n.gvrs { + reserved.Store(false) + } + + // Clear the map + n.gvrs = make(map[schema.GroupVersionResource]*atomic.Bool) + + // Flip the main reserved flag + n.reserved.Store(false) + + // Remove from global registry + informerNameRegistry.Lock() + defer informerNameRegistry.Unlock() + delete(informerNameRegistry.names, n.name) +} + +// Name returns the name of this InformerName. +func (n *InformerName) Name() string { + if n == nil { + return "" + } + return n.name +} + +// InformerNameAndResource represents a specific informer identity with both +// a name and a GVR. This is passed to FIFO and SharedIndexInformer for metrics. +// +// The Reserved() method provides a lock-free check to determine +// if metrics should be published. This is called on every queue operation +// so it must be fast. +type InformerNameAndResource struct { + name string + gvr schema.GroupVersionResource + reserved *atomic.Bool +} + +// Reserved returns true if this informer identity is reserved for metrics. +// This is a lock-free atomic load, safe and fast for hot-path usage. +// +// Returns false if: +// - The InformerNameAndResource is zero-valued (no name was configured) +// - The parent InformerName was released +// - This was a duplicate GVR registration +func (n InformerNameAndResource) Reserved() bool { + if n.reserved == nil { + return false + } + return n.reserved.Load() +} + +// Name returns the informer name. +func (n InformerNameAndResource) Name() string { + return n.name +} + +// GroupVersionResource returns the GVR for this informer identity. +func (n InformerNameAndResource) GroupVersionResource() schema.GroupVersionResource { + return n.gvr +} + +// ResetInformerNamesForTesting clears the informer name registry. +// This is exported for testing purposes only. +func ResetInformerNamesForTesting() { + informerNameRegistry.Lock() + names := make([]*InformerName, 0, len(informerNameRegistry.names)) + for _, name := range informerNameRegistry.names { + names = append(names, name) + } + informerNameRegistry.Unlock() + + for _, name := range names { + name.Release() + } +} diff --git a/vendor/k8s.io/client-go/tools/cache/reflector.go b/vendor/k8s.io/client-go/tools/cache/reflector.go index af2c7a22d0..a0e3a701cd 100644 --- a/vendor/k8s.io/client-go/tools/cache/reflector.go +++ b/vendor/k8s.io/client-go/tools/cache/reflector.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "io" + "math" "math/rand" "reflect" "strings" @@ -50,9 +51,21 @@ import ( const defaultExpectedTypeName = "" -// We try to spread the load on apiserver by setting timeouts for -// watch requests - it is random in [minWatchTimeout, 2*minWatchTimeout]. -var defaultMinWatchTimeout = 5 * time.Minute +var ( + // We try to spread the load on apiserver by setting timeouts for + // watch requests - it is random in [minWatchTimeout, 2*minWatchTimeout]. + defaultMinWatchTimeout = 5 * time.Minute + defaultMaxWatchTimeout = 2 * defaultMinWatchTimeout + // We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when + // API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is + // 0.22 QPS. + defaultBackoffInit = 800 * time.Millisecond + defaultBackoffMax = 30 * time.Second + // If we don't backoff for 2min, assume API server is healthy and we reset the backoff. + defaultBackoffReset = 2 * time.Minute + defaultBackoffFactor = 2.0 + defaultBackoffJitter = 1.0 +) // ReflectorStore is the subset of cache.Store that the reflector uses type ReflectorStore interface { @@ -76,6 +89,12 @@ type ReflectorStore interface { Resync() error } +// ReflectorBookmarkStore is an optional interface that allows a store +// to be informed of bookmark events received by the reflector. +type ReflectorBookmarkStore interface { + Bookmark(resourceVersion string) error +} + // TransformingStore is an optional interface that can be implemented by the provided store. // If implemented on the provided store reflector will use the same transformer in its internal stores. type TransformingStore interface { @@ -85,6 +104,7 @@ type TransformingStore interface { // Reflector watches a specified resource and causes all changes to be reflected in the given store. type Reflector struct { + logger klog.Logger // name identifies this reflector. By default, it will be a file:line if possible. name string // The name of the type we expect to place in the store. The name @@ -103,11 +123,14 @@ type Reflector struct { store ReflectorStore // listerWatcher is used to perform lists and watches. listerWatcher ListerWatcherWithContext - // backoff manages backoff of ListWatch - backoffManager wait.BackoffManager - resyncPeriod time.Duration + // delay returns the next backoff interval for retries. + resyncPeriod time.Duration + delayHandler wait.DelayFunc // minWatchTimeout defines the minimum timeout for watch requests. minWatchTimeout time.Duration + // maxWatchTimeout defines the maximum timeout for watch requests. + // Actual timeout is random in [minWatchTimeout, maxWatchTimeout]. + maxWatchTimeout time.Duration // clock allows tests to manipulate time clock clock.Clock // paginatedResult defines whether pagination should be forced for list calls. @@ -227,6 +250,10 @@ func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, // ReflectorOptions configures a Reflector. type ReflectorOptions struct { + // Logger, if not nil, is used instead of klog.Background() for logging. + // The name of the reflector gets added automatically. + Logger *klog.Logger + // Name is the Reflector's name. If unset/unspecified, the name defaults to the closest source_file.go:line // in the call stack that is outside this package. Name string @@ -248,6 +275,12 @@ type ReflectorOptions struct { // Clock allows tests to control time. If unset defaults to clock.RealClock{} Clock clock.Clock + + // Backoff is an optional custom backoff configuration. + // If set, it will be used instead of the default exponential backoff. + // DelayWithReset(clock, resetDuration) will be called on it to create the delay function. + // TODO(#136943): Expose this configuration through SharedInformerFactory. + Backoff *wait.Backoff } // NewReflectorWithOptions creates a new Reflector object which will keep the @@ -265,21 +298,42 @@ func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store R if reflectorClock == nil { reflectorClock = clock.RealClock{} } + minWatchTimeout := defaultMinWatchTimeout + maxWatchTimeout := defaultMaxWatchTimeout if options.MinWatchTimeout > defaultMinWatchTimeout { minWatchTimeout = options.MinWatchTimeout + maxWatchTimeout = 2 * minWatchTimeout + } + if maxWatchTimeout < minWatchTimeout { + klog.TODO().V(3).Info( + "maxWatchTimeout was less than minWatchTimeout, overriding to minWatchTimeout. Watch timeout randomization is disabled.", + "minWatchTimeout", minWatchTimeout, + "maxWatchTimeout", maxWatchTimeout, + ) + maxWatchTimeout = minWatchTimeout } + + backoff := options.Backoff + if backoff == nil { + backoff = &wait.Backoff{ + Duration: defaultBackoffInit, + Cap: defaultBackoffMax, + Steps: int(math.Ceil(float64(defaultBackoffMax) / float64(defaultBackoffInit))), + Factor: defaultBackoffFactor, + Jitter: defaultBackoffJitter, + } + } + r := &Reflector{ - name: options.Name, - resyncPeriod: options.ResyncPeriod, - minWatchTimeout: minWatchTimeout, - typeDescription: options.TypeDescription, - listerWatcher: ToListerWatcherWithContext(lw), - store: store, - // We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when - // API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is - // 0.22 QPS. If we don't backoff for 2min, assume API server is healthy and we reset the backoff. - backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + name: options.Name, + resyncPeriod: options.ResyncPeriod, + minWatchTimeout: minWatchTimeout, + maxWatchTimeout: maxWatchTimeout, + typeDescription: options.TypeDescription, + listerWatcher: ToListerWatcherWithContext(lw), + store: store, + delayHandler: backoff.DelayWithReset(reflectorClock, defaultBackoffReset), clock: reflectorClock, watchErrorHandler: WatchErrorHandlerWithContext(DefaultWatchErrorHandler), expectedType: reflect.TypeOf(expectedType), @@ -289,6 +343,13 @@ func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store R r.name = naming.GetNameFromCallsite(internalPackages...) } + logger := klog.Background() + if options.Logger != nil { + logger = *options.Logger + } + logger = klog.LoggerWithName(logger, r.name) + r.logger = logger + if r.typeDescription == "" { r.typeDescription = getTypeDescriptionFromObject(expectedType) } @@ -299,11 +360,8 @@ func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store R r.useWatchList = clientfeatures.FeatureGates().Enabled(clientfeatures.WatchListClient) if r.useWatchList && watchlist.DoesClientNotSupportWatchListSemantics(lw) { - // Using klog.TODO() here because switching to a caller-provided contextual logger - // would require an API change and updating all existing call sites. - klog.TODO().V(2).Info( - "The provided ListWatcher doesn't support WatchList semantics. The feature will be disabled. If you are using a custom client, check the documentation of watchlist.DoesClientNotSupportWatchListSemantics() method", - "listWatcherType", fmt.Sprintf("%T", lw), + r.logger.V(2).Info( + "The client used to build this informer/reflector doesn't support WatchList semantics. The feature will be disabled. This is expected in unit tests but not in production. For details, see the documentation of watchlist.DoesClientNotSupportWatchListSemantics().", "feature", clientfeatures.WatchListClient, ) r.useWatchList = false @@ -365,11 +423,14 @@ func (r *Reflector) Run(stopCh <-chan struct{}) { func (r *Reflector) RunWithContext(ctx context.Context) { logger := klog.FromContext(ctx) logger.V(3).Info("Starting reflector", "type", r.typeDescription, "resyncPeriod", r.resyncPeriod, "reflector", r.name) - wait.BackoffUntil(func() { + // Until runs the loop immediately (immediate=true) and resets the backoff timer after each + // successful iteration (sliding=true). See backoff constants at top of file for generalized QPS targets (~0.22 QPS). + _ = r.delayHandler.Until(ctx, true, true, func(ctx context.Context) (bool, error) { if err := r.ListAndWatchWithContext(ctx); err != nil { r.watchErrorHandler(ctx, r, err) } - }, r.backoffManager, true, ctx.Done()) + return false, nil + }) logger.V(3).Info("Stopping reflector", "type", r.typeDescription, "resyncPeriod", r.resyncPeriod, "reflector", r.name) } @@ -521,8 +582,10 @@ func (r *Reflector) watch(ctx context.Context, w watch.Interface, resyncerrc cha // start the clock before sending the request, since some proxies won't flush headers until after the first watch event is sent start := r.clock.Now() + // if w is already initialized, it must be past any synthetic non-rv-ordered added events + propagateRVFromStart := true if w == nil { - timeoutSeconds := int64(r.minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + timeoutSeconds := int64(r.minWatchTimeout.Seconds() + rand.Float64()*(r.maxWatchTimeout.Seconds()-r.minWatchTimeout.Seconds())) options := metav1.ListOptions{ ResourceVersion: r.LastSyncResourceVersion(), // We want to avoid situations of hanging watchers. Stop any watchers that do not @@ -533,6 +596,11 @@ func (r *Reflector) watch(ctx context.Context, w watch.Interface, resyncerrc cha // watch bookmarks, it will ignore this field). AllowWatchBookmarks: true, } + if options.ResourceVersion == "" || options.ResourceVersion == "0" { + // if we're starting the watch at a resource version that will get synthetic ADDED events in non-rv order, + // wait until we're through that set of events before propagating the RV + propagateRVFromStart = false + } w, err = r.listerWatcher.WatchWithContext(ctx, options) if err != nil { @@ -541,7 +609,7 @@ func (r *Reflector) watch(ctx context.Context, w watch.Interface, resyncerrc cha select { case <-stopCh: return nil - case <-r.backoffManager.Backoff().C(): + case <-r.clock.After(r.delayHandler()): continue } } @@ -549,7 +617,25 @@ func (r *Reflector) watch(ctx context.Context, w watch.Interface, resyncerrc cha } } - err = handleWatch(ctx, start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.typeDescription, r.setLastSyncResourceVersion, + err = handleWatch(ctx, start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.typeDescription, + func(rv string, eventReceivedBesidesAdded bool) { + // We update the resource version in the store only if we have received at least one event that is + // not an added event, or if the resource version has been set previously. This is because we can + // encounter 2 scenarios: + // 1. The watch is started from a resource version specified by the LastSyncResourceVersion field. + // In this case, we can update the resource version in the store without worrying about it being + // out of order since we will not receive any synthetic added events for resources that may be + // out of order. + // 2. The watch is started when the LastSyncResourceVersion field is empty. In this case, we may not + // update the LastSyncResourceVersion until we receive at least one event that is not an added + // event, since that is the only way to ensure that the watch has exited the initial list phase. + if propagateRVFromStart || eventReceivedBesidesAdded { + r.setLastSyncResourceVersion(rv) + if rvu, ok := r.store.(ResourceVersionUpdater); ok { + rvu.UpdateResourceVersion(rv) + } + } + }, r.clock, resyncerrc) // handleWatch always stops the watcher. So we don't need to here. // Just set it to nil to trigger a retry on the next loop. @@ -568,7 +654,7 @@ func (r *Reflector) watch(ctx context.Context, w watch.Interface, resyncerrc cha select { case <-stopCh: return nil - case <-r.backoffManager.Backoff().C(): + case <-r.clock.After(r.delayHandler()): continue } case apierrors.IsInternalError(err) && retry.ShouldRetry(): @@ -641,6 +727,11 @@ func (r *Reflector) list(ctx context.Context) error { // the reflector makes forward progress. list, paginatedResult, err = pager.ListWithAlloc(context.Background(), metav1.ListOptions{ResourceVersion: r.relistResourceVersion()}) } + if err == nil { + if unsupportedList, unsupportedListGVK := isUnsupportedTableListObject(list); unsupportedList { + err = fmt.Errorf("unsupported list gvk: %v, type: %v", unsupportedListGVK, r.typeDescription) + } + } close(listCh) }() select { @@ -650,6 +741,7 @@ func (r *Reflector) list(ctx context.Context) error { panic(r) case <-listCh: } + initTrace.Step("Objects listed", trace.Field{Key: "error", Value: err}) if err != nil { return fmt.Errorf("failed to list %v: %w", r.typeDescription, err) @@ -722,7 +814,7 @@ func (r *Reflector) watchList(ctx context.Context) (watch.Interface, error) { isErrorRetriableWithSideEffectsFn := func(err error) bool { if canRetry := isWatchErrorRetriable(err); canRetry { logger.V(2).Info("watch-list failed - backing off", "reflector", r.name, "type", r.typeDescription, "err", err) - <-r.backoffManager.Backoff().C() + <-r.clock.After(r.delayHandler()) return true } if isExpiredError(err) || isTooLargeResourceVersionError(err) { @@ -758,7 +850,7 @@ func (r *Reflector) watchList(ctx context.Context) (watch.Interface, error) { // TODO(#115478): large "list", slow clients, slow network, p&f // might slow down streaming and eventually fail. // maybe in such a case we should retry with an increased timeout? - timeoutSeconds := int64(r.minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + timeoutSeconds := int64(r.minWatchTimeout.Seconds() + rand.Float64()*(r.maxWatchTimeout.Seconds()-r.minWatchTimeout.Seconds())) options := metav1.ListOptions{ ResourceVersion: lastKnownRV, AllowWatchBookmarks: true, @@ -776,7 +868,11 @@ func (r *Reflector) watchList(ctx context.Context) (watch.Interface, error) { return nil, err } watchListBookmarkReceived, err := handleListWatch(ctx, start, w, temporaryStore, r.expectedType, r.expectedGVK, r.name, r.typeDescription, - func(rv string) { resourceVersion = rv }, + func(rv string, eventReceivedBesidesAdded bool) { + if eventReceivedBesidesAdded { + resourceVersion = rv + } + }, r.clock, make(chan error)) if err != nil { w.Stop() // stop and retry with clean state @@ -833,7 +929,7 @@ func handleListWatch( expectedGVK *schema.GroupVersionKind, name string, expectedTypeName string, - setLastSyncResourceVersion func(string), + setLastSyncResourceVersion func(string, bool), clock clock.Clock, errCh chan error, ) (bool, error) { @@ -854,7 +950,7 @@ func handleWatch( expectedGVK *schema.GroupVersionKind, name string, expectedTypeName string, - setLastSyncResourceVersion func(string), + setLastSyncResourceVersion func(string, bool), clock clock.Clock, errCh chan error, ) error { @@ -882,12 +978,13 @@ func handleAnyWatch( expectedGVK *schema.GroupVersionKind, name string, expectedTypeName string, - setLastSyncResourceVersion func(string), + setLastSyncResourceVersion func(string, bool), exitOnWatchListBookmarkReceived bool, clock clock.Clock, errCh chan error, ) (bool, error) { watchListBookmarkReceived := false + eventReceivedBesidesAdded := false eventCount := 0 logger := klog.FromContext(ctx) initialEventsEndBookmarkWarningTicker := newInitialEventsEndBookmarkTicker(logger, name, clock, start, exitOnWatchListBookmarkReceived) @@ -925,14 +1022,11 @@ loop: continue } } - // For now, let’s block unsupported Table - // resources for watchlist only + // we don't support receiving resources in Table format // see #132926 for more info - if exitOnWatchListBookmarkReceived { - if unsupportedGVK := isUnsupportedTableObject(event.Object); unsupportedGVK { - utilruntime.HandleErrorWithContext(ctx, nil, "Unsupported watch event object gvk", "reflector", name, "actualGVK", event.Object.GetObjectKind().GroupVersionKind()) - continue - } + if unsupportedGVK := isUnsupportedTableObject(event.Object); unsupportedGVK { + utilruntime.HandleErrorWithContext(ctx, nil, "Unsupported watch event object gvk", "reflector", name, "actualGVK", event.Object.GetObjectKind().GroupVersionKind()) + continue } meta, err := meta.Accessor(event.Object) if err != nil { @@ -947,6 +1041,7 @@ loop: utilruntime.HandleErrorWithContext(ctx, err, "Unable to add watch event object to store", "reflector", name, "object", event.Object) } case watch.Modified: + eventReceivedBesidesAdded = true err := store.Update(event.Object) if err != nil { utilruntime.HandleErrorWithContext(ctx, err, "Unable to update watch event object to store", "reflector", name, "object", event.Object) @@ -955,22 +1050,29 @@ loop: // TODO: Will any consumers need access to the "last known // state", which is passed in event.Object? If so, may need // to change this. + eventReceivedBesidesAdded = true err := store.Delete(event.Object) if err != nil { utilruntime.HandleErrorWithContext(ctx, err, "Unable to delete watch event object from store", "reflector", name, "object", event.Object) } case watch.Bookmark: // A `Bookmark` means watch has synced here, just update the resourceVersion + eventReceivedBesidesAdded = true if meta.GetAnnotations()[metav1.InitialEventsAnnotationKey] == "true" { watchListBookmarkReceived = true } + // Propagate the resource version from the bookmark event to stores which indicate they want it + if bookmarkStore, ok := store.(ReflectorBookmarkStore); ok { + err := bookmarkStore.Bookmark(resourceVersion) + if err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "Unable to send bookmark event to store", "reflector", name, "object", event.Object) + } + } default: utilruntime.HandleErrorWithContext(ctx, err, "Unknown watch event", "reflector", name, "event", event) } - setLastSyncResourceVersion(resourceVersion) - if rvu, ok := store.(ResourceVersionUpdater); ok { - rvu.UpdateResourceVersion(resourceVersion) - } + // when eventReceivedBesidesAdded is true, that indicates we are definitely past any initial synthetic Added events + setLastSyncResourceVersion(resourceVersion, eventReceivedBesidesAdded) eventCount++ if exitOnWatchListBookmarkReceived && watchListBookmarkReceived { stopWatcher = false @@ -1220,3 +1322,12 @@ func isUnsupportedTableObject(rawObject runtime.Object) bool { return unsupportedTableGVK[rawObject.GetObjectKind().GroupVersionKind()] } + +func isUnsupportedTableListObject(rawObject runtime.Object) (bool, schema.GroupVersionKind) { + unstructuredObj, ok := rawObject.(*unstructured.UnstructuredList) + if !ok { + return false, schema.GroupVersionKind{} + } + + return unsupportedTableGVK[unstructuredObj.GetObjectKind().GroupVersionKind()], unstructuredObj.GetObjectKind().GroupVersionKind() +} diff --git a/vendor/k8s.io/client-go/tools/cache/reflector_metrics.go b/vendor/k8s.io/client-go/tools/cache/reflector_metrics.go index 5c00115f59..65e8a38afb 100644 --- a/vendor/k8s.io/client-go/tools/cache/reflector_metrics.go +++ b/vendor/k8s.io/client-go/tools/cache/reflector_metrics.go @@ -40,6 +40,12 @@ type SummaryMetric interface { Observe(float64) } +// HistogramMetric captures individual observations into configurable buckets. +// It also provides a sum and count of observations. +type HistogramMetric interface { + Observe(float64) +} + type noopMetric struct{} func (noopMetric) Inc() {} diff --git a/vendor/k8s.io/client-go/tools/cache/shared_informer.go b/vendor/k8s.io/client-go/tools/cache/shared_informer.go index 8973a33e8f..4cec4283f1 100644 --- a/vendor/k8s.io/client-go/tools/cache/shared_informer.go +++ b/vendor/k8s.io/client-go/tools/cache/shared_informer.go @@ -20,7 +20,11 @@ import ( "context" "errors" "fmt" + "reflect" + "slices" + "strings" "sync" + "sync/atomic" "time" "k8s.io/apimachinery/pkg/api/meta" @@ -31,6 +35,7 @@ import ( "k8s.io/utils/buffer" "k8s.io/utils/clock" "k8s.io/utils/ptr" + utiltrace "k8s.io/utils/trace" "k8s.io/klog/v2" @@ -193,6 +198,14 @@ type SharedInformer interface { // For that, please call HasSynced on the handle returned by // AddEventHandler. HasSynced() bool + // HasSyncedChecker completes if the shared informer's store has been + // informed by at least one full LIST of the authoritative state + // of the informer's object collection. This is unrelated to "resync". + // + // Note that this doesn't tell you if an individual handler is synced!! + // For that, please use HasSyncedChecker on the handle returned by + // AddEventHandler. + HasSyncedChecker() DoneChecker // LastSyncResourceVersion is the resource version observed when last synced with the underlying // store. The value returned is not synchronized with access to the underlying store and is not // thread-safe. @@ -246,6 +259,10 @@ type ResourceEventHandlerRegistration interface { // HasSynced reports if both the parent has synced and all pre-sync // events have been delivered. HasSynced() bool + + // HasSyncedChecker reports if both the parent has synced and all pre-sync + // events have been delivered. + HasSyncedChecker() DoneChecker } // Optional configuration options for [SharedInformer.AddEventHandlerWithOptions]. @@ -302,9 +319,13 @@ func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defa func NewSharedIndexInformerWithOptions(lw ListerWatcher, exampleObject runtime.Object, options SharedIndexInformerOptions) SharedIndexInformer { realClock := &clock.RealClock{} + processor := &sharedProcessor{clock: realClock} + processor.listenersRCond = sync.NewCond(processor.listenersLock.RLocker()) + return &sharedIndexInformer{ - indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers), - processor: &sharedProcessor{clock: realClock}, + indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers, WithStoreMetrics(options.Identifier, options.InformerMetricsProvider)), + processor: processor, + synced: make(chan struct{}), listerWatcher: lw, objectType: exampleObject, objectDescription: options.ObjectDescription, @@ -312,6 +333,9 @@ func NewSharedIndexInformerWithOptions(lw ListerWatcher, exampleObject runtime.O defaultEventHandlerResyncPeriod: options.ResyncPeriod, clock: realClock, cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), + identifier: options.Identifier, + informerMetricsProvider: options.InformerMetricsProvider, + keyFunc: DeletionHandlingMetaNamespaceKeyFunc, } } @@ -327,6 +351,14 @@ type SharedIndexInformerOptions struct { // ObjectDescription is the sharedIndexInformer's object description. This is passed through to the // underlying Reflector's type description. ObjectDescription string + + // Identifier is used to identify the FIFO for metrics and logging purposes. + // If not set, metrics will not be published. + Identifier InformerNameAndResource + + // InformerMetricsProvider is the metrics provider for the FIFO queue. + // If not set, metrics will be no-ops. + InformerMetricsProvider InformerMetricsProvider } // InformerSynced is a function that can be used to determine if an informer has synced. This is useful for determining if caches have synced. @@ -399,6 +431,147 @@ func WaitForCacheSync(stopCh <-chan struct{}, cacheSyncs ...InformerSynced) bool return true } +// WaitFor waits for a set of activities to complete, like cache syncing. +// It returns true if it was successful, false if the context was canceled +// before all activities are completed. +// +// If a non-nil "what" is provided, then progress information is logged +// while waiting ("Waiting", for=""). Verbosity is V(0). This can +// be made less verbose by the caller with: +// +// WaitFor(klog.NewContext(ctx, klog.FromContext(ctx).V(2)), ...) +// +// In contrast to other WaitForCacheSync alternatives, this one here doesn't +// need polling, which makes it react immediately. When used in a synctest unit +// test, waiting completes without moving time forward randomly, which +// makes tests more predictable. +func WaitFor(ctx context.Context, what string, checkers ...DoneChecker) bool { + logger := klog.FromContext(ctx) + if what != "" { + helper, l := logger.WithCallStackHelper() + logger = l + helper() + logger.Info("Waiting", "for", what) + } + + // Check in parallel to ensure that we log "Done waiting" as soon + // as possible for each checker. The timing may be useful to know. + // We cannot log inside the goroutine, the stack unwinding wouldn't + // work, so instead each goroutine just notifies the parent + // goroutine when it's checker is done and the main goroutine then + // logs it. + var wg sync.WaitGroup + type result struct { + checker DoneChecker + done bool + } + doneChecker := make(chan result) + for _, checker := range checkers { + wg.Go(func() { + select { + case <-checker.Done(): + doneChecker <- result{checker, true} + case <-ctx.Done(): + // We can end up here even when the checker is already done, + // select is not deterministic. Check once more without blocking + // before finally giving up. + select { + case <-checker.Done(): + doneChecker <- result{checker, true} + default: + doneChecker <- result{checker, false} + } + } + }) + } + instances := make([]string, 0, len(checkers)) + for range len(checkers) { + // We are guaranteed to get exactly one result from each goroutine, so this won't block forever. + result := <-doneChecker + if result.done { + if what != "" { + logger.Info("Done waiting", "for", what, "instance", result.checker.Name()) + } + } else { + // We don't need this information unless we are a) logging or b) debugging interactively. + instances = append(instances, result.checker.Name()) + } + } + wg.Wait() + + if what != "" && len(instances) > 0 { + slices.Sort(instances) + logger.Info("Timed out waiting", "for", what, "cause", context.Cause(ctx), "instances", instances) + } + + done := len(instances) == 0 + return done +} + +// DoneChecker, in contrast to [InformerSynced], supports waiting +// for some activity to finish without polling and has a name +// that describes itself. +// +// To check for completion without blocking, use [IsDone]. +type DoneChecker interface { + // Name returns a string describing the entity that is being waited for. + // + // Note that this name might be computed, so callers should only + // get the name outside of a hot code path. + Name() string + + // Done returns a channel that will be closed on completion + // of the activity. + Done() <-chan struct{} +} + +// IsDone returns true if the activity is done, false otherwise. +func IsDone(checker DoneChecker) bool { + select { + case <-checker.Done(): + return true + default: + return false + } +} + +// SyncResult is the result of a shared informer factory's WaitForCacheSyncWithContext. +// Under the hood such factories use [WaitFor] to wait for all instantiated informers, +// then provide this summary of what was synced. +// +// Note that the informers may have synced already before all event handlers registered with +// those informers have synced. Code which wants to be sure that all of its state is up-to-date +// should do its own WaitFor with the informer's HasSyncedChecker() *and* the +// registration handle's HasSyncChecker() results. +type SyncResult struct { + // Err is nil if all informer caches were synced, otherwise it is + // the reason why waiting for cache syncing stopped (= context.Cause(ctx)). + Err error + + // Synced maps each registered informer in a SharedInformerFactory to + // true if it has synced, false otherwise. + Synced map[reflect.Type]bool +} + +// AsError turns a SyncResult into an error if not all caches were synced, +// otherwise it returns nil. The error wraps context.Cause(ctx) and +// includes information about the informers which were not synced. +func (c SyncResult) AsError() error { + if c.Err == nil { + return nil + } + + unsynced := make([]string, 0, len(c.Synced)) + for t, synced := range c.Synced { + if !synced { + unsynced = append(unsynced, t.String()) + } + } + slices.Sort(unsynced) + + return fmt.Errorf("failed to sync all caches: %s: %w", strings.Join(unsynced, ", "), c.Err) +} + // `*sharedIndexInformer` implements SharedIndexInformer and has three // main components. One is an indexed local cache, `indexer Indexer`. // The second main component is a Controller that pulls @@ -416,6 +589,10 @@ type sharedIndexInformer struct { indexer Indexer controller Controller + // synced gets created when creating the sharedIndexInformer. + // It gets closed when Run detects that the processor created + synced chan struct{} + processor *sharedProcessor cacheMutationDetector MutationDetector @@ -449,6 +626,15 @@ type sharedIndexInformer struct { watchErrorHandler WatchErrorHandlerWithContext transform TransformFunc + + // identifier is used to identify this informer for metrics and logging purposes. + identifier InformerNameAndResource + + // informerMetricsProvider is the metrics provider for the FIFO queue. + informerMetricsProvider InformerMetricsProvider + + // keyFunc is called when processing deltas by the underlying process function. + keyFunc KeyFunc } // dummyController hides the fact that a SharedInformer is different from a dedicated one @@ -470,6 +656,10 @@ func (v *dummyController) HasSynced() bool { return v.informer.HasSynced() } +func (v *dummyController) HasSyncedChecker() DoneChecker { + return v.informer.HasSyncedChecker() +} + func (v *dummyController) LastSyncResourceVersion() string { if clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.InformerResourceVersion) { return v.informer.LastSyncResourceVersion() @@ -539,7 +729,7 @@ func (s *sharedIndexInformer) RunWithContext(ctx context.Context) { s.startedLock.Lock() defer s.startedLock.Unlock() - fifo := newQueueFIFO(s.indexer, s.transform) + logger, fifo := newQueueFIFO(logger, s.objectType, s.indexer, s.transform, s.identifier, s.informerMetricsProvider) cfg := &Config{ Queue: fifo, @@ -549,8 +739,12 @@ func (s *sharedIndexInformer) RunWithContext(ctx context.Context) { FullResyncPeriod: s.resyncCheckPeriod, ShouldResync: s.processor.shouldResync, - Process: s.HandleDeltas, - ProcessBatch: s.HandleBatchDeltas, + Process: func(obj interface{}, isInInitialList bool) error { + return s.handleDeltas(logger, obj, isInInitialList) + }, + ProcessBatch: func(deltas []Delta, isInInitialList bool) error { + return s.handleBatchDeltas(logger, deltas, isInInitialList) + }, WatchErrorHandlerWithContext: s.watchErrorHandler, } @@ -570,6 +764,15 @@ func (s *sharedIndexInformer) RunWithContext(ctx context.Context) { // has a RunWithContext method that we can use here. wg.StartWithChannel(processorStopCtx.Done(), s.cacheMutationDetector.Run) wg.StartWithContext(processorStopCtx, s.processor.run) + wg.Start(func() { + select { + case <-ctx.Done(): + // We were stopped without completing the sync. + case <-s.controller.HasSyncedChecker().Done(): + // Controller has synced and thus so have we. + close(s.synced) + } + }) defer func() { s.startedLock.Lock() @@ -586,13 +789,31 @@ func (s *sharedIndexInformer) HasStarted() bool { } func (s *sharedIndexInformer) HasSynced() bool { - s.startedLock.Lock() - defer s.startedLock.Unlock() - - if s.controller == nil { + select { + case <-s.synced: + return true + default: return false } - return s.controller.HasSynced() +} + +func (s *sharedIndexInformer) HasSyncedChecker() DoneChecker { + return &sharedIndexInformerDone{ + s: s, + } +} + +// sharedIndexInformerDone implements [NamedCacheSync] for a [sharedIndexInformer]. +type sharedIndexInformerDone struct { + s *sharedIndexInformer +} + +func (sd *sharedIndexInformerDone) Name() string { + return fmt.Sprintf("SharedIndexInformer %T", sd.s.objectType) +} + +func (sd *sharedIndexInformerDone) Done() <-chan struct{} { + return sd.s.synced } func (s *sharedIndexInformer) LastSyncResourceVersion() string { @@ -684,10 +905,11 @@ func (s *sharedIndexInformer) AddEventHandlerWithOptions(handler ResourceEventHa } } - listener := newProcessListener(logger, handler, resyncPeriod, determineResyncPeriod(logger, resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize, s.HasSynced) + listener := newProcessListener(logger, handler, resyncPeriod, determineResyncPeriod(logger, resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize, s.HasSyncedChecker()) if !s.started { - return s.processor.addListener(listener), nil + handle, _ := s.processor.addListener(listener) + return handle, nil } // in order to safely join, we have to @@ -698,7 +920,7 @@ func (s *sharedIndexInformer) AddEventHandlerWithOptions(handler ResourceEventHa s.blockDeltas.Lock() defer s.blockDeltas.Unlock() - handle := s.processor.addListener(listener) + handle, started := s.processor.addListener(listener) for _, item := range s.indexer.List() { // Note that we enqueue these notifications with the lock held // and before returning the handle. That means there is never a @@ -710,23 +932,29 @@ func (s *sharedIndexInformer) AddEventHandlerWithOptions(handler ResourceEventHa // thread adding them and the counter is temporarily zero). listener.add(addNotification{newObj: item, isInInitialList: true}) } + + // Initial list is added, now we can allow the listener to detect that "upstream has synced". + if started { + s.processor.wg.Start(listener.watchSynced) + } + return handle, nil } -func (s *sharedIndexInformer) HandleDeltas(obj interface{}, isInInitialList bool) error { +func (s *sharedIndexInformer) handleDeltas(logger klog.Logger, obj interface{}, isInInitialList bool) error { s.blockDeltas.Lock() defer s.blockDeltas.Unlock() if deltas, ok := obj.(Deltas); ok { - return processDeltas(s, s.indexer, deltas, isInInitialList) + return processDeltas(logger, s, s.indexer, deltas, isInInitialList, s.keyFunc) } return errors.New("object given as Process argument is not Deltas") } -func (s *sharedIndexInformer) HandleBatchDeltas(deltas []Delta, isInInitialList bool) error { +func (s *sharedIndexInformer) handleBatchDeltas(logger klog.Logger, deltas []Delta, isInInitialList bool) error { s.blockDeltas.Lock() defer s.blockDeltas.Unlock() - return processDeltasInBatch(s, s.indexer, deltas, isInInitialList) + return processDeltasInBatch(logger, s, s.indexer, deltas, isInInitialList, s.keyFunc) } // Conforms to ResourceEventHandler @@ -795,6 +1023,7 @@ func (s *sharedIndexInformer) RemoveEventHandler(handle ResourceEventHandlerRegi type sharedProcessor struct { listenersStarted bool listenersLock sync.RWMutex + listenersRCond *sync.Cond // Caller of Wait must hold a read lock on listenersLock. // Map from listeners to whether or not they are currently syncing listeners map[*processorListener]bool clock clock.Clock @@ -818,7 +1047,7 @@ func (p *sharedProcessor) getListener(registration ResourceEventHandlerRegistrat return nil } -func (p *sharedProcessor) addListener(listener *processorListener) ResourceEventHandlerRegistration { +func (p *sharedProcessor) addListener(listener *processorListener) (ResourceEventHandlerRegistration, bool) { p.listenersLock.Lock() defer p.listenersLock.Unlock() @@ -829,11 +1058,13 @@ func (p *sharedProcessor) addListener(listener *processorListener) ResourceEvent p.listeners[listener] = true if p.listenersStarted { + // Not starting listener.watchSynced! + // The caller must first add the initial list, then start it. p.wg.Start(listener.run) p.wg.Start(listener.pop) } - return listener + return listener, p.listenersStarted } func (p *sharedProcessor) removeListener(handle ResourceEventHandlerRegistration) error { @@ -864,6 +1095,14 @@ func (p *sharedProcessor) distribute(obj interface{}, sync bool) { p.listenersLock.RLock() defer p.listenersLock.RUnlock() + // Before we start blocking on writes to the listeners' channels, + // ensure that they all have been started. If the processor stops, + // p.listeners gets cleared, in which case we also continue here + // and return without doing anything. + for !p.listenersStarted && len(p.listeners) > 0 { + p.listenersRCond.Wait() + } + for listener, isSyncing := range p.listeners { switch { case !sync: @@ -878,15 +1117,26 @@ func (p *sharedProcessor) distribute(obj interface{}, sync bool) { } } +// sharedProcessorRunHook can be used inside tests to execute additional code +// at the start of sharedProcessor.run. +var sharedProcessorRunHook atomic.Pointer[func()] + func (p *sharedProcessor) run(ctx context.Context) { func() { - p.listenersLock.RLock() - defer p.listenersLock.RUnlock() + hook := sharedProcessorRunHook.Load() + if hook != nil { + (*hook)() + } + // Changing listenersStarted needs a write lock. + p.listenersLock.Lock() + defer p.listenersLock.Unlock() for listener := range p.listeners { + p.wg.Start(listener.watchSynced) p.wg.Start(listener.run) p.wg.Start(listener.pop) } p.listenersStarted = true + p.listenersRCond.Signal() }() <-ctx.Done() @@ -903,6 +1153,9 @@ func (p *sharedProcessor) run(ctx context.Context) { // Reset to false since no listeners are running p.listenersStarted = false + // Wake up sharedProcessor.distribute. + p.listenersRCond.Signal() + p.wg.Wait() // Wait for all .pop() and .run() to stop } @@ -940,7 +1193,7 @@ func (p *sharedProcessor) resyncCheckPeriodChanged(logger klog.Logger, resyncChe } // processorListener relays notifications from a sharedProcessor to -// one ResourceEventHandler --- using two goroutines, two unbuffered +// one ResourceEventHandler --- using three goroutines, two unbuffered // channels, and an unbounded ring buffer. The `add(notification)` // function sends the given notification to `addCh`. One goroutine // runs `pop()`, which pumps notifications from `addCh` to `nextCh` @@ -948,16 +1201,24 @@ func (p *sharedProcessor) resyncCheckPeriodChanged(logger klog.Logger, resyncChe // Another goroutine runs `run()`, which receives notifications from // `nextCh` and synchronously invokes the appropriate handler method. // +// The third goroutine watches the upstream "has synced" channel +// and notifies a SingleFileTracker instance. That instance then +// combines the upstream state and the processListener state to +// implement the overall "event handler has synced". +// // processorListener also keeps track of the adjusted requested resync // period of the listener. type processorListener struct { logger klog.Logger nextCh chan interface{} addCh chan interface{} + done chan struct{} - handler ResourceEventHandler + handler ResourceEventHandler + handlerName string - syncTracker *synctrack.SingleFileTracker + syncTracker *synctrack.SingleFileTracker + upstreamHasSynced DoneChecker // pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed. // There is one per listener, but a failing/stalled listener will have infinite pendingNotifications @@ -965,6 +1226,9 @@ type processorListener struct { // TODO: This is no worse than before, since reflectors were backed by unbounded DeltaFIFOs, but // we should try to do something better. pendingNotifications buffer.RingGrowing + // pendingNotificationsLength tracks pendingNotifications size and is only mutated by pop(). + // run() reads this to decide when to enable expensive time tracing. + pendingNotificationsLength atomic.Int64 // requestedResyncPeriod is how frequently the listener wants a // full resync from the shared informer, but modified by two @@ -995,13 +1259,23 @@ func (p *processorListener) HasSynced() bool { return p.syncTracker.HasSynced() } -func newProcessListener(logger klog.Logger, handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int, hasSynced func() bool) *processorListener { +// HasNamedSync is done if the source informer has synced, and all +// corresponding events have been delivered. +func (p *processorListener) HasSyncedChecker() DoneChecker { + return p.syncTracker +} + +func newProcessListener(logger klog.Logger, handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int, hasSynced DoneChecker) *processorListener { + handlerName := nameForHandler(handler) ret := &processorListener{ logger: logger, nextCh: make(chan interface{}), addCh: make(chan interface{}), + done: make(chan struct{}), + upstreamHasSynced: hasSynced, handler: handler, - syncTracker: &synctrack.SingleFileTracker{UpstreamHasSynced: hasSynced}, + handlerName: handlerName, + syncTracker: synctrack.NewSingleFileTracker(fmt.Sprintf("%s + event handler %s", hasSynced.Name(), handlerName)), pendingNotifications: *buffer.NewRingGrowing(bufferSize), requestedResyncPeriod: requestedResyncPeriod, resyncPeriod: resyncPeriod, @@ -1022,6 +1296,7 @@ func (p *processorListener) add(notification interface{}) { func (p *processorListener) pop() { defer utilruntime.HandleCrashWithLogger(p.logger) defer close(p.nextCh) // Tell .run() to stop + defer close(p.done) // Tell .watchSynced() to stop var nextCh chan<- interface{} var notification interface{} @@ -1031,7 +1306,9 @@ func (p *processorListener) pop() { // Notification dispatched var ok bool notification, ok = p.pendingNotifications.ReadOne() - if !ok { // Nothing to pop + if ok { + p.pendingNotificationsLength.Add(-1) + } else { // Nothing to pop nextCh = nil // Disable this select case } case notificationToAdd, ok := <-p.addCh: @@ -1044,6 +1321,7 @@ func (p *processorListener) pop() { nextCh = p.nextCh } else { // There is already a notification waiting to be dispatched p.pendingNotifications.WriteOne(notificationToAdd) + p.pendingNotificationsLength.Add(1) } } } @@ -1066,6 +1344,14 @@ func (p *processorListener) run() { // Gets reset below, but only if we get that far. sleepAfterCrash = true defer utilruntime.HandleCrashWithLogger(p.logger) + pendingNotifications := p.pendingNotificationsLength.Load() + if pendingNotifications > initialBufferSize { + trace := utiltrace.New("processorListener handler", + utiltrace.Field{Key: "handler", Value: p.handlerName}, + utiltrace.Field{Key: "pendingNotifications", Value: pendingNotifications}, + ) + defer trace.LogIfLong(100 * time.Millisecond) + } switch notification := next.(type) { case updateNotification: @@ -1085,6 +1371,16 @@ func (p *processorListener) run() { } } +func (p *processorListener) watchSynced() { + select { + case <-p.upstreamHasSynced.Done(): + // Notify tracker that the upstream has synced. + p.syncTracker.UpstreamHasSynced() + case <-p.done: + // Give up waiting for sync. + } +} + // shouldResync determines if the listener needs a resync. If the listener's resyncPeriod is 0, // this always returns false. func (p *processorListener) shouldResync(now time.Time) bool { diff --git a/vendor/k8s.io/client-go/tools/cache/store.go b/vendor/k8s.io/client-go/tools/cache/store.go index a412fd7014..261ed60d9c 100644 --- a/vendor/k8s.io/client-go/tools/cache/store.go +++ b/vendor/k8s.io/client-go/tools/cache/store.go @@ -55,6 +55,15 @@ type Store interface { // ListKeys returns a list of all the keys currently associated with non-empty accumulators ListKeys() []string + // LastStoreSyncResourceVersion returns the latest resource version that the store has seen. + // This is used to determine the latest resource version the store has seen from objects + // observed being written to the store. + LastStoreSyncResourceVersion() string + + // Bookmark observes a new resource version passed into it and + // will be used to get the latest resource version of the store. + Bookmark(rv string) + // Get returns the accumulator associated with the given object's key Get(obj interface{}) (item interface{}, exists bool, err error) @@ -200,6 +209,10 @@ type cache struct { keyFunc KeyFunc // Called with every object put in the cache. transformer TransformFunc + // identifier is used to identify the store for metrics. + identifier InformerNameAndResource + // metrics is the metrics provider for the store. + metrics InformerMetricsProvider } var _ Store = &cache{} @@ -276,7 +289,7 @@ func (c *cache) Delete(obj interface{}) error { if err != nil { return KeyError{obj, err} } - c.cacheStorage.Delete(key) + c.cacheStorage.DeleteWithObject(key, obj) return nil } @@ -292,6 +305,14 @@ func (c *cache) ListKeys() []string { return c.cacheStorage.ListKeys() } +func (c *cache) LastStoreSyncResourceVersion() string { + return c.cacheStorage.LastStoreSyncResourceVersion() +} + +func (c *cache) Bookmark(rv string) { + c.cacheStorage.Bookmark(rv) +} + // GetIndexers returns the indexers of cache func (c *cache) GetIndexers() Indexers { return c.cacheStorage.GetIndexers() @@ -378,22 +399,41 @@ func WithTransformer(transformer TransformFunc) StoreOption { } } +func WithStoreMetrics(identifier InformerNameAndResource, metrics InformerMetricsProvider) StoreOption { + return func(c *cache) { + c.identifier = identifier + c.metrics = metrics + } +} + // NewStore returns a Store implemented simply with a map and a lock. func NewStore(keyFunc KeyFunc, opts ...StoreOption) Store { c := &cache{ - cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}), - keyFunc: keyFunc, + keyFunc: keyFunc, } for _, opt := range opts { opt(c) } + threadSafeOpts := []ThreadSafeStoreOption{} + if c.metrics != nil { + threadSafeOpts = append(threadSafeOpts, WithThreadSafeStoreMetrics(c.identifier, c.metrics)) + } + c.cacheStorage = NewThreadSafeStore(Indexers{}, Indices{}, threadSafeOpts...) return c } // NewIndexer returns an Indexer implemented simply with a map and a lock. -func NewIndexer(keyFunc KeyFunc, indexers Indexers) Indexer { - return &cache{ - cacheStorage: NewThreadSafeStore(indexers, Indices{}), - keyFunc: keyFunc, +func NewIndexer(keyFunc KeyFunc, indexers Indexers, opts ...StoreOption) Indexer { + c := &cache{ + keyFunc: keyFunc, + } + for _, opt := range opts { + opt(c) } + threadSafeOpts := []ThreadSafeStoreOption{} + if c.metrics != nil { + threadSafeOpts = append(threadSafeOpts, WithThreadSafeStoreMetrics(c.identifier, c.metrics)) + } + c.cacheStorage = NewThreadSafeStore(indexers, Indices{}, threadSafeOpts...) + return c } diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go index 3fa2beb6b7..e941dafb85 100644 --- a/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go @@ -20,6 +20,7 @@ limitations under the License. package synctrack import ( + "context" "sync" "sync/atomic" @@ -27,11 +28,32 @@ import ( ) // AsyncTracker helps propagate HasSynced in the face of multiple worker threads. +// The user has to monitor the upstream "has synced" +// and notify the tracker when that changes from false to true. type AsyncTracker[T comparable] struct { - UpstreamHasSynced func() bool + // name describes the instance. + name string + + // upstreamHasSynced is changed from false (initial value) to true + // when UpstreamHasSynced is called. + upstreamHasSynced atomic.Bool lock sync.Mutex waiting sets.Set[T] + + // synced gets canceled once both the tracker and upstream are synced. + // A context is convenient for this because it gives us a channel + // and handles thread-safety. + synced context.Context + cancel func() +} + +func NewAsyncTracker[T comparable](name string) *AsyncTracker[T] { + t := &AsyncTracker[T]{ + name: name, + } + t.synced, t.cancel = context.WithCancel(context.Background()) + return t } // Start should be called prior to processing each key which is part of the @@ -57,6 +79,28 @@ func (t *AsyncTracker[T]) Finished(key T) { if t.waiting != nil { t.waiting.Delete(key) } + + // Maybe synced now? + if t.upstreamHasSynced.Load() && len(t.waiting) == 0 { + // Mark as synced. + t.cancel() + } +} + +// UpstreamHasSynced needs to be called at least once as soon as +// the upstream "has synced" becomes true. It tells AsyncTracker +// that the source is synced. +// +// Must be called after handing over the initial list to Start. +func (t *AsyncTracker[T]) UpstreamHasSynced() { + // Upstream is done, but we might not be yet. + t.upstreamHasSynced.Store(true) + t.lock.Lock() + defer t.lock.Unlock() + if len(t.waiting) == 0 { + // Mark as synced. + t.cancel() + } } // HasSynced returns true if the source is synced and every key present in the @@ -64,27 +108,51 @@ func (t *AsyncTracker[T]) Finished(key T) { // itself synced until *after* it has delivered the notification for the last // key, and that notification handler must have called Start. func (t *AsyncTracker[T]) HasSynced() bool { - // Call UpstreamHasSynced first: it might take a lock, which might take - // a significant amount of time, and we can't hold our lock while - // waiting on that or a user is likely to get a deadlock. - if !t.UpstreamHasSynced() { - return false - } - t.lock.Lock() - defer t.lock.Unlock() - return t.waiting.Len() == 0 + return t.synced.Err() != nil +} + +// Done returns a channel that is closed if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *AsyncTracker[T]) Done() <-chan struct{} { + return t.synced.Done() +} + +func (t *AsyncTracker[T]) Name() string { + return t.name } // SingleFileTracker helps propagate HasSynced when events are processed in -// order (i.e. via a queue). +// order (i.e. via a queue). The user has to monitor the upstream "has synced" +// and notify the tracker when that changes from false to true. type SingleFileTracker struct { + // name describes the instance. + name string + // Important: count is used with atomic operations so it must be 64-bit // aligned, otherwise atomic operations will panic. Having it at the top of // the struct will guarantee that, even on 32-bit arches. // See https://pkg.go.dev/sync/atomic#pkg-note-BUG for more information. count int64 - UpstreamHasSynced func() bool + // upstreamHasSynced is changed from false (initial value) to true + // when UpstreamHasSynced is called. + upstreamHasSynced atomic.Bool + + // synced gets canceled once both the tracker and upstream are synced. + // A context is convenient for this because it gives us a channel + // and handles thread-safety. + synced context.Context + cancel func() +} + +func NewSingleFileTracker(name string) *SingleFileTracker { + t := &SingleFileTracker{ + name: name, + } + t.synced, t.cancel = context.WithCancel(context.Background()) + return t } // Start should be called prior to processing each key which is part of the @@ -103,6 +171,26 @@ func (t *SingleFileTracker) Finished() { if result < 0 { panic("synctrack: negative counter; this logic error means HasSynced may return incorrect value") } + + // Maybe synced now? + if result == 0 && t.upstreamHasSynced.Load() { + // Mark as synced. + t.cancel() + } +} + +// UpstreamHasSynced needs to be called at least once as soon as +// the upstream "has synced" becomes true. It tells SingleFileTracker +// that the source is synced. +// +// Must be called after handing over the initial list to Start. +func (t *SingleFileTracker) UpstreamHasSynced() { + // Upstream is done, but we might not be yet. + t.upstreamHasSynced.Store(true) + if atomic.LoadInt64(&t.count) == 0 { + // Mark as synced. + t.cancel() + } } // HasSynced returns true if the source is synced and every key present in the @@ -110,11 +198,17 @@ func (t *SingleFileTracker) Finished() { // itself synced until *after* it has delivered the notification for the last // key, and that notification handler must have called Start. func (t *SingleFileTracker) HasSynced() bool { - // Call UpstreamHasSynced first: it might take a lock, which might take - // a significant amount of time, and we don't want to then act on a - // stale count value. - if !t.UpstreamHasSynced() { - return false - } - return atomic.LoadInt64(&t.count) <= 0 + return t.synced.Err() != nil +} + +// Done returns a channel that is closed if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *SingleFileTracker) Done() <-chan struct{} { + return t.synced.Done() +} + +func (t *SingleFileTracker) Name() string { + return t.name } diff --git a/vendor/k8s.io/client-go/tools/cache/the_real_fifo.go b/vendor/k8s.io/client-go/tools/cache/the_real_fifo.go index 933e41bbdc..f29c66653c 100644 --- a/vendor/k8s.io/client-go/tools/cache/the_real_fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/the_real_fifo.go @@ -23,11 +23,20 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/klog/v2" utiltrace "k8s.io/utils/trace" ) // RealFIFOOptions is the configuration parameters for RealFIFO. type RealFIFOOptions struct { + // If set, log output will go to this logger instead of klog.Background(). + // The name of the fifo gets added automatically. + Logger *klog.Logger + + // Name can be used to override the default "RealFIFO" name for the new instance. + // Optional. Used only if Identifier.Name returns an empty string. + Name string + // KeyFunction is used to figure out what key an object should have. (It's // exposed in the returned RealFIFO's keyOf() method, with additional // handling around deleted objects and queue state). @@ -37,12 +46,37 @@ type RealFIFOOptions struct { // KnownObjects is expected to return a list of keys that the consumer of // this queue "knows about". It is used to decide which items are missing // when Replace() is called; 'Deleted' deltas are produced for the missing items. - // KnownObjects is required. + // KnownObjects is required if AtomicEvents is false since it is used to + // query the state of the internal store for Replace and Resync handling. KnownObjects KeyListerGetter // If set, will be called for objects before enqueueing them. Please // see the comment on TransformFunc for details. Transformer TransformFunc + + // AtomicEvents is used to specify whether the RealFIFO will emit events + // atomically or not. If it is set, a single event will be emitted + // atomically for Replace and Resync operations. + // If AtomicEvents is true, KnownObjects must be nil. + AtomicEvents bool + + // UnlockWhileProcessing is used to specify whether the RealFIFO can unlock + // the lock while processing events. If it is set, the lock can be unlocked + // while processing events to allow other goroutines to add items to the queue. + // If UnlockWhileProcessing is true, AtomicEvents must be true as well. + UnlockWhileProcessing bool + + // Identifier is used to identify this FIFO for metrics and logging purposes. + // Optional. If zero value, metrics will not be published and trace logs will not + // include Name or Resource fields. + Identifier InformerNameAndResource + + // MetricsProvider is used to create metrics for the FIFO. + MetricsProvider InformerMetricsProvider + + // EmitDeltaTypeBookmark is used to specify whether the RealFIFO will emit + // bookmark deltas or not. This can only be set if AtomicEvents is true. + EmitDeltaTypeBookmark bool } const ( @@ -57,11 +91,23 @@ var _ QueueWithBatch = &RealFIFO{} // 1. delivers notifications for items that have been deleted // 2. delivers multiple notifications per item instead of simply the most recent value type RealFIFO struct { + // logger is a per-instance logger. This gets chosen when constructing + // the instance, with klog.Background() as default. + logger klog.Logger + + // name is the name of the fifo. It is included in the logger. + name string + lock sync.RWMutex cond sync.Cond items []Delta + // synced is initially an open channel. It gets closed (once!) by checkSynced_locked + // as soon as the initial sync is considered complete. + synced chan struct{} + syncedClosed bool + // populated is true if the first batch of items inserted by Replace() has been populated // or Delete/Add/Update was called first. populated bool @@ -73,7 +119,8 @@ type RealFIFO struct { keyFunc KeyFunc // knownObjects list keys that are "known" --- affecting Delete(), - // Replace(), and Resync() + // Replace(), and Resync(). + // It is nil if emitAtomicEvents is true. knownObjects KeyListerGetter // Indication the queue is closed. @@ -86,11 +133,55 @@ type RealFIFO struct { // batchSize determines the maximum number of objects we can combine into a batch. batchSize int + + // emitAtomicEvents defines whether events like Replace and Resync should be emitted + // atomically rather than as a series of events. This means that any call to the FIFO + // will emit a single event. + // If it is set: + // * a single ReplacedAll event will be emitted instead of multiple Replace events + // * a single SyncAll event will be emitted instead of multiple Sync events + emitAtomicEvents bool + + // unlockWhileProcessing defines whether we can unlock while processing events. + // This may only be set if emitAtomicEvents is true. If unlockWhileProcessing is true, + // Pop and PopBatch must be called from a single threaded consumer. + unlockWhileProcessing bool + + // identifier is used to identify this FIFO for metrics and logging purposes. + identifier InformerNameAndResource + + // metrics holds all metrics for this FIFO. + metrics *fifoMetrics + + // emitDeltaTypeBookmark defines whether bookmark deltas should be emitted. + // This may only be set if emitAtomicEvents is true, which avoids events + // propagating out of RV order during Replace and Resync. + emitDeltaTypeBookmark bool } +// ReplacedAllInfo is the object associated with a Delta of type=ReplacedAll +type ReplacedAllInfo struct { + // ResourceVersion is the resource version passed to the Replace() call that created this Delta + ResourceVersion string + // Objects are the list of objects passed to the Replace() call that created this Delta, + // with any configured transformation already applied. + Objects []interface{} +} + +// BookmarkInfo is the object associated with a Delta of type=Bookmark +type BookmarkInfo struct { + // ResourceVersion is the resource version passed to the Bookmark() call that created this Delta + ResourceVersion string +} + +// SyncAllInfo is the object associated with a Delta of type=SyncAll +// It is used to trigger a resync of the entire queue. +type SyncAllInfo struct{} + var ( _ = Queue(&RealFIFO{}) // RealFIFO is a Queue _ = TransformingStore(&RealFIFO{}) // RealFIFO implements TransformingStore to allow memory optimizations + _ = DoneChecker(&RealFIFO{}) // RealFIFO and implements DoneChecker. ) // Close the queue. @@ -127,11 +218,37 @@ func (f *RealFIFO) HasSynced() bool { return f.hasSynced_locked() } -// ignoring lint to reduce delta to the original for review. It's ok adjust later. -// -//lint:file-ignore ST1003: should not use underscores in Go names +// HasSyncedChecker is done if an Add/Update/Delete/AddIfNotPresent are called first, +// or the first batch of items inserted by Replace() has been popped. +func (f *RealFIFO) HasSyncedChecker() DoneChecker { + return f +} + +// Name implements [DoneChecker.Name] +func (f *RealFIFO) Name() string { + return f.name +} + +// Done implements [DoneChecker.Done] +func (f *RealFIFO) Done() <-chan struct{} { + return f.synced +} + +// hasSynced_locked returns the result of a prior checkSynced_locked call. func (f *RealFIFO) hasSynced_locked() bool { - return f.populated && f.initialPopulationCount == 0 + return f.syncedClosed +} + +// checkSynced_locked checks whether the initial batch of items (set via Replace) has been delivered +// and closes the synced channel as needed. It must be called after changing f.populated and/or +// f.initialPopulationCount while the mutex is still locked. +func (f *RealFIFO) checkSynced_locked() { + synced := f.populated && f.initialPopulationCount == 0 + if synced && !f.syncedClosed { + // Initial sync is complete. + f.syncedClosed = true + close(f.synced) + } } // addToItems_locked appends to the delta list. @@ -169,6 +286,48 @@ func (f *RealFIFO) addToItems_locked(deltaActionType DeltaType, skipTransform bo Object: obj, }) f.cond.Broadcast() + f.metrics.numberOfQueuedItem.Set(float64(len(f.items))) + + return nil +} + +// addReplaceToItemsLocked appends to the delta list. +func (f *RealFIFO) addReplaceToItemsLocked(objs []interface{}, resourceVersion string) error { + // Replaced items must be transformed before being added to the queue. These objects must + // all be objects that have not been transformed yet. + if f.transformer != nil { + transformedObjs := make([]interface{}, len(objs)) + for i, obj := range objs { + transformedObj, err := f.transformer(obj) + if err != nil { + return err + } + transformedObjs[i] = transformedObj + } + objs = transformedObjs + } + + info := ReplacedAllInfo{ + ResourceVersion: resourceVersion, + Objects: objs, + } + f.items = append(f.items, Delta{ + Type: ReplacedAll, + Object: info, + }) + f.cond.Broadcast() + f.metrics.numberOfQueuedItem.Set(float64(len(f.items))) + + return nil +} + +func (f *RealFIFO) addResyncToItemsLocked() error { + f.items = append(f.items, Delta{ + Type: SyncAll, + Object: SyncAllInfo{}, + }) + f.cond.Broadcast() + f.metrics.numberOfQueuedItem.Set(float64(len(f.items))) return nil } @@ -180,6 +339,7 @@ func (f *RealFIFO) Add(obj interface{}) error { defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() retErr := f.addToItems_locked(Added, false, obj) return retErr @@ -191,6 +351,7 @@ func (f *RealFIFO) Update(obj interface{}) error { defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() retErr := f.addToItems_locked(Updated, false, obj) return retErr @@ -204,6 +365,7 @@ func (f *RealFIFO) Delete(obj interface{}) error { defer f.lock.Unlock() f.populated = true + f.checkSynced_locked() retErr := f.addToItems_locked(Deleted, false, obj) return retErr @@ -217,10 +379,14 @@ func (f *RealFIFO) IsClosed() bool { } // Pop waits until an item is ready and processes it. If multiple items are -// ready, they are returned in the order in which they were added/updated. -// The item is removed from the queue (and the store) before it is processed. -// process function is called under lock, so it is safe -// update data structures in it that need to be in sync with the queue. +// ready, they are returned in the order in which they were added/updated. The +// item is removed from the queue (and the store) before it is processed. The +// process function is only guaranteed to be called under lock if +// UnlockWhileProcessing is false. If the process function is updating data +// structures that need to be in sync with the queue, ensure +// UnlockWhileProcessing is false. It is expected that the caller of Pop will be +// a single threaded consumer since otherwise it is possible for multiple +// PopProcessFuncs to be running simultaneously. func (f *RealFIFO) Pop(process PopProcessFunc) (interface{}, error) { f.lock.Lock() defer f.lock.Unlock() @@ -241,9 +407,15 @@ func (f *RealFIFO) Pop(process PopProcessFunc) (interface{}, error) { // The underlying array still exists and references this object, so the object will not be garbage collected unless we zero the reference. f.items[0] = Delta{} f.items = f.items[1:] - if f.initialPopulationCount > 0 { - f.initialPopulationCount-- - } + // Decrement initialPopulationCount if needed. + // This is done in a defer so we only do this *after* processing is complete, + // so concurrent calls to hasSynced will not incorrectly return true while processing is still happening. + defer func() { + if f.initialPopulationCount > 0 { + f.initialPopulationCount-- + f.checkSynced_locked() + } + }() // Only log traces if the queue depth is greater than 10 and it takes more than // 100 milliseconds to process one item from the queue. @@ -252,19 +424,66 @@ func (f *RealFIFO) Pop(process PopProcessFunc) (interface{}, error) { // https://github.com/kubernetes/kubernetes/issues/103789 if len(f.items) > 10 { id, _ := f.keyOf(item) - trace := utiltrace.New("RealFIFO Pop Process", - utiltrace.Field{Key: "ID", Value: id}, - utiltrace.Field{Key: "Depth", Value: len(f.items)}, - utiltrace.Field{Key: "Reason", Value: "slow event handlers blocking the queue"}) + fields := []utiltrace.Field{ + {Key: "ID", Value: id}, + {Key: "Depth", Value: len(f.items)}, + {Key: "Reason", Value: "slow event handlers blocking the queue"}, + } + if name := f.identifier.Name(); len(name) > 0 { + fields = append(fields, utiltrace.Field{Key: "Name", Value: name}) + } + if gvr := f.identifier.GroupVersionResource(); !gvr.Empty() { + fields = append(fields, utiltrace.Field{Key: "Resource", Value: gvr}) + } + trace := utiltrace.New("RealFIFO Pop Process", fields...) defer trace.LogIfLong(100 * time.Millisecond) } + f.metrics.numberOfQueuedItem.Set(float64(len(f.items))) - // we wrap in Deltas here to be compatible with preview Pop functions and those interpreting the return value. - err := process(Deltas{item}, isInInitialList) + // Process the item, this may unlock the lock, and allow other goroutines to add items to the queue. + err := f.whileProcessing_locked(func() error { + // we wrap in Deltas here to be compatible with preview Pop functions and those interpreting the return value. + return process(Deltas{item}, isInInitialList) + }) return Deltas{item}, err } -func (f *RealFIFO) PopBatch(process ProcessBatchFunc) error { +// whileProcessing_locked calls the `process` function and records processing latency. +// The lock must be held before calling `whileProcessing_locked`, and is held when `whileProcessing_locked` returns. +// whileProcessing_locked releases the lock during the call to `process` if f.unlockWhileProcessing is true and the f.items queue is not too long. +func (f *RealFIFO) whileProcessing_locked(process func() error) error { + // Unlock before calling `process` so new items can be enqueued during processing. + // Only do this if the queue contains less than 2 full batches of items, + // to prevent the queue from growing unboundedly. + if f.unlockWhileProcessing && len(f.items) < f.batchSize*2 { + f.lock.Unlock() + defer f.lock.Lock() + } + startTime := time.Now() + err := process() + f.metrics.processingLatency.Observe(time.Since(startTime).Seconds()) + return err +} + +// batchable stores the delta types that can be batched +var batchable = map[DeltaType]bool{ + Sync: true, + Replaced: true, + Added: true, + Updated: true, + Deleted: true, +} + +// PopBatch pops as many items as possible to be processed as a batch using processBatch, +// or pop a single item using processSingle if multiple items cannot be batched. +// +// The processBatch and processSingle functions are only guaranteed to be called +// under lock if UnlockWhileProcessing is false. If the process functions are +// updating data structures that need to be in sync with the queue, ensure +// UnlockWhileProcessing is false. It is expected that the caller of PopBatch +// will be a single threaded consumer, since otherwise it is possible for +// multiple ProcessBatchFunc or PopProcessFunc's to be running simultaneously. +func (f *RealFIFO) PopBatch(processBatch ProcessBatchFunc, processSingle PopProcessFunc) error { f.lock.Lock() defer f.lock.Unlock() @@ -282,12 +501,25 @@ func (f *RealFIFO) PopBatch(process ProcessBatchFunc) error { isInInitialList := !f.hasSynced_locked() unique := sets.NewString() deltas := make([]Delta, 0, min(len(f.items), f.batchSize)) + moveDeltaToProcessList := func(i int) { + deltas = append(deltas, f.items[i]) + // The underlying array still exists and references this object, so the object will not be garbage collected unless we zero the reference. + f.items[i] = Delta{} + } // only bundle unique items into a batch for i := 0; i < f.batchSize && i < len(f.items); i++ { if f.initialPopulationCount > 0 && i >= f.initialPopulationCount { break } item := f.items[i] + if !batchable[item.Type] { + if len(deltas) == 0 { + // if an unbatchable delta is first in the list, process just that one by itself + moveDeltaToProcessList(i) + } + // close the batch when an unbatchable delta is encountered + break + } id, err := f.keyOf(item) if err != nil { // close the batch here if error happens @@ -295,23 +527,26 @@ func (f *RealFIFO) PopBatch(process ProcessBatchFunc) error { // still pop the broken item out of queue to be compatible with the non-batch behavior it should be safe // when 1st element is broken, however for Nth broken element, there's possible risk that broken item // still can be processed and broke the uniqueness of the batch unexpectedly. - deltas = append(deltas, item) - // The underlying array still exists and references this object, so the object will not be garbage collected unless we zero the reference. - f.items[i] = Delta{} + moveDeltaToProcessList(i) break } if unique.Has(id) { + // close the batch if a duplicate item is encountered break } unique.Insert(id) - deltas = append(deltas, item) - // The underlying array still exists and references this object, so the object will not be garbage collected unless we zero the reference. - f.items[i] = Delta{} - } - if f.initialPopulationCount > 0 { - f.initialPopulationCount -= len(deltas) + moveDeltaToProcessList(i) } f.items = f.items[len(deltas):] + // Decrement initialPopulationCount if needed. + // This is done in a defer so we only do this *after* processing is complete, + // so concurrent calls to hasSynced will not incorrectly return true while processing is still happening. + defer func() { + if f.initialPopulationCount > 0 { + f.initialPopulationCount -= len(deltas) + f.checkSynced_locked() + } + }() // Only log traces if the queue depth is greater than 10 and it takes more than // 100 milliseconds to process one item from the queue (with a max of 1 second for the whole batch) @@ -320,16 +555,46 @@ func (f *RealFIFO) PopBatch(process ProcessBatchFunc) error { // https://github.com/kubernetes/kubernetes/issues/103789 if len(f.items) > 10 { id, _ := f.keyOf(deltas[0]) - trace := utiltrace.New("RealFIFO PopBatch Process", - utiltrace.Field{Key: "ID", Value: id}, - utiltrace.Field{Key: "Depth", Value: len(f.items)}, - utiltrace.Field{Key: "Reason", Value: "slow event handlers blocking the queue"}, - utiltrace.Field{Key: "BatchSize", Value: len(deltas)}) + fields := []utiltrace.Field{ + {Key: "ID", Value: id}, + {Key: "Depth", Value: len(f.items)}, + {Key: "Reason", Value: "slow event handlers blocking the queue"}, + {Key: "BatchSize", Value: len(deltas)}, + } + if name := f.identifier.Name(); len(name) > 0 { + fields = append(fields, utiltrace.Field{Key: "Name", Value: name}) + } + if gvr := f.identifier.GroupVersionResource(); !gvr.Empty() { + fields = append(fields, utiltrace.Field{Key: "Resource", Value: gvr}) + } + trace := utiltrace.New("RealFIFO PopBatch Process", fields...) defer trace.LogIfLong(min(100*time.Millisecond*time.Duration(len(deltas)), time.Second)) } + f.metrics.numberOfQueuedItem.Set(float64(len(f.items))) - err := process(deltas, isInInitialList) - return err + if len(deltas) == 1 { + return f.whileProcessing_locked(func() error { + return processSingle(Deltas{deltas[0]}, isInInitialList) + }) + } + return f.whileProcessing_locked(func() error { + return processBatch(deltas, isInInitialList) + }) +} + +func (f *RealFIFO) Bookmark(resourceVersion string) error { + if !f.emitDeltaTypeBookmark { + return nil + } + f.lock.Lock() + defer f.lock.Unlock() + + f.items = append(f.items, Delta{ + Type: Bookmark, + Object: BookmarkInfo{ResourceVersion: resourceVersion}, + }) + f.cond.Broadcast() + return nil } // Replace @@ -340,22 +605,58 @@ func (f *RealFIFO) Replace(newItems []interface{}, resourceVersion string) error f.lock.Lock() defer f.lock.Unlock() + var err error + if f.emitAtomicEvents { + err = f.addReplaceToItemsLocked(newItems, resourceVersion) + } else { + err = reconcileReplacement(f.logger, f.items, f.knownObjects, newItems, f.keyOf, + func(obj DeletedFinalStateUnknown) error { + return f.addToItems_locked(Deleted, true, obj) + }, + func(obj interface{}) error { + return f.addToItems_locked(Replaced, false, obj) + }) + } + if err != nil { + return err + } + + if !f.populated { + f.populated = true + f.initialPopulationCount = len(f.items) + f.checkSynced_locked() + } + + return nil +} + +// reconcileReplacement takes the items that are already in the queue and the set of new items +// and based upon the state of the items in the queue and known objects will call onDelete and onReplace +// depending upon whether the item is being deleted or replaced/added. +func reconcileReplacement( + logger klog.Logger, + queuedItems []Delta, + knownObjects KeyListerGetter, + newItems []interface{}, + keyOf func(obj interface{}) (string, error), + onDelete func(obj DeletedFinalStateUnknown) error, + onReplace func(obj interface{}) error, +) error { // determine the keys of everything we're adding. We cannot add the items until after the synthetic deletes have been // created for items that don't existing in newItems newKeys := sets.Set[string]{} for _, obj := range newItems { - key, err := f.keyOf(obj) + key, err := keyOf(obj) if err != nil { return KeyError{obj, err} } newKeys.Insert(key) } - queuedItems := f.items queuedKeys := []string{} lastQueuedItemForKey := map[string]Delta{} for _, queuedItem := range queuedItems { - queuedKey, err := f.keyOf(queuedItem.Object) + queuedKey, err := keyOf(queuedItem.Object) if err != nil { return KeyError{queuedItem.Object, err} } @@ -387,7 +688,7 @@ func (f *RealFIFO) Replace(newItems []interface{}, resourceVersion string) error // if we got here, then the last entry we have for the queued item is *not* a deletion and we need to add a delete deletedObj := lastQueuedItem.Object - retErr := f.addToItems_locked(Deleted, true, DeletedFinalStateUnknown{ + retErr := onDelete(DeletedFinalStateUnknown{ Key: queuedKey, Obj: deletedObj, }) @@ -397,7 +698,7 @@ func (f *RealFIFO) Replace(newItems []interface{}, resourceVersion string) error } // Detect deletions for objects not present in the queue, but present in KnownObjects - knownKeys := f.knownObjects.ListKeys() + knownKeys := knownObjects.ListKeys() for _, knownKey := range knownKeys { if newKeys.Has(knownKey) { // still present continue @@ -406,15 +707,15 @@ func (f *RealFIFO) Replace(newItems []interface{}, resourceVersion string) error continue } - deletedObj, exists, err := f.knownObjects.GetByKey(knownKey) + deletedObj, exists, err := knownObjects.GetByKey(knownKey) if err != nil { deletedObj = nil - utilruntime.HandleError(fmt.Errorf("error during lookup, placing DeleteFinalStateUnknown marker without object: key=%q, err=%w", knownKey, err)) + utilruntime.HandleErrorWithLogger(logger, err, "Error during lookup, placing DeleteFinalStateUnknown marker without object", "key", knownKey) } else if !exists { deletedObj = nil - utilruntime.HandleError(fmt.Errorf("key does not exist in known objects store, placing DeleteFinalStateUnknown marker without object: key=%q", knownKey)) + utilruntime.HandleErrorWithLogger(logger, nil, "Key does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", "key", knownKey) } - retErr := f.addToItems_locked(Deleted, false, DeletedFinalStateUnknown{ + retErr := onDelete(DeletedFinalStateUnknown{ Key: knownKey, Obj: deletedObj, }) @@ -425,17 +726,11 @@ func (f *RealFIFO) Replace(newItems []interface{}, resourceVersion string) error // now that we have the deletes we need for items, we can add the newItems to the items queue for _, obj := range newItems { - retErr := f.addToItems_locked(Replaced, false, obj) - if retErr != nil { - return fmt.Errorf("couldn't enqueue object: %w", retErr) + if err := onReplace(obj); err != nil { + return fmt.Errorf("couldn't enqueue object: %w", err) } } - if !f.populated { - f.populated = true - f.initialPopulationCount = len(f.items) - } - return nil } @@ -446,6 +741,10 @@ func (f *RealFIFO) Resync() error { f.lock.Lock() defer f.lock.Unlock() + if f.emitAtomicEvents { + return f.addResyncToItemsLocked() + } + if f.knownObjects == nil { return nil } @@ -471,10 +770,10 @@ func (f *RealFIFO) Resync() error { knownObj, exists, err := f.knownObjects.GetByKey(knownKey) if err != nil { - utilruntime.HandleError(fmt.Errorf("unable to queue object for sync: key=%q, err=%w", knownKey, err)) + utilruntime.HandleErrorWithLogger(f.logger, err, "Unable to queue object for sync", "key", knownKey) continue } else if !exists { - utilruntime.HandleError(fmt.Errorf("key does not exist in known objects store, unable to queue object for sync: key=%q", knownKey)) + utilruntime.HandleErrorWithLogger(f.logger, nil, "Key does not exist in known objects store, unable to queue object for sync", "key", knownKey) continue } @@ -494,6 +793,8 @@ func (f *RealFIFO) Transformer() TransformFunc { // NewRealFIFO returns a Store which can be used to queue up items to // process. +// +// Deprecated: Use NewRealFIFOWithOptions instead. func NewRealFIFO(keyFunc KeyFunc, knownObjects KeyListerGetter, transformer TransformFunc) *RealFIFO { return NewRealFIFOWithOptions(RealFIFOOptions{ KeyFunction: keyFunc, @@ -509,18 +810,50 @@ func NewRealFIFOWithOptions(opts RealFIFOOptions) *RealFIFO { opts.KeyFunction = MetaNamespaceKeyFunc } - if opts.KnownObjects == nil { - panic("coding error: knownObjects must be provided") + if opts.AtomicEvents { + // If we are emitting atomic events, we must not rely on the known objects store + // as it is a requirement to be able to release the lock while processing events. + if opts.KnownObjects != nil { + panic("coding error: knownObjects must not be provided when AtomicEvents is true") + } + } else { + if opts.UnlockWhileProcessing { + panic("coding error: UnlockWhileProcessing must be false when AtomicEvents is false") + } + if opts.KnownObjects == nil { + panic("coding error: knownObjects must be provided when AtomicEvents is false") + } + // If we are not emitting atomic events, we must not emit bookmark deltas. + if opts.EmitDeltaTypeBookmark { + panic("coding error: EmitDeltaTypeBookmark must be false when AtomicEvents is false") + } } f := &RealFIFO{ - items: make([]Delta, 0, 10), - keyFunc: opts.KeyFunction, - knownObjects: opts.KnownObjects, - transformer: opts.Transformer, - batchSize: defaultBatchSize, + logger: klog.Background(), + name: "RealFIFO", + items: make([]Delta, 0, 10), + synced: make(chan struct{}), + keyFunc: opts.KeyFunction, + knownObjects: opts.KnownObjects, + transformer: opts.Transformer, + batchSize: defaultBatchSize, + emitAtomicEvents: opts.AtomicEvents, + emitDeltaTypeBookmark: opts.EmitDeltaTypeBookmark, + unlockWhileProcessing: opts.UnlockWhileProcessing, + identifier: opts.Identifier, + metrics: newFIFOMetrics(opts.Identifier, opts.MetricsProvider), } - + if opts.Logger != nil { + f.logger = *opts.Logger + } + if name := opts.Name; name != "" { + f.name = name + } + if name := opts.Identifier.Name(); name != "" { + f.name = name + } + f.logger = klog.LoggerWithName(f.logger, f.name) f.cond.L = &f.lock return f } diff --git a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go index ef3a599a9b..74ac8f1ab2 100644 --- a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go +++ b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go @@ -18,10 +18,13 @@ package cache import ( "fmt" + "strconv" "sync" "time" + "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/util/sets" + clientgofeaturegate "k8s.io/client-go/features" utiltrace "k8s.io/utils/trace" ) @@ -43,13 +46,19 @@ import ( type ThreadSafeStore interface { Add(key string, obj interface{}) Update(key string, obj interface{}) + // Delete is equivalent to calling DeleteWithObject(key, nil) however it is + // not recommended to use this function as it will not update the resource + // version of the store, possibly causing it to be out of date. Delete(key string) + DeleteWithObject(key string, obj interface{}) Get(key string) (item interface{}, exists bool) List() []interface{} ListKeys() []string Replace(map[string]interface{}, string) Index(indexName string, obj interface{}) ([]interface{}, error) IndexKeys(indexName, indexedValue string) ([]string, error) + Bookmark(rv string) + LastStoreSyncResourceVersion() string ListIndexFuncValues(name string) []string ByIndex(indexName, indexedValue string) ([]interface{}, error) GetIndexers() Indexers @@ -73,6 +82,14 @@ type ThreadSafeStoreTransaction struct { Key string } +type ThreadSafeStoreOption = func(*threadSafeMap) + +func WithThreadSafeStoreMetrics(identifier InformerNameAndResource, metricsProvider InformerMetricsProvider) ThreadSafeStoreOption { + return func(c *threadSafeMap) { + c.metrics = newStoreMetrics(identifier, metricsProvider) + } +} + // storeIndex implements the indexing functionality for Store interface type storeIndex struct { // indexers maps a name to an IndexFunc @@ -242,9 +259,20 @@ type threadSafeMap struct { // index implements the indexing functionality index *storeIndex + rv string + + // metrics is used to expose metrics about the store + // and must be non-nil. If not provided, a noop implementation will be used. + metrics *storeMetrics } func (c *threadSafeMap) Transaction(txns ...ThreadSafeStoreTransaction) { + if len(txns) == 0 { + return + } + finalObj := txns[len(txns)-1].Object + rv, rvErr := rvFromObject(finalObj) + rvInt, parseErr := parseRVForMetricsWithTruncation(rv) c.lock.Lock() defer c.lock.Unlock() trace := utiltrace.New("ThreadSafeMap Transaction Process", @@ -262,6 +290,12 @@ func (c *threadSafeMap) Transaction(txns ...ThreadSafeStoreTransaction) { c.deleteLocked(txn.Key) } } + if rvErr == nil { + c.rv = rv + if parseErr == nil { + c.metrics.storeResourceVersion.Set(float64(rvInt)) + } + } } func (c *threadSafeMap) Add(key string, obj interface{}) { @@ -273,9 +307,17 @@ func (c *threadSafeMap) addLocked(key string, obj interface{}) { } func (c *threadSafeMap) Update(key string, obj interface{}) { + rv, rvErr := rvFromObject(obj) + rvInt, parseErr := parseRVForMetricsWithTruncation(rv) c.lock.Lock() defer c.lock.Unlock() c.updateLocked(key, obj) + if rvErr == nil { + c.rv = rv + if parseErr == nil { + c.metrics.storeResourceVersion.Set(float64(rvInt)) + } + } } func (c *threadSafeMap) updateLocked(key string, obj interface{}) { @@ -285,9 +327,26 @@ func (c *threadSafeMap) updateLocked(key string, obj interface{}) { } func (c *threadSafeMap) Delete(key string) { + c.DeleteWithObject(key, nil) +} + +func (c *threadSafeMap) DeleteWithObject(key string, obj interface{}) { + var rv string + var rvInt int64 + var rvErr, parseErr error + if obj != nil { + rv, rvErr = rvFromObject(obj) + rvInt, parseErr = parseRVForMetricsWithTruncation(rv) + } c.lock.Lock() defer c.lock.Unlock() c.deleteLocked(key) + if obj != nil && rvErr == nil { + c.rv = rv + if parseErr == nil { + c.metrics.storeResourceVersion.Set(float64(rvInt)) + } + } } func (c *threadSafeMap) deleteLocked(key string) { @@ -327,10 +386,18 @@ func (c *threadSafeMap) ListKeys() []string { } func (c *threadSafeMap) Replace(items map[string]interface{}, resourceVersion string) { + var rvInt int64 + var parseErr error + if resourceVersion != "" { + rvInt, parseErr = parseRVForMetricsWithTruncation(resourceVersion) + } c.lock.Lock() defer c.lock.Unlock() c.items = items - + c.rv = resourceVersion + if parseErr == nil { + c.metrics.storeResourceVersion.Set(float64(rvInt)) + } // rebuild any index c.index.reset() for key, item := range c.items { @@ -338,6 +405,15 @@ func (c *threadSafeMap) Replace(items map[string]interface{}, resourceVersion st } } +func rvFromObject(obj interface{}) (rv string, err error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", err + } + rv = meta.GetResourceVersion() + return rv, nil +} + // Index returns a list of items that match the given object on the index function. // Index is thread-safe so long as you treat all items as immutable. func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) { @@ -356,6 +432,32 @@ func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, return list, nil } +// LastStoreSyncResourceVersion returns the latest resource version that the store has seen. +func (c *threadSafeMap) LastStoreSyncResourceVersion() string { + // We cannot return the resource version if the AtomicFIFO feature gate is not enabled. + if !clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.AtomicFIFO) { + return "" + } + c.lock.RLock() + defer c.lock.RUnlock() + return c.rv +} + +// Bookmark sets the latest resource version that the store has seen. +func (c *threadSafeMap) Bookmark(rv string) { + var rvInt int64 + var parseErr error + if rv != "" { + rvInt, parseErr = parseRVForMetricsWithTruncation(rv) + } + c.lock.Lock() + defer c.lock.Unlock() + c.rv = rv + if parseErr == nil { + c.metrics.storeResourceVersion.Set(float64(rvInt)) + } +} + // ByIndex returns a list of the items whose indexed values in the given index include the given indexed value func (c *threadSafeMap) ByIndex(indexName, indexedValue string) ([]interface{}, error) { c.lock.RLock() @@ -420,13 +522,31 @@ func (c *threadSafeMap) Resync() error { return nil } -// NewThreadSafeStore creates a new instance of ThreadSafeStore. -func NewThreadSafeStore(indexers Indexers, indices Indices) ThreadSafeStore { - return &threadSafeMap{ +func NewThreadSafeStore(indexers Indexers, indices Indices, opts ...ThreadSafeStoreOption) ThreadSafeStore { + store := &threadSafeMap{ items: map[string]interface{}{}, index: &storeIndex{ indexers: indexers, indices: indices, }, } + for _, opt := range opts { + opt(store) + } + if store.metrics == nil { + store.metrics = newStoreMetrics(InformerNameAndResource{}, noopInformerMetricsProvider{}) + } + return store +} + +func parseRVForMetricsWithTruncation(rv string) (int64, error) { + if rv == "" { + return 0, nil + } + // Truncate to last 15 digits to ensure metrics are always less than 2^53-1 + // and avoid imprecise float64 representation. + if len(rv) > 15 { + rv = rv[len(rv)-15:] + } + return strconv.ParseInt(rv, 10, 64) } diff --git a/vendor/k8s.io/client-go/tools/clientcmd/api/types.go b/vendor/k8s.io/client-go/tools/clientcmd/api/types.go index cb21c040a3..66d0e9230b 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/api/types.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/api/types.go @@ -298,12 +298,12 @@ type ExecConfig struct { // the logical AND of all checks corresponding to the specified fields within // the entry. type AllowlistEntry struct { - // Name matching is performed by first resolving the absolute path of both + // Command matching is performed by first resolving the absolute path of both // the plugin and the name in the allowlist entry using `exec.LookPath`. It // will be called on both, and the resulting strings must be equal. If - // either call to `exec.LookPath` results in an error, the `Name` check + // either call to `exec.LookPath` results in an error, the `Command` check // will be considered a failure. - Name string `json:"-"` + Command string `json:"-"` } // PluginPolicy describes the policy type and allowlist (if any) for client-go diff --git a/vendor/k8s.io/client-go/tools/clientcmd/client_config.go b/vendor/k8s.io/client-go/tools/clientcmd/client_config.go index ed35891e5a..efac2830bb 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/client_config.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/client_config.go @@ -679,11 +679,13 @@ func (config *inClusterClientConfig) Possible() bool { // to the default config. func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config, error) { if kubeconfigPath == "" && masterUrl == "" { + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.Warning("Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.") kubeconfig, err := restclient.InClusterConfig() if err == nil { return kubeconfig, nil } + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.Warning("error creating inClusterConfig, falling back to default config: ", err) } return NewNonInteractiveDeferredLoadingClientConfig( diff --git a/vendor/k8s.io/client-go/tools/clientcmd/config.go b/vendor/k8s.io/client-go/tools/clientcmd/config.go index 2cd213ccb3..828ac974dc 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/config.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/config.go @@ -492,6 +492,7 @@ func getConfigFromFile(filename string) (*clientcmdapi.Config, error) { func GetConfigFromFileOrDie(filename string) *clientcmdapi.Config { config, err := getConfigFromFile(filename) if err != nil { + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.FatalDepth(1, err) } diff --git a/vendor/k8s.io/client-go/tools/clientcmd/loader.go b/vendor/k8s.io/client-go/tools/clientcmd/loader.go index b127e2e08f..d1d0a82954 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/loader.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/loader.go @@ -137,6 +137,7 @@ type WarningHandler func(error) func (handler WarningHandler) Warn(err error) { if handler == nil { + //nolint:logcheck // This is the fallback when logging is not initialized. With nothing provided, using the global logger is the only option. klog.V(1).Info(err) } else { handler(err) @@ -402,6 +403,7 @@ func LoadFromFile(filename string) (*clientcmdapi.Config, error) { if err != nil { return nil, err } + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.V(6).Infoln("Config loaded from file: ", filename) // set LocationOfOrigin on every Cluster, User, and Context diff --git a/vendor/k8s.io/client-go/tools/clientcmd/merged_client_builder.go b/vendor/k8s.io/client-go/tools/clientcmd/merged_client_builder.go index 0fc2fd0a0c..db7bf0a82e 100644 --- a/vendor/k8s.io/client-go/tools/clientcmd/merged_client_builder.go +++ b/vendor/k8s.io/client-go/tools/clientcmd/merged_client_builder.go @@ -118,6 +118,7 @@ func (config *DeferredLoadingClientConfig) ClientConfig() (*restclient.Config, e // check for in-cluster configuration and use it if config.icc.Possible() { + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.V(4).Infof("Using in-cluster configuration") return config.icc.ClientConfig() } @@ -160,6 +161,7 @@ func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) { } } + //nolint:logcheck // A helper function like this should not log. But this is probably part of the the established client-go API and not worth changing. klog.V(4).Infof("Using in-cluster namespace") // allow the namespace from the service account token directory to be used. diff --git a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go index 29d34c4e90..00798d82ac 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go @@ -199,8 +199,8 @@ type LeaderElector struct { // clock is wrapper around time to allow for less flaky testing clock clock.Clock - // used to lock the observedRecord - observedRecordLock sync.Mutex + // used to lock the observedRecord and the observedTime + observedRecordLock sync.RWMutex metrics leaderMetricsAdapter } @@ -256,7 +256,7 @@ func (le *LeaderElector) acquire(ctx context.Context) bool { desc := le.config.Lock.Describe() logger := klog.FromContext(ctx) logger.Info("Attempting to acquire leader lease...", "lock", desc) - wait.JitterUntil(func() { + wait.JitterUntilWithContext(ctx, func(ctx context.Context) { if !le.config.Coordinated { succeeded = le.tryAcquireOrRenew(ctx) } else { @@ -271,7 +271,7 @@ func (le *LeaderElector) acquire(ctx context.Context) bool { le.metrics.leaderOn(le.config.Name) logger.Info("Successfully acquired lease", "lock", desc) cancel() - }, le.config.RetryPeriod, JitterFactor, true, ctx.Done()) + }, le.config.RetryPeriod, JitterFactor, true) return succeeded } @@ -281,8 +281,13 @@ func (le *LeaderElector) renew(ctx context.Context) { ctx, cancel := context.WithCancel(ctx) defer cancel() logger := klog.FromContext(ctx) - wait.Until(func() { + wait.UntilWithContext(ctx, func(ctx context.Context) { err := wait.PollUntilContextTimeout(ctx, le.config.RetryPeriod, le.config.RenewDeadline, true, func(ctx context.Context) (done bool, err error) { + // PollUntilContextTimeout invokes condition even when the context is canceled when immediate=true. + // Short-circuit this to prevent unnecessary processing and error log messages. + if err := ctx.Err(); err != nil { + return false, err + } if !le.config.Coordinated { return le.tryAcquireOrRenew(ctx), nil } else { @@ -298,7 +303,7 @@ func (le *LeaderElector) renew(ctx context.Context) { le.metrics.leaderOff(le.config.Name) logger.Info("Failed to renew lease", "lock", desc, "err", err) cancel() - }, le.config.RetryPeriod, ctx.Done()) + }, le.config.RetryPeriod) // if we hold the lease, give it up if le.config.ReleaseOnCancel { @@ -372,7 +377,11 @@ func (le *LeaderElector) tryCoordinatedRenew(ctx context.Context) bool { le.observedRawRecord = oldLeaderElectionRawRecord } - hasExpired := le.observedTime.Add(time.Second * time.Duration(oldLeaderElectionRecord.LeaseDurationSeconds)).Before(now.Time) + le.observedRecordLock.RLock() + obsTime := le.observedTime + le.observedRecordLock.RUnlock() + + hasExpired := obsTime.Add(time.Second * time.Duration(oldLeaderElectionRecord.LeaseDurationSeconds)).Before(now.Time) if hasExpired { logger.Info("Lease has expired", "lock", le.config.Lock.Describe()) return false @@ -442,7 +451,7 @@ func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool { le.setObservedRecord(&leaderElectionRecord) return true } - logger.Error(err, "Failed to update lease optimistically, falling back to slow path", "lock", le.config.Lock.Describe()) + logger.V(2).Info("Failed to update lease optimistically, falling back to slow path", "lock", le.config.Lock.Describe(), "err", err) } // 2. obtain or create the ElectionRecord @@ -512,7 +521,12 @@ func (le *LeaderElector) Check(maxTolerableExpiredLease time.Duration) error { // If we are more than timeout seconds after the lease duration that is past the timeout // on the lease renew. Time to start reporting ourselves as unhealthy. We should have // died but conditions like deadlock can prevent this. (See #70819) - if le.clock.Since(le.observedTime) > le.config.LeaseDuration+maxTolerableExpiredLease { + le.observedRecordLock.RLock() + lastObservation := le.observedTime + leaseDuration := le.config.LeaseDuration + le.observedRecordLock.RUnlock() + + if le.clock.Since(lastObservation) > leaseDuration+maxTolerableExpiredLease { return fmt.Errorf("failed election to renew leadership on lease %s", le.config.Name) } @@ -520,7 +534,11 @@ func (le *LeaderElector) Check(maxTolerableExpiredLease time.Duration) error { } func (le *LeaderElector) isLeaseValid(now time.Time) bool { - return le.observedTime.Add(time.Second * time.Duration(le.getObservedRecord().LeaseDurationSeconds)).After(now) + // Lock to safely read both the time and the record + le.observedRecordLock.RLock() + defer le.observedRecordLock.RUnlock() + + return le.observedTime.Add(time.Second * time.Duration(le.observedRecord.LeaseDurationSeconds)).After(now) } // setObservedRecord will set a new observedRecord and update observedTime to the current time. @@ -536,8 +554,8 @@ func (le *LeaderElector) setObservedRecord(observedRecord *rl.LeaderElectionReco // getObservedRecord returns observersRecord. // Protect critical sections with lock. func (le *LeaderElector) getObservedRecord() rl.LeaderElectionRecord { - le.observedRecordLock.Lock() - defer le.observedRecordLock.Unlock() + le.observedRecordLock.RLock() + defer le.observedRecordLock.RUnlock() return le.observedRecord } diff --git a/vendor/k8s.io/client-go/tools/leaderelection/leasecandidate.go b/vendor/k8s.io/client-go/tools/leaderelection/leasecandidate.go index b2fa14a5f3..e2d0ef437a 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/leasecandidate.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/leasecandidate.go @@ -19,6 +19,7 @@ package leaderelection import ( "context" "reflect" + "sync" "time" v1 "k8s.io/api/coordination/v1" @@ -34,6 +35,8 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" "k8s.io/utils/clock" + + coordinationv1beta1listers "k8s.io/client-go/listers/coordination/v1beta1" ) const requeueInterval = 5 * time.Minute @@ -45,6 +48,7 @@ type CacheSyncWaiter interface { type LeaseCandidate struct { leaseClient coordinationv1beta1client.LeaseCandidateInterface leaseCandidateInformer cache.SharedIndexInformer + leaseCandidateLister coordinationv1beta1listers.LeaseCandidateLister informerFactory informers.SharedInformerFactory hasSynced cache.InformerSynced @@ -80,15 +84,18 @@ func NewCandidate(clientset kubernetes.Interface, // are started for leader elected components informerFactory := informers.NewSharedInformerFactoryWithOptions( clientset, 5*time.Minute, + informers.WithNamespace(candidateNamespace), informers.WithTweakListOptions(func(options *metav1.ListOptions) { options.FieldSelector = fieldSelector }), ) leaseCandidateInformer := informerFactory.Coordination().V1beta1().LeaseCandidates().Informer() + leaseCandidateLister := informerFactory.Coordination().V1beta1().LeaseCandidates().Lister() lc := &LeaseCandidate{ leaseClient: clientset.CoordinationV1beta1().LeaseCandidates(candidateNamespace), leaseCandidateInformer: leaseCandidateInformer, + leaseCandidateLister: leaseCandidateLister, informerFactory: informerFactory, name: candidateName, namespace: candidateNamespace, @@ -118,19 +125,25 @@ func NewCandidate(clientset kubernetes.Interface, } func (c *LeaseCandidate) Run(ctx context.Context) { - defer c.queue.ShutDown() - logger := klog.FromContext(ctx) logger = klog.LoggerWithName(logger, "leasecandidate") ctx = klog.NewContext(ctx, logger) + var wg sync.WaitGroup + defer func() { + c.queue.ShutDown() + wg.Wait() + }() + c.informerFactory.Start(ctx.Done()) if !cache.WaitForNamedCacheSyncWithContext(ctx, c.hasSynced) { return } c.enqueueLease() - go c.runWorker(ctx) + wg.Go(func() { + c.runWorker(ctx) + }) <-ctx.Done() } @@ -166,7 +179,7 @@ func (c *LeaseCandidate) enqueueLease() { // a bool (true if this call created the lease), or any error that occurs. func (c *LeaseCandidate) ensureLease(ctx context.Context) error { logger := klog.FromContext(ctx) - lease, err := c.leaseClient.Get(ctx, c.name, metav1.GetOptions{}) + lease, err := c.leaseCandidateLister.LeaseCandidates(c.namespace).Get(c.name) if apierrors.IsNotFound(err) { logger.V(2).Info("Creating lease candidate") // lease does not exist, create it. diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go index 79a748b74d..b03e3c1284 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go @@ -105,7 +105,7 @@ func (ll *LeaseLock) RecordEvent(s string) { // Populate the type meta, so we don't have to get it from the schema subject.Kind = "Lease" subject.APIVersion = coordinationv1.SchemeGroupVersion.String() - ll.LockConfig.EventRecorder.Eventf(subject, corev1.EventTypeNormal, "LeaderElection", events) + ll.LockConfig.EventRecorder.Eventf(subject, corev1.EventTypeNormal, "LeaderElection", "%s", events) } // Describe is used to convert details on current resource lock diff --git a/vendor/k8s.io/client-go/tools/metrics/metrics.go b/vendor/k8s.io/client-go/tools/metrics/metrics.go index e364b7e1cf..2f626475b2 100644 --- a/vendor/k8s.io/client-go/tools/metrics/metrics.go +++ b/vendor/k8s.io/client-go/tools/metrics/metrics.go @@ -80,11 +80,29 @@ type TransportCacheMetric interface { } // TransportCreateCallsMetric counts the number of times a transport is created -// partitioned by the result of the cache: hit, miss, uncacheable +// partitioned by the result of the cache: hit, miss, miss-gc, uncacheable type TransportCreateCallsMetric interface { Increment(result string) } +// TransportCAReloadsMetric counts the number of times a CA reload is attempted, +// partitioned by the result and reason. +type TransportCAReloadsMetric interface { + Increment(result, reason string) +} + +// TransportCertRotationGCCallsMetric counts the number of times a cert rotation +// goroutine cancel func is called via GC cleanup. +type TransportCertRotationGCCallsMetric interface { + Increment() +} + +// TransportCacheGCCallsMetric counts the number of times a GC cleanup +// attempts to delete a cache entry, partitioned by the result: deleted, skipped. +type TransportCacheGCCallsMetric interface { + Increment(result string) +} + var ( // ClientCertExpiry is the expiry time of a client certificate ClientCertExpiry ExpiryMetric = noopExpiry{} @@ -117,23 +135,34 @@ var ( // TransportCreateCalls is the metric that counts the number of times a new transport // is created TransportCreateCalls TransportCreateCallsMetric = noopTransportCreateCalls{} + // TransportCAReloads is the metric that counts the number of times a CA reload is attempted + TransportCAReloads TransportCAReloadsMetric = noopTransportCAReloads{} + // TransportCertRotationGCCalls counts the number of times a cert rotation goroutine + // cancel func is called via GC cleanup + TransportCertRotationGCCalls TransportCertRotationGCCallsMetric = noopTransportCertRotationGCCalls{} + // TransportCacheGCCalls counts the number of times a GC cleanup attempts + // to delete a transport cache entry, partitioned by result: deleted, skipped. + TransportCacheGCCalls TransportCacheGCCallsMetric = noopTransportCacheGCCalls{} ) // RegisterOpts contains all the metrics to register. Metrics may be nil. type RegisterOpts struct { - ClientCertExpiry ExpiryMetric - ClientCertRotationAge DurationMetric - RequestLatency LatencyMetric - ResolverLatency ResolverLatencyMetric - RequestSize SizeMetric - ResponseSize SizeMetric - RateLimiterLatency LatencyMetric - RequestResult ResultMetric - ExecPluginCalls CallsMetric - ExecPluginPolicyCalls PolicyCallsMetric - RequestRetry RetryMetric - TransportCacheEntries TransportCacheMetric - TransportCreateCalls TransportCreateCallsMetric + ClientCertExpiry ExpiryMetric + ClientCertRotationAge DurationMetric + RequestLatency LatencyMetric + ResolverLatency ResolverLatencyMetric + RequestSize SizeMetric + ResponseSize SizeMetric + RateLimiterLatency LatencyMetric + RequestResult ResultMetric + ExecPluginCalls CallsMetric + ExecPluginPolicyCalls PolicyCallsMetric + RequestRetry RetryMetric + TransportCacheEntries TransportCacheMetric + TransportCreateCalls TransportCreateCallsMetric + TransportCAReloads TransportCAReloadsMetric + TransportCertRotationGCCalls TransportCertRotationGCCallsMetric + TransportCacheGCCalls TransportCacheGCCallsMetric } // Register registers metrics for the rest client to use. This can @@ -179,6 +208,15 @@ func Register(opts RegisterOpts) { if opts.TransportCreateCalls != nil { TransportCreateCalls = opts.TransportCreateCalls } + if opts.TransportCAReloads != nil { + TransportCAReloads = opts.TransportCAReloads + } + if opts.TransportCertRotationGCCalls != nil { + TransportCertRotationGCCalls = opts.TransportCertRotationGCCalls + } + if opts.TransportCacheGCCalls != nil { + TransportCacheGCCalls = opts.TransportCacheGCCalls + } }) } @@ -226,3 +264,15 @@ func (noopTransportCache) Observe(int) {} type noopTransportCreateCalls struct{} func (noopTransportCreateCalls) Increment(string) {} + +type noopTransportCAReloads struct{} + +func (noopTransportCAReloads) Increment(result, reason string) {} + +type noopTransportCertRotationGCCalls struct{} + +func (noopTransportCertRotationGCCalls) Increment() {} + +type noopTransportCacheGCCalls struct{} + +func (noopTransportCacheGCCalls) Increment(string) {} diff --git a/vendor/k8s.io/client-go/tools/portforward/fallback_dialer.go b/vendor/k8s.io/client-go/tools/portforward/fallback_dialer.go index 7fcc2492bf..91f8fad4dd 100644 --- a/vendor/k8s.io/client-go/tools/portforward/fallback_dialer.go +++ b/vendor/k8s.io/client-go/tools/portforward/fallback_dialer.go @@ -19,9 +19,11 @@ package portforward import ( "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/klog/v2" + streamhttp "k8s.io/streaming/pkg/httpstream" ) var _ httpstream.Dialer = &FallbackDialer{} +var _ streamhttp.Dialer = &StreamingFallbackDialer{} // FallbackDialer encapsulates a primary and secondary dialer, including // the boolean function to determine if the primary dialer failed. Implements @@ -42,6 +44,24 @@ func NewFallbackDialer(primary, secondary httpstream.Dialer, shouldFallback func } } +// StreamingFallbackDialer encapsulates a primary and secondary streaming dialer +// with fallback behavior. +type StreamingFallbackDialer struct { + primary streamhttp.Dialer + secondary streamhttp.Dialer + shouldFallback func(error) bool +} + +// NewFallbackDialerForStreaming creates a fallback dialer for in-tree callers +// that use k8s.io/streaming/pkg/httpstream types. +func NewFallbackDialerForStreaming(primary, secondary streamhttp.Dialer, shouldFallback func(error) bool) streamhttp.Dialer { + return &StreamingFallbackDialer{ + primary: primary, + secondary: secondary, + shouldFallback: shouldFallback, + } +} + // Dial is the single function necessary to implement the "httpstream.Dialer" interface. // It takes the protocol version strings to request, returning an the upgraded // httstream.Connection and the negotiated protocol version accepted. If the initial @@ -55,3 +75,14 @@ func (f *FallbackDialer) Dial(protocols ...string) (httpstream.Connection, strin } return conn, version, err } + +// Dial is the single function necessary to implement the +// "k8s.io/streaming/pkg/httpstream.Dialer" interface. +func (f *StreamingFallbackDialer) Dial(protocols ...string) (streamhttp.Connection, string, error) { + conn, version, err := f.primary.Dial(protocols...) + if err != nil && f.shouldFallback(err) { + klog.V(4).Infof("fallback to secondary dialer from primary dialer err: %v", err) + return f.secondary.Dial(protocols...) + } + return conn, version, err +} diff --git a/vendor/k8s.io/client-go/tools/portforward/portforward.go b/vendor/k8s.io/client-go/tools/portforward/portforward.go index 126c14e8fa..11e0df6307 100644 --- a/vendor/k8s.io/client-go/tools/portforward/portforward.go +++ b/vendor/k8s.io/client-go/tools/portforward/portforward.go @@ -26,10 +26,13 @@ import ( "strconv" "strings" "sync" + "time" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" + streamhttp "k8s.io/streaming/pkg/httpstream" netutils "k8s.io/utils/net" ) @@ -164,6 +167,12 @@ func New(dialer httpstream.Dialer, ports []string, stopChan <-chan struct{}, rea return NewOnAddresses(dialer, []string{"localhost"}, ports, stopChan, readyChan, out, errOut) } +// NewForStreaming creates a new PortForwarder with localhost listen addresses +// for in-tree callers that use k8s.io/streaming/pkg/httpstream types. +func NewForStreaming(dialer streamhttp.Dialer, ports []string, stopChan <-chan struct{}, readyChan chan struct{}, out, errOut io.Writer) (*PortForwarder, error) { + return NewOnAddressesForStreaming(dialer, []string{"localhost"}, ports, stopChan, readyChan, out, errOut) +} + // NewOnAddresses creates a new PortForwarder with custom listen addresses. func NewOnAddresses(dialer httpstream.Dialer, addresses []string, ports []string, stopChan <-chan struct{}, readyChan chan struct{}, out, errOut io.Writer) (*PortForwarder, error) { if len(addresses) == 0 { @@ -191,6 +200,95 @@ func NewOnAddresses(dialer httpstream.Dialer, addresses []string, ports []string }, nil } +// NewOnAddressesForStreaming creates a new PortForwarder with custom listen +// addresses for in-tree callers that use k8s.io/streaming/pkg/httpstream types. +func NewOnAddressesForStreaming(dialer streamhttp.Dialer, addresses []string, ports []string, stopChan <-chan struct{}, readyChan chan struct{}, out, errOut io.Writer) (*PortForwarder, error) { + return NewOnAddresses(&compatDialerAdapter{delegate: dialer}, addresses, ports, stopChan, readyChan, out, errOut) +} + +type compatDialerAdapter struct { + delegate streamhttp.Dialer +} + +func (d *compatDialerAdapter) Dial(protocols ...string) (httpstream.Connection, string, error) { + conn, protocol, err := d.delegate.Dial(protocols...) + if err != nil { + return nil, "", err + } + return &compatConnectionAdapter{delegate: conn}, protocol, nil +} + +type compatConnectionAdapter struct { + delegate streamhttp.Connection +} + +func (c *compatConnectionAdapter) CreateStream(headers http.Header) (httpstream.Stream, error) { + stream, err := c.delegate.CreateStream(headers) + if err != nil { + return nil, err + } + return &compatStreamAdapter{delegate: stream}, nil +} + +func (c *compatConnectionAdapter) Close() error { + return c.delegate.Close() +} + +func (c *compatConnectionAdapter) CloseChan() <-chan bool { + return c.delegate.CloseChan() +} + +func (c *compatConnectionAdapter) SetIdleTimeout(timeout time.Duration) { + c.delegate.SetIdleTimeout(timeout) +} + +func (c *compatConnectionAdapter) RemoveStreams(streams ...httpstream.Stream) { + streamingStreams := make([]streamhttp.Stream, 0, len(streams)) + for _, stream := range streams { + if stream == nil { + continue + } + if s, ok := stream.(*compatStreamAdapter); ok { + streamingStreams = append(streamingStreams, s.delegate) + continue + } + if s, ok := stream.(streamhttp.Stream); ok { + streamingStreams = append(streamingStreams, s) + continue + } + klog.V(5).Infof("dropping unadaptable stream %T in portforward RemoveStreams", stream) + } + c.delegate.RemoveStreams(streamingStreams...) +} + +type compatStreamAdapter struct { + delegate streamhttp.Stream +} + +func (s *compatStreamAdapter) Read(p []byte) (int, error) { + return s.delegate.Read(p) +} + +func (s *compatStreamAdapter) Write(p []byte) (int, error) { + return s.delegate.Write(p) +} + +func (s *compatStreamAdapter) Close() error { + return s.delegate.Close() +} + +func (s *compatStreamAdapter) Reset() error { + return s.delegate.Reset() +} + +func (s *compatStreamAdapter) Headers() http.Header { + return s.delegate.Headers() +} + +func (s *compatStreamAdapter) Identifier() uint32 { + return s.delegate.Identifier() +} + // ForwardPorts formats and executes a port forwarding request. The connection will remain // open until stopChan is closed. func (pf *PortForwarder) ForwardPorts() error { diff --git a/vendor/k8s.io/client-go/tools/portforward/tunneling_dialer.go b/vendor/k8s.io/client-go/tools/portforward/tunneling_dialer.go index 2bef5ecd72..cc9352bfea 100644 --- a/vendor/k8s.io/client-go/tools/portforward/tunneling_dialer.go +++ b/vendor/k8s.io/client-go/tools/portforward/tunneling_dialer.go @@ -24,11 +24,13 @@ import ( "time" "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/httpstream/spdy" + httpstreamspdy "k8s.io/apimachinery/pkg/util/httpstream/spdy" constants "k8s.io/apimachinery/pkg/util/portforward" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport/websocket" "k8s.io/klog/v2" + streamhttp "k8s.io/streaming/pkg/httpstream" + streamspdy "k8s.io/streaming/pkg/httpstream/spdy" ) const PingPeriod = 10 * time.Second @@ -40,6 +42,14 @@ type tunnelingDialer struct { holder websocket.ConnectionHolder } +// streamingTunnelingDialer implements "k8s.io/streaming/pkg/httpstream.Dialer" +// for in-tree callers. +type streamingTunnelingDialer struct { + url *url.URL + transport http.RoundTripper + holder websocket.ConnectionHolder +} + // NewTunnelingDialer creates and returns the tunnelingDialer structure which implemements the "httpstream.Dialer" // interface. The dialer can upgrade a websocket request, creating a websocket connection. This function // returns an error if one occurs. @@ -55,25 +65,36 @@ func NewSPDYOverWebsocketDialer(url *url.URL, config *restclient.Config) (httpst }, nil } -// Dial upgrades to a tunneling streaming connection, returning a SPDY connection -// containing a WebSockets connection (which implements "net.Conn"). Also -// returns the protocol negotiated, or an error. -func (d *tunnelingDialer) Dial(protocols ...string) (httpstream.Connection, string, error) { +// NewSPDYOverWebsocketDialerForStreaming creates a SPDY-over-websocket dialer +// for in-tree callers that use k8s.io/streaming/pkg/httpstream types. +func NewSPDYOverWebsocketDialerForStreaming(url *url.URL, config *restclient.Config) (streamhttp.Dialer, error) { + transport, holder, err := websocket.RoundTripperFor(config) + if err != nil { + return nil, err + } + return &streamingTunnelingDialer{ + url: url, + transport: transport, + holder: holder, + }, nil +} + +func negotiateSPDYOverWebsocket(url *url.URL, transport http.RoundTripper, holder websocket.ConnectionHolder, protocols ...string) (*TunnelingConnection, string, error) { // There is no passed context, so skip the context when creating request for now. // Websockets requires "GET" method: RFC 6455 Sec. 4.1 (page 17). - req, err := http.NewRequest("GET", d.url.String(), nil) + req, err := http.NewRequest("GET", url.String(), nil) if err != nil { return nil, "", err } // Add the spdy tunneling prefix to the requested protocols. The tunneling // handler will know how to negotiate these protocols. - tunnelingProtocols := []string{} + tunnelingProtocols := make([]string, 0, len(protocols)) for _, protocol := range protocols { tunnelingProtocol := constants.WebsocketsSPDYTunnelingPrefix + protocol tunnelingProtocols = append(tunnelingProtocols, tunnelingProtocol) } klog.V(4).Infoln("Before WebSocket Upgrade Connection...") - conn, err := websocket.Negotiate(d.transport, d.holder, req, tunnelingProtocols...) + conn, err := websocket.Negotiate(transport, holder, req, tunnelingProtocols...) if err != nil { return nil, "", err } @@ -84,10 +105,32 @@ func (d *tunnelingDialer) Dial(protocols ...string) (httpstream.Connection, stri protocol = strings.TrimPrefix(protocol, constants.WebsocketsSPDYTunnelingPrefix) klog.V(4).Infof("negotiated protocol: %s", protocol) - // Wrap the websocket connection which implements "net.Conn". - tConn := NewTunnelingConnection("client", conn) + return NewTunnelingConnection("client", conn), protocol, nil +} + +// Dial upgrades to a tunneling streaming connection, returning a SPDY connection +// containing a WebSockets connection (which implements "net.Conn"). Also +// returns the protocol negotiated, or an error. +func (d *tunnelingDialer) Dial(protocols ...string) (httpstream.Connection, string, error) { + tConn, protocol, err := negotiateSPDYOverWebsocket(d.url, d.transport, d.holder, protocols...) + if err != nil { + return nil, "", err + } + // Create SPDY connection injecting the previously created tunneling connection. + spdyConn, err := httpstreamspdy.NewClientConnectionWithPings(tConn, PingPeriod) + + return spdyConn, protocol, err +} + +// Dial upgrades to a tunneling streaming connection for callers using +// k8s.io/streaming/pkg/httpstream types. +func (d *streamingTunnelingDialer) Dial(protocols ...string) (streamhttp.Connection, string, error) { + tConn, protocol, err := negotiateSPDYOverWebsocket(d.url, d.transport, d.holder, protocols...) + if err != nil { + return nil, "", err + } // Create SPDY connection injecting the previously created tunneling connection. - spdyConn, err := spdy.NewClientConnectionWithPings(tConn, PingPeriod) + spdyConn, err := streamspdy.NewClientConnectionWithPings(tConn, PingPeriod) return spdyConn, protocol, err } diff --git a/vendor/k8s.io/client-go/tools/record/event.go b/vendor/k8s.io/client-go/tools/record/event.go index 58322d44d2..305a924388 100644 --- a/vendor/k8s.io/client-go/tools/record/event.go +++ b/vendor/k8s.io/client-go/tools/record/event.go @@ -408,7 +408,10 @@ func (e *eventBroadcasterImpl) StartEventWatcher(eventHandler func(*v1.Event)) w case <-e.cancelationCtx.Done(): watcher.Stop() return - case watchEvent := <-watcher.ResultChan(): + case watchEvent, ok := <-watcher.ResultChan(): + if !ok { + return + } event, ok := watchEvent.Object.(*v1.Event) if !ok { // This is all local, so there's no reason this should diff --git a/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go b/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go index 90bb39b4a4..23dd50778d 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go @@ -21,6 +21,7 @@ import ( "io" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" ) // errorStreamDecoder interprets the data on the error channel and creates a go error object from it. @@ -32,11 +33,11 @@ type errorStreamDecoder interface { // decodes it with the given errorStreamDecoder, sends the decoded error (or nil if the remote // command exited successfully) to the returned error channel, and closes it. // This function returns immediately. -func watchErrorStream(errorStream io.Reader, d errorStreamDecoder) chan error { +func watchErrorStream(logger klog.Logger, errorStream io.Reader, d errorStreamDecoder) chan error { errorChan := make(chan error) go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) message, err := io.ReadAll(errorStream) switch { diff --git a/vendor/k8s.io/client-go/tools/remotecommand/fallback.go b/vendor/k8s.io/client-go/tools/remotecommand/fallback.go index 503323080d..bcd5fd3138 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/fallback.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/fallback.go @@ -53,7 +53,7 @@ func (f *FallbackExecutor) Stream(options StreamOptions) error { func (f *FallbackExecutor) StreamWithContext(ctx context.Context, options StreamOptions) error { err := f.primary.StreamWithContext(ctx, options) if err != nil && f.shouldFallback(err) { - klog.V(4).Infof("RemoteCommand fallback: %v", err) + klog.FromContext(ctx).V(4).Info("RemoteCommand fallback", "err", err) return f.secondary.StreamWithContext(ctx, options) } return err diff --git a/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go b/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go index 4cff05cd81..ca892f9b74 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go @@ -21,7 +21,8 @@ import ( "io" "net/http" - "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // StreamOptions holds information pertaining to the current streaming session: @@ -54,5 +55,5 @@ type streamCreator interface { } type streamProtocolHandler interface { - stream(conn streamCreator, ready chan<- struct{}) error + stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error } diff --git a/vendor/k8s.io/client-go/tools/remotecommand/spdy.go b/vendor/k8s.io/client-go/tools/remotecommand/spdy.go index 34825771a0..ebf3c53c3a 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/spdy.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/spdy.go @@ -22,11 +22,11 @@ import ( "net/http" "net/url" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport/spdy" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // spdyStreamExecutor handles transporting standard shell streams over an httpstream connection. @@ -109,7 +109,7 @@ func (e *spdyStreamExecutor) newConnectionAndStream(ctx context.Context, options return fmt.Errorf("redirect not allowed") } } - conn, protocol, err := spdy.Negotiate( + conn, protocol, err := spdy.NegotiateStreaming( e.upgrader, &client, req, @@ -121,6 +121,7 @@ func (e *spdyStreamExecutor) newConnectionAndStream(ctx context.Context, options var streamer streamProtocolHandler + logger := klog.FromContext(ctx) switch protocol { case remotecommand.StreamProtocolV5Name: streamer = newStreamProtocolV5(options) @@ -131,7 +132,7 @@ func (e *spdyStreamExecutor) newConnectionAndStream(ctx context.Context, options case remotecommand.StreamProtocolV2Name: streamer = newStreamProtocolV2(options) case "": - klog.V(4).Infof("The server did not negotiate a streaming protocol version. Falling back to %s", remotecommand.StreamProtocolV1Name) + logger.V(4).Info("The server did not negotiate a streaming protocol version, falling back", "protocol", remotecommand.StreamProtocolV1Name) fallthrough case remotecommand.StreamProtocolV1Name: streamer = newStreamProtocolV1(options) @@ -161,7 +162,7 @@ func (e *spdyStreamExecutor) StreamWithContext(ctx context.Context, options Stre // The SPDY executor does not need to synchronize stream creation, so we pass a nil // ready channel. The underlying spdystream library handles stream multiplexing // without a race condition. - errorChan <- streamer.stream(conn, nil) + errorChan <- streamer.stream(klog.FromContext(ctx), conn, nil) }() select { diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v1.go b/vendor/k8s.io/client-go/tools/remotecommand/v1.go index 293d809dde..5d903b67a2 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/v1.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/v1.go @@ -21,9 +21,9 @@ import ( "io" "net/http" - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/httpstream" + v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // streamProtocolV1 implements the first version of the streaming exec & attach @@ -47,15 +47,15 @@ func newStreamProtocolV1(options StreamOptions) streamProtocolHandler { } } -func (p *streamProtocolV1) stream(conn streamCreator, ready chan<- struct{}) error { +func (p *streamProtocolV1) stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error { doneChan := make(chan struct{}, 2) errorChan := make(chan error) cp := func(s string, dst io.Writer, src io.Reader) { - klog.V(6).Infof("Copying %s", s) - defer klog.V(6).Infof("Done copying %s", s) + logger.V(6).Info("Copying", "data", s) + defer logger.V(6).Info("Done copying", "data", s) if _, err := io.Copy(dst, src); err != nil && err != io.EOF { - klog.Errorf("Error copying %s: %v", s, err) + logger.Error(err, "Error copying", "data", s) } if s == v1.StreamTypeStdout || s == v1.StreamTypeStderr { doneChan <- struct{}{} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v2.go b/vendor/k8s.io/client-go/tools/remotecommand/v2.go index a81538a092..75286a12fd 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/v2.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/v2.go @@ -22,8 +22,9 @@ import ( "net/http" "sync" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" ) // streamProtocolV2 implements version 2 of the streaming protocol for attach @@ -87,13 +88,13 @@ func (p *streamProtocolV2) createStreams(conn streamCreator) error { return nil } -func (p *streamProtocolV2) copyStdin() { +func (p *streamProtocolV2) copyStdin(logger klog.Logger) { if p.Stdin != nil { var once sync.Once // copy from client's stdin to container's stdin go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) // if p.stdin is noninteractive, p.g. `echo abc | kubectl exec -i -- cat`, make sure // we close remoteStdin as soon as the copy from p.stdin to remoteStdin finishes. Otherwise @@ -101,7 +102,7 @@ func (p *streamProtocolV2) copyStdin() { defer once.Do(func() { p.remoteStdin.Close() }) if _, err := io.Copy(p.remoteStdin, readerWrapper{p.Stdin}); err != nil { - runtime.HandleError(err) + runtime.HandleErrorWithLogger(logger, err, "Copying stdin failed") } }() @@ -120,26 +121,26 @@ func (p *streamProtocolV2) copyStdin() { // When that happens, we must Close() on our side of remoteStdin, to // allow the copy in hijack to complete, and hijack to return. go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) defer once.Do(func() { p.remoteStdin.Close() }) // this "copy" doesn't actually read anything - it's just here to wait for // the server to close remoteStdin. if _, err := io.Copy(io.Discard, p.remoteStdin); err != nil { - runtime.HandleError(err) + runtime.HandleErrorWithLogger(logger, err, "Waiting for server to close stdin failed") } }() } } -func (p *streamProtocolV2) copyStdout(wg *sync.WaitGroup) { +func (p *streamProtocolV2) copyStdout(logger klog.Logger, wg *sync.WaitGroup) { if p.Stdout == nil { return } wg.Add(1) go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) defer wg.Done() // make sure, packet in queue can be consumed. // block in queue may lead to deadlock in conn.server @@ -147,29 +148,29 @@ func (p *streamProtocolV2) copyStdout(wg *sync.WaitGroup) { defer io.Copy(io.Discard, p.remoteStdout) if _, err := io.Copy(p.Stdout, p.remoteStdout); err != nil { - runtime.HandleError(err) + runtime.HandleErrorWithLogger(logger, err, "Copying stdout failed") } }() } -func (p *streamProtocolV2) copyStderr(wg *sync.WaitGroup) { +func (p *streamProtocolV2) copyStderr(logger klog.Logger, wg *sync.WaitGroup) { if p.Stderr == nil || p.Tty { return } wg.Add(1) go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) defer wg.Done() defer io.Copy(io.Discard, p.remoteStderr) if _, err := io.Copy(p.Stderr, p.remoteStderr); err != nil { - runtime.HandleError(err) + runtime.HandleErrorWithLogger(logger, err, "Copying stderr failed") } }() } -func (p *streamProtocolV2) stream(conn streamCreator, ready chan<- struct{}) error { +func (p *streamProtocolV2) stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error { if err := p.createStreams(conn); err != nil { return err } @@ -181,13 +182,13 @@ func (p *streamProtocolV2) stream(conn streamCreator, ready chan<- struct{}) err // now that all the streams have been created, proceed with reading & copying - errorChan := watchErrorStream(p.errorStream, &errorDecoderV2{}) + errorChan := watchErrorStream(logger, p.errorStream, &errorDecoderV2{}) - p.copyStdin() + p.copyStdin(logger) var wg sync.WaitGroup - p.copyStdout(&wg) - p.copyStderr(&wg) + p.copyStdout(logger, &wg) + p.copyStderr(logger, &wg) // we're waiting for stdout/stderr to finish copying wg.Wait() diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v3.go b/vendor/k8s.io/client-go/tools/remotecommand/v3.go index ece4cfafeb..b1e533a8a0 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/v3.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/v3.go @@ -22,8 +22,9 @@ import ( "net/http" "sync" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" ) // streamProtocolV3 implements version 3 of the streaming protocol for attach @@ -62,12 +63,12 @@ func (p *streamProtocolV3) createStreams(conn streamCreator) error { return nil } -func (p *streamProtocolV3) handleResizes() { +func (p *streamProtocolV3) handleResizes(logger klog.Logger) { if p.resizeStream == nil || p.TerminalSizeQueue == nil { return } go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(logger) encoder := json.NewEncoder(p.resizeStream) for { @@ -76,13 +77,13 @@ func (p *streamProtocolV3) handleResizes() { return } if err := encoder.Encode(&size); err != nil { - runtime.HandleError(err) + runtime.HandleErrorWithLogger(logger, err, "Encoding terminal size failed") } } }() } -func (p *streamProtocolV3) stream(conn streamCreator, ready chan<- struct{}) error { +func (p *streamProtocolV3) stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error { if err := p.createStreams(conn); err != nil { return err } @@ -94,15 +95,15 @@ func (p *streamProtocolV3) stream(conn streamCreator, ready chan<- struct{}) err // now that all the streams have been created, proceed with reading & copying - errorChan := watchErrorStream(p.errorStream, &errorDecoderV3{}) + errorChan := watchErrorStream(logger, p.errorStream, &errorDecoderV3{}) - p.handleResizes() + p.handleResizes(logger) - p.copyStdin() + p.copyStdin(logger) var wg sync.WaitGroup - p.copyStdout(&wg) - p.copyStderr(&wg) + p.copyStdout(logger, &wg) + p.copyStderr(logger, &wg) // we're waiting for stdout/stderr to finish copying wg.Wait() diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v4.go b/vendor/k8s.io/client-go/tools/remotecommand/v4.go index ecedad071e..47018ba5fe 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/v4.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/v4.go @@ -26,6 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/remotecommand" "k8s.io/client-go/util/exec" + "k8s.io/klog/v2" ) // streamProtocolV4 implements version 4 of the streaming protocol for attach @@ -47,11 +48,11 @@ func (p *streamProtocolV4) createStreams(conn streamCreator) error { return p.streamProtocolV3.createStreams(conn) } -func (p *streamProtocolV4) handleResizes() { - p.streamProtocolV3.handleResizes() +func (p *streamProtocolV4) handleResizes(logger klog.Logger) { + p.streamProtocolV3.handleResizes(logger) } -func (p *streamProtocolV4) stream(conn streamCreator, ready chan<- struct{}) error { +func (p *streamProtocolV4) stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error { if err := p.createStreams(conn); err != nil { return err } @@ -63,15 +64,15 @@ func (p *streamProtocolV4) stream(conn streamCreator, ready chan<- struct{}) err // now that all the streams have been created, proceed with reading & copying - errorChan := watchErrorStream(p.errorStream, &errorDecoderV4{}) + errorChan := watchErrorStream(logger, p.errorStream, &errorDecoderV4{}) - p.handleResizes() + p.handleResizes(logger) - p.copyStdin() + p.copyStdin(logger) var wg sync.WaitGroup - p.copyStdout(&wg) - p.copyStderr(&wg) + p.copyStdout(logger, &wg) + p.copyStderr(logger, &wg) // we're waiting for stdout/stderr to finish copying wg.Wait() diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v5.go b/vendor/k8s.io/client-go/tools/remotecommand/v5.go index edfd3ccb26..ca79a88287 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/v5.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/v5.go @@ -16,6 +16,8 @@ limitations under the License. package remotecommand +import "k8s.io/klog/v2" + // streamProtocolV5 add support for V5 of the remote command subprotocol. // For the streamProtocolHandler, this version is the same as V4. type streamProtocolV5 struct { @@ -30,6 +32,6 @@ func newStreamProtocolV5(options StreamOptions) streamProtocolHandler { } } -func (p *streamProtocolV5) stream(conn streamCreator, ready chan<- struct{}) error { - return p.streamProtocolV4.stream(conn, ready) +func (p *streamProtocolV5) stream(logger klog.Logger, conn streamCreator, ready chan<- struct{}) error { + return p.streamProtocolV4.stream(logger, conn, ready) } diff --git a/vendor/k8s.io/client-go/tools/remotecommand/websocket.go b/vendor/k8s.io/client-go/tools/remotecommand/websocket.go index e0433198fa..f531e7ccff 100644 --- a/vendor/k8s.io/client-go/tools/remotecommand/websocket.go +++ b/vendor/k8s.io/client-go/tools/remotecommand/websocket.go @@ -29,11 +29,11 @@ import ( gwebsocket "github.com/gorilla/websocket" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/apimachinery/pkg/util/remotecommand" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport/websocket" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // writeDeadline defines the time that a client-side write to the websocket @@ -130,7 +130,8 @@ func (e *wsStreamExecutor) StreamWithContext(ctx context.Context, options Stream } defer conn.Close() e.negotiated = conn.Subprotocol() - klog.V(4).Infof("The subprotocol is %s", e.negotiated) + logger := klog.FromContext(ctx) + logger.V(4).Info("Subprotocol negotiated", "protocol", e.negotiated) var streamer streamProtocolHandler switch e.negotiated { @@ -143,7 +144,7 @@ func (e *wsStreamExecutor) StreamWithContext(ctx context.Context, options Stream case remotecommand.StreamProtocolV2Name: streamer = newStreamProtocolV2(options) case "": - klog.V(4).Infof("The server did not negotiate a streaming protocol version. Falling back to %s", remotecommand.StreamProtocolV1Name) + logger.V(4).Info("The server did not negotiate a streaming protocol version, falling back", "protocol", remotecommand.StreamProtocolV1Name) fallthrough case remotecommand.StreamProtocolV1Name: streamer = newStreamProtocolV1(options) @@ -159,7 +160,7 @@ func (e *wsStreamExecutor) StreamWithContext(ctx context.Context, options Stream }() readyChan := make(chan struct{}) - creator := newWSStreamCreator(conn) + creator := newWSStreamCreator(logger, conn) go func() { select { // Wait until all streams have been created before starting the readDemuxLoop. @@ -177,7 +178,7 @@ func (e *wsStreamExecutor) StreamWithContext(ctx context.Context, options Stream e.heartbeatDeadline, ) }() - errorChan <- streamer.stream(creator, readyChan) + errorChan <- streamer.stream(logger, creator, readyChan) }() select { @@ -191,7 +192,8 @@ func (e *wsStreamExecutor) StreamWithContext(ctx context.Context, options Stream } type wsStreamCreator struct { - conn *gwebsocket.Conn + logger klog.Logger + conn *gwebsocket.Conn // Protects writing to websocket connection; reading is lock-free connWriteLock sync.Mutex // map of stream id to stream; multiple streams read/write the connection @@ -202,8 +204,9 @@ type wsStreamCreator struct { setStreamErr error } -func newWSStreamCreator(conn *gwebsocket.Conn) *wsStreamCreator { +func newWSStreamCreator(logger klog.Logger, conn *gwebsocket.Conn) *wsStreamCreator { return &wsStreamCreator{ + logger: logger, conn: conn, streams: map[byte]*stream{}, } @@ -238,6 +241,7 @@ func (c *wsStreamCreator) CreateStream(headers http.Header) (httpstream.Stream, } reader, writer := io.Pipe() s := &stream{ + logger: klog.LoggerWithValues(c.logger, "id", id), headers: headers, readPipe: reader, writePipe: writer, @@ -260,11 +264,11 @@ func (c *wsStreamCreator) CreateStream(headers http.Header) (httpstream.Stream, // connection reader at a time (a read mutex would provide no benefit). func (c *wsStreamCreator) readDemuxLoop(bufferSize int, period time.Duration, deadline time.Duration) { // Initialize and start the ping/pong heartbeat. - h := newHeartbeat(c.conn, period, deadline) + h := newHeartbeat(c.logger, c.conn, period, deadline) // Set initial timeout for websocket connection reading. - klog.V(5).Infof("Websocket initial read deadline: %s", deadline) + c.logger.V(5).Info("Websocket read starts", "deadline", deadline) if err := c.conn.SetReadDeadline(time.Now().Add(deadline)); err != nil { - klog.Errorf("Websocket initial setting read deadline failed %v", err) + c.logger.Error(err, "Websocket initial setting read deadline failed") return } go h.start() @@ -308,7 +312,7 @@ func (c *wsStreamCreator) readDemuxLoop(bufferSize int, period time.Duration, de streamID := readBuffer[0] s := c.getStream(streamID) if s == nil { - klog.Errorf("Unknown stream id %d, discarding message", streamID) + c.logger.Error(nil, "Unknown stream, discarding message", "id", streamID) continue } for { @@ -351,6 +355,7 @@ func (c *wsStreamCreator) closeAllStreamReaders(err error) { } type stream struct { + logger klog.Logger headers http.Header readPipe *io.PipeReader writePipe *io.PipeWriter @@ -369,8 +374,8 @@ func (s *stream) Read(p []byte) (n int, err error) { // Write writes directly to the underlying WebSocket connection. func (s *stream) Write(p []byte) (n int, err error) { - klog.V(8).Infof("Write() on stream %d", s.id) - defer klog.V(8).Infof("Write() done on stream %d", s.id) + s.logger.V(8).Info("Write() on stream") + defer s.logger.V(8).Info("Write() done on stream") s.connWriteLock.Lock() defer s.connWriteLock.Unlock() if s.conn == nil { @@ -378,7 +383,7 @@ func (s *stream) Write(p []byte) (n int, err error) { } err = s.conn.SetWriteDeadline(time.Now().Add(writeDeadline)) if err != nil { - klog.V(4).Infof("Websocket setting write deadline failed %v", err) + s.logger.V(4).Info("Websocket setting write deadline failed", "err", err) return 0, err } // Message writer buffers the message data, so we don't need to do that ourselves. @@ -407,8 +412,8 @@ func (s *stream) Write(p []byte) (n int, err error) { // Close half-closes the stream, indicating this side is finished with the stream. func (s *stream) Close() error { - klog.V(6).Infof("Close() on stream %d", s.id) - defer klog.V(6).Infof("Close() done on stream %d", s.id) + s.logger.V(6).Info("Close() on stream") + defer s.logger.V(6).Info("Close() done on stream") s.connWriteLock.Lock() defer s.connWriteLock.Unlock() if s.conn == nil { @@ -421,8 +426,8 @@ func (s *stream) Close() error { } func (s *stream) Reset() error { - klog.V(4).Infof("Reset() on stream %d", s.id) - defer klog.V(4).Infof("Reset() done on stream %d", s.id) + s.logger.V(4).Info("Reset() on stream") + defer s.logger.V(4).Info("Reset() done on stream") s.Close() return s.writePipe.Close() } @@ -442,7 +447,8 @@ func (s *stream) Identifier() uint32 { // inside the "readDemuxLoop" will return an i/o error prompting a connection close // and cleanup. type heartbeat struct { - conn *gwebsocket.Conn + logger klog.Logger + conn *gwebsocket.Conn // period defines how often a "ping" heartbeat message is sent to the other endpoint period time.Duration // closing the "closer" channel will clean up the heartbeat timers @@ -456,8 +462,9 @@ type heartbeat struct { // newHeartbeat creates heartbeat structure encapsulating fields necessary to // run the websocket connection ping/pong mechanism and sets up handlers on // the websocket connection. -func newHeartbeat(conn *gwebsocket.Conn, period time.Duration, deadline time.Duration) *heartbeat { +func newHeartbeat(logger klog.Logger, conn *gwebsocket.Conn, period time.Duration, deadline time.Duration) *heartbeat { h := &heartbeat{ + logger: logger, conn: conn, period: period, closer: make(chan struct{}), @@ -467,10 +474,10 @@ func newHeartbeat(conn *gwebsocket.Conn, period time.Duration, deadline time.Dur // be empty. h.conn.SetPongHandler(func(msg string) error { // Push the read deadline into the future. - klog.V(6).Infof("Pong message received (%s)--resetting read deadline", msg) + logger.V(6).Info("Pong message received -- resetting read deadline", "message", msg) err := h.conn.SetReadDeadline(time.Now().Add(deadline)) if err != nil { - klog.Errorf("Websocket setting read deadline failed %v", err) + logger.Error(err, "Websocket setting read deadline failed") return err } if len(msg) > 0 { @@ -502,16 +509,16 @@ func (h *heartbeat) start() { for { select { case <-h.closer: - klog.V(5).Infof("closed channel--returning") + h.logger.V(5).Info("Closed channel -- returning") return case <-t.C: // "WriteControl" does not need to be protected by a mutex. According to // gorilla/websockets library docs: "The Close and WriteControl methods can // be called concurrently with all other methods." if err := h.conn.WriteControl(gwebsocket.PingMessage, h.message, time.Now().Add(pingReadDeadline)); err == nil { - klog.V(6).Infof("Websocket Ping succeeeded") + h.logger.V(6).Info("Websocket Ping succeeeded") } else { - klog.Errorf("Websocket Ping failed: %v", err) + h.logger.Error(err, "Websocket Ping failed") if errors.Is(err, gwebsocket.ErrCloseSent) { // we continue because c.conn.CloseChan will manage closing the connection already continue diff --git a/vendor/k8s.io/client-go/tools/watch/retrywatcher.go b/vendor/k8s.io/client-go/tools/watch/retrywatcher.go index 45249d8e47..7d702907f9 100644 --- a/vendor/k8s.io/client-go/tools/watch/retrywatcher.go +++ b/vendor/k8s.io/client-go/tools/watch/retrywatcher.go @@ -26,12 +26,12 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/dump" "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" + "k8s.io/utils/dump" ) // resourceVersionGetter is an interface used to get resource version from events. diff --git a/vendor/k8s.io/client-go/transport/ca_rotation.go b/vendor/k8s.io/client-go/transport/ca_rotation.go new file mode 100644 index 0000000000..b802eedf48 --- /dev/null +++ b/vendor/k8s.io/client-go/transport/ca_rotation.go @@ -0,0 +1,154 @@ +/* +Copyright 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 transport + +import ( + "bytes" + "context" + "net/http" + "os" + "sync" + "time" + + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/client-go/tools/metrics" + "k8s.io/klog/v2" + "k8s.io/utils/clock" +) + +var _ utilnet.RoundTripperWrapper = &atomicTransportHolder{} + +// atomicTransportHolder holds a transport that can be atomically updated +// when CA files change, enabling graceful CA rotation without cache complexity +type atomicTransportHolder struct { + caFile string + currentCAData []byte // Track the actual CA data currently in use + // clock and caRefreshDuration are used to allow for testing time-based logic. + clock clock.Clock + caRefreshDuration time.Duration + // mu covers transport and transportLastChecked + mu sync.RWMutex + transport *http.Transport + transportLastChecked time.Time +} + +func (h *atomicTransportHolder) RoundTrip(req *http.Request) (*http.Response, error) { + return h.getTransport(req.Context()).RoundTrip(req) +} + +func (h *atomicTransportHolder) WrappedRoundTripper() http.RoundTripper { + h.mu.RLock() + defer h.mu.RUnlock() + + return h.transport +} + +func (h *atomicTransportHolder) getTransport(ctx context.Context) *http.Transport { + if rt := h.getTransportIfFresh(); rt != nil { + return rt + } + + h.mu.Lock() + defer h.mu.Unlock() + + h.tryRefreshTransportLocked(ctx) + return h.transport +} + +func (h *atomicTransportHolder) getTransportIfFresh() *http.Transport { + h.mu.RLock() + defer h.mu.RUnlock() + + if h.clock.Since(h.transportLastChecked) < h.caRefreshDuration { + return h.transport + } + return nil +} + +func (h *atomicTransportHolder) tryRefreshTransportLocked(ctx context.Context) { + // If some other goroutine already checked/updated the CA + if h.clock.Since(h.transportLastChecked) < h.caRefreshDuration { + return + } + + // only attempt CA reload once per caRefreshDuration, even if the reload fails + h.transportLastChecked = h.clock.Now() + + logger := klog.FromContext(ctx).WithValues("caFile", h.caFile) + + logger.V(4).Info("Checking CA file content") + + // Load new CA data from file + newCAData, err := os.ReadFile(h.caFile) + // Return old transport on read error + if err != nil { + logger.Error(err, "Failed to read CA data from file") + metrics.TransportCAReloads.Increment("failure", "read_error") + return + } + + if len(newCAData) == 0 { + logger.Info("CA file empty, skipping transport rotation") + metrics.TransportCAReloads.Increment("failure", "empty") + return + } + + if bytes.Equal(h.currentCAData, newCAData) { + logger.V(4).Info("CA file unchanged, skipping transport rotation") + metrics.TransportCAReloads.Increment("success", "unchanged") + return + } + + logger.V(4).Info("CA content changed, updating transport") + + // Load new CA pool + newCAs, err := rootCertPool(newCAData) + // Return old transport on parse error + if err != nil { + logger.Error(err, "Failed to parse CA data from file") + metrics.TransportCAReloads.Increment("failure", "ca_parse_error") + return + } + newTransport := h.transport.Clone() + newTransport.TLSClientConfig.RootCAs = newCAs + oldTransport := h.transport + h.transport = newTransport + // Update our tracking of current CA data + h.currentCAData = newCAData + + // Close idle connections on the old transport to encourage migration + oldTransport.CloseIdleConnections() + + logger.V(4).Info("Transport updated for CA rotation") + metrics.TransportCAReloads.Increment("success", "updated") +} + +// newAtomicTransportHolder creates a new holder for CA file reloading scenarios. +// The caFile must be specified. +// caData may be empty but should correspond to the contents of caFile. +// transport must have a TLS config and its root CAs should match caData. +func newAtomicTransportHolder(caFile string, caData []byte, transport *http.Transport) *atomicTransportHolder { + c := clock.RealClock{} + return &atomicTransportHolder{ + caFile: caFile, + currentCAData: caData, + clock: c, + caRefreshDuration: 5 * time.Minute, + transport: transport, + transportLastChecked: c.Now(), + } +} diff --git a/vendor/k8s.io/client-go/transport/cache.go b/vendor/k8s.io/client-go/transport/cache.go index b8dd866119..16b62ec9fe 100644 --- a/vendor/k8s.io/client-go/transport/cache.go +++ b/vendor/k8s.io/client-go/transport/cache.go @@ -21,12 +21,14 @@ import ( "fmt" "net" "net/http" + "runtime" "strings" "sync" "time" + "weak" utilnet "k8s.io/apimachinery/pkg/util/net" - "k8s.io/apimachinery/pkg/util/wait" + clientgofeaturegate "k8s.io/client-go/features" "k8s.io/client-go/tools/metrics" "k8s.io/klog/v2" ) @@ -35,22 +37,26 @@ import ( // same RoundTripper will be returned for configs with identical TLS options If // the config has no custom TLS options, http.DefaultTransport is returned. type tlsTransportCache struct { - mu sync.Mutex - transports map[tlsCacheKey]*http.Transport + mu sync.Mutex + transports map[tlsCacheKey]weak.Pointer[trackedTransport] // GC-enabled + strongTransports map[tlsCacheKey]http.RoundTripper // GC-disabled } -// DialerStopCh is stop channel that is passed down to dynamic cert dialer. -// It's exposed as variable for testing purposes to avoid testing for goroutine -// leakages. -var DialerStopCh = wait.NeverStop - const idleConnsPerHost = 25 -var tlsCache = &tlsTransportCache{transports: make(map[tlsCacheKey]*http.Transport)} +var tlsCache = newTLSCache() + +func newTLSCache() *tlsTransportCache { + return &tlsTransportCache{ + transports: make(map[tlsCacheKey]weak.Pointer[trackedTransport]), + strongTransports: make(map[tlsCacheKey]http.RoundTripper), + } +} type tlsCacheKey struct { insecure bool caData string + caFile string certData string keyData string `datapolicy:"security-key"` certFile string @@ -68,8 +74,8 @@ func (t tlsCacheKey) String() string { if len(t.keyData) > 0 { keyText = "" } - return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, serverName:%s, disableCompression:%t, getCert:%p, dial:%p", - t.insecure, t.caData, t.certData, keyText, t.serverName, t.disableCompression, t.getCert, t.dial) + return fmt.Sprintf("insecure:%v, caData:%#v, caFile:%s, certData:%#v, keyData:%s, serverName:%s, disableCompression:%t, getCert:%p, dial:%p", + t.insecure, t.caData, t.caFile, t.certData, keyText, t.serverName, t.disableCompression, t.getCert, t.dial) } func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { @@ -82,14 +88,18 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { // Ensure we only create a single transport for the given TLS options c.mu.Lock() defer c.mu.Unlock() - defer metrics.TransportCacheEntries.Observe(len(c.transports)) + defer func() { metrics.TransportCacheEntries.Observe(c.lenLocked()) }() // See if we already have a custom transport for this config - if t, ok := c.transports[key]; ok { - metrics.TransportCreateCalls.Increment("hit") - return t, nil + if t, ok := c.getLocked(key); ok { + if t != nil { + metrics.TransportCreateCalls.Increment("hit") + return t, nil + } + metrics.TransportCreateCalls.Increment("miss-gc") + } else { + metrics.TransportCreateCalls.Increment("miss") } - metrics.TransportCreateCalls.Increment("miss") } else { metrics.TransportCreateCalls.Increment("uncacheable") } @@ -116,6 +126,7 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { // If we use are reloading files, we need to handle certificate rotation properly // TODO(jackkleeman): We can also add rotation here when config.HasCertCallback() is true + var cancel context.CancelFunc if config.TLS.ReloadTLSFiles && tlsConfig != nil && tlsConfig.GetClientCertificate != nil { // The TLS cache is a singleton, so sharing the same name for all of its // background activity seems okay. @@ -123,7 +134,9 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { dynamicCertDialer := certRotatingDialer(logger, tlsConfig.GetClientCertificate, dial) tlsConfig.GetClientCertificate = dynamicCertDialer.GetClientCertificate dial = dynamicCertDialer.connDialer.DialContext - go dynamicCertDialer.run(DialerStopCh) + var ctx context.Context + ctx, cancel = context.WithCancel(context.Background()) + go dynamicCertDialer.run(ctx.Done()) } proxy := http.ProxyFromEnvironment @@ -131,7 +144,7 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { proxy = config.Proxy } - transport := utilnet.SetTransportDefaults(&http.Transport{ + httpTransport := utilnet.SetTransportDefaults(&http.Transport{ Proxy: proxy, TLSHandshakeTimeout: 10 * time.Second, TLSClientConfig: tlsConfig, @@ -139,13 +152,101 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { DialContext: dial, DisableCompression: config.DisableCompression, }) + var transport http.RoundTripper = httpTransport + + if config.TLS.ReloadCAFiles && tlsConfig != nil && tlsConfig.RootCAs != nil && len(config.TLS.CAFile) > 0 { + transport = newAtomicTransportHolder(config.TLS.CAFile, config.TLS.CAData, httpTransport) + } + + if !canCache && cancel == nil { + return transport, nil // uncacheable config with no cert rotation - nothing to GC + } + + if !clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.ClientsAllowTLSCacheGC) { + if canCache { + c.strongTransports[key] = transport + } + return transport, nil // cancel is intentionally discarded and the cert rotation go routine leaks + } + + transportWithGC := &trackedTransport{rt: transport} + + if cancel != nil { + // capture metric as local var so that cleanups do not influence other tests via globals + transportCertRotationGCCalls := metrics.TransportCertRotationGCCalls + runtime.AddCleanup(transportWithGC, func(_ struct{}) { + cancel() + transportCertRotationGCCalls.Increment() + }, struct{}{}) + } if canCache { - // Cache a single transport for these options - c.transports[key] = transport + wp := weak.Make(transportWithGC) + c.transports[key] = wp + // capture metrics as local vars so that cleanups do not influence other tests via globals + transportCacheGCCalls := metrics.TransportCacheGCCalls + transportCacheEntries := metrics.TransportCacheEntries + runtime.AddCleanup(transportWithGC, func(key tlsCacheKey) { + c.mu.Lock() + defer c.mu.Unlock() + + // make sure we only delete the weak pointer created by this specific setLocked call + if c.transports[key] != wp { + transportCacheGCCalls.Increment("skipped") + return + } + delete(c.transports, key) + transportCacheGCCalls.Increment("deleted") + transportCacheEntries.Observe(c.lenLocked()) + }, key) } - return transport, nil + return transportWithGC, nil +} + +func (c *tlsTransportCache) getLocked(key tlsCacheKey) (http.RoundTripper, bool) { + if !clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.ClientsAllowTLSCacheGC) { + v, ok := c.strongTransports[key] + return v, ok + } + + wp, ok := c.transports[key] + if !ok { + return nil, false + } + + v := wp.Value() + + if v == nil { // avoid typed nil + return nil, true // key exists but value has been garbage collected + } + + return v, true +} + +func (c *tlsTransportCache) lenLocked() int { + if !clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.ClientsAllowTLSCacheGC) { + return len(c.strongTransports) + } + return len(c.transports) +} + +// trackedTransport wraps an http.RoundTripper to serve as the weak.Pointer +// target in the TLS transport cache. Dropping all references to this object +// triggers GC cleanup of the cache entry and any cert rotation goroutine. +type trackedTransport struct { + rt http.RoundTripper +} + +var _ http.RoundTripper = &trackedTransport{} +var _ utilnet.RoundTripperWrapper = &trackedTransport{} + +func (v *trackedTransport) RoundTrip(req *http.Request) (*http.Response, error) { + return v.rt.RoundTrip(req) +} + +func (v *trackedTransport) WrappedRoundTripper() http.RoundTripper { + return v.rt } // tlsConfigKey returns a unique key for tls.Config objects returned from TLSConfigFor @@ -162,7 +263,6 @@ func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) { k := tlsCacheKey{ insecure: c.TLS.Insecure, - caData: string(c.TLS.CAData), serverName: c.TLS.ServerName, nextProtos: strings.Join(c.TLS.NextProtos, ","), disableCompression: c.DisableCompression, @@ -178,5 +278,14 @@ func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) { k.keyData = string(c.TLS.KeyData) } + if c.TLS.ReloadCAFiles { + // When reloading CA files, include CA file path in cache key instead of CA data + // This allows the CA to be reloaded from disk on each transport creation + k.caFile = c.TLS.CAFile + } else { + // When not reloading, cache the CA data directly + k.caData = string(c.TLS.CAData) + } + return k, true, nil } diff --git a/vendor/k8s.io/client-go/transport/config.go b/vendor/k8s.io/client-go/transport/config.go index d8a3d64b30..f3ddcca33c 100644 --- a/vendor/k8s.io/client-go/transport/config.go +++ b/vendor/k8s.io/client-go/transport/config.go @@ -134,7 +134,8 @@ type TLSConfig struct { CAFile string // Path of the PEM-encoded server trusted root certificates. CertFile string // Path of the PEM-encoded client certificate. KeyFile string // Path of the PEM-encoded client key. - ReloadTLSFiles bool // Set to indicate that the original config provided files, and that they should be reloaded + ReloadTLSFiles bool // Set to indicate that the original config provided files, and that they should be reloaded. + ReloadCAFiles bool // Set to indicate that CA files should be reloaded from disk. Insecure bool // Server should be accessed without verifying the certificate. For testing only. ServerName string // Override for the server name passed to the server for SNI and used to verify certificates. diff --git a/vendor/k8s.io/client-go/transport/round_trippers.go b/vendor/k8s.io/client-go/transport/round_trippers.go index 39fcebd941..a50977671a 100644 --- a/vendor/k8s.io/client-go/transport/round_trippers.go +++ b/vendor/k8s.io/client-go/transport/round_trippers.go @@ -319,7 +319,7 @@ func (rt *bearerAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, token = refreshedToken.AccessToken } } - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + req.Header.Set("Authorization", "Bearer "+token) return rt.rt.RoundTrip(req) } diff --git a/vendor/k8s.io/client-go/transport/spdy/spdy.go b/vendor/k8s.io/client-go/transport/spdy/spdy.go index 9fddc6c5f2..3bb04b77f3 100644 --- a/vendor/k8s.io/client-go/transport/spdy/spdy.go +++ b/vendor/k8s.io/client-go/transport/spdy/spdy.go @@ -23,8 +23,10 @@ import ( "time" "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/httpstream/spdy" + httpstreamspdy "k8s.io/apimachinery/pkg/util/httpstream/spdy" restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" + streamhttp "k8s.io/streaming/pkg/httpstream" ) // Upgrader validates a response from the server after a SPDY upgrade. @@ -43,7 +45,7 @@ func RoundTripperFor(config *restclient.Config) (http.RoundTripper, Upgrader, er if config.Proxy != nil { proxy = config.Proxy } - upgradeRoundTripper, err := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{ + upgradeRoundTripper, err := httpstreamspdy.NewRoundTripperWithConfig(httpstreamspdy.RoundTripperConfig{ TLS: tlsConfig, Proxier: proxy, PingPeriod: time.Second * 5, @@ -79,6 +81,18 @@ func NewDialer(upgrader Upgrader, client *http.Client, method string, url *url.U } } +// NewDialerForStreaming creates a SPDY dialer for in-tree callers that use +// k8s.io/streaming/pkg/httpstream types. +func NewDialerForStreaming(upgrader Upgrader, client *http.Client, method string, url *url.URL) streamhttp.Dialer { + return &streamingDialerAdapter{delegate: NewDialer(upgrader, client, method, url)} +} + +// NewUpgraderForStreaming adapts a streaming upgrader for callers that need +// the compatibility Upgrader interface. +func NewUpgraderForStreaming(upgrader streamhttp.UpgradeRoundTripper) Upgrader { + return &compatUpgraderAdapter{delegate: upgrader} +} + func (d *dialer) Dial(protocols ...string) (httpstream.Connection, string, error) { req, err := http.NewRequest(d.method, d.url.String(), nil) if err != nil { @@ -105,3 +119,199 @@ func Negotiate(upgrader Upgrader, client *http.Client, req *http.Request, protoc } return conn, resp.Header.Get(httpstream.HeaderProtocolVersion), nil } + +// NegotiateStreaming is for in-tree callers that still operate on +// k8s.io/streaming/pkg/httpstream types. +func NegotiateStreaming(upgrader Upgrader, client *http.Client, req *http.Request, protocols ...string) (streamhttp.Connection, string, error) { + conn, protocol, err := Negotiate(upgrader, client, req, protocols...) + if err != nil { + return nil, "", err + } + return wrapStreamingConnection(conn), protocol, nil +} + +type streamingDialerAdapter struct { + delegate httpstream.Dialer +} + +func (d *streamingDialerAdapter) Dial(protocols ...string) (streamhttp.Connection, string, error) { + conn, protocol, err := d.delegate.Dial(protocols...) + if err != nil { + return nil, "", err + } + return wrapStreamingConnection(conn), protocol, nil +} + +type compatUpgraderAdapter struct { + delegate streamhttp.UpgradeRoundTripper +} + +func (u *compatUpgraderAdapter) NewConnection(resp *http.Response) (httpstream.Connection, error) { + conn, err := u.delegate.NewConnection(resp) + if err != nil { + return nil, err + } + return wrapCompatConnection(conn), nil +} + +type streamingStreamAdapter struct { + delegate httpstream.Stream +} + +func (s *streamingStreamAdapter) Read(p []byte) (int, error) { + return s.delegate.Read(p) +} + +func (s *streamingStreamAdapter) Write(p []byte) (int, error) { + return s.delegate.Write(p) +} + +func (s *streamingStreamAdapter) Close() error { + return s.delegate.Close() +} + +func (s *streamingStreamAdapter) Reset() error { + return s.delegate.Reset() +} + +func (s *streamingStreamAdapter) Headers() http.Header { + return s.delegate.Headers() +} + +func (s *streamingStreamAdapter) Identifier() uint32 { + return s.delegate.Identifier() +} + +type streamingConnectionAdapter struct { + delegate httpstream.Connection +} + +func (c *streamingConnectionAdapter) CreateStream(headers http.Header) (streamhttp.Stream, error) { + stream, err := c.delegate.CreateStream(headers) + if err != nil { + return nil, err + } + return &streamingStreamAdapter{delegate: stream}, nil +} + +func (c *streamingConnectionAdapter) Close() error { + return c.delegate.Close() +} + +func (c *streamingConnectionAdapter) CloseChan() <-chan bool { + return c.delegate.CloseChan() +} + +func (c *streamingConnectionAdapter) SetIdleTimeout(timeout time.Duration) { + c.delegate.SetIdleTimeout(timeout) +} + +func (c *streamingConnectionAdapter) RemoveStreams(streams ...streamhttp.Stream) { + compatStreams := make([]httpstream.Stream, 0, len(streams)) + for _, stream := range streams { + if stream == nil { + continue + } + if s, ok := stream.(*streamingStreamAdapter); ok { + compatStreams = append(compatStreams, s.delegate) + continue + } + if s, ok := stream.(httpstream.Stream); ok { + compatStreams = append(compatStreams, s) + continue + } + klog.V(5).Infof("dropping unadaptable streaming stream %T in RemoveStreams", stream) + } + c.delegate.RemoveStreams(compatStreams...) +} + +func wrapStreamingConnection(conn httpstream.Connection) streamhttp.Connection { + if conn == nil { + return nil + } + if wrapped, ok := conn.(*compatConnectionAdapter); ok { + return wrapped.delegate + } + return &streamingConnectionAdapter{delegate: conn} +} + +type compatStreamAdapter struct { + delegate streamhttp.Stream +} + +func (s *compatStreamAdapter) Read(p []byte) (int, error) { + return s.delegate.Read(p) +} + +func (s *compatStreamAdapter) Write(p []byte) (int, error) { + return s.delegate.Write(p) +} + +func (s *compatStreamAdapter) Close() error { + return s.delegate.Close() +} + +func (s *compatStreamAdapter) Reset() error { + return s.delegate.Reset() +} + +func (s *compatStreamAdapter) Headers() http.Header { + return s.delegate.Headers() +} + +func (s *compatStreamAdapter) Identifier() uint32 { + return s.delegate.Identifier() +} + +type compatConnectionAdapter struct { + delegate streamhttp.Connection +} + +func (c *compatConnectionAdapter) CreateStream(headers http.Header) (httpstream.Stream, error) { + stream, err := c.delegate.CreateStream(headers) + if err != nil { + return nil, err + } + return &compatStreamAdapter{delegate: stream}, nil +} + +func (c *compatConnectionAdapter) Close() error { + return c.delegate.Close() +} + +func (c *compatConnectionAdapter) CloseChan() <-chan bool { + return c.delegate.CloseChan() +} + +func (c *compatConnectionAdapter) SetIdleTimeout(timeout time.Duration) { + c.delegate.SetIdleTimeout(timeout) +} + +func (c *compatConnectionAdapter) RemoveStreams(streams ...httpstream.Stream) { + streamingStreams := make([]streamhttp.Stream, 0, len(streams)) + for _, stream := range streams { + if stream == nil { + continue + } + if s, ok := stream.(*compatStreamAdapter); ok { + streamingStreams = append(streamingStreams, s.delegate) + continue + } + if s, ok := stream.(streamhttp.Stream); ok { + streamingStreams = append(streamingStreams, s) + continue + } + klog.V(5).Infof("dropping unadaptable compat stream %T in RemoveStreams", stream) + } + c.delegate.RemoveStreams(streamingStreams...) +} + +func wrapCompatConnection(conn streamhttp.Connection) httpstream.Connection { + if conn == nil { + return nil + } + if wrapped, ok := conn.(*streamingConnectionAdapter); ok { + return wrapped.delegate + } + return &compatConnectionAdapter{delegate: conn} +} diff --git a/vendor/k8s.io/client-go/transport/transport.go b/vendor/k8s.io/client-go/transport/transport.go index 8fdcc5700b..be97b76210 100644 --- a/vendor/k8s.io/client-go/transport/transport.go +++ b/vendor/k8s.io/client-go/transport/transport.go @@ -28,6 +28,7 @@ import ( "time" utilnet "k8s.io/apimachinery/pkg/util/net" + clientgofeaturegate "k8s.io/client-go/features" "k8s.io/klog/v2" ) @@ -211,17 +212,26 @@ func TLSConfigFor(c *Config) (*tls.Config, error) { // KeyData, and CAFile fields, or returns an error. If no error is returned, all three fields are // either populated or were empty to start. func loadTLSFiles(c *Config) error { - var err error - c.TLS.CAData, err = dataFromSliceOrFile(c.TLS.CAData, c.TLS.CAFile) - if err != nil { - return err + // Check that we are purely loading CA from file + if clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.ClientsAllowCARotation) { + if len(c.TLS.CAFile) > 0 && len(c.TLS.CAData) == 0 { + c.TLS.ReloadCAFiles = true + } + } else if c.TLS.ReloadCAFiles { + return fmt.Errorf("ReloadCAFiles=true requires ClientsAllowCARotation to be enabled") } - // Check that we are purely loading from files + // Check that we are purely loading certs and keys from files if len(c.TLS.CertFile) > 0 && len(c.TLS.CertData) == 0 && len(c.TLS.KeyFile) > 0 && len(c.TLS.KeyData) == 0 { c.TLS.ReloadTLSFiles = true } + var err error + c.TLS.CAData, err = dataFromSliceOrFile(c.TLS.CAData, c.TLS.CAFile) + if err != nil { + return err + } + c.TLS.CertData, err = dataFromSliceOrFile(c.TLS.CertData, c.TLS.CertFile) if err != nil { return err @@ -254,6 +264,11 @@ func rootCertPool(caData []byte) (*x509.CertPool, error) { // code for a look at the platform specific insanity), so we'll use the fact that RootCAs == nil gives us the system values // It doesn't allow trusting either/or, but hopefully that won't be an issue if len(caData) == 0 { + // When the ClientsAllowCARotation feature gate is enabled, it returns an empty but non-nil pool. + // This ensures we don't fall back to system roots when a user explicitly points CAFile to a zero-byte file. + if clientgofeaturegate.FeatureGates().Enabled(clientgofeaturegate.ClientsAllowCARotation) { + return x509.NewCertPool(), nil + } return nil, nil } diff --git a/vendor/k8s.io/client-go/transport/websocket/roundtripper.go b/vendor/k8s.io/client-go/transport/websocket/roundtripper.go index 924518e8bb..5285d6b144 100644 --- a/vendor/k8s.io/client-go/transport/websocket/roundtripper.go +++ b/vendor/k8s.io/client-go/transport/websocket/roundtripper.go @@ -31,11 +31,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" utilnet "k8s.io/apimachinery/pkg/util/net" restclient "k8s.io/client-go/rest" "k8s.io/client-go/transport" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/httpstream/wsstream" ) var ( diff --git a/vendor/k8s.io/client-go/util/certificate/csr/csr.go b/vendor/k8s.io/client-go/util/certificate/csr/csr.go index 6f99dcd24b..6b0efff067 100644 --- a/vendor/k8s.io/client-go/util/certificate/csr/csr.go +++ b/vendor/k8s.io/client-go/util/certificate/csr/csr.go @@ -78,13 +78,15 @@ func RequestCertificateWithContext(ctx context.Context, client clientset.Interfa csr.Spec.ExpirationSeconds = DurationToExpirationSeconds(*requestedDuration) } + logger := klog.FromContext(ctx) + reqName, reqUID, err = create(ctx, client, csr) switch { case err == nil: + logger.V(2).Info("Certificate signing request created", "csr", reqName) return reqName, reqUID, err case apierrors.IsAlreadyExists(err) && len(name) > 0: - logger := klog.FromContext(ctx) logger.Info("csr for this node already exists, reusing") req, err := get(ctx, client, name) if err != nil { diff --git a/vendor/k8s.io/client-go/util/watchlist/watch_list.go b/vendor/k8s.io/client-go/util/watchlist/watch_list.go index 1551a49f79..3641f3baee 100644 --- a/vendor/k8s.io/client-go/util/watchlist/watch_list.go +++ b/vendor/k8s.io/client-go/util/watchlist/watch_list.go @@ -90,6 +90,9 @@ type unSupportedWatchListSemantics interface { // // A client does NOT support WatchList only if // it implements `IsWatchListSemanticsUnSupported` and that returns true. +// +// For an explanation of how WatchList works, see: +// https://kubernetes.io/docs/reference/using-api/api-concepts/#streaming-lists func DoesClientNotSupportWatchListSemantics(client any) bool { lw, ok := client.(unSupportedWatchListSemantics) if !ok { diff --git a/vendor/k8s.io/cloud-provider/OWNERS b/vendor/k8s.io/cloud-provider/OWNERS index 1ac1c0f0e6..3f7357c0b6 100644 --- a/vendor/k8s.io/cloud-provider/OWNERS +++ b/vendor/k8s.io/cloud-provider/OWNERS @@ -1,11 +1,9 @@ # See the OWNERS docs at https://go.k8s.io/owners approvers: - - mikedanese - - dims - - wlan0 - - andrewsykim - cheftako + - elmiko + - joelspeed reviewers: - aojea - wojtek-t @@ -25,6 +23,10 @@ reviewers: - wlan0 - cheftako - andrewsykim +emeritus_approvers: + - mikedanese + - dims + - andrewsykim labels: - sig/cloud-provider - area/cloudprovider diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go index af7c788035..1879de834d 100644 --- a/vendor/k8s.io/cloud-provider/controllers/node/config/types.go +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go @@ -21,4 +21,8 @@ type NodeControllerConfiguration struct { // ConcurrentNodeSyncs is the number of workers // concurrently synchronizing nodes ConcurrentNodeSyncs int32 + // ConcurrentNodeStatusUpdates is the number of workers + // concurrently updating node statuses. + // If unspecified or 0, ConcurrentNodeSyncs is used instead + ConcurrentNodeStatusUpdates int32 } diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go index ca85a557cb..0c9234fbc0 100644 --- a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go @@ -21,4 +21,8 @@ type NodeControllerConfiguration struct { // ConcurrentNodeSyncs is the number of workers // concurrently synchronizing nodes ConcurrentNodeSyncs int32 + // ConcurrentNodeStatusUpdates is the number of workers + // concurrently updating node statuses. + // If unspecified or 0, ConcurrentNodeSyncs is used instead + ConcurrentNodeStatusUpdates int32 } diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go index cf3852db29..89ccc8833a 100644 --- a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go @@ -49,10 +49,12 @@ func RegisterConversions(s *runtime.Scheme) error { func autoConvert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in *NodeControllerConfiguration, out *config.NodeControllerConfiguration, s conversion.Scope) error { out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + out.ConcurrentNodeStatusUpdates = in.ConcurrentNodeStatusUpdates return nil } func autoConvert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in *config.NodeControllerConfiguration, out *NodeControllerConfiguration, s conversion.Scope) error { out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + out.ConcurrentNodeStatusUpdates = in.ConcurrentNodeStatusUpdates return nil } diff --git a/vendor/k8s.io/cloud-provider/options/nodecontroller.go b/vendor/k8s.io/cloud-provider/options/nodecontroller.go index 4823c437b1..9573276db0 100644 --- a/vendor/k8s.io/cloud-provider/options/nodecontroller.go +++ b/vendor/k8s.io/cloud-provider/options/nodecontroller.go @@ -36,6 +36,8 @@ func (o *NodeControllerOptions) AddFlags(fs *pflag.FlagSet) { } fs.Int32Var(&o.ConcurrentNodeSyncs, "concurrent-node-syncs", o.ConcurrentNodeSyncs, "Number of workers concurrently synchronizing nodes.") + // If concurrent-node-status-updates is not specified it will be derived from concurrent-node-syncs for backwards compatibility + fs.Int32Var(&o.ConcurrentNodeStatusUpdates, "concurrent-node-status-updates", 0, "Number of workers concurrently updating node statuses. If unspecified or 0, --concurrent-node-syncs is used instead") } // ApplyTo fills up ServiceController config with options. @@ -45,6 +47,13 @@ func (o *NodeControllerOptions) ApplyTo(cfg *nodeconfig.NodeControllerConfigurat } cfg.ConcurrentNodeSyncs = o.ConcurrentNodeSyncs + // Concurrent node status updates used to be derived from the concurrent-node-syncs flag, + // so for backwards compatibility it will default to concurrent-node-syncs if concurrent-node-status-updates is not specified + if o.ConcurrentNodeStatusUpdates > 0 { + cfg.ConcurrentNodeStatusUpdates = o.ConcurrentNodeStatusUpdates + } else { + cfg.ConcurrentNodeStatusUpdates = o.ConcurrentNodeSyncs + } return nil } @@ -58,5 +67,8 @@ func (o *NodeControllerOptions) Validate() []error { if o.ConcurrentNodeSyncs <= 0 { errors = append(errors, fmt.Errorf("concurrent-node-syncs must be a positive number")) } + if o.ConcurrentNodeStatusUpdates < 0 { + errors = append(errors, fmt.Errorf("concurrent-node-status-updates cannot be a negative number")) + } return errors } diff --git a/vendor/k8s.io/cloud-provider/options/options.go b/vendor/k8s.io/cloud-provider/options/options.go index 0534f9f614..2f24aab31d 100644 --- a/vendor/k8s.io/cloud-provider/options/options.go +++ b/vendor/k8s.io/cloud-provider/options/options.go @@ -242,7 +242,9 @@ func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, allControllers // sync back to component config // TODO: find more elegant way than syncing back the values. c.ComponentConfig.NodeStatusUpdateFrequency = o.NodeStatusUpdateFrequency - c.ComponentConfig.NodeController.ConcurrentNodeSyncs = o.NodeController.ConcurrentNodeSyncs + if err = o.NodeController.ApplyTo(&c.ComponentConfig.NodeController); err != nil { + return err + } return nil } diff --git a/vendor/k8s.io/cloud-provider/options/webhook.go b/vendor/k8s.io/cloud-provider/options/webhook.go index 5174ae80f1..8dfc011c54 100644 --- a/vendor/k8s.io/cloud-provider/options/webhook.go +++ b/vendor/k8s.io/cloud-provider/options/webhook.go @@ -29,6 +29,7 @@ import ( "k8s.io/apiserver/pkg/server/dynamiccertificates" apiserveroptions "k8s.io/apiserver/pkg/server/options" "k8s.io/cloud-provider/config" + cliflag "k8s.io/component-base/cli/flag" netutils "k8s.io/utils/net" ) @@ -124,18 +125,54 @@ func (o *WebhookServingOptions) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&o.BindPort, "webhook-secure-port", o.BindPort, "Secure port to serve cloud provider webhooks. If 0, don't serve webhooks at all.") + fs.BoolVar(&o.DisableHTTP2Serving, "webhook-disable-http2-serving", o.DisableHTTP2Serving, + "If true, HTTP2 serving will be disabled for the webhook server [default=false]") + fs.StringVar(&o.ServerCert.CertDirectory, "webhook-cert-dir", o.ServerCert.CertDirectory, ""+ "The directory where the TLS certs are located. "+ - "If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.") + "If --webhook-tls-cert-file and --webhook-tls-private-key-file are provided, this flag will be ignored.") fs.StringVar(&o.ServerCert.CertKey.CertFile, "webhook-tls-cert-file", o.ServerCert.CertKey.CertFile, ""+ "File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+ - "after server cert). If HTTPS serving is enabled, and --tls-cert-file and "+ - "--tls-private-key-file are not provided, a self-signed certificate and key "+ - "are generated for the public address and saved to the directory specified by --cert-dir.") + "after server cert). If HTTPS serving is enabled, and --webhook-tls-cert-file and "+ + "--webhook-tls-private-key-file are not provided, a self-signed certificate and key "+ + "are generated for the public address and saved to the directory specified by --webhook-cert-dir.") fs.StringVar(&o.ServerCert.CertKey.KeyFile, "webhook-tls-private-key-file", o.ServerCert.CertKey.KeyFile, - "File containing the default x509 private key matching --tls-cert-file.") + "File containing the default x509 private key matching --webhook-tls-cert-file.") + + tlsCipherPreferredValues := cliflag.PreferredTLSCipherNames() + tlsCipherInsecureValues := cliflag.InsecureTLSCipherNames() + fs.StringSliceVar(&o.CipherSuites, "webhook-tls-cipher-suites", o.CipherSuites, + "Comma-separated list of cipher suites for the webhook server. "+ + "If omitted, the default Go cipher suites will be used. \n"+ + "Preferred values: "+strings.Join(tlsCipherPreferredValues, ", ")+". \n"+ + "Insecure values: "+strings.Join(tlsCipherInsecureValues, ", ")+".") + + fs.Int32SliceVar(&o.CurvePreferences, "webhook-tls-curve-preferences", o.CurvePreferences, + "Comma-separated list of numeric Go crypto/tls CurveID values, "+ + "as the allowed key exchange mechanisms for the webhook server. "+ + "The supported values depend on the Go version used. "+ + "See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. "+ + "The order of the list is ignored, and key exchange mechanisms are chosen "+ + "by Go from this list using an internal preference order. "+ + "If omitted, the default Go curves will be used.") + + tlsPossibleVersions := cliflag.TLSPossibleVersions() + fs.StringVar(&o.MinTLSVersion, "webhook-tls-min-version", o.MinTLSVersion, + "Minimum TLS version supported for the webhook server. "+ + "Possible values: "+strings.Join(tlsPossibleVersions, ", ")) + + fs.Var(cliflag.NewNamedCertKeyArray(&o.SNICertKeys), "webhook-tls-sni-cert-key", ""+ + "A pair of x509 certificate and private key file paths, optionally suffixed with a list of "+ + "domain patterns which are fully qualified domain names, possibly with prefixed wildcard "+ + "segments. The domain patterns also allow IP addresses, but IPs should only be used if "+ + "the webhook server has visibility to the IP address requested by a client. "+ + "If no domain patterns are provided, the names of the certificate are "+ + "extracted. Non-wildcard matches trump over wildcard matches, explicit domain patterns "+ + "trump over extracted names. For multiple key/certificate pairs, use the "+ + "--webhook-tls-sni-cert-key multiple times. "+ + "Examples: \"example.crt,example.key\" or \"foo.crt,foo.key:*.foo.com,foo.com\".") } func (o *WebhookServingOptions) Validate() []error { @@ -176,19 +213,53 @@ func (o *WebhookServingOptions) ApplyTo(cfg **server.SecureServingInfo, webhookC } *cfg = &server.SecureServingInfo{ - Listener: listener, + Listener: listener, + DisableHTTP2: o.DisableHTTP2Serving, } + c := *cfg serverCertFile, serverKeyFile := o.ServerCert.CertKey.CertFile, o.ServerCert.CertKey.KeyFile if len(serverCertFile) != 0 || len(serverKeyFile) != 0 { var err error - (*cfg).Cert, err = dynamiccertificates.NewDynamicServingContentFromFiles("serving-cert", serverCertFile, serverKeyFile) + c.Cert, err = dynamiccertificates.NewDynamicServingContentFromFiles("serving-cert", serverCertFile, serverKeyFile) if err != nil { - return err + return fmt.Errorf("failed to load serving cert: %w", err) } } else if o.ServerCert.GeneratedCert != nil { - (*cfg).Cert = o.ServerCert.GeneratedCert + c.Cert = o.ServerCert.GeneratedCert + } + + if len(o.CipherSuites) != 0 { + cipherSuites, err := cliflag.TLSCipherSuites(o.CipherSuites) + if err != nil { + return fmt.Errorf("failed to parse cipher suites: %w", err) + } + c.CipherSuites = cipherSuites + } + + if len(o.CurvePreferences) != 0 { + curvePreferences, err := cliflag.TLSCurvePreferences(o.CurvePreferences) + if err != nil { + return fmt.Errorf("failed to parse curve preferences: %w", err) + } + c.CurvePreferences = curvePreferences + } + + c.MinTLSVersion, err = cliflag.TLSVersion(o.MinTLSVersion) + if err != nil { + return fmt.Errorf("failed to parse TLS version: %w", err) + } + + // load SNI certs + namedTLSCerts := make([]dynamiccertificates.SNICertKeyContentProvider, 0, len(o.SNICertKeys)) + for _, nck := range o.SNICertKeys { + tlsCert, err := dynamiccertificates.NewDynamicSNIContentFromFiles("sni-serving-cert", nck.CertFile, nck.KeyFile, nck.Names...) + if err != nil { + return fmt.Errorf("failed to load SNI cert and key: %w", err) + } + namedTLSCerts = append(namedTLSCerts, tlsCert) } + c.SNICerts = namedTLSCerts return nil } diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go index c5df71d666..bf49841944 100644 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go +++ b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go @@ -124,6 +124,10 @@ var managedFieldsClientset = ` // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// Compared to NewSimpleClientset, the Clientset returned here supports field tracking and thus +// server-side apply. Beware though that support in that for CRDs is missing +// (https://github.com/kubernetes/kubernetes/issues/126850). func NewClientset(objects ...runtime.Object) *Clientset { o := testing.NewFieldManagedObjectTracker( scheme, @@ -162,10 +166,6 @@ var common = ` // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. -// -// Deprecated: NewClientset replaces this with support for field management, which significantly improves -// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. -// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { @@ -211,7 +211,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker { return c.tracker } -// IsWatchListSemanticsSupported informs the reflector that this client +// IsWatchListSemanticsUnSupported informs the reflector that this client // doesn't support WatchList semantics. // // This is a synthetic method whose sole purpose is to satisfy the optional diff --git a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go index f5207a980e..a437189b58 100644 --- a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go +++ b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go @@ -24,7 +24,6 @@ import ( type Args struct { OutputFile string - BoundingDirs []string // Only deal with types rooted under these dirs. GoHeaderFile string } @@ -37,8 +36,6 @@ func New() *Args { func (args *Args) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&args.OutputFile, "output-file", "generated.deepcopy.go", "the name of the file to be generated") - fs.StringSliceVar(&args.BoundingDirs, "bounding-dirs", args.BoundingDirs, - "Comma-separated list of import paths which bound the types for which deep-copies will be generated.") fs.StringVar(&args.GoHeaderFile, "go-header-file", "", "the path to a file containing boilerplate header text; the string \"YEAR\" will be replaced with the current 4-digit year") } diff --git a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go index 0d86cd39cb..ace09baa23 100644 --- a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go +++ b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go @@ -128,16 +128,6 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target klog.Fatalf("Failed loading boilerplate: %v", err) } - boundingDirs := []string{} - if args.BoundingDirs == nil { - args.BoundingDirs = context.Inputs - } - for i := range args.BoundingDirs { - // Strip any trailing slashes - they are not exactly "correct" but - // this is friendlier. - boundingDirs = append(boundingDirs, strings.TrimRight(args.BoundingDirs[i], "/")) - } - targets := []generator.Target{} for _, i := range context.Inputs { @@ -197,7 +187,7 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target }, GeneratorsFunc: func(c *generator.Context) (generators []generator.Generator) { return []generator.Generator{ - NewGenDeepCopy(args.OutputFile, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister), + NewGenDeepCopy(args.OutputFile, pkg.Path, (ptagValue == tagValuePackage), ptagRegister), } }, }) @@ -210,20 +200,18 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target type genDeepCopy struct { generator.GoGenerator targetPackage string - boundingDirs []string allTypes bool registerTypes bool imports namer.ImportTracker typesForInit []*types.Type } -func NewGenDeepCopy(outputFilename, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator { +func NewGenDeepCopy(outputFilename, targetPackage string, allTypes, registerTypes bool) generator.Generator { return &genDeepCopy{ GoGenerator: generator.GoGenerator{ OutputFilename: outputFilename, }, targetPackage: targetPackage, - boundingDirs: boundingDirs, allTypes: allTypes, registerTypes: registerTypes, imports: generator.NewImportTrackerForPackage(targetPackage), diff --git a/vendor/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go b/vendor/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go index 2379117c58..0ce7d17f7d 100644 --- a/vendor/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go +++ b/vendor/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go @@ -73,12 +73,18 @@ func extractDefaultTag(comments []string) ([]string, error) { return tags[defaultTagName], nil } -func extractTag(comments []string) ([]string, error) { +func extractTag(comments []string) ([]string, bool) { tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{tagName}, comments) if err != nil { - return nil, err + klog.Fatalf("Error extracting %s tag: %v", tagName, err) + } + + values, found := tags[tagName] + if !found || len(values) == 0 { + return nil, false } - return tags[tagName], nil + + return values, true } func extractInputTag(comments []string) ([]string, error) { @@ -330,9 +336,10 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target getManualDefaultingFunctions(context, context.Universe[pp], existingDefaulters) } - typesWith, err := extractTag(pkg.Comments) - if err != nil { - klog.Fatalf("Error extracting %s tag: %v", tagName, err) + typesWith, found := extractTag(pkg.Comments) + if !found { + klog.V(2).InfoS(" did not find required tag", "tag", tagName) + continue } shouldCreateObjectDefaulterFn := func(t *types.Type) bool { if defaults, ok := existingDefaulters[t]; ok && defaults.object != nil { diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go index 773482d6e3..067dfed0c1 100644 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go +++ b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go @@ -279,7 +279,6 @@ func Run(g *Generator) { path := filepath.Join(g.OutputDir, p.ImportPath()) outputPath := filepath.Join(g.OutputDir, p.OutputPath()) - protomessageOutputPath := filepath.Join(g.OutputDir, p.ProtomessageOutputPath()) // generate the gogoprotobuf protoc cmd := exec.Command("protoc", append(args, path)...) @@ -296,14 +295,11 @@ func Run(g *Generator) { // alter the generated protobuf file to remove the generated types (but leave the serializers) and rewrite the // package statement to match the desired package name - if err := RewriteGeneratedGogoProtobufFile(outputPath, protomessageOutputPath, p.ExtractGeneratedType, p.OptionalTypeName, buf.Bytes(), g.DropGogoGo); err != nil { + if err := RewriteGeneratedGogoProtobufFile(outputPath, p.ExtractGeneratedType, p.OptionalTypeName, buf.Bytes(), g.DropGogoGo); err != nil { log.Fatalf("Unable to rewrite generated %s: %v", outputPath, err) } outputPaths := []string{outputPath} - if g.DropGogoGo { - outputPaths = append(outputPaths, protomessageOutputPath) - } // sort imports cmd = exec.Command("goimports", append([]string{"-w"}, outputPaths...)...) diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go index c35b73242a..b31a7c4dd7 100644 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go +++ b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go @@ -80,7 +80,7 @@ type protobufPackage struct { } func (p *protobufPackage) Clean() error { - for _, s := range []string{p.ImportPath(), p.OutputPath(), p.ProtomessageOutputPath()} { + for _, s := range []string{p.ImportPath(), p.OutputPath()} { if err := os.Remove(filepath.Join(p.Dir(), filepath.Base(s))); err != nil && !os.IsNotExist(err) { return err } @@ -200,10 +200,6 @@ func (p *protobufPackage) OutputPath() string { return filepath.Join(p.Path(), "generated.pb.go") } -func (p *protobufPackage) ProtomessageOutputPath() string { - return filepath.Join(p.Path(), "generated.protomessage.pb.go") -} - var ( _ = generator.Target(&protobufPackage{}) ) diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go index ba0d112f6e..3753c27c9a 100644 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go +++ b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go @@ -27,7 +27,6 @@ import ( "go/token" "os" "reflect" - "regexp" "strings" customreflect "k8s.io/code-generator/third_party/forked/golang/reflect" @@ -78,45 +77,7 @@ type ExtractFunc func(*ast.TypeSpec) bool // and should have its marshal functions adjusted to remove the 'Items' accessor. type OptionalFunc func(name string) bool -func RewriteGeneratedGogoProtobufFile(file, protomessageFile string, extractFn ExtractFunc, optionalFn OptionalFunc, header []byte, dropGogo bool) error { - - // Optionally extract ProtoMessage() marker methods to a separate build-tagged file - if dropGogo { - data, err := os.ReadFile(file) - if err != nil { - return err - } - - packageRE := regexp.MustCompile(`^package .*`) - wrotePackage := false - - protomessageFuncRE := regexp.MustCompile(`^func \(.*\) ProtoMessage\(\) \{\}$`) - - b := bytes.NewBuffer(nil) - // add build tag - b.WriteString("//go:build kubernetes_protomessage_one_more_release\n") - b.WriteString("// +build kubernetes_protomessage_one_more_release\n\n") - // add boilerplate - b.Write(header) - b.WriteString("\n// Code generated by go-to-protobuf. DO NOT EDIT.\n\n") - for _, line := range bytes.Split(data, []byte("\n")) { - // copy package - if packageRE.Match(line) && !wrotePackage { - b.Write(line) - b.WriteString("\n\n") - wrotePackage = true - } - // copy empty ProtoMessage impls - if protomessageFuncRE.Match(line) { - b.Write(line) - b.WriteString("\n\n") - } - } - if err := os.WriteFile(protomessageFile, b.Bytes(), os.FileMode(0644)); err != nil { - return err - } - } - +func RewriteGeneratedGogoProtobufFile(file string, extractFn ExtractFunc, optionalFn OptionalFunc, header []byte, dropGogo bool) error { return rewriteFile(file, header, func(fset *token.FileSet, file *ast.File) error { cmap := ast.NewCommentMap(fset, file, file.Comments) diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go index a005f5e5e8..237de9342f 100644 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go +++ b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go @@ -74,8 +74,15 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i gvNewFuncs[groupPkgName] = c.Universe.Function(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "New"}) } m := map[string]interface{}{ + "cacheDoneChecker": c.Universe.Type(cacheDoneChecker), + "cacheInformerName": c.Universe.Type(cacheInformerName), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), + "cacheSyncResult": c.Universe.Type(cacheSyncResult), "cacheTransformFunc": c.Universe.Type(cacheTransformFunc), + "cacheWaitFor": c.Universe.Function(cacheWaitForFunc), + "contextContext": c.Universe.Type(contextContext), + "contextCause": c.Universe.Function(contextCauseFunc), + "fmtErrorf": c.Universe.Function(fmtErrorfFunc), "groupVersions": g.groupVersions, "gvInterfaces": gvInterfaces, "gvNewFuncs": gvNewFuncs, @@ -87,10 +94,12 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i "reflectType": c.Universe.Type(reflectType), "runtimeObject": c.Universe.Type(runtimeObject), "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), + "stringsBuilder": c.Universe.Type(stringsBuilder), "syncMutex": c.Universe.Type(syncMutex), "timeDuration": c.Universe.Type(timeDuration), "namespaceAll": c.Universe.Type(metav1NamespaceAll), "object": c.Universe.Type(metav1Object), + "waitContextForChannel": c.Universe.Function(waitContextForChannelFunc), } sw.Do(sharedInformerFactoryStruct, m) @@ -111,6 +120,7 @@ type sharedInformerFactory struct { defaultResync {{.timeDuration|raw}} customResync map[{{.reflectType|raw}}]{{.timeDuration|raw}} transform {{.cacheTransformFunc|raw}} + informerName *{{.cacheInformerName|raw}} informers map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}} // startedInformers is used for tracking which informers have been started. @@ -157,6 +167,21 @@ func WithTransform(transform {{.cacheTransformFunc|raw}}) SharedInformerOption { } } +// WithInformerName sets the InformerName for informer identity used in metrics. +// The InformerName must be created via cache.NewInformerName() at startup, +// which validates global uniqueness. Each informer type will register its +// GVR under this name. +func WithInformerName(informerName *{{.cacheInformerName|raw}}) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.informerName = informerName + return factory + } +} + +func (f *sharedInformerFactory) InformerName() *{{.cacheInformerName|raw}} { + return f.informerName +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -191,6 +216,10 @@ func NewSharedInformerFactoryWithOptions(client {{.clientSetInterface|raw}}, def } func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.StartWithContext({{.waitContextForChannel|raw}}(stopCh)) +} + +func (f *sharedInformerFactory) StartWithContext(ctx {{.contextContext|raw}}) { f.lock.Lock() defer f.lock.Unlock() @@ -200,15 +229,9 @@ func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() + f.wg.Go(func() { + informer.RunWithContext(ctx) + }) f.startedInformers[informerType] = true } } @@ -222,27 +245,54 @@ func (f *sharedInformerFactory) Shutdown() { // Will return immediately if there is nothing to wait for. f.wg.Wait() + f.informerName.Release() } func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { - informers := func()map[reflect.Type]cache.SharedIndexInformer{ - f.lock.Lock() - defer f.lock.Unlock() - - informers := map[reflect.Type]cache.SharedIndexInformer{} - for informerType, informer := range f.informers { - if f.startedInformers[informerType] { - informers[informerType] = informer - } - } - return informers - }() - - res := map[reflect.Type]bool{} - for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) - } - return res + result := f.WaitForCacheSyncWithContext(wait.ContextForChannel(stopCh)) + return result.Synced +} + +func (f *sharedInformerFactory) WaitForCacheSyncWithContext(ctx context.Context) {{.cacheSyncResult|raw}} { + informers := func() map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}} { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}}{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer + } + } + return informers + }() + + // Wait for informers to sync, without polling. + cacheSyncs := make([]{{.cacheDoneChecker|raw}}, 0, len(informers)) + for _, informer := range informers { + cacheSyncs = append(cacheSyncs, informer.HasSyncedChecker()) + } + {{.cacheWaitFor|raw}}(ctx, "" /* no logging */, cacheSyncs...) + + res := {{.cacheSyncResult|raw}} { + Synced: make(map[{{.reflectType|raw}}]bool, len(informers)), + } + failed := false + for informType, informer := range informers { + hasSynced := informer.HasSynced() + if !hasSynced { + failed = true + } + res.Synced[informType] = hasSynced + } + if failed { + // context.Cause is more informative than ctx.Err(). + // This must be non-nil, otherwise WaitFor wouldn't have stopped + // prematurely. + res.Err = {{.contextCause|raw}}(ctx) + } + + return res } // InformerFor returns the SharedIndexInformer for obj using an internal @@ -263,7 +313,9 @@ func (f *sharedInformerFactory) InformerFor(obj {{.runtimeObject|raw}}, newFunc } informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) + if f.transform != nil { + informer.SetTransform(f.transform) + } f.informers[informerType] = informer return informer @@ -276,33 +328,52 @@ var sharedInformerFactoryInterface = ` // // It is typically used like this: // -// ctx, cancel := context.WithCancel(context.Background()) -// defer cancel() -// factory := NewSharedInformerFactory(client, resyncPeriod) -// defer factory.WaitForStop() // Returns immediately if nothing was started. -// genericInformer := factory.ForResource(resource) -// typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } -// } +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// handle, err := typeInformer.Informer().AddEventHandler(...) +// if err != nil { +// return fmt.Errorf("register event handler: %v", err) +// } +// defer typeInformer.Informer().RemoveEventHandler(handle) // Avoids leaking goroutines. +// factory.StartWithContext(ctx) // Start processing these informers. +// synced := factory.WaitForCacheSyncWithContext(ctx) +// if err := synced.AsError(); err != nil { +// return err +// } +// for v := range synced { +// // Only if desired log some information similar to this. +// fmt.Fprintf(os.Stdout, "cache synced: %s", v) +// } +// +// // Also make sure that all of the initial cache events have been delivered. +// if !WaitFor(ctx, "event handler sync", handle.HasSyncedChecker()) { +// // Must have failed because of context. +// return fmt.Errorf("sync event handler: %w", context.Cause(ctx)) +// } // -// // Creating informers can also be created after Start, but then -// // Start must be called again: -// anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.StartWithContext(ctx) type SharedInformerFactory interface { {{.informerFactoryInterface|raw}} // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + // + // Contextual logging: StartWithContext should be used instead of Start in code which supports contextual logging. Start(stopCh <-chan struct{}) + // StartWithContext initializes all requested informers. They are handled in goroutines + // which run until the context gets canceled. + // Warning: StartWithContext does not block. When run in a go-routine, it will race with a later WaitForCacheSync. + StartWithContext(ctx context.Context) + // Shutdown marks a factory as shutting down. At that point no new // informers can be started anymore and Start will return without // doing anything. @@ -317,7 +388,13 @@ type SharedInformerFactory interface { // WaitForCacheSync blocks until all started informers' caches were synced // or the stop channel gets closed. - WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // + // Contextual logging: WaitForCacheSync should be used instead of WaitForCacheSync in code which supports contextual logging. It also returns a more useful result. + WaitForCacheSync(stopCh <-chan struct{}) map[{{.reflectType|raw}}]bool + + // WaitForCacheSyncWithContext blocks until all started informers' caches were synced + // or the context gets canceled. + WaitForCacheSyncWithContext(ctx {{.contextContext|raw}}) {{.cacheSyncResult|raw}} // ForResource gives generic access to a shared informer of the matching type. ForResource(resource {{.schemaGroupVersionResource|raw}}) (GenericInformer, error) diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go index 278f8ed915..e59b8bcc5f 100644 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go +++ b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go @@ -63,6 +63,8 @@ func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types. klog.V(5).Infof("processing type %v", t) m := map[string]interface{}{ + "cacheIndexers": c.Universe.Type(cacheIndexers), + "cacheInformerName": c.Universe.Type(cacheInformerName), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), "clientSetPackage": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "runtimeObject": c.Universe.Type(runtimeObject), @@ -83,8 +85,27 @@ type NewInformerFunc func({{.clientSetPackage|raw}}, {{.timeDuration|raw}}) cach type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}} + InformerName() *{{.cacheInformerName|raw}} } // TweakListOptionsFunc is a function that transforms a {{.v1ListOptions|raw}}. type TweakListOptionsFunc func(*{{.v1ListOptions|raw}}) + +// InformerOptions holds the options for creating an informer. +type InformerOptions struct { + // ResyncPeriod is the resync period for this informer. + // If not set, defaults to 0 (no resync). + ResyncPeriod {{.timeDuration|raw}} + + // Indexers are the indexers for this informer. + Indexers {{.cacheIndexers|raw}} + + // InformerName is used to uniquely identify this informer for metrics. + // If not set, metrics will not be published for this informer. + // Use cache.NewInformerName() to create an InformerName at startup. + InformerName *{{.cacheInformerName|raw}} + + // TweakListOptions is an optional function to modify the list options. + TweakListOptions TweakListOptionsFunc +} ` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go index 7d74c13a6b..ced706a64b 100644 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go +++ b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go @@ -84,13 +84,18 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w "cacheMetaNamespaceIndexFunc": c.Universe.Function(cacheMetaNamespaceIndexFunc), "cacheNamespaceIndex": c.Universe.Variable(cacheNamespaceIndex), "cacheNewSharedIndexInformer": c.Universe.Function(cacheNewSharedIndexInformer), + "cacheNewSharedIndexInformerWithOptions": c.Universe.Function(cacheNewSharedIndexInformerWithOptions), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), + "cacheSharedIndexInformerOptions": c.Universe.Type(cacheSharedIndexInformerOptions), "cacheToListWatcherWithWatchListSemantics": c.Universe.Function(cacheToListWatcherWithWatchListSemanticsFunc), + "cacheInformerName": c.Universe.Type(cacheInformerName), "clientSetInterface": clientSetInterface, "contextContext": c.Universe.Type(contextContext), "contextBackground": c.Universe.Function(contextBackgroundFunc), "group": namer.IC(g.groupGoName), + "groupName": g.groupVersion.Group.String(), "informerFor": informerFor, + "interfacesInformerOptions": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "InformerOptions"}), "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "listOptions": c.Universe.Type(listOptions), @@ -98,11 +103,14 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w "namespaceAll": c.Universe.Type(metav1NamespaceAll), "namespaced": !tags.NonNamespaced, "newLister": c.Universe.Function(types.Name{Package: listerPackage, Name: "New" + t.Name.Name + "Lister"}), + "resourceName": strings.ToLower(t.Name.Name) + "s", "runtimeObject": c.Universe.Type(runtimeObject), + "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), "timeDuration": c.Universe.Type(timeDuration), "type": t, "v1ListOptions": c.Universe.Type(v1ListOptions), "version": namer.IC(g.groupVersion.Version.String()), + "versionName": g.groupVersion.Version.String(), "watchInterface": c.Universe.Type(watchInterface), } @@ -110,6 +118,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w sw.Do(typeInformerStruct, m) sw.Do(typeInformerPublicConstructor, m) sw.Do(typeFilteredInformerPublicConstructor, m) + sw.Do(typeInformerPublicConstructorWithOptions, m) sw.Do(typeInformerConstructor, m) sw.Do(typeInformerInformer, m) sw.Do(typeInformerLister, m) @@ -139,7 +148,7 @@ var typeInformerPublicConstructor = ` // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func New$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$) $.cacheSharedIndexInformer|raw$ { - return NewFiltered$.type|public$Informer(client$if .namespaced$, namespace$end$, resyncPeriod, indexers, nil) + return New$.type|public$InformerWithOptions(client$if .namespaced$, namespace$end$, $.interfacesInformerOptions|raw${ResyncPeriod: resyncPeriod, Indexers: indexers}) } ` @@ -148,43 +157,58 @@ var typeFilteredInformerPublicConstructor = ` // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func NewFiltered$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) $.cacheSharedIndexInformer|raw$ { - return $.cacheNewSharedIndexInformer|raw$( + return New$.type|public$InformerWithOptions(client$if .namespaced$, namespace$end$, $.interfacesInformerOptions|raw${ResyncPeriod: resyncPeriod, Indexers: indexers, TweakListOptions: tweakListOptions}) +} +` + +var typeInformerPublicConstructorWithOptions = ` +// New$.type|public$InformerWithOptions constructs a new informer for $.type|public$ type with additional options. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func New$.type|public$InformerWithOptions(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, options $.interfacesInformerOptions|raw$) $.cacheSharedIndexInformer|raw$ { + gvr := $.schemaGroupVersionResource|raw${Group: "$.groupName$", Version: "$.versionName$", Resource: "$.resourceName$"} + identifier := options.InformerName.WithResource(gvr) + tweakListOptions := options.TweakListOptions + return $.cacheNewSharedIndexInformerWithOptions|raw$( $.cacheToListWatcherWithWatchListSemantics|raw$(&$.cacheListWatch|raw${ - ListFunc: func(options $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { + ListFunc: func(opts $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List($.contextBackground|raw$(), options) + return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List($.contextBackground|raw$(), opts) }, - WatchFunc: func(options $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { + WatchFunc: func(opts $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch($.contextBackground|raw$(), options) + return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch($.contextBackground|raw$(), opts) }, - ListWithContextFunc: func(ctx $.contextContext|raw$, options $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { + ListWithContextFunc: func(ctx $.contextContext|raw$, opts $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List(ctx, options) + return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List(ctx, opts) }, - WatchFuncWithContext: func(ctx $.contextContext|raw$, options $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { + WatchFuncWithContext: func(ctx $.contextContext|raw$, opts $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { if tweakListOptions != nil { - tweakListOptions(&options) + tweakListOptions(&opts) } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch(ctx, options) + return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch(ctx, opts) }, }, client), &$.type|raw${}, - resyncPeriod, - indexers, + $.cacheSharedIndexInformerOptions|raw${ + ResyncPeriod: options.ResyncPeriod, + Indexers: options.Indexers, + Identifier: identifier, + }, ) } ` var typeInformerConstructor = ` func (f *$.type|private$Informer) defaultInformer(client $.clientSetInterface|raw$, resyncPeriod $.timeDuration|raw$) $.cacheSharedIndexInformer|raw$ { - return NewFiltered$.type|public$Informer(client$if .namespaced$, f.namespace$end$, resyncPeriod, $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}, f.tweakListOptions) + return New$.type|public$InformerWithOptions(client$if .namespaced$, f.namespace$end$, $.interfacesInformerOptions|raw${ResyncPeriod: resyncPeriod, Indexers: $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}, InformerName: f.factory.InformerName(), TweakListOptions: f.tweakListOptions}) } ` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go index 2e1edbd624..445b4604fc 100644 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go +++ b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go @@ -20,17 +20,24 @@ import "k8s.io/gengo/v2/types" var ( apiScheme = types.Name{Package: "k8s.io/kubernetes/pkg/api/legacyscheme", Name: "Scheme"} + cacheDoneChecker = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "DoneChecker"} cacheGenericLister = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "GenericLister"} cacheIndexers = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "Indexers"} + cacheInformerName = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "InformerName"} cacheListWatch = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "ListWatch"} cacheMetaNamespaceIndexFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "MetaNamespaceIndexFunc"} cacheNamespaceIndex = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NamespaceIndex"} cacheNewGenericLister = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NewGenericLister"} cacheNewSharedIndexInformer = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NewSharedIndexInformer"} + cacheNewSharedIndexInformerWithOptions = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NewSharedIndexInformerWithOptions"} cacheSharedIndexInformer = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "SharedIndexInformer"} + cacheSharedIndexInformerOptions = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "SharedIndexInformerOptions"} + cacheSyncResult = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "SyncResult"} cacheTransformFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "TransformFunc"} cacheToListWatcherWithWatchListSemanticsFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "ToListWatcherWithWatchListSemantics"} + cacheWaitForFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "WaitFor"} contextBackgroundFunc = types.Name{Package: "context", Name: "Background"} + contextCauseFunc = types.Name{Package: "context", Name: "Cause"} contextContext = types.Name{Package: "context", Name: "Context"} fmtErrorfFunc = types.Name{Package: "fmt", Name: "Errorf"} listOptions = types.Name{Package: "k8s.io/kubernetes/pkg/apis/core", Name: "ListOptions"} @@ -38,10 +45,12 @@ var ( runtimeObject = types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "Object"} schemaGroupResource = types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupResource"} schemaGroupVersionResource = types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersionResource"} + stringsBuilder = types.Name{Package: "strings", Name: "Builder"} syncMutex = types.Name{Package: "sync", Name: "Mutex"} timeDuration = types.Name{Package: "time", Name: "Duration"} v1ListOptions = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"} metav1NamespaceAll = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "NamespaceAll"} metav1Object = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "Object"} + waitContextForChannelFunc = types.Name{Package: "k8s.io/apimachinery/pkg/util/wait", Name: "ContextForChannel"} watchInterface = types.Name{Package: "k8s.io/apimachinery/pkg/watch", Name: "Interface"} ) diff --git a/vendor/k8s.io/code-generator/kube_codegen.sh b/vendor/k8s.io/code-generator/kube_codegen.sh index 3fb0478932..94b2717084 100644 --- a/vendor/k8s.io/code-generator/kube_codegen.sh +++ b/vendor/k8s.io/code-generator/kube_codegen.sh @@ -28,6 +28,24 @@ set -o pipefail KUBE_CODEGEN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" GOFLAGS=-mod=readonly +# This file is intended for out-of-tree projects running code generators. +# In that context, all in-tree Kubernetes types (e.g. metav1.TypeMeta, +# resource.Quantity) live in the read-only Go module cache, so generators +# must not attempt to write output files for them. These packages are passed +# as --readonly-pkg to generators that support it (validation-gen, openapi-gen). +# NOTE: These must be passed as separate arguments using an array loop, not +# via "$(printf ...)". Double-quoting a printf command substitution collapses +# the output into a single argument, which silently breaks flag parsing. +KUBE_CODEGEN_READONLY_PKGS=( + k8s.io/apimachinery/pkg/apis/meta/v1 + k8s.io/apimachinery/pkg/api/resource + k8s.io/apimachinery/pkg/runtime + k8s.io/apimachinery/pkg/types + k8s.io/apimachinery/pkg/util/intstr + k8s.io/apimachinery/pkg/version + time +) + # Callers which want a specific tag of the k8s.io/code-generator repo should # set the KUBE_CODEGEN_TAG to the tag name, e.g. KUBE_CODEGEN_TAG="release-1.32" # before sourcing this file. @@ -180,6 +198,7 @@ function kube::codegen::gen_helpers() { | LC_ALL=C sort -u ) + if [ "${#input_pkgs[@]}" != 0 ]; then echo "Generating validation code for ${#input_pkgs[@]} targets" @@ -189,9 +208,14 @@ function kube::codegen::gen_helpers() { -name zz_generated.validations.go \ | xargs -0 rm -f + local readonly_args=() + for pkg in "${KUBE_CODEGEN_READONLY_PKGS[@]}"; do + readonly_args+=("--readonly-pkg" "${pkg}") + done "${GOBIN}/validation-gen" \ -v "${v}" \ --output-file zz_generated.validations.go \ + "${readonly_args[@]}" \ --go-header-file "${boilerplate}" \ "${input_pkgs[@]}" fi @@ -409,6 +433,15 @@ function kube::codegen::gen_openapi() { -name zz_generated.openapi.go \ | xargs -0 rm -f + local readonly_args=() + for pkg in "${KUBE_CODEGEN_READONLY_PKGS[@]}"; do + readonly_args+=("--readonly-pkg" "${pkg}") + done + # These apimachinery packages are passed as explicit inputs + # because they contain types referenced by most API types + # (e.g. ObjectMeta, Quantity). openapi-gen needs them for + # type resolution even though they are not in the caller's + # input directory. "${GOBIN}/openapi-gen" \ -v "${v}" \ --output-file zz_generated.openapi.go \ @@ -417,6 +450,7 @@ function kube::codegen::gen_openapi() { --output-pkg "${out_pkg}" \ --report-filename "${new_report}" \ --output-model-name-file="${output_model_name_file}" \ + "${readonly_args[@]}" \ "k8s.io/apimachinery/pkg/apis/meta/v1" \ "k8s.io/apimachinery/pkg/runtime" \ "k8s.io/apimachinery/pkg/version" \ diff --git a/vendor/k8s.io/code-generator/tools.go b/vendor/k8s.io/code-generator/tools.go index 4080b2c590..394ad78d4c 100644 --- a/vendor/k8s.io/code-generator/tools.go +++ b/vendor/k8s.io/code-generator/tools.go @@ -1,5 +1,4 @@ //go:build tools -// +build tools /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/cli/flag/curves_flag.go b/vendor/k8s.io/component-base/cli/flag/curves_flag.go new file mode 100644 index 0000000000..2ae9f47345 --- /dev/null +++ b/vendor/k8s.io/component-base/cli/flag/curves_flag.go @@ -0,0 +1,50 @@ +/* +Copyright 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 flag + +import ( + "crypto/tls" + "fmt" + "math" + "strings" +) + +// TLSCurvePreferences returns a list of Go's crypto/tls CurveID values from the ids passed. +// The supported values depend on the Go version used. +// See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. +func TLSCurvePreferences(curveIDs []int32) ([]tls.CurveID, error) { + if len(curveIDs) == 0 { + return nil, nil + } + seen := make(map[int32]bool, len(curveIDs)) + result := make([]tls.CurveID, 0, len(curveIDs)) + for _, id := range curveIDs { + if id <= 0 || id > math.MaxUint16 { + return nil, fmt.Errorf("curve preference %d is out of range (must be 1-%d)", id, math.MaxUint16) + } + if seen[id] { + return nil, fmt.Errorf("duplicate curve preference %d", id) + } + seen[id] = true + curve := tls.CurveID(id) + if strings.HasPrefix(curve.String(), "CurveID(") { + return nil, fmt.Errorf("curve preference %d is not supported by the current Go version", id) + } + result = append(result, curve) + } + return result, nil +} diff --git a/vendor/k8s.io/component-base/cli/withoutrace.go b/vendor/k8s.io/component-base/cli/withoutrace.go index 4ae2749a13..3f1f6ab553 100644 --- a/vendor/k8s.io/component-base/cli/withoutrace.go +++ b/vendor/k8s.io/component-base/cli/withoutrace.go @@ -1,5 +1,4 @@ //go:build !race -// +build !race /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/cli/withrace.go b/vendor/k8s.io/component-base/cli/withrace.go index a71cec991d..122d338240 100644 --- a/vendor/k8s.io/component-base/cli/withrace.go +++ b/vendor/k8s.io/component-base/cli/withrace.go @@ -1,5 +1,4 @@ //go:build race -// +build race /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/configz/OWNERS b/vendor/k8s.io/component-base/configz/OWNERS index 3c2009a85b..6b7e9de520 100644 --- a/vendor/k8s.io/component-base/configz/OWNERS +++ b/vendor/k8s.io/component-base/configz/OWNERS @@ -1,9 +1,5 @@ # See the OWNERS docs at https://go.k8s.io/owners -# For lack of a better idea, assigned configz to api-approvers because -# configz is an API that has been around for a long time, even if we don't -# guarantee its stability. - # Disable inheritance as this is an api owners file options: no_parent_owners: true diff --git a/vendor/k8s.io/component-base/configz/configz.go b/vendor/k8s.io/component-base/configz/configz.go index 53e809d34c..20067701f6 100644 --- a/vendor/k8s.io/component-base/configz/configz.go +++ b/vendor/k8s.io/component-base/configz/configz.go @@ -20,23 +20,34 @@ limitations under the License. // object, and the program should call InstallHandler once. e.g., // // func main() { +// if err := setupConfigz(); err != nil { +// klog.Fatalf("Failed to setup configz: %v", err) +// } +// http.ListenAndServe(":8080", http.DefaultServeMux) +// } +// +// func setupConfigz() error { // boatConfig := getBoatConfig() // planeConfig := getPlaneConfig() // // bcz, err := configz.New("boat") // if err != nil { -// panic(err) +// return fmt.Errorf("unable to register boat config: %w", err) +// } +// if err := bcz.Set(boatConfig); err != nil { +// return fmt.Errorf("unable to set boat config: %w", err) // } -// bcz.Set(boatConfig) // // pcz, err := configz.New("plane") // if err != nil { -// panic(err) +// return fmt.Errorf("unable to register plane config: %w", err) +// } +// if err := pcz.Set(planeConfig); err != nil { +// return fmt.Errorf("unable to set plane config: %w", err) // } -// pcz.Set(planeConfig) // // configz.InstallHandler(http.DefaultServeMux) -// http.ListenAndServe(":8080", http.DefaultServeMux) +// return nil // } package configz @@ -45,6 +56,8 @@ import ( "fmt" "net/http" "sync" + + "k8s.io/apimachinery/pkg/runtime" ) const DefaultConfigzPath = "/configz" @@ -57,7 +70,7 @@ var ( // Config is a handle to a ComponentConfig object. Don't create these directly; // use New() instead. type Config struct { - val interface{} + val runtime.Object } // InstallHandler adds an HTTP handler on the given mux for the "/configz" @@ -92,10 +105,24 @@ func Delete(name string) { } // Set sets the ComponentConfig for this Config. -func (v *Config) Set(val interface{}) { +func (v *Config) Set(val runtime.Object) error { configsGuard.Lock() defer configsGuard.Unlock() + if val == nil { + return fmt.Errorf("val may not be nil") + } + gvk := val.GetObjectKind().GroupVersionKind() + if len(gvk.Kind) == 0 { + return fmt.Errorf("val must specify a kind") + } + if gvk.GroupVersion().Empty() { + return fmt.Errorf("val must specify a group/version") + } + if gvk.Version == runtime.APIVersionInternal { + return fmt.Errorf("val must specify an external version") + } v.val = val + return nil } // MarshalJSON marshals the ComponentConfig as JSON data. diff --git a/vendor/k8s.io/component-base/featuregate/feature_gate.go b/vendor/k8s.io/component-base/featuregate/feature_gate.go index 79c51ad51f..af0500df42 100644 --- a/vendor/k8s.io/component-base/featuregate/feature_gate.go +++ b/vendor/k8s.io/component-base/featuregate/feature_gate.go @@ -189,6 +189,14 @@ type MutableFeatureGate interface { OverrideDefault(name Feature, override bool) error } +// MutableFeatureGateWithLogger provides alternatives to some methods in [MutableFeatureGate] +// which use a logger provided by the caller instead of the global klog logger. +type MutableFeatureGateWithLogger interface { + SetWithLogger(logger klog.Logger, value string) error + SetFromMapWithLogger(logger klog.Logger, m map[string]bool) error + OverrideDefaultWithLogger(logger klog.Logger, name Feature, override bool) error +} + // MutableVersionedFeatureGate parses and stores flag gates for known features from // a string like feature1=true,feature2=false,... // MutableVersionedFeatureGate sets options based on the emulated version of the featured gate. @@ -241,6 +249,14 @@ type MutableVersionedFeatureGate interface { DeepCopyAndReset() MutableVersionedFeatureGate } +// MutableVersionedFeatureGateWithLogger provides alternatives to some methods in [MutableVersionedFeatureGate] +// which use a logger provided by the caller instead of the global klog logger. +type MutableVersionedFeatureGateWithLogger interface { + SetEmulationVersionWithLogger(logger klog.Logger, emulationVersion *version.Version) error + SetEmulationVersionAndMinCompatibilityVersionWithLogger(logger klog.Logger, emulationVersion *version.Version, minCompatibilityVersion *version.Version) error + OverrideDefaultAtVersionWithLogger(logger klog.Logger, name Feature, override bool, ver *version.Version) error +} + // featureGate implements FeatureGate as well as pflag.Value for flag parsing. type featureGate struct { featureGateName string @@ -267,6 +283,9 @@ type featureGate struct { minCompatibilityVersion atomic.Pointer[version.Version] } +var _ MutableVersionedFeatureGateWithLogger = &featureGate{} +var _ MutableFeatureGateWithLogger = &featureGate{} + func setUnsetAlphaGates(known map[Feature]VersionedSpecs, enabled map[Feature]bool, val bool, emuVer, minCompatVer *version.Version) { for k, v := range known { if k == "AllAlpha" || k == "AllBeta" { @@ -337,7 +356,18 @@ func NewFeatureGate() *featureGate { // Set parses a string of the form "key1=value1,key2=value2,..." into a // map[string]bool of known keys or returns an error. +// +//logcheck:context // SetWithLogger must be used instead. func (f *featureGate) Set(value string) error { + return f.SetWithLogger(klog.Background(), value) +} + +// Set parses a string of the form "key1=value1,key2=value2,..." into a +// map[string]bool of known keys or returns an error. +func (f *featureGate) SetWithLogger(logger klog.Logger, value string) error { + helper, logger := logger.WithCallStackHelper() + helper() + m := make(map[string]bool) for _, s := range strings.Split(value, ",") { if len(s) == 0 { @@ -355,7 +385,7 @@ func (f *featureGate) Set(value string) error { } m[k] = boolValue } - return f.SetFromMap(m) + return f.SetFromMapWithLogger(logger, m) } // Validate checks if the flag gates are valid at the emulated version. @@ -367,11 +397,15 @@ func (f *featureGate) Validate() []error { return []error{fmt.Errorf("cannot cast enabledRaw to map[string]bool")} } enabled := map[Feature]bool{} - return f.unsafeSetFromMap(enabled, m, f.EmulationVersion(), f.MinCompatibilityVersion()) + // Disable logging here. They would be misleading because we don't actually set anything. + return f.unsafeSetFromMap(klog.Logger{}, enabled, m, f.EmulationVersion(), f.MinCompatibilityVersion()) } // unsafeSetFromMap stores flag gates for known features from a map[string]bool into an enabled map. -func (f *featureGate) unsafeSetFromMap(enabled map[Feature]bool, m map[string]bool, emulationVersion, minCompatibilityVersion *version.Version) []error { +func (f *featureGate) unsafeSetFromMap(logger klog.Logger, enabled map[Feature]bool, m map[string]bool, emulationVersion, minCompatibilityVersion *version.Version) []error { + helper, logger := logger.WithCallStackHelper() + helper() + var errs []error // Copy existing state known := map[Feature]VersionedSpecs{} @@ -404,9 +438,9 @@ func (f *featureGate) unsafeSetFromMap(enabled map[Feature]bool, m map[string]bo enabled[key] = v if featureSpec.PreRelease == Deprecated { - klog.Warningf("Setting deprecated feature gate %s=%t. It will be removed in a future release.", k, v) + logger.Info("Warning: setting deprecated feature gate. It will be removed in a future release.", "featureGate", k, "value", v) } else if featureSpec.PreRelease == GA { - klog.Warningf("Setting GA feature gate %s=%t. It will be removed in a future release.", k, v) + logger.Info("Warning: setting GA feature gate. It will be removed in a future release.", "featureGate", k, "value", v) } } @@ -436,7 +470,17 @@ func (f *featureGate) unsafeSetFromMap(enabled map[Feature]bool, m map[string]bo } // SetFromMap stores flag gates for known features from a map[string]bool or returns an error +// +//logcheck:context // SetFromMapWithLogger must be used instead. func (f *featureGate) SetFromMap(m map[string]bool) error { + return f.SetFromMapWithLogger(klog.Background(), m) +} + +// SetFromMapWithLogger stores flag gates for known features from a map[string]bool or returns an error +func (f *featureGate) SetFromMapWithLogger(logger klog.Logger, m map[string]bool) error { + helper, logger := logger.WithCallStackHelper() + helper() + f.lock.Lock() defer f.lock.Unlock() @@ -458,11 +502,11 @@ func (f *featureGate) SetFromMap(m map[string]bool) error { } f.enabledRaw.Store(enabledRaw) - errs := f.unsafeSetFromMap(enabled, enabledRaw, f.EmulationVersion(), f.MinCompatibilityVersion()) + errs := f.unsafeSetFromMap(logger, enabled, enabledRaw, f.EmulationVersion(), f.MinCompatibilityVersion()) if len(errs) == 0 { // Persist changes f.enabled.Store(enabled) - klog.V(1).Infof("feature gates: %v", f.enabled) + logger.V(1).Info("Updated", "featureGates", enabled) } return utilerrors.NewAggregate(errs) } @@ -711,15 +755,32 @@ func (f *featureGate) Dependencies() map[Feature][]Feature { return maps.Clone(*f.dependencies.Load()) } +//logcheck:context // OverridedDefaultWithLogger must be used instead. func (f *featureGate) OverrideDefault(name Feature, override bool) error { - return f.overrideDefaultAtEmulationAndMinCompatVersion(name, override, f.EmulationVersion(), f.MinCompatibilityVersion()) + return f.OverrideDefaultWithLogger(klog.Background(), name, override) +} + +func (f *featureGate) OverrideDefaultWithLogger(logger klog.Logger, name Feature, override bool) error { + helper, logger := logger.WithCallStackHelper() + helper() + return f.overrideDefaultAtEmulationAndMinCompatVersion(logger, name, override, f.EmulationVersion(), f.MinCompatibilityVersion()) } +//logcheck:context // OverrideDefaultAtWithLogger must be used instead. func (f *featureGate) OverrideDefaultAtVersion(name Feature, override bool, ver *version.Version) error { - return f.overrideDefaultAtEmulationAndMinCompatVersion(name, override, ver, nil) + return f.OverrideDefaultAtVersionWithLogger(klog.Background(), name, override, ver) +} + +func (f *featureGate) OverrideDefaultAtVersionWithLogger(logger klog.Logger, name Feature, override bool, ver *version.Version) error { + helper, logger := logger.WithCallStackHelper() + helper() + return f.overrideDefaultAtEmulationAndMinCompatVersion(logger, name, override, ver, nil) } -func (f *featureGate) overrideDefaultAtEmulationAndMinCompatVersion(name Feature, override bool, emuVer, minCompatVer *version.Version) error { +func (f *featureGate) overrideDefaultAtEmulationAndMinCompatVersion(logger klog.Logger, name Feature, override bool, emuVer, minCompatVer *version.Version) error { + helper, logger := logger.WithCallStackHelper() + helper() + f.lock.Lock() defer f.lock.Unlock() @@ -741,9 +802,9 @@ func (f *featureGate) overrideDefaultAtEmulationAndMinCompatVersion(name Feature case spec.PreRelease == PreAlpha: return fmt.Errorf("cannot override default: feature %q is not available before version %s", name, emuVer) case spec.PreRelease == Deprecated: - klog.Warningf("Overriding default of deprecated feature gate %s=%t. It will be removed in a future release.", name, override) + logger.Info("Warning: overriding default of deprecated feature gate. It will be removed in a future release.", "featureGate", name, "value", override) case spec.PreRelease == GA: - klog.Warningf("Overriding default of GA feature gate %s=%t. It will be removed in a future release.", name, override) + logger.Info("Warning: overriding default of GA feature gate. It will be removed in a future release.", "featureGate", name, "value", override) } spec.Default = override @@ -783,17 +844,32 @@ func (f *featureGate) GetAllVersioned() map[Feature]VersionedSpecs { return retval } +//logcheck:context // SetEmulationVersionWithLogger must be used instead. func (f *featureGate) SetEmulationVersion(emulationVersion *version.Version) error { - return f.SetEmulationVersionAndMinCompatibilityVersion(emulationVersion, emulationVersion.SubtractMinor(1)) + return f.SetEmulationVersionWithLogger(klog.Background(), emulationVersion) +} + +func (f *featureGate) SetEmulationVersionWithLogger(logger klog.Logger, emulationVersion *version.Version) error { + helper, logger := logger.WithCallStackHelper() + helper() + return f.SetEmulationVersionAndMinCompatibilityVersionWithLogger(logger, emulationVersion, emulationVersion.SubtractMinor(1)) } +//logcheck:context // SetEmulationVersionAndMinCompatibilityWithLogger must be used instead. func (f *featureGate) SetEmulationVersionAndMinCompatibilityVersion(emulationVersion *version.Version, minCompatibilityVersion *version.Version) error { + return f.SetEmulationVersionAndMinCompatibilityVersionWithLogger(klog.Background(), emulationVersion, minCompatibilityVersion) +} + +func (f *featureGate) SetEmulationVersionAndMinCompatibilityVersionWithLogger(logger klog.Logger, emulationVersion *version.Version, minCompatibilityVersion *version.Version) error { + helper, logger := logger.WithCallStackHelper() + helper() + if emulationVersion.EqualTo(f.EmulationVersion()) && minCompatibilityVersion.EqualTo(f.MinCompatibilityVersion()) { return nil } f.lock.Lock() defer f.lock.Unlock() - klog.V(1).Infof("set feature gate emulationVersion to %s, minCompatibilityVersion to %s", emulationVersion, minCompatibilityVersion) + logger.V(1).Info("Set feature gate emulation", "emulationVersion", emulationVersion, "minCompatibilityVersion", minCompatibilityVersion) // Copy existing state enabledRaw := map[string]bool{} @@ -802,7 +878,7 @@ func (f *featureGate) SetEmulationVersionAndMinCompatibilityVersion(emulationVer } // enabled map should be reset whenever emulationVersion is changed. enabled := map[Feature]bool{} - errs := f.unsafeSetFromMap(enabled, enabledRaw, emulationVersion, minCompatibilityVersion) + errs := f.unsafeSetFromMap(logger, enabled, enabledRaw, emulationVersion, minCompatibilityVersion) queriedFeatures := f.queriedFeatures.Load().(sets.Set[Feature]) known := f.known.Load().(map[Feature]VersionedSpecs) @@ -810,7 +886,7 @@ func (f *featureGate) SetEmulationVersionAndMinCompatibilityVersion(emulationVer newVal := featureEnabled(feature, enabled, known, emulationVersion, minCompatibilityVersion) oldVal := featureEnabled(feature, f.enabled.Load().(map[Feature]bool), known, f.EmulationVersion(), f.MinCompatibilityVersion()) if newVal != oldVal { - klog.Warningf("SetEmulationVersionAndMinCompatibilityVersion will change already queried feature:%s from %v to %v", feature, oldVal, newVal) + logger.Info("Warning: SetEmulationVersionAndMinCompatibilityVersion will change already queried feature", "featureGate", feature, "oldValue", oldVal, "newValue", newVal) } } diff --git a/vendor/k8s.io/component-base/logs/api/v1/options_no_slog.go b/vendor/k8s.io/component-base/logs/api/v1/options_no_slog.go index 816948e0a6..ef4d5603d0 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/options_no_slog.go +++ b/vendor/k8s.io/component-base/logs/api/v1/options_no_slog.go @@ -1,5 +1,4 @@ //go:build !go1.21 -// +build !go1.21 /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/logs/api/v1/options_slog.go b/vendor/k8s.io/component-base/logs/api/v1/options_slog.go index 31765e644d..6e8f1b4423 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/options_slog.go +++ b/vendor/k8s.io/component-base/logs/api/v1/options_slog.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/metrics/OWNERS b/vendor/k8s.io/component-base/metrics/OWNERS index be371a4a09..b70cf0be7c 100644 --- a/vendor/k8s.io/component-base/metrics/OWNERS +++ b/vendor/k8s.io/component-base/metrics/OWNERS @@ -2,8 +2,9 @@ approvers: - sig-instrumentation-approvers - - logicalhan - RainbowMango +emeritus_approvers: + - logicalhan reviewers: - sig-instrumentation-reviewers - YoyinZyc diff --git a/vendor/k8s.io/component-base/metrics/api/v1/config.go b/vendor/k8s.io/component-base/metrics/api/v1/config.go new file mode 100644 index 0000000000..9825713687 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/api/v1/config.go @@ -0,0 +1,127 @@ +/* +Copyright 2025 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 v1 + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + + "github.com/blang/semver/v4" + "go.yaml.in/yaml/v2" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +var ( + labelExpr = `[a-zA-Z_][a-zA-Z0-9_]*` + metricNameExpr = `[a-zA-Z_:][a-zA-Z0-9_:]*` + allowListMappingKeyRegex = regexp.MustCompile(`^` + metricNameExpr + `,` + labelExpr + `$`) + metricNameRegex = regexp.MustCompile(`^` + metricNameExpr + `$`) +) + +// Validate validates a MetricsConfiguration. +func Validate(c *MetricsConfiguration, currentVersion semver.Version, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + if c == nil { + return errs + } + errs = append(errs, validateShowHiddenMetricsVersion(currentVersion, c.ShowHiddenMetricsForVersion, fldPath.Child("showHiddenMetricsForVersion"))...) + errs = append(errs, validateDisabledMetrics(c.DisabledMetrics, fldPath.Child("disabledMetrics"))...) + errs = append(errs, validateAllowListMapping(c.AllowListMapping, fldPath.Child("allowListMapping"))...) + errs = append(errs, validateAllowListMappingManifest(c.AllowListMappingManifest, fldPath.Child("allowListMappingManifest"))...) + if c.AllowListMapping != nil && c.AllowListMappingManifest != "" { + errs = append(errs, field.Invalid(fldPath, c, "cannot specify both allowListMapping and allowListMappingManifest")) + } + + return errs +} + +func validateAllowListMapping(allowListMapping map[string]string, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + for k := range allowListMapping { + if !allowListMappingKeyRegex.MatchString(k) { + return append(errs, field.Invalid(fldPath, allowListMapping, fmt.Sprintf("must have keys with format `metricName,labelName` where metricName matches %q and labelName matches %q", metricNameExpr, labelExpr))) + } + } + + return errs +} + +// validateAllowListMappingManifest validates the allow list mapping manifest file. +// This function is used to validate the manifest file provided via the flag --allow-metric-labels-manifest, or the configuration file. +// In the former case, the path resolution is relative to the current working directory. +// In the latter case, the path resolution is relative to the configuration file's location, and components are required to pass in the resolved absolute path. +// NOTE: If its the latter case, components are expected to pass in the *absolute* path to the manifest file. +func validateAllowListMappingManifest(allowListMappingManifestPath string, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + if allowListMappingManifestPath == "" { + return errs + } + data, err := os.ReadFile(filepath.Clean(allowListMappingManifestPath)) + if err != nil { + return append(errs, field.Invalid(fldPath, allowListMappingManifestPath, fmt.Errorf("failed to read allow list manifest: %w", err).Error())) + } + allowListMapping := make(map[string]string) + err = yaml.Unmarshal(data, &allowListMapping) + if err != nil { + return append(errs, field.Invalid(fldPath, allowListMappingManifestPath, fmt.Errorf("failed to parse allow list manifest: %w", err).Error())) + } + allowListMappingErrs := validateAllowListMapping(allowListMapping, fldPath) + if len(allowListMappingErrs) > 0 { + return append(errs, field.Invalid(fldPath, allowListMappingManifestPath, fmt.Sprintf("invalid allow list mapping in manifest: %v", allowListMappingErrs))) + } + + return errs +} + +func validateDisabledMetrics(names []string, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + for _, name := range names { + if !metricNameRegex.MatchString(name) { + return append(errs, field.Invalid(fldPath, names, fmt.Sprintf("must be fully qualified metric names matching %q, got %q", metricNameRegex.String(), name))) + } + } + + return errs +} + +func validateShowHiddenMetricsVersion(currentVersion semver.Version, targetVersionStr string, fldPath *field.Path) field.ErrorList { + errs := field.ErrorList{} + if targetVersionStr == "" { + return errs + } + + validVersionStr := fmt.Sprintf("%d.%d", currentVersion.Major, currentVersion.Minor-1) + if targetVersionStr != validVersionStr { + return append(errs, field.Invalid(fldPath, targetVersionStr, fmt.Sprintf("must be omitted or have the value '%v'; only the previous minor version is allowed", validVersionStr))) + } + + return errs +} + +// ValidateShowHiddenMetricsVersionForKubeletBackwardCompatOnly validates the ShowHiddenMetricsForVersion field. +// TODO: This is kept here for backward compatibility in Kubelet (as metrics configuration fields were exposed on an individual basis earlier). +// TODO: Revisit this after Kubelet supports the new metrics configuration API: https://github.com/kubernetes/kubernetes/pull/123426 +func ValidateShowHiddenMetricsVersionForKubeletBackwardCompatOnly(currentVersion semver.Version, targetVersionStr string) error { + errs := validateShowHiddenMetricsVersion(currentVersion, targetVersionStr, field.NewPath("showHiddenMetricsForVersion")) + if len(errs) > 0 { + return fmt.Errorf("invalid showHiddenMetricsForVersion: %v", errs.ToAggregate().Error()) + } + + return nil +} diff --git a/vendor/k8s.io/component-base/metrics/api/v1/doc.go b/vendor/k8s.io/component-base/metrics/api/v1/doc.go new file mode 100644 index 0000000000..8c457bd0da --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/api/v1/doc.go @@ -0,0 +1,34 @@ +/* +Copyright 2025 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. +*/ + +// +k8s:deepcopy-gen=package + +// Package v1 contains the configuration API for metrics. +// +// The intention is to only have a single version of this API, potentially with +// new fields added over time in a backwards-compatible manner. Fields for +// alpha or beta features are allowed as long as they are defined so that not +// changing the defaults leaves those features disabled. +// +// The "v1" package name is just a reminder that API compatibility rules apply, +// not an indication of the stability of all features covered by it. +// +// NOTE: Component owners are advised to rely on `k8s.io/component-base/metrics` to operate upon +// `k8s.io/component-base/metrics/api/v1.MetricsConfiguration` as the former contains functions to apply and validate +// the configuration, which in turn rely on members of the same package, which cannot be moved, +// or imported (cyclic dependency) here. + +package v1 // import "k8s.io/component-base/metrics/api/v1" diff --git a/vendor/k8s.io/component-base/metrics/api/v1/types.go b/vendor/k8s.io/component-base/metrics/api/v1/types.go new file mode 100644 index 0000000000..b95aa37235 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/api/v1/types.go @@ -0,0 +1,39 @@ +/* +Copyright 2025 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 v1 + +// MetricsConfiguration contains all metrics options. +type MetricsConfiguration struct { + // ShowHiddenMetricsForVersion is the previous version for which you want to show hidden metrics. + // Only the previous minor version is meaningful, other values will not be allowed. + // The format is ., e.g.: '1.16'. + // The purpose of this format is make sure you have the opportunity to notice if the next release hides additional metrics, + // rather than being surprised when they are permanently removed in the release after that. + ShowHiddenMetricsForVersion string `json:"showHiddenMetricsForVersion,omitempty"` + // DisabledMetrics is a list of fully qualified metric names that should be disabled. + // Disabling metrics is higher in precedence than showing hidden metrics. + DisabledMetrics []string `json:"disabledMetrics,omitempty"` + // AllowListMapping is the map from metric-label to value allow-list of this label. + // The key's format is ,, while its value is a list of allowed values for that label of that metric, i.e., ,,... + // For e.g., metric1,label1='v1,v2,v3', metric1,label2='v1,v2,v3' metric2,label1='v1,v2,v3'." + AllowListMapping map[string]string `json:"allowListMapping,omitempty"` + // The path to the manifest file that contains the allow-list mapping. Provided for convenience over AllowListMapping. + // The file contents must represent a map of string keys and values, i.e., + // "metric1,label1": "value11,value12" + // "metric2,label2": "" + AllowListMappingManifest string `json:"allowListMappingManifest,omitempty"` +} diff --git a/vendor/k8s.io/component-base/metrics/api/v1/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/metrics/api/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..6c96349a91 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,50 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetricsConfiguration) DeepCopyInto(out *MetricsConfiguration) { + *out = *in + if in.DisabledMetrics != nil { + in, out := &in.DisabledMetrics, &out.DisabledMetrics + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AllowListMapping != nil { + in, out := &in.AllowListMapping, &out.AllowListMapping + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfiguration. +func (in *MetricsConfiguration) DeepCopy() *MetricsConfiguration { + if in == nil { + return nil + } + out := new(MetricsConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/component-base/metrics/desc.go b/vendor/k8s.io/component-base/metrics/desc.go index f921be6156..a40c488a50 100644 --- a/vendor/k8s.io/component-base/metrics/desc.go +++ b/vendor/k8s.io/component-base/metrics/desc.go @@ -115,7 +115,7 @@ func (d *Desc) determineDeprecationStatus(currentVersion semver.Version) { d.markDeprecationOnce.Do(func() { d.isDeprecated = isDeprecated(currentVersion, *deprecatedVersion) if shouldHide(d.stabilityLevel, ¤tVersion, deprecatedVersion) { - if shouldShowHidden() { + if ShouldShowHidden() { klog.Warningf("Hidden metrics(%s) have been manually overridden, showing this very deprecated metric.", d.fqName) return } diff --git a/vendor/k8s.io/component-base/metrics/features/kube_features.go b/vendor/k8s.io/component-base/metrics/features/kube_features.go index b2f8c65275..79ed690acf 100644 --- a/vendor/k8s.io/component-base/metrics/features/kube_features.go +++ b/vendor/k8s.io/component-base/metrics/features/kube_features.go @@ -17,14 +17,38 @@ limitations under the License. package features import ( + "k8s.io/apimachinery/pkg/util/version" "k8s.io/component-base/featuregate" + internalmetrics "k8s.io/component-base/metrics/internal" +) + +const ( + // owner: @richabanker + // kep: https://kep.k8s.io/5808 + // alpha: v1.36 + // + // Enables native histogram support for Kubernetes metrics. + // When enabled, histogram metrics will be exposed in both classic + // and native histogram formats. + NativeHistograms featuregate.Feature = "NativeHistograms" ) func featureGates() map[featuregate.Feature]featuregate.VersionedSpecs { - return map[featuregate.Feature]featuregate.VersionedSpecs{} + return map[featuregate.Feature]featuregate.VersionedSpecs{ + NativeHistograms: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + } } // AddFeatureGates adds all feature gates used by this package. func AddFeatureGates(mutableFeatureGate featuregate.MutableVersionedFeatureGate) error { return mutableFeatureGate.AddVersioned(featureGates()) } + +// ApplyFeatureGates propagates the current feature gate state to the metrics +// subsystem. It must be called after feature gates are finalised and before +// any histogram metrics are registered. +func ApplyFeatureGates(featureGate featuregate.FeatureGate) { + internalmetrics.SetNativeHistogramsEnabled(featureGate.Enabled(NativeHistograms)) +} diff --git a/vendor/k8s.io/component-base/metrics/histogram.go b/vendor/k8s.io/component-base/metrics/histogram.go index 73b56d1b80..f1e51036f7 100644 --- a/vendor/k8s.io/component-base/metrics/histogram.go +++ b/vendor/k8s.io/component-base/metrics/histogram.go @@ -19,6 +19,7 @@ package metrics import ( "context" "sync" + "time" "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" @@ -91,7 +92,7 @@ func (h *Histogram) DeprecatedVersion() *semver.Version { // and stores a reference to it func (h *Histogram) initializeMetric() { h.HistogramOpts.annotateStabilityLevel() - // this actually creates the underlying prometheus gauge. + // this actually creates the underlying prometheus histogram. h.setPrometheusHistogram(prometheus.NewHistogram(h.HistogramOpts.toPromHistogramOpts())) } @@ -214,6 +215,21 @@ func (v *HistogramVec) With(labels map[string]string) ObserverMetric { return v.HistogramVec.With(labels) } +// ObserveSince returns a function that observes the duration since the given start time. +// This is intended to be used with defer to measure the time elapsed since a given point: +// +// start := time.Now() +// defer metricVec.ObserveSince(start, "label1", "label2")() +// +// The returned function must be called (typically via defer) to record the observation. +// This pattern avoids the common pitfall where arguments to deferred functions are evaluated +// immediately, which would result in incorrect timing measurements. +func (v *HistogramVec) ObserveSince(start time.Time, lvs ...string) func() { + return func() { + v.WithLabelValues(lvs...).Observe(time.Since(start).Seconds()) + } +} + // Delete deletes the metric where the variable labels are the same as those // passed in as labels. It returns true if a metric was deleted. // @@ -292,3 +308,8 @@ func (vc *HistogramVecWithContext) With(labels map[string]string) *exemplarHisto observer: vc.HistogramVec.With(labels), } } + +// ObserveSince is the wrapper of HistogramVec.ObserveSince. +func (vc *HistogramVecWithContext) ObserveSince(start time.Time, lvs ...string) func() { + return vc.HistogramVec.ObserveSince(start, lvs...) +} diff --git a/vendor/k8s.io/component-base/metrics/internal/nativehistograms.go b/vendor/k8s.io/component-base/metrics/internal/nativehistograms.go new file mode 100644 index 0000000000..c7d1769f24 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/internal/nativehistograms.go @@ -0,0 +1,57 @@ +/* +Copyright 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 internal holds shared state for the metrics package that must not be +// directly accessible by external callers. +package internal + +import "sync/atomic" + +var nativeHistogramsEnabled atomic.Bool + +// NativeHistogramOptions holds the bucket configuration options for native histograms. +type NativeHistogramOptions struct { + BucketFactor float64 + MaxBucketNumber uint32 +} + +// defaultNativeHistogramOptions are the defaults applied to all histogram metrics +// when native histograms are enabled. +var defaultNativeHistogramOptions = NativeHistogramOptions{ + // BucketFactor is the growth factor for native histogram buckets. + // A value of 1.1 means each bucket is at most 10% wider than the previous one. + BucketFactor: 1.1, + // MaxBucketNumber is the maximum number of buckets per native histogram. + // Based on the OTel SDK recommendation for base2 exponential bucket histogram aggregation. + MaxBucketNumber: 160, +} + +// SetNativeHistogramsEnabled records whether native histograms are enabled. +// This should be called exactly once during component initialisation, driven +// by the NativeHistograms feature gate. +func SetNativeHistogramsEnabled(enabled bool) { + nativeHistogramsEnabled.Store(enabled) +} + +// NativeHistogramsEnabled reports whether native histograms are currently enabled. +func NativeHistogramsEnabled() bool { + return nativeHistogramsEnabled.Load() +} + +// NativeHistogramConfig returns the default bucket configuration for native histograms. +func NativeHistogramConfig() NativeHistogramOptions { + return defaultNativeHistogramOptions +} diff --git a/vendor/k8s.io/component-base/metrics/metric.go b/vendor/k8s.io/component-base/metrics/metric.go index cb40a856c6..1d05044b58 100644 --- a/vendor/k8s.io/component-base/metrics/metric.go +++ b/vendor/k8s.io/component-base/metrics/metric.go @@ -116,7 +116,7 @@ func (r *lazyMetric) preprocessMetric(currentVersion semver.Version) { r.isDeprecated.Store(isDeprecated(currentVersion, *deprecatedVersion)) if shouldHide(r.stabilityLevel, ¤tVersion, deprecatedVersion) { - if shouldShowHidden() { + if ShouldShowHidden() { klog.Warningf("Hidden metrics (%s) have been manually overridden, showing this very deprecated metric.", r.fqName) return } @@ -189,7 +189,7 @@ func (r *lazyMetric) FQName() string { /* This code is directly lifted from the prometheus codebase. It's a convenience struct which -allows you satisfy the Collector interface automatically if you already satisfy the Metric interface. +allows you to satisfy the Collector interface automatically if you already satisfy the Metric interface. For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/collector.go#L98-L120 */ diff --git a/vendor/k8s.io/component-base/metrics/options.go b/vendor/k8s.io/component-base/metrics/options.go index 17f44ef2a3..4e842d6c08 100644 --- a/vendor/k8s.io/component-base/metrics/options.go +++ b/vendor/k8s.io/component-base/metrics/options.go @@ -17,21 +17,59 @@ limitations under the License. package metrics import ( - "fmt" - "regexp" + "os" + "path/filepath" + "strings" + "sync" + "sync/atomic" - "github.com/blang/semver/v4" "github.com/spf13/pflag" - + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/component-base/version" + "k8s.io/klog/v2" + + "go.yaml.in/yaml/v2" + v1 "k8s.io/component-base/metrics/api/v1" +) + +var ( + disabledMetricsLock sync.RWMutex + disabledMetrics = map[string]struct{}{} + showHiddenOnce sync.Once + showHidden atomic.Bool +) + +var ( + disabledMetricsTotal = NewCounter( + &CounterOpts{ + Name: "disabled_metrics_total", + Help: "The count of disabled metrics.", + StabilityLevel: BETA, + }, + ) + + hiddenMetricsTotal = NewCounter( + &CounterOpts{ + Name: "hidden_metrics_total", + Help: "The count of hidden metrics.", + StabilityLevel: BETA, + }, + ) + + cardinalityEnforcementUnexpectedCategorizationsTotal = NewCounter( + &CounterOpts{ + Name: "cardinality_enforcement_unexpected_categorizations_total", + Help: "The count of unexpected categorizations during cardinality enforcement.", + StabilityLevel: ALPHA, + }, + ) ) // Options has all parameters needed for exposing metrics from components type Options struct { - ShowHiddenMetricsForVersion string - DisabledMetrics []string - AllowListMapping map[string]string - AllowListMappingManifest string + // Configuration serialization is omitted here since the parent is never expected to be embedded. + v1.MetricsConfiguration `json:"-"` } // NewOptions returns default metrics options @@ -39,29 +77,8 @@ func NewOptions() *Options { return &Options{} } -// Validate validates metrics flags options. -func (o *Options) Validate() []error { - if o == nil { - return nil - } - - var errs []error - err := validateShowHiddenMetricsVersion(parseVersion(version.Get()), o.ShowHiddenMetricsForVersion) - if err != nil { - errs = append(errs, err) - } - - if err := validateAllowMetricLabel(o.AllowListMapping); err != nil { - errs = append(errs, err) - } - - if len(errs) == 0 { - return nil - } - return errs -} - // AddFlags adds flags for exposing component metrics. +// This won't be called in embedded instances within component configurations. func (o *Options) AddFlags(fs *pflag.FlagSet) { if o == nil { return @@ -84,53 +101,175 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) { "e.g. metric1,label1='v1,v2,v3', metric1,label2='v1,v2,v3' metric2,label1='v1,v2,v3'.") fs.StringVar(&o.AllowListMappingManifest, "allow-metric-labels-manifest", o.AllowListMappingManifest, "The path to the manifest file that contains the allow-list mapping. "+ - "The format of the file is the same as the flag --allow-metric-labels. "+ + "The format of the file is the same as the flag --allow-metric-labels, i.e., \n"+ + "allowListMapping:\n \"metric1,label1\": \"value11,value12\"\n \"metric2,label2\": \"\"\n"+ "Note that the flag --allow-metric-labels will override the manifest file.") } -// Apply applies parameters into global configuration of metrics. -func (o *Options) Apply() { - if o == nil { +// SetShowHidden will enable showing hidden metrics. This will no-opt +// after the initial call +func SetShowHidden() { + showHiddenOnce.Do(func() { + showHidden.Store(true) + + // re-register collectors that has been hidden in phase of last registry. + for _, r := range registries { + r.enableHiddenCollectors() + r.enableHiddenStableCollectors() + } + }) +} + +// ShouldShowHidden returns whether showing hidden deprecated metrics is enabled. +// While the primary use case for this is internal (to determine registration behavior) this can also be used to introspect. +func ShouldShowHidden() bool { + return showHidden.Load() +} + +// SetDisabledMetric will disable a metric by name. +// This will also increment the disabled metrics counter. +// Note that this is a no-op if the metric is already disabled. +func SetDisabledMetrics(names []string) { + for _, name := range names { + func(name string) { + // An empty metric name is not a valid Prometheus metric. + if name == "" { + klog.Warningf("Attempted to disable an empty metric name, ignoring.") + return + } + disabledMetricsLock.Lock() + defer disabledMetricsLock.Unlock() + if _, ok := disabledMetrics[name]; !ok { + disabledMetrics[name] = struct{}{} + disabledMetricsTotal.Inc() + } + }(name) + } +} + +type MetricLabelAllowList struct { + labelToAllowList map[string]sets.Set[string] +} + +func (allowList *MetricLabelAllowList) ConstrainToAllowedList(labelNameList, labelValueList []string) { + for index, value := range labelValueList { + name := labelNameList[index] + if allowValues, ok := allowList.labelToAllowList[name]; ok { + if !allowValues.Has(value) { + labelValueList[index] = "unexpected" + cardinalityEnforcementUnexpectedCategorizationsTotal.Inc() + } + } + } +} + +func (allowList *MetricLabelAllowList) ConstrainLabelMap(labels map[string]string) { + for name, value := range labels { + if allowValues, ok := allowList.labelToAllowList[name]; ok { + if !allowValues.Has(value) { + labels[name] = "unexpected" + cardinalityEnforcementUnexpectedCategorizationsTotal.Inc() + } + } + } +} + +func SetLabelAllowList(allowListMapping map[string]string) { + if len(allowListMapping) == 0 { + klog.Errorf("empty allow-list mapping supplied, ignoring.") return } - if len(o.ShowHiddenMetricsForVersion) > 0 { - SetShowHidden() + + allowListLock.Lock() + defer allowListLock.Unlock() + for metricLabelName, labelValues := range allowListMapping { + metricName := strings.Split(metricLabelName, ",")[0] + labelName := strings.Split(metricLabelName, ",")[1] + valueSet := sets.New[string](strings.Split(labelValues, ",")...) + + allowList, ok := labelValueAllowLists[metricName] + if ok { + allowList.labelToAllowList[labelName] = valueSet + } else { + labelToAllowList := make(map[string]sets.Set[string]) + labelToAllowList[labelName] = valueSet + labelValueAllowLists[metricName] = &MetricLabelAllowList{ + labelToAllowList, + } + } } - // set disabled metrics - for _, metricName := range o.DisabledMetrics { - SetDisabledMetric(metricName) +} + +func SetLabelAllowListFromManifest(manifest string) { + if manifest == "" { + klog.Errorf("The manifest file is empty, ignoring.") + return } - if o.AllowListMapping != nil { - SetLabelAllowListFromCLI(o.AllowListMapping) - } else if len(o.AllowListMappingManifest) > 0 { - SetLabelAllowListFromManifest(o.AllowListMappingManifest) + + data, err := os.ReadFile(filepath.Clean(manifest)) + if err != nil { + klog.Errorf("Failed to read allow list manifest: %v", err) + return + } + allowListMapping := make(map[string]string) + err = yaml.Unmarshal(data, &allowListMapping) + if err != nil { + klog.Errorf("Failed to parse allow list manifest: %v", err) + return } + SetLabelAllowList(allowListMapping) } -func validateShowHiddenMetricsVersion(currentVersion semver.Version, targetVersionStr string) error { - if targetVersionStr == "" { - return nil +// Apply applies a MetricsConfiguration into global configuration of metrics. +func Apply(c *v1.MetricsConfiguration) { + if c == nil { + return } - validVersionStr := fmt.Sprintf("%d.%d", currentVersion.Major, currentVersion.Minor-1) - if targetVersionStr != validVersionStr { - return fmt.Errorf("--show-hidden-metrics-for-version must be omitted or have the value '%v'. Only the previous minor version is allowed", validVersionStr) + if len(c.ShowHiddenMetricsForVersion) > 0 { + SetShowHidden() + } + SetDisabledMetrics(c.DisabledMetrics) + if c.AllowListMapping != nil { + SetLabelAllowList(c.AllowListMapping) + } else { + SetLabelAllowListFromManifest(c.AllowListMappingManifest) + } +} + +// Apply applies parameters into global configuration of metrics. +func (o *Options) Apply() { + if o == nil { + return + } + + Apply(&o.MetricsConfiguration) +} + +// ValidateShowHiddenMetricsVersion checks invalid version for which show hidden metrics. +// TODO: This is kept here for backward compatibility in Kubelet (as metrics configuration fields were exposed on an individual basis earlier). +// TODO: Revisit this after Kubelet supports the new metrics configuration API. +func ValidateShowHiddenMetricsVersion(v string) []error { + err := v1.ValidateShowHiddenMetricsVersionForKubeletBackwardCompatOnly(parseVersion(version.Get()), v) + if err != nil { + return []error{err} } return nil } -func validateAllowMetricLabel(allowListMapping map[string]string) error { - if allowListMapping == nil { +// Validate validates metrics flags options. +func (o *Options) Validate() []error { + if o == nil { return nil } - metricNameRegex := `[a-zA-Z_:][a-zA-Z0-9_:]*` - labelRegex := `[a-zA-Z_][a-zA-Z0-9_]*` - for k := range allowListMapping { - reg := regexp.MustCompile(metricNameRegex + `,` + labelRegex) - if reg.FindString(k) != k { - return fmt.Errorf("--allow-metric-labels must have a list of kv pair with format `metricName,labelName=labelValue, labelValue,...`") - } + currentVersion := parseVersion(version.Get()) + fldPath := field.NewPath("metrics") + fldErrs := v1.Validate(&o.MetricsConfiguration, currentVersion, fldPath) + + if len(fldErrs) == 0 { + return nil } - return nil + + return fldErrs.ToAggregate().Errors() } diff --git a/vendor/k8s.io/component-base/metrics/opts.go b/vendor/k8s.io/component-base/metrics/opts.go index 247b9fd1c1..59beb23685 100644 --- a/vendor/k8s.io/component-base/metrics/opts.go +++ b/vendor/k8s.io/component-base/metrics/opts.go @@ -18,18 +18,13 @@ package metrics import ( "fmt" - "os" - "path/filepath" - "strings" "sync" "time" "github.com/prometheus/client_golang/prometheus" - yaml "go.yaml.in/yaml/v2" - "k8s.io/apimachinery/pkg/util/sets" + internalmetrics "k8s.io/component-base/metrics/internal" promext "k8s.io/component-base/metrics/prometheusextension" - "k8s.io/klog/v2" ) var ( @@ -201,7 +196,7 @@ func (o *HistogramOpts) annotateStabilityLevel() { // convenience function to allow easy transformation to the prometheus // counterpart. This will do more once we have a proper label abstraction func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts { - return prometheus.HistogramOpts{ + opts := prometheus.HistogramOpts{ Namespace: o.Namespace, Subsystem: o.Subsystem, Name: o.Name, @@ -209,6 +204,16 @@ func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts { ConstLabels: o.ConstLabels, Buckets: o.Buckets, } + + // When native histograms are enabled, configure exponential bucket options + // to expose metrics in both classic and native histogram formats. + if internalmetrics.NativeHistogramsEnabled() { + nativeOpts := internalmetrics.NativeHistogramConfig() + opts.NativeHistogramBucketFactor = nativeOpts.BucketFactor + opts.NativeHistogramMaxBucketNumber = nativeOpts.MaxBucketNumber + } + + return opts } // TimingHistogramOpts bundles the options for creating a TimingHistogram metric. It is @@ -325,66 +330,3 @@ func (o *SummaryOpts) toPromSummaryOpts() prometheus.SummaryOpts { BufCap: o.BufCap, } } - -type MetricLabelAllowList struct { - labelToAllowList map[string]sets.Set[string] -} - -func (allowList *MetricLabelAllowList) ConstrainToAllowedList(labelNameList, labelValueList []string) { - for index, value := range labelValueList { - name := labelNameList[index] - if allowValues, ok := allowList.labelToAllowList[name]; ok { - if !allowValues.Has(value) { - labelValueList[index] = "unexpected" - cardinalityEnforcementUnexpectedCategorizationsTotal.Inc() - } - } - } -} - -func (allowList *MetricLabelAllowList) ConstrainLabelMap(labels map[string]string) { - for name, value := range labels { - if allowValues, ok := allowList.labelToAllowList[name]; ok { - if !allowValues.Has(value) { - labels[name] = "unexpected" - cardinalityEnforcementUnexpectedCategorizationsTotal.Inc() - } - } - } -} - -func SetLabelAllowListFromCLI(allowListMapping map[string]string) { - allowListLock.Lock() - defer allowListLock.Unlock() - for metricLabelName, labelValues := range allowListMapping { - metricName := strings.Split(metricLabelName, ",")[0] - labelName := strings.Split(metricLabelName, ",")[1] - valueSet := sets.New[string](strings.Split(labelValues, ",")...) - - allowList, ok := labelValueAllowLists[metricName] - if ok { - allowList.labelToAllowList[labelName] = valueSet - } else { - labelToAllowList := make(map[string]sets.Set[string]) - labelToAllowList[labelName] = valueSet - labelValueAllowLists[metricName] = &MetricLabelAllowList{ - labelToAllowList, - } - } - } -} - -func SetLabelAllowListFromManifest(manifest string) { - allowListMapping := make(map[string]string) - data, err := os.ReadFile(filepath.Clean(manifest)) - if err != nil { - klog.Errorf("Failed to read allow list manifest: %v", err) - return - } - err = yaml.Unmarshal(data, &allowListMapping) - if err != nil { - klog.Errorf("Failed to parse allow list manifest: %v", err) - return - } - SetLabelAllowListFromCLI(allowListMapping) -} diff --git a/vendor/k8s.io/component-base/metrics/processstarttime_others.go b/vendor/k8s.io/component-base/metrics/processstarttime_others.go index 611a12906b..5e9c867587 100644 --- a/vendor/k8s.io/component-base/metrics/processstarttime_others.go +++ b/vendor/k8s.io/component-base/metrics/processstarttime_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/metrics/processstarttime_windows.go b/vendor/k8s.io/component-base/metrics/processstarttime_windows.go index afee6f9b13..9a38abd33c 100644 --- a/vendor/k8s.io/component-base/metrics/processstarttime_windows.go +++ b/vendor/k8s.io/component-base/metrics/processstarttime_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go index 59fd1cf6df..52e04f6ee8 100644 --- a/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go +++ b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go @@ -41,21 +41,21 @@ var ( depth = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ Subsystem: WorkQueueSubsystem, Name: DepthKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "Current depth of workqueue", }, []string{"name"}) adds = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ Subsystem: WorkQueueSubsystem, Name: AddsKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "Total number of adds handled by workqueue", }, []string{"name"}) latency = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ Subsystem: WorkQueueSubsystem, Name: QueueLatencyKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "How long in seconds an item stays in workqueue before being requested.", Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), }, []string{"name"}) @@ -63,7 +63,7 @@ var ( workDuration = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ Subsystem: WorkQueueSubsystem, Name: WorkDurationKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "How long in seconds processing an item from workqueue takes.", Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), }, []string{"name"}) @@ -71,7 +71,7 @@ var ( unfinished = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ Subsystem: WorkQueueSubsystem, Name: UnfinishedWorkKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "How many seconds of work has done that " + "is in progress and hasn't been observed by work_duration. Large " + "values indicate stuck threads. One can deduce the number of stuck " + @@ -81,7 +81,7 @@ var ( longestRunningProcessor = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ Subsystem: WorkQueueSubsystem, Name: LongestRunningProcessorKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "How many seconds has the longest running " + "processor for workqueue been running.", }, []string{"name"}) @@ -89,7 +89,7 @@ var ( retries = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ Subsystem: WorkQueueSubsystem, Name: RetriesKey, - StabilityLevel: k8smetrics.ALPHA, + StabilityLevel: k8smetrics.BETA, Help: "Total number of retries handled by workqueue", }, []string{"name"}) diff --git a/vendor/k8s.io/component-base/metrics/registry.go b/vendor/k8s.io/component-base/metrics/registry.go index aa12f2e2c8..bccfd90f64 100644 --- a/vendor/k8s.io/component-base/metrics/registry.go +++ b/vendor/k8s.io/component-base/metrics/registry.go @@ -19,7 +19,6 @@ package metrics import ( "strings" "sync" - "sync/atomic" "github.com/blang/semver/v4" "github.com/prometheus/client_golang/prometheus" @@ -30,12 +29,8 @@ import ( ) var ( - showHiddenOnce sync.Once - disabledMetricsLock sync.RWMutex - showHidden atomic.Bool - registries []*kubeRegistry // stores all registries created by NewKubeRegistry() - registriesLock sync.RWMutex - disabledMetrics = map[string]struct{}{} + registries []*kubeRegistry // stores all registries created by NewKubeRegistry() + registriesLock sync.RWMutex registeredMetricsTotal = NewCounterVec( &CounterOpts{ @@ -45,30 +40,6 @@ var ( }, []string{"stability_level", "deprecated_version"}, ) - - disabledMetricsTotal = NewCounter( - &CounterOpts{ - Name: "disabled_metrics_total", - Help: "The count of disabled metrics.", - StabilityLevel: BETA, - }, - ) - - hiddenMetricsTotal = NewCounter( - &CounterOpts{ - Name: "hidden_metrics_total", - Help: "The count of hidden metrics.", - StabilityLevel: BETA, - }, - ) - - cardinalityEnforcementUnexpectedCategorizationsTotal = NewCounter( - &CounterOpts{ - Name: "cardinality_enforcement_unexpected_categorizations_total", - Help: "The count of unexpected categorizations during cardinality enforcement.", - StabilityLevel: ALPHA, - }, - ) ) // shouldHide is used to check if a specific metric with deprecated version should be hidden @@ -125,44 +96,6 @@ func isDeprecated(currentVersion, deprecatedVersion semver.Version) bool { return currentVersion.Minor >= deprecatedVersion.Minor } -// ValidateShowHiddenMetricsVersion checks invalid version for which show hidden metrics. -func ValidateShowHiddenMetricsVersion(v string) []error { - err := validateShowHiddenMetricsVersion(parseVersion(version.Get()), v) - if err != nil { - return []error{err} - } - - return nil -} - -func SetDisabledMetric(name string) { - disabledMetricsLock.Lock() - defer disabledMetricsLock.Unlock() - disabledMetrics[name] = struct{}{} - disabledMetricsTotal.Inc() -} - -// SetShowHidden will enable showing hidden metrics. This will no-opt -// after the initial call -func SetShowHidden() { - showHiddenOnce.Do(func() { - showHidden.Store(true) - - // re-register collectors that has been hidden in phase of last registry. - for _, r := range registries { - r.enableHiddenCollectors() - r.enableHiddenStableCollectors() - } - }) -} - -// shouldShowHidden returns whether showing hidden deprecated metrics -// is enabled. While the primary usecase for this is internal (to determine -// registration behavior) this can also be used to introspect -func shouldShowHidden() bool { - return showHidden.Load() -} - // Registerable is an interface for a collector metric which we // will register with KubeRegistry. type Registerable interface { @@ -350,7 +283,7 @@ func (kr *kubeRegistry) trackStableCollectors(cs ...StableCollector) { kr.stableCollectors = append(kr.stableCollectors, cs...) } -// enableHiddenCollectors will re-register all of the hidden collectors. +// enableHiddenCollectors will re-register all the hidden collectors. func (kr *kubeRegistry) enableHiddenCollectors() { if len(kr.hiddenCollectors) == 0 { return diff --git a/vendor/k8s.io/component-base/metrics/testutil/metrics.go b/vendor/k8s.io/component-base/metrics/testutil/metrics.go index a8d710aff5..f1f8b28b4e 100644 --- a/vendor/k8s.io/component-base/metrics/testutil/metrics.go +++ b/vendor/k8s.io/component-base/metrics/testutil/metrics.go @@ -45,6 +45,7 @@ var ( type Metrics map[string]Samples type Samples = model.Samples type Sample = model.Sample +type Time = model.Time type Metric = model.Metric type LabelValue = model.LabelValue type LabelName = model.LabelName @@ -113,6 +114,10 @@ func TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) { return textParser.TextToMetricFamilies(in) } +func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) { + return expfmt.MetricFamilyToText(out, in) +} + // PrintSample returns formatted representation of metric Sample func PrintSample(sample *model.Sample) string { buf := make([]string, 0) diff --git a/vendor/k8s.io/component-base/metrics/testutil/testutil.go b/vendor/k8s.io/component-base/metrics/testutil/testutil.go index d023a0dea8..4d9ba5b3e7 100644 --- a/vendor/k8s.io/component-base/metrics/testutil/testutil.go +++ b/vendor/k8s.io/component-base/metrics/testutil/testutil.go @@ -17,12 +17,15 @@ limitations under the License. package testutil import ( + "errors" "fmt" "io" + "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" apimachineryversion "k8s.io/apimachinery/pkg/version" "k8s.io/component-base/metrics" @@ -167,3 +170,73 @@ func AssertHistogramTotalCount(t TB, name string, labelFilter map[string]string, } } } + +// AssertHasNativeHistogram verifies that a native histogram metric with the given labels exists and has valid data. +func AssertHasNativeHistogram(t TB, mf *dto.MetricFamily, labelFilter map[string]string) { + if mf.GetType() != dto.MetricType_HISTOGRAM { + t.Errorf("metric %q is not a histogram", mf.GetName()) + return + } + + for _, m := range mf.GetMetric() { + if !LabelsMatch(m, labelFilter) { + continue + } + h := m.GetHistogram() + if h == nil { + continue + } + + if h.Schema == nil { + t.Errorf("expected native histogram data to be present for metric %q with labels %v", mf.GetName(), labelFilter) + } + + // If there are observations, PositiveSpan should have data for positive durations + if h.GetSampleCount() > 0 && len(h.GetPositiveSpan()) == 0 { + t.Errorf("expected PositiveSpan data for histogram with observations") + } + + return + } + t.Errorf("metric %q with labels %v not found", mf.GetName(), labelFilter) +} + +// ScrapeMetricsProto scrapes metrics from a URL using protobuf format. +// This is necessary for native histograms as they are only fully exposed in protobuf format. +// Returns a map of metric families keyed by metric name. +func ScrapeMetricsProto(url string, client *http.Client) (map[string]*dto.MetricFamily, error) { + if client == nil { + return nil, fmt.Errorf("http client is required") + } + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + // Request protobuf format to get native histogram data + req.Header.Set("Accept", string(expfmt.NewFormat(expfmt.TypeProtoDelim))) + + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("request failed: %w", err) + } + defer func() { _ = resp.Body.Close() }() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + // Parse protobuf format + decoder := expfmt.NewDecoder(resp.Body, expfmt.ResponseFormat(resp.Header)) + result := make(map[string]*dto.MetricFamily) + for { + var mf dto.MetricFamily + if err := decoder.Decode(&mf); err != nil { + if errors.Is(err, io.EOF) { + break + } + return nil, fmt.Errorf("failed to decode metric: %w", err) + } + result[mf.GetName()] = &mf + } + return result, nil +} diff --git a/vendor/k8s.io/component-base/metrics/version.go b/vendor/k8s.io/component-base/metrics/version.go index f963e205eb..eba29ce9be 100644 --- a/vendor/k8s.io/component-base/metrics/version.go +++ b/vendor/k8s.io/component-base/metrics/version.go @@ -23,7 +23,7 @@ var ( &GaugeOpts{ Name: "kubernetes_build_info", Help: "A metric with a constant '1' value labeled by major, minor, git version, git commit, git tree state, build date, Go version, and compiler from which Kubernetes was built, and platform on which it is running.", - StabilityLevel: ALPHA, + StabilityLevel: BETA, }, []string{"major", "minor", "git_version", "git_commit", "git_tree_state", "build_date", "go_version", "compiler", "platform"}, ) diff --git a/vendor/k8s.io/component-base/version/base.go b/vendor/k8s.io/component-base/version/base.go index 94da79c081..453b63d82f 100644 --- a/vendor/k8s.io/component-base/version/base.go +++ b/vendor/k8s.io/component-base/version/base.go @@ -60,5 +60,5 @@ const ( // DefaultKubeBinaryVersion is the hard coded k8 binary version based on the latest K8s release. // It is supposed to be consistent with gitMajor and gitMinor, except for local tests, where gitMajor and gitMinor are "". // Should update for each minor release! - DefaultKubeBinaryVersion = "1.35" + DefaultKubeBinaryVersion = "1.36" ) diff --git a/vendor/k8s.io/component-base/zpages/features/kube_features.go b/vendor/k8s.io/component-base/zpages/features/kube_features.go index ed5e41e011..91b45dfeed 100644 --- a/vendor/k8s.io/component-base/zpages/features/kube_features.go +++ b/vendor/k8s.io/component-base/zpages/features/kube_features.go @@ -29,6 +29,7 @@ const ( // owner: @richabanker // kep: https://kep.k8s.io/4827 // alpha: v1.32 + // beta: v1.36 // // Enables /statusz endpoint for a component making it accessible to // users with the system:monitoring cluster role. @@ -39,9 +40,11 @@ func featureGates() map[featuregate.Feature]featuregate.VersionedSpecs { return map[featuregate.Feature]featuregate.VersionedSpecs{ ComponentFlagz: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, ComponentStatusz: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, } } diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/.mockery.yaml b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/.mockery.yaml deleted file mode 100644 index bb07cc3ad5..0000000000 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/.mockery.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -dir: testing -pkgname: testing -template: testify -template-data: - boilerplate-file: ../../../../../hack/boilerplate/boilerplate.generatego.txt -packages: - k8s.io/component-helpers/nodedeclaredfeatures: - config: - filename: mocks.go # New file name - interfaces: - Feature: {} - FeatureGate: {} \ No newline at end of file diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/OWNERS b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/OWNERS new file mode 100644 index 0000000000..43c2071106 --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-node-approvers +reviewers: + - sig-node-reviewers + - sig-scheduling +labels: + - sig/node + - sig/scheduling diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/bitmap.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/bitmap.go new file mode 100644 index 0000000000..983f998486 --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/bitmap.go @@ -0,0 +1,125 @@ +/* +Copyright 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 nodedeclaredfeatures + +import ( + "fmt" + "slices" +) + +type bitmap struct { + words []uint64 + size int +} + +// newBitmap creates a new bitmap that can store the number of bits specified by size. +func newBitmap(size int) bitmap { + if size < 0 { + panic(fmt.Sprintf("bitmap size must be positive: %d", size)) + } + return bitmap{make([]uint64, (size+63)/64), size} +} + +// Set sets the bit at the specified index. +func (b bitmap) Set(i int) { + if i < 0 || i >= b.size { + panic(fmt.Sprintf("bitmap index out of range: %d", i)) + } + + b.words[i/64] |= 1 << (i % 64) +} + +// Get returns the bit value at the specified index. +func (b bitmap) Get(i int) bool { + if i < 0 || i >= b.size { + panic(fmt.Sprintf("bitmap index out of range: %d", i)) + } + + return b.words[i/64]&(1<<(i%64)) != 0 +} + +// Difference returns a new bitmap containing bits set in b but not in other. +func (b bitmap) Difference(other bitmap) (bitmap, error) { + if b.size != other.size { + return bitmap{}, fmt.Errorf("bitmap size mismatch: %d != %d", b.size, other.size) + } + + diff := newBitmap(b.size) + for i := range b.words { + diff.words[i] = b.words[i] &^ other.words[i] + } + return diff, nil +} + +// Contains checks whether b is a subset of other. +func (b bitmap) IsSubset(other bitmap) (bool, error) { + if b.size != other.size { + return false, fmt.Errorf("bitmap size mismatch; %d != %d", b.size, other.size) + } + for i := range b.words { + if b.words[i]&^other.words[i] != 0 { + return false, nil + } + } + return true, nil +} + +// Equal returns true if b and other have the same bits set. +func (b bitmap) Equal(other bitmap) bool { + if b.size != other.size { + return false + } + + for i := range b.words { + if b.words[i] != other.words[i] { + return false + } + } + return true +} + +// IsEmpty returns true if no bits are set in the bitmap. +func (b bitmap) IsEmpty() bool { + for i := range b.words { + if b.words[i] != 0 { + return false + } + } + return true +} + +// Clone returns a deep copy of the bitmap. +func (b bitmap) Clone() bitmap { + return bitmap{ + words: slices.Clone(b.words), + size: b.size, + } +} + +// String returns a binary representation, with leftmost character representing +// the first (0th) bit. +func (b bitmap) String() string { + buf := make([]byte, b.size) + for i := 0; i < b.size; i++ { + if (b.words[i/64]>>(uint(i)%64))&1 != 0 { + buf[i] = '1' + } else { + buf[i] = '0' + } + } + return string(buf) +} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/OWNERS b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/OWNERS new file mode 100644 index 0000000000..83690e1aee --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/OWNERS @@ -0,0 +1,6 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - sig-autoscaling-maintainers +labels: + - sig/autoscaling diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet/feature.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet/feature.go new file mode 100644 index 0000000000..410c40a252 --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet/feature.go @@ -0,0 +1,62 @@ +/* +Copyright 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 extendwebsocketstokubelet + +import ( + "k8s.io/apimachinery/pkg/util/version" + "k8s.io/component-helpers/nodedeclaredfeatures/types" +) + +// Ensure the feature struct implements the unified Feature interface. +var _ types.Feature = &extendWebSocketsToKubeletFeature{} + +const ( + ExtendWebSocketsToKubeletFeatureGate = "ExtendWebSocketsToKubelet" +) + +// Feature is the implementation of the `ExtendWebSocketsToKubelet` feature. +var Feature = &extendWebSocketsToKubeletFeature{} + +type extendWebSocketsToKubeletFeature struct{} + +func (f *extendWebSocketsToKubeletFeature) Name() string { + return ExtendWebSocketsToKubeletFeatureGate +} + +func (f *extendWebSocketsToKubeletFeature) Requirements() *types.FeatureRequirements { + return &types.FeatureRequirements{ + EnabledFeatureGates: []string{ExtendWebSocketsToKubeletFeatureGate}, + } +} + +func (f *extendWebSocketsToKubeletFeature) Discover(cfg *types.NodeConfiguration) bool { + return cfg.FeatureGates.Enabled(ExtendWebSocketsToKubeletFeatureGate) +} + +func (f *extendWebSocketsToKubeletFeature) InferForScheduling(podInfo *types.PodInfo) bool { + // This feature does not affect scheduling. + return false +} + +func (f *extendWebSocketsToKubeletFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool { + // This feature does not affect updates. + return false +} + +func (f *extendWebSocketsToKubeletFeature) MaxVersion() *version.Version { + return nil +} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/guaranteed_cpu_resize.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/guaranteed_cpu_resize.go deleted file mode 100644 index 4372df64d4..0000000000 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/guaranteed_cpu_resize.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2025 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 inplacepodresize - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/version" - "k8s.io/component-helpers/nodedeclaredfeatures" -) - -// Ensure the feature struct implements the unified Feature interface. -var _ nodedeclaredfeatures.Feature = &guaranteedQoSPodCPUResizeFeature{} - -const ( - // IPPRExclusiveCPUsFeatureGate is the feature gate for IPPRExclusiveCPUsFeatureGate. - IPPRExclusiveCPUsFeatureGate = "InPlacePodVerticalScalingExclusiveCPUs" - // CPUManagerPolicyStatic is the value for the static CPUManagerPolicy. - CPUManagerPolicyStatic = "static" - // CPUManagerPolicyNone is the value for the none CPUManagerPolicy. - CPUManagerPolicyNone = "none" - // GuaranteedQoSPodCPUResize is a declared feature that indicates a node supports in-place pod resize for guaranteed QoS pods with exclusive CPUs. - GuaranteedQoSPodCPUResize = "GuaranteedQoSPodCPUResize" -) - -// GuaranteedQoSPodCPUResizeFeature is the implementation of the `GuaranteedQoSPodCPUResize` feature. -var GuaranteedQoSPodCPUResizeFeature = &guaranteedQoSPodCPUResizeFeature{} - -type guaranteedQoSPodCPUResizeFeature struct{} - -func (f *guaranteedQoSPodCPUResizeFeature) Name() string { - return GuaranteedQoSPodCPUResize -} - -func (f *guaranteedQoSPodCPUResizeFeature) Discover(cfg *nodedeclaredfeatures.NodeConfiguration) bool { - featureGateEnabled := cfg.FeatureGates.Enabled(IPPRExclusiveCPUsFeatureGate) - cpuManagerPolicy := cfg.StaticConfig.CPUManagerPolicy - if (featureGateEnabled && cpuManagerPolicy == CPUManagerPolicyStatic) || (cpuManagerPolicy == CPUManagerPolicyNone) { - return true - } - return false -} - -func (f *guaranteedQoSPodCPUResizeFeature) InferForScheduling(podInfo *nodedeclaredfeatures.PodInfo) bool { - // This feature is only relevant for pod updates (resizes). - return false -} - -func (f *guaranteedQoSPodCPUResizeFeature) InferForUpdate(oldPodInfo, newPodInfo *nodedeclaredfeatures.PodInfo) bool { - // Since this is an update, the QOS class must already be se ans must be the same for old and new pod spec. - if oldPodInfo.Status != nil && oldPodInfo.Status.QOSClass != v1.PodQOSGuaranteed { - return false - } - - oldPodSpec := oldPodInfo.Spec - newPodSpec := newPodInfo.Spec - - // Check if CPU request is changing for any container. - for i := range oldPodSpec.Containers { - oldCPU := oldPodSpec.Containers[i].Resources.Requests.Cpu() - newCPU := newPodSpec.Containers[i].Resources.Requests.Cpu() - if oldCPU != nil && newCPU != nil && !oldCPU.Equal(*newCPU) { - return true - } - } - - return false -} - -func (f *guaranteedQoSPodCPUResizeFeature) MaxVersion() *version.Version { - return nil -} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/nonsidecar_initcontainers_resize.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/nonsidecar_initcontainers_resize.go new file mode 100644 index 0000000000..1bfbd07428 --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/nonsidecar_initcontainers_resize.go @@ -0,0 +1,72 @@ +/* +Copyright 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 inplacepodresize + +import ( + "reflect" + + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/version" + "k8s.io/component-helpers/nodedeclaredfeatures/types" +) + +// Ensure the feature struct implements the unified Feature interface. +var _ types.Feature = &podLevelResourcesResizeFeature{} + +// IPPRInitContainersFeatureGate is the feature gate for IPPRPodLevelResourcesVerticalScaling. +const IPPRInitContainersFeatureGate = "InPlacePodVerticalScalingInitContainers" + +// Feature is the implementation of the `NonSidecarInitContainerResize` feature. +var NonSidecarInitContainerResizeFeature = &nonSidecarInitContainerResizeFeature{} + +type nonSidecarInitContainerResizeFeature struct{} + +func (f *nonSidecarInitContainerResizeFeature) Name() string { + return IPPRInitContainersFeatureGate +} + +func (f *nonSidecarInitContainerResizeFeature) Discover(cfg *types.NodeConfiguration) bool { + return cfg.FeatureGates.Enabled(IPPRInitContainersFeatureGate) +} + +func (f *nonSidecarInitContainerResizeFeature) Requirements() *types.FeatureRequirements { + return &types.FeatureRequirements{ + EnabledFeatureGates: []string{IPPRInitContainersFeatureGate}, + } +} + +func (f *nonSidecarInitContainerResizeFeature) InferForScheduling(podInfo *types.PodInfo) bool { + // This feature is only relevant for pod updates. + return false +} + +func (f *nonSidecarInitContainerResizeFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool { + for i, ctr := range oldPodInfo.Spec.InitContainers { + if !isSidecar(ctr) && !reflect.DeepEqual(ctr.Resources, newPodInfo.Spec.InitContainers[i].Resources) { + return true + } + } + return false +} + +func (f *nonSidecarInitContainerResizeFeature) MaxVersion() *version.Version { + return nil +} + +func isSidecar(initContainer core.Container) bool { + return initContainer.RestartPolicy != nil && *initContainer.RestartPolicy == core.ContainerRestartPolicyAlways +} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/pod_level_resource_resize.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/pod_level_resource_resize.go index a1f65d53ee..6cfa0c7866 100644 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/pod_level_resource_resize.go +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize/pod_level_resource_resize.go @@ -17,14 +17,13 @@ limitations under the License. package inplacepodresize import ( - "reflect" - + apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/util/version" - "k8s.io/component-helpers/nodedeclaredfeatures" + "k8s.io/component-helpers/nodedeclaredfeatures/types" ) // Ensure the feature struct implements the unified Feature interface. -var _ nodedeclaredfeatures.Feature = &podLevelResourcesResizeFeature{} +var _ types.Feature = &podLevelResourcesResizeFeature{} // IPPRPodLevelResourcesFeatureGate is the feature gate for IPPRPodLevelResourcesVerticalScaling. const IPPRPodLevelResourcesFeatureGate = "InPlacePodLevelResourcesVerticalScaling" @@ -38,20 +37,26 @@ func (f *podLevelResourcesResizeFeature) Name() string { return IPPRPodLevelResourcesFeatureGate } -func (f *podLevelResourcesResizeFeature) Discover(cfg *nodedeclaredfeatures.NodeConfiguration) bool { +func (f *podLevelResourcesResizeFeature) Discover(cfg *types.NodeConfiguration) bool { return cfg.FeatureGates.Enabled(IPPRPodLevelResourcesFeatureGate) } -func (f *podLevelResourcesResizeFeature) InferForScheduling(podInfo *nodedeclaredfeatures.PodInfo) bool { +func (f *podLevelResourcesResizeFeature) Requirements() *types.FeatureRequirements { + return &types.FeatureRequirements{ + EnabledFeatureGates: []string{IPPRPodLevelResourcesFeatureGate}, + } +} + +func (f *podLevelResourcesResizeFeature) InferForScheduling(podInfo *types.PodInfo) bool { // This feature is only relevant for pod updates. return false } -func (f *podLevelResourcesResizeFeature) InferForUpdate(oldPodInfo, newPodInfo *nodedeclaredfeatures.PodInfo) bool { +func (f *podLevelResourcesResizeFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool { if oldPodInfo.Spec.Resources == nil && newPodInfo.Spec.Resources == nil { return false } - return !reflect.DeepEqual(oldPodInfo.Spec.Resources, newPodInfo.Spec.Resources) + return !apiequality.Semantic.DeepEqual(oldPodInfo.Spec.Resources, newPodInfo.Spec.Resources) } func (f *podLevelResourcesResizeFeature) MaxVersion() *version.Version { diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/registry.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/registry.go index 953a655e23..ad290dc58e 100644 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/registry.go +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/registry.go @@ -17,16 +17,20 @@ limitations under the License. package features import ( - "k8s.io/component-helpers/nodedeclaredfeatures" + "k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet" "k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize" "k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers" + "k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork" + "k8s.io/component-helpers/nodedeclaredfeatures/types" ) // AllFeatures is the central registry for all declared features. // New features are added to this list to be automatically included in both // discovery and inference logic. -var AllFeatures = []nodedeclaredfeatures.Feature{ +var AllFeatures = []types.Feature{ restartallcontainers.Feature, - inplacepodresize.GuaranteedQoSPodCPUResizeFeature, inplacepodresize.PodLevelResourcesResizeFeature, + extendwebsocketstokubelet.Feature, + inplacepodresize.NonSidecarInitContainerResizeFeature, + usernamespaceshostnetwork.Feature, } diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers/restart_all_containers.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers/restart_all_containers.go index db496d3079..39000819f1 100644 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers/restart_all_containers.go +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers/restart_all_containers.go @@ -19,11 +19,11 @@ package restartallcontainers import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/version" - "k8s.io/component-helpers/nodedeclaredfeatures" + "k8s.io/component-helpers/nodedeclaredfeatures/types" ) // Ensure the feature struct implements the unified Feature interface. -var _ nodedeclaredfeatures.Feature = &restartAllContainersFeature{} +var _ types.Feature = &restartAllContainersFeature{} const ( RestartRulesFeatureGate = "ContainerRestartRules" @@ -39,11 +39,17 @@ func (f *restartAllContainersFeature) Name() string { return RestartAllContainersOnContainerExits } -func (f *restartAllContainersFeature) Discover(cfg *nodedeclaredfeatures.NodeConfiguration) bool { +func (f *restartAllContainersFeature) Discover(cfg *types.NodeConfiguration) bool { return cfg.FeatureGates.Enabled(RestartAllContainersOnContainerExits) } -func (f *restartAllContainersFeature) InferForScheduling(podInfo *nodedeclaredfeatures.PodInfo) bool { +func (f *restartAllContainersFeature) Requirements() *types.FeatureRequirements { + return &types.FeatureRequirements{ + EnabledFeatureGates: []string{RestartAllContainersOnContainerExits}, + } +} + +func (f *restartAllContainersFeature) InferForScheduling(podInfo *types.PodInfo) bool { for _, c := range podInfo.Spec.Containers { for _, rule := range c.RestartPolicyRules { if rule.Action == v1.ContainerRestartRuleActionRestartAllContainers { @@ -61,7 +67,7 @@ func (f *restartAllContainersFeature) InferForScheduling(podInfo *nodedeclaredfe return false } -func (f *restartAllContainersFeature) InferForUpdate(oldPodInfo, newPodInfo *nodedeclaredfeatures.PodInfo) bool { +func (f *restartAllContainersFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool { // container.restartPolicy and container.restartPolicyRules are not mutable. return false } diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork/user_namespaces_host_network.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork/user_namespaces_host_network.go new file mode 100644 index 0000000000..266fab337c --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork/user_namespaces_host_network.go @@ -0,0 +1,77 @@ +/* +Copyright 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 usernamespaceshostnetwork + +import ( + "k8s.io/apimachinery/pkg/util/version" + "k8s.io/component-helpers/nodedeclaredfeatures/types" +) + +// Ensure the feature struct implements the unified Feature interface. +var _ types.Feature = &userNamespacesHostNetworkFeature{} + +const ( + // UserNamespacesHostNetworkSupportFeatureGate is the feature gate name. + UserNamespacesHostNetworkSupportFeatureGate = "UserNamespacesHostNetworkSupport" + // UserNamespacesHostNetworkSupport is the declared feature name. + UserNamespacesHostNetworkSupport = "UserNamespacesHostNetworkSupport" +) + +// Feature is the implementation of the `UserNamespacesHostNetworkSupport` feature. +var Feature = &userNamespacesHostNetworkFeature{} + +type userNamespacesHostNetworkFeature struct{} + +func (f *userNamespacesHostNetworkFeature) Requirements() *types.FeatureRequirements { + return &types.FeatureRequirements{ + EnabledFeatureGates: []string{UserNamespacesHostNetworkSupportFeatureGate}, + RequiredRuntimeFeatures: &types.RuntimeFeatures{ + UserNamespacesHostNetwork: true, + }, + } +} + +func (f *userNamespacesHostNetworkFeature) Name() string { + return UserNamespacesHostNetworkSupport +} + +func (f *userNamespacesHostNetworkFeature) Discover(cfg *types.NodeConfiguration) bool { + // This feature requires both the feature gate to be enabled AND + // runtime-level support for user namespaces with host network. + if !cfg.FeatureGates.Enabled(UserNamespacesHostNetworkSupportFeatureGate) { + return false + } + + return cfg.RuntimeFeatures.UserNamespacesHostNetwork +} + +func (f *userNamespacesHostNetworkFeature) InferForScheduling(podInfo *types.PodInfo) bool { + // A pod needs this feature if it uses both host network AND user namespaces. + if podInfo.Spec.HostNetwork && podInfo.Spec.HostUsers != nil && !*podInfo.Spec.HostUsers { + return true + } + return false +} + +func (f *userNamespacesHostNetworkFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool { + // HostNetwork and HostUsers fields are immutable, so no update inference is needed. + return false +} + +func (f *userNamespacesHostNetworkFeature) MaxVersion() *version.Version { + return nil +} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/featureset.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/featureset.go new file mode 100644 index 0000000000..ad749b457c --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/featureset.go @@ -0,0 +1,110 @@ +/* +Copyright 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 nodedeclaredfeatures + +import ( + "fmt" + "math/bits" + "slices" +) + +// FeatureSet is a set of node features. +type FeatureSet = bitmap + +// FeatureMapper maps feature names to bit positions in a FeatureSet. +type FeatureMapper struct { + registeredFeatures []string +} + +// NewFeatureMapper creates a FeatureMapper from a list of known features. +func NewFeatureMapper(features []string) *FeatureMapper { + sortedFeatures := slices.Clone(features) + slices.Sort(sortedFeatures) + return &FeatureMapper{sortedFeatures} +} + +// NewFeatureSet returns an empty FeatureSet sized to the registered features. +func (m *FeatureMapper) NewFeatureSet() FeatureSet { + return FeatureSet(newBitmap(len(m.registeredFeatures))) +} + +// MapSorted creates a FeatureSet from a sorted slice of feature names. +func (m *FeatureMapper) MapSorted(sortedFeatures []string) (FeatureSet, error) { + return m.mapSorted(sortedFeatures, false) +} + +// MustMapSorted is a convenience wrapper around MapSorted that panics on errors. +func (m *FeatureMapper) MustMapSorted(sortedFeatures []string) FeatureSet { + s, err := m.MapSorted(sortedFeatures) + if err != nil { + panic(err) + } + return s +} + +// TryMap creates a FeatureSet from a sorted slice, ignoring unknown features. +func (m *FeatureMapper) TryMap(sortedFeatures []string) FeatureSet { + fs, _ := m.mapSorted(sortedFeatures, true) + return fs +} + +func (m *FeatureMapper) mapSorted(sortedFeatures []string, ignoreUnknown bool) (FeatureSet, error) { + s := m.NewFeatureSet() + + if len(sortedFeatures) == 0 { + return s, nil + } + + i, j := 0, 0 + for i < len(sortedFeatures) && j < len(m.registeredFeatures) { + if sortedFeatures[i] == m.registeredFeatures[j] { + s.Set(j) + i++ + j++ + } else if sortedFeatures[i] < m.registeredFeatures[j] { + if !ignoreUnknown { + return s, fmt.Errorf("unknown feature %s", sortedFeatures[i]) + } + i++ + } else { + j++ + } + } + + if !ignoreUnknown && i < len(sortedFeatures) { + return s, fmt.Errorf("unknown feature %s", sortedFeatures[i]) + } + return s, nil +} + +// Unmap returns the names of the features set in the FeatureSet (sorted). +func (m *FeatureMapper) Unmap(s FeatureSet) ([]string, error) { + if s.size != len(m.registeredFeatures) { + return nil, fmt.Errorf("feature size mismatch! s.size=%d; len(m.registeredFeatures)=%d", s.size, len(m.registeredFeatures)) + } + + var keys []string + for i, w := range s.words { + for w != 0 { + t := bits.TrailingZeros64(w) // Find the index of the least significant bit. + index := i*64 + t + keys = append(keys, m.registeredFeatures[index]) + w &^= 1 << uint(t) // Clear the least significant bit. + } + } + return keys, nil +} diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/framework.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/framework.go index fa4986e088..285a2edbb6 100644 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/framework.go +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/framework.go @@ -19,54 +19,42 @@ package nodedeclaredfeatures import ( "fmt" "slices" + "strings" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/version" + "k8s.io/component-helpers/nodedeclaredfeatures/features" + "k8s.io/component-helpers/nodedeclaredfeatures/types" ) // Framework provides functions for discovering node features and inferring pod feature requirements. // It is stateful and holds the feature registry. type Framework struct { - registry []Feature + *FeatureMapper + registry []types.Feature } -// FeatureSet is a set of node features. -type FeatureSet struct { - sets.Set[string] -} - -// NewFeatureSet creates a FeatureSet from a list of feature names. -func NewFeatureSet(features ...string) FeatureSet { - return FeatureSet{Set: sets.New(features...)} -} - -// Equal returns true if both the sets have the same features. -func (s *FeatureSet) Equal(other FeatureSet) bool { - return s.Set.Equal(other.Set) -} - -// Clone returns a copy of the FeatureSet. -func (s *FeatureSet) Clone() FeatureSet { - if s.Set == nil { - return FeatureSet{Set: nil} - } - return FeatureSet{Set: s.Set.Clone()} -} +var DefaultFramework = New(features.AllFeatures) // New creates a new instance of the Framework. -func New(registry []Feature) (*Framework, error) { - if registry == nil { - return nil, fmt.Errorf("registry must not be nil") +func New(registry []types.Feature) *Framework { + // Ensure the features are sorted. + slices.SortFunc(registry, func(a, b types.Feature) int { + return strings.Compare(a.Name(), b.Name()) + }) + featureNames := make([]string, len(registry)) + for i, f := range registry { + featureNames[i] = f.Name() } return &Framework{ - registry: registry, - }, nil + registry: registry, + FeatureMapper: NewFeatureMapper(featureNames), + } } // DiscoverNodeFeatures determines which features from the registry are enabled // for a specific node configuration. It returns a sorted, unique list of feature names. -func (f *Framework) DiscoverNodeFeatures(cfg *NodeConfiguration) []string { +func (f *Framework) DiscoverNodeFeatures(cfg *types.NodeConfiguration) []string { var enabledFeatures []string for _, f := range f.registry { if f.Discover(cfg) { @@ -76,41 +64,40 @@ func (f *Framework) DiscoverNodeFeatures(cfg *NodeConfiguration) []string { enabledFeatures = append(enabledFeatures, f.Name()) } } - slices.Sort(enabledFeatures) return enabledFeatures } // InferForPodScheduling determines which features from the registry are required by a pod scheduling for a given target version. -func (f *Framework) InferForPodScheduling(podInfo *PodInfo, targetVersion *version.Version) (FeatureSet, error) { +func (f *Framework) InferForPodScheduling(podInfo *types.PodInfo, targetVersion *version.Version) (FeatureSet, error) { if targetVersion == nil { return FeatureSet{}, fmt.Errorf("target version cannot be nil") } - reqs := NewFeatureSet() - for _, f := range f.registry { + reqs := f.NewFeatureSet() + for i, f := range f.registry { if f.MaxVersion() != nil && targetVersion.GreaterThan(f.MaxVersion()) { // If target version is greater than the feature's max version, no need to require the feature continue } if f.InferForScheduling(podInfo) { - reqs.Insert(f.Name()) + reqs.Set(i) } } return reqs, nil } // InferForPodUpdate determines which features are required by a pod update operation for a given target version. -func (f *Framework) InferForPodUpdate(oldPodInfo, newPodInfo *PodInfo, targetVersion *version.Version) (FeatureSet, error) { +func (f *Framework) InferForPodUpdate(oldPodInfo, newPodInfo *types.PodInfo, targetVersion *version.Version) (FeatureSet, error) { if targetVersion == nil { return FeatureSet{}, fmt.Errorf("target version cannot be nil") } - reqs := NewFeatureSet() - for _, f := range f.registry { + reqs := f.NewFeatureSet() + for i, f := range f.registry { if f.MaxVersion() != nil && targetVersion.GreaterThan(f.MaxVersion()) { // If target version is greater than the feature's max version, no need to require the feature continue } if f.InferForUpdate(oldPodInfo, newPodInfo) { - reqs.Insert(f.Name()) + reqs.Set(i) } } return reqs, nil @@ -129,30 +116,46 @@ type MatchResult struct { // It returns a MatchResult: // - IsMatch is true if all requiredFeatures are present in node.status.declaredFeatures. // - UnsatisfiedRequirements lists features in requiredFeatures but not in node.status.declaredFeatures. -func MatchNode(requiredFeatures FeatureSet, node *v1.Node) (*MatchResult, error) { +func (f *Framework) MatchNode(requiredFeatures FeatureSet, node *v1.Node) (*MatchResult, error) { if node == nil { return nil, fmt.Errorf("node cannot be nil") } - return MatchNodeFeatureSet(requiredFeatures, NewFeatureSet(node.Status.DeclaredFeatures...)) + fs := f.TryMap(node.Status.DeclaredFeatures) + return f.MatchNodeFeatureSet(requiredFeatures, fs) } // MatchNodeFeatureSet compares a set of required features against a set of features present on a node. // It returns a MatchResult: // - IsMatch is true if all requiredFeatures are present in nodeFeatures. // - UnsatisfiedRequirements lists features in requiredFeatures but not in nodeFeatures. -func MatchNodeFeatureSet(requiredFeatures FeatureSet, nodeFeatures FeatureSet) (*MatchResult, error) { - if requiredFeatures.Len() == 0 { +func (f *Framework) MatchNodeFeatureSet(requiredFeatures FeatureSet, nodeFeatures FeatureSet) (*MatchResult, error) { + if requiredFeatures.IsEmpty() { return &MatchResult{IsMatch: true}, nil // No requirements to match. } - var mismatched []string - for req := range requiredFeatures.Set { - if !nodeFeatures.Has(req) { - mismatched = append(mismatched, req) - continue - } + // Perform an explicit IsSubset check first to optimize for the success path, + // since IsSubset is faster than Difference (no allocations). + isMatch, err := requiredFeatures.IsSubset(nodeFeatures) + if err != nil { + return nil, err } - if len(mismatched) > 0 { - return &MatchResult{IsMatch: false, UnsatisfiedRequirements: mismatched}, nil + if isMatch { + return &MatchResult{IsMatch: true}, nil + } + + diff, _ := requiredFeatures.Difference(nodeFeatures) // Difference will error IFF IsSubset also does, so we can ignore the error here. + unsatisfiedRequirements, err := f.Unmap(diff) + if err != nil { + return nil, err + } + return &MatchResult{IsMatch: false, UnsatisfiedRequirements: unsatisfiedRequirements}, nil +} + +// GetFeatureRequirements returns the feature gates that a feature depends on. +func (f *Framework) GetFeatureRequirements(name string) (*FeatureRequirements, error) { + for _, r := range f.registry { + if r.Name() == name { + return r.Requirements(), nil + } } - return &MatchResult{IsMatch: true}, nil + return nil, fmt.Errorf("feature '%s' not registered", name) } diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types.go index c56fa0c1c5..5fd12dfc86 100644 --- a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types.go +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types.go @@ -14,68 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -//go:generate mockery package nodedeclaredfeatures import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/version" + "k8s.io/component-helpers/nodedeclaredfeatures/types" ) -// PodInfo is an extensible data structure that wraps the pod object -// and can be expanded in the future to include ancillary resources -// like ResourceClaims or PVCs. -type PodInfo struct { - // Spec is the Pod's specification. - Spec *v1.PodSpec - // Status is the Pod's current status. This field can be nil, for example, - // when this struct represents a pod not yet created. - // (e.g., during scheduling). - Status *v1.PodStatus - // Add other ancillary resources here in the future as needed. - // Example: ResourceClaims []*v1.ResourceClaim -} +// The following type aliases are provided as convenience to framework users. -// Feature encapsulates all logic for a given declared feature. -type Feature interface { - // Name returns the feature's well-known name. - Name() string - - // Discover checks if a node provides the feature based on its configuration. - Discover(cfg *NodeConfiguration) bool - - // InferForScheduling checks if pod scheduling requires the feature. - InferForScheduling(podInfo *PodInfo) bool - - // InferForUpdate checks if a pod update requires the feature. - InferForUpdate(oldPodInfo, newPodInfo *PodInfo) bool - - // MaxVersion specifies the upper bound Kubernetes version (inclusive) for this feature's relevance - // as a scheduling factor. Should be set based on the feature's GA version - // and the cluster's version skew policy. Nil means no upper version bound. - // Comparisons use the full semantic versioning scheme. - MaxVersion() *version.Version -} - -// FeatureGate is an interface that abstracts feature gate checking. -type FeatureGate interface { - // Enabled returns true if the named feature gate is enabled. - Enabled(key string) bool -} - -// StaticConfiguration provides a view of a node's static configuration. -type StaticConfiguration struct { - // Kubelet's CPU Manager policy - CPUManagerPolicy string -} - -// NodeConfiguration provides a generic view of a node's static configuration. -type NodeConfiguration struct { - // FeatureGates holds an implementation of the FeatureGate interface. - FeatureGates FeatureGate - // StaticConfig holds node static configuration. - StaticConfig StaticConfiguration - // Version holds the current node version. This is used for full semantic version comparisons - // with Feature.MaxVersion() to determine if a feature needs to be reported. - Version *version.Version -} +type PodInfo = types.PodInfo +type Feature = types.Feature +type FeatureRequirements = types.FeatureRequirements +type RuntimeFeatures = types.RuntimeFeatures +type FeatureGate = types.FeatureGate +type StaticConfiguration = types.StaticConfiguration +type NodeConfiguration = types.NodeConfiguration diff --git a/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types/types.go b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types/types.go new file mode 100644 index 0000000000..0c4376f130 --- /dev/null +++ b/vendor/k8s.io/component-helpers/nodedeclaredfeatures/types/types.go @@ -0,0 +1,108 @@ +/* +Copyright 2025 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 types + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/version" +) + +// PodInfo is an extensible data structure that wraps the pod object +// and can be expanded in the future to include ancillary resources +// like ResourceClaims or PVCs. +type PodInfo struct { + // Spec is the Pod's specification. + Spec *v1.PodSpec + // Status is the Pod's current status. This field can be nil, for example, + // when this struct represents a pod not yet created. + // (e.g., during scheduling). + Status *v1.PodStatus + // Add other ancillary resources here in the future as needed. + // Example: ResourceClaims []*v1.ResourceClaim +} + +// Feature encapsulates all logic for a given declared feature. +type Feature interface { + // Name returns the feature's well-known name. + Name() string + + // Discover checks if a node provides the feature based on its configuration. + Discover(cfg *NodeConfiguration) bool + + // Requirements returns the feature's feature gate and static config dependencies. + Requirements() *FeatureRequirements + + // InferForScheduling checks if pod scheduling requires the feature. + InferForScheduling(podInfo *PodInfo) bool + + // InferForUpdate checks if a pod update requires the feature. + InferForUpdate(oldPodInfo, newPodInfo *PodInfo) bool + + // MaxVersion specifies the upper bound Kubernetes version (inclusive) for this feature's relevance + // as a scheduling factor. Should be set based on the feature's GA version + // and the cluster's version skew policy. Nil means no upper version bound. + // Comparisons use the full semantic versioning scheme. + MaxVersion() *version.Version +} + +// FeatureRequirements lists the potential dependencies of a feature. +type FeatureRequirements struct { + // EnabledFeatureGates lists feature gate strings that the feature depends on. + EnabledFeatureGates []string + // RequiredRuntimeFeatures lists runtime capabilities that must be true for the + // feature to be declared. Nil means the feature has no runtime requirements. + RequiredRuntimeFeatures *RuntimeFeatures +} + +// FeatureGate is an interface that abstracts feature gate checking. +type FeatureGate interface { + // Enabled returns true if the named feature gate is enabled. + Enabled(key string) bool +} + +// RuntimeFeatures provides information about CRI runtime-level capabilities. +type RuntimeFeatures struct { + // UserNamespacesHostNetwork indicates if the runtime supports user namespaces with host network. + UserNamespacesHostNetwork bool +} + +// StaticConfiguration provides a view of a node's static configuration required for feature discovery. +type StaticConfiguration struct { + // Add configuration fields here as required by registered features. +} + +// NodeConfiguration provides a generic view of a node's static configuration. +type NodeConfiguration struct { + // FeatureGates holds an implementation of the FeatureGate interface. + FeatureGates FeatureGate + // StaticConfig holds node static configuration. + StaticConfig StaticConfiguration + // Version holds the current node version. This is used for full semantic version comparisons + // with Feature.MaxVersion() to determine if a feature needs to be reported. + Version *version.Version + // RuntimeFeatures holds runtime-level capabilities discovered from CRI. + RuntimeFeatures RuntimeFeatures +} + +// FeatureGateMap is provided as a convenience implementation of FeatureGate +type FeatureGateMap map[string]bool + +func (m FeatureGateMap) Enabled(key string) bool { + return m[key] +} + +var _ FeatureGate = FeatureGateMap{} diff --git a/vendor/k8s.io/component-helpers/resource/helpers.go b/vendor/k8s.io/component-helpers/resource/helpers.go index c8b3c7ece6..23f57a7fca 100644 --- a/vendor/k8s.io/component-helpers/resource/helpers.go +++ b/vendor/k8s.io/component-helpers/resource/helpers.go @@ -60,6 +60,8 @@ type PodResourcesOptions struct { SkipPodLevelResources bool // SkipContainerLevelResources SkipContainerLevelResources bool + // Use node allocatable resource claim information from pod status to compute the effective pod resource request. + UseDRANodeAllocatableResourceClaimStatus bool } var supportedPodLevelResources = sets.New(v1.ResourceCPU, v1.ResourceMemory) @@ -275,6 +277,16 @@ func AggregateContainerRequests(pod *v1.Pod, opts PodResourcesOptions) v1.Resour } maxResourceList(reqs, initContainerReqs) + + // Add resources from node allocatable ResourceClaims + if opts.UseDRANodeAllocatableResourceClaimStatus && len(pod.Status.NodeAllocatableResourceClaimStatuses) > 0 { + for _, claimStatus := range pod.Status.NodeAllocatableResourceClaimStatuses { + for resName, resQty := range claimStatus.Resources { + addResourceList(reqs, v1.ResourceList{resName: resQty}) + } + } + } + return reqs } diff --git a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go index da82429bc5..0b00126fd8 100644 --- a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go +++ b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go @@ -40,6 +40,11 @@ const ( // kep: http://kep.k8s.io/2699 // Enable webhook in cloud controller manager CloudControllerManagerWebhook featuregate.Feature = "CloudControllerManagerWebhook" + + // owner: @jefftree, @tchap + // + // Make kube-controller-manager release leader election lock on exit. + ControllerManagerReleaseLeaderElectionLockOnExit featuregate.Feature = "ControllerManagerReleaseLeaderElectionLockOnExit" ) func SetupCurrentKubernetesSpecificFeatureGates(featuregates featuregate.MutableVersionedFeatureGate) error { @@ -55,4 +60,7 @@ var versionedCloudPublicFeatureGates = map[featuregate.Feature]featuregate.Versi CloudControllerManagerWebhook: { {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha}, }, + ControllerManagerReleaseLeaderElectionLockOnExit: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, } diff --git a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go index ab5bda03a6..5898e8d9c4 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go +++ b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go @@ -1117,7 +1117,7 @@ type Mount struct { // Mount an image reference (image ID, with or without digest), which is a // special use case for image volume mounts. If this field is set, then // host_path should be unset. All image mounts are per feature definition - // readonly (noexec). The kubelet does an PullImage RPC and evaluates the returned + // readonly. The kubelet does an PullImage RPC and evaluates the returned // PullImageResponse.image_ref value, which is then set to the // ImageSpec.image field. Runtimes are expected to mount the image as // required. @@ -3044,6 +3044,96 @@ func (x *ListPodSandboxResponse) GetItems() []*PodSandbox { return nil } +type StreamPodSandboxesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Filter for the list request. + Filter *PodSandboxFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamPodSandboxesRequest) Reset() { + *x = StreamPodSandboxesRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPodSandboxesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPodSandboxesRequest) ProtoMessage() {} + +func (x *StreamPodSandboxesRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPodSandboxesRequest.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxesRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{32} +} + +func (x *StreamPodSandboxesRequest) GetFilter() *PodSandboxFilter { + if x != nil { + return x.Filter + } + return nil +} + +type StreamPodSandboxesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of PodSandboxes. + PodSandboxes []*PodSandbox `protobuf:"bytes,1,rep,name=pod_sandboxes,json=podSandboxes,proto3" json:"pod_sandboxes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamPodSandboxesResponse) Reset() { + *x = StreamPodSandboxesResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPodSandboxesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPodSandboxesResponse) ProtoMessage() {} + +func (x *StreamPodSandboxesResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPodSandboxesResponse.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxesResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{33} +} + +func (x *StreamPodSandboxesResponse) GetPodSandboxes() []*PodSandbox { + if x != nil { + return x.PodSandboxes + } + return nil +} + type PodSandboxStatsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // ID of the pod sandbox for which to retrieve stats. @@ -3054,7 +3144,7 @@ type PodSandboxStatsRequest struct { func (x *PodSandboxStatsRequest) Reset() { *x = PodSandboxStatsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[32] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3066,7 +3156,7 @@ func (x *PodSandboxStatsRequest) String() string { func (*PodSandboxStatsRequest) ProtoMessage() {} func (x *PodSandboxStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[32] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3079,7 +3169,7 @@ func (x *PodSandboxStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxStatsRequest.ProtoReflect.Descriptor instead. func (*PodSandboxStatsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{32} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{34} } func (x *PodSandboxStatsRequest) GetPodSandboxId() string { @@ -3098,7 +3188,7 @@ type PodSandboxStatsResponse struct { func (x *PodSandboxStatsResponse) Reset() { *x = PodSandboxStatsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[33] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3110,7 +3200,7 @@ func (x *PodSandboxStatsResponse) String() string { func (*PodSandboxStatsResponse) ProtoMessage() {} func (x *PodSandboxStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[33] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3123,7 +3213,7 @@ func (x *PodSandboxStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxStatsResponse.ProtoReflect.Descriptor instead. func (*PodSandboxStatsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{33} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{35} } func (x *PodSandboxStatsResponse) GetStats() *PodSandboxStats { @@ -3149,7 +3239,7 @@ type PodSandboxStatsFilter struct { func (x *PodSandboxStatsFilter) Reset() { *x = PodSandboxStatsFilter{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[34] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3161,7 +3251,7 @@ func (x *PodSandboxStatsFilter) String() string { func (*PodSandboxStatsFilter) ProtoMessage() {} func (x *PodSandboxStatsFilter) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[34] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3174,7 +3264,7 @@ func (x *PodSandboxStatsFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxStatsFilter.ProtoReflect.Descriptor instead. func (*PodSandboxStatsFilter) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{34} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{36} } func (x *PodSandboxStatsFilter) GetId() string { @@ -3201,7 +3291,7 @@ type ListPodSandboxStatsRequest struct { func (x *ListPodSandboxStatsRequest) Reset() { *x = ListPodSandboxStatsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[35] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3213,7 +3303,7 @@ func (x *ListPodSandboxStatsRequest) String() string { func (*ListPodSandboxStatsRequest) ProtoMessage() {} func (x *ListPodSandboxStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[35] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3226,7 +3316,7 @@ func (x *ListPodSandboxStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPodSandboxStatsRequest.ProtoReflect.Descriptor instead. func (*ListPodSandboxStatsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{35} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{37} } func (x *ListPodSandboxStatsRequest) GetFilter() *PodSandboxStatsFilter { @@ -3246,7 +3336,7 @@ type ListPodSandboxStatsResponse struct { func (x *ListPodSandboxStatsResponse) Reset() { *x = ListPodSandboxStatsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[36] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3258,7 +3348,7 @@ func (x *ListPodSandboxStatsResponse) String() string { func (*ListPodSandboxStatsResponse) ProtoMessage() {} func (x *ListPodSandboxStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[36] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3271,7 +3361,7 @@ func (x *ListPodSandboxStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPodSandboxStatsResponse.ProtoReflect.Descriptor instead. func (*ListPodSandboxStatsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{36} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{38} } func (x *ListPodSandboxStatsResponse) GetStats() []*PodSandboxStats { @@ -3281,6 +3371,96 @@ func (x *ListPodSandboxStatsResponse) GetStats() []*PodSandboxStats { return nil } +type StreamPodSandboxStatsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Filter for the list request. + Filter *PodSandboxStatsFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamPodSandboxStatsRequest) Reset() { + *x = StreamPodSandboxStatsRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPodSandboxStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPodSandboxStatsRequest) ProtoMessage() {} + +func (x *StreamPodSandboxStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPodSandboxStatsRequest.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxStatsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{39} +} + +func (x *StreamPodSandboxStatsRequest) GetFilter() *PodSandboxStatsFilter { + if x != nil { + return x.Filter + } + return nil +} + +type StreamPodSandboxStatsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of pod sandbox stats. + PodSandboxStats []*PodSandboxStats `protobuf:"bytes,1,rep,name=pod_sandbox_stats,json=podSandboxStats,proto3" json:"pod_sandbox_stats,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamPodSandboxStatsResponse) Reset() { + *x = StreamPodSandboxStatsResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPodSandboxStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPodSandboxStatsResponse) ProtoMessage() {} + +func (x *StreamPodSandboxStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPodSandboxStatsResponse.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxStatsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{40} +} + +func (x *StreamPodSandboxStatsResponse) GetPodSandboxStats() []*PodSandboxStats { + if x != nil { + return x.PodSandboxStats + } + return nil +} + // PodSandboxAttributes provides basic information of the pod sandbox. type PodSandboxAttributes struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -3301,7 +3481,7 @@ type PodSandboxAttributes struct { func (x *PodSandboxAttributes) Reset() { *x = PodSandboxAttributes{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[37] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3313,7 +3493,7 @@ func (x *PodSandboxAttributes) String() string { func (*PodSandboxAttributes) ProtoMessage() {} func (x *PodSandboxAttributes) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[37] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3326,7 +3506,7 @@ func (x *PodSandboxAttributes) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxAttributes.ProtoReflect.Descriptor instead. func (*PodSandboxAttributes) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{37} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{41} } func (x *PodSandboxAttributes) GetId() string { @@ -3373,7 +3553,7 @@ type PodSandboxStats struct { func (x *PodSandboxStats) Reset() { *x = PodSandboxStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[38] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3385,7 +3565,7 @@ func (x *PodSandboxStats) String() string { func (*PodSandboxStats) ProtoMessage() {} func (x *PodSandboxStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[38] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3398,7 +3578,7 @@ func (x *PodSandboxStats) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxStats.ProtoReflect.Descriptor instead. func (*PodSandboxStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{38} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{42} } func (x *PodSandboxStats) GetAttributes() *PodSandboxAttributes { @@ -3443,7 +3623,7 @@ type LinuxPodSandboxStats struct { func (x *LinuxPodSandboxStats) Reset() { *x = LinuxPodSandboxStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[39] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3455,7 +3635,7 @@ func (x *LinuxPodSandboxStats) String() string { func (*LinuxPodSandboxStats) ProtoMessage() {} func (x *LinuxPodSandboxStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[39] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3468,7 +3648,7 @@ func (x *LinuxPodSandboxStats) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxPodSandboxStats.ProtoReflect.Descriptor instead. func (*LinuxPodSandboxStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{39} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{43} } func (x *LinuxPodSandboxStats) GetCpu() *CpuUsage { @@ -3532,7 +3712,7 @@ type WindowsPodSandboxStats struct { func (x *WindowsPodSandboxStats) Reset() { *x = WindowsPodSandboxStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[40] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3544,7 +3724,7 @@ func (x *WindowsPodSandboxStats) String() string { func (*WindowsPodSandboxStats) ProtoMessage() {} func (x *WindowsPodSandboxStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[40] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3557,7 +3737,7 @@ func (x *WindowsPodSandboxStats) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsPodSandboxStats.ProtoReflect.Descriptor instead. func (*WindowsPodSandboxStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{40} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{44} } func (x *WindowsPodSandboxStats) GetCpu() *WindowsCpuUsage { @@ -3610,7 +3790,7 @@ type NetworkUsage struct { func (x *NetworkUsage) Reset() { *x = NetworkUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[41] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3622,7 +3802,7 @@ func (x *NetworkUsage) String() string { func (*NetworkUsage) ProtoMessage() {} func (x *NetworkUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[41] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3635,7 +3815,7 @@ func (x *NetworkUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkUsage.ProtoReflect.Descriptor instead. func (*NetworkUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{41} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{45} } func (x *NetworkUsage) GetTimestamp() int64 { @@ -3674,7 +3854,7 @@ type WindowsNetworkUsage struct { func (x *WindowsNetworkUsage) Reset() { *x = WindowsNetworkUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[42] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3686,7 +3866,7 @@ func (x *WindowsNetworkUsage) String() string { func (*WindowsNetworkUsage) ProtoMessage() {} func (x *WindowsNetworkUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[42] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3699,7 +3879,7 @@ func (x *WindowsNetworkUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsNetworkUsage.ProtoReflect.Descriptor instead. func (*WindowsNetworkUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{42} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{46} } func (x *WindowsNetworkUsage) GetTimestamp() int64 { @@ -3742,7 +3922,7 @@ type NetworkInterfaceUsage struct { func (x *NetworkInterfaceUsage) Reset() { *x = NetworkInterfaceUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[43] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3754,7 +3934,7 @@ func (x *NetworkInterfaceUsage) String() string { func (*NetworkInterfaceUsage) ProtoMessage() {} func (x *NetworkInterfaceUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[43] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3767,7 +3947,7 @@ func (x *NetworkInterfaceUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkInterfaceUsage.ProtoReflect.Descriptor instead. func (*NetworkInterfaceUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{43} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{47} } func (x *NetworkInterfaceUsage) GetName() string { @@ -3824,7 +4004,7 @@ type WindowsNetworkInterfaceUsage struct { func (x *WindowsNetworkInterfaceUsage) Reset() { *x = WindowsNetworkInterfaceUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[44] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3836,7 +4016,7 @@ func (x *WindowsNetworkInterfaceUsage) String() string { func (*WindowsNetworkInterfaceUsage) ProtoMessage() {} func (x *WindowsNetworkInterfaceUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[44] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3849,7 +4029,7 @@ func (x *WindowsNetworkInterfaceUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsNetworkInterfaceUsage.ProtoReflect.Descriptor instead. func (*WindowsNetworkInterfaceUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{44} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{48} } func (x *WindowsNetworkInterfaceUsage) GetName() string { @@ -3900,7 +4080,7 @@ type ProcessUsage struct { func (x *ProcessUsage) Reset() { *x = ProcessUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[45] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3912,7 +4092,7 @@ func (x *ProcessUsage) String() string { func (*ProcessUsage) ProtoMessage() {} func (x *ProcessUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[45] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3925,7 +4105,7 @@ func (x *ProcessUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use ProcessUsage.ProtoReflect.Descriptor instead. func (*ProcessUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{45} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{49} } func (x *ProcessUsage) GetTimestamp() int64 { @@ -3955,7 +4135,7 @@ type WindowsProcessUsage struct { func (x *WindowsProcessUsage) Reset() { *x = WindowsProcessUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[46] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3967,7 +4147,7 @@ func (x *WindowsProcessUsage) String() string { func (*WindowsProcessUsage) ProtoMessage() {} func (x *WindowsProcessUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[46] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3980,7 +4160,7 @@ func (x *WindowsProcessUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsProcessUsage.ProtoReflect.Descriptor instead. func (*WindowsProcessUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{46} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{50} } func (x *WindowsProcessUsage) GetTimestamp() int64 { @@ -4013,13 +4193,16 @@ type ImageSpec struct { // If the runtime handler is unknown, the request should be rejected. // An empty string would select the default runtime handler. RuntimeHandler string `protobuf:"bytes,19,opt,name=runtime_handler,json=runtimeHandler,proto3" json:"runtime_handler,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // The digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + ImageRef string `protobuf:"bytes,20,opt,name=image_ref,json=imageRef,proto3" json:"image_ref,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ImageSpec) Reset() { *x = ImageSpec{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[47] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4031,7 +4214,7 @@ func (x *ImageSpec) String() string { func (*ImageSpec) ProtoMessage() {} func (x *ImageSpec) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[47] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4044,7 +4227,7 @@ func (x *ImageSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageSpec.ProtoReflect.Descriptor instead. func (*ImageSpec) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{47} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{51} } func (x *ImageSpec) GetImage() string { @@ -4075,17 +4258,24 @@ func (x *ImageSpec) GetRuntimeHandler() string { return "" } +func (x *ImageSpec) GetImageRef() string { + if x != nil { + return x.ImageRef + } + return "" +} + type KeyValue struct { state protoimpl.MessageState `protogen:"open.v1"` Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *KeyValue) Reset() { *x = KeyValue{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[48] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4097,7 +4287,7 @@ func (x *KeyValue) String() string { func (*KeyValue) ProtoMessage() {} func (x *KeyValue) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[48] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4110,7 +4300,7 @@ func (x *KeyValue) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyValue.ProtoReflect.Descriptor instead. func (*KeyValue) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{48} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{52} } func (x *KeyValue) GetKey() string { @@ -4120,11 +4310,11 @@ func (x *KeyValue) GetKey() string { return "" } -func (x *KeyValue) GetValue() string { +func (x *KeyValue) GetValue() []byte { if x != nil { return x.Value } - return "" + return nil } // LinuxContainerResources specifies Linux specific configuration for @@ -4159,7 +4349,7 @@ type LinuxContainerResources struct { func (x *LinuxContainerResources) Reset() { *x = LinuxContainerResources{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[49] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4171,7 +4361,7 @@ func (x *LinuxContainerResources) String() string { func (*LinuxContainerResources) ProtoMessage() {} func (x *LinuxContainerResources) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[49] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4184,7 +4374,7 @@ func (x *LinuxContainerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxContainerResources.ProtoReflect.Descriptor instead. func (*LinuxContainerResources) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{49} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{53} } func (x *LinuxContainerResources) GetCpuPeriod() int64 { @@ -4273,7 +4463,7 @@ type HugepageLimit struct { func (x *HugepageLimit) Reset() { *x = HugepageLimit{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[50] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4285,7 +4475,7 @@ func (x *HugepageLimit) String() string { func (*HugepageLimit) ProtoMessage() {} func (x *HugepageLimit) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[50] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4298,7 +4488,7 @@ func (x *HugepageLimit) ProtoReflect() protoreflect.Message { // Deprecated: Use HugepageLimit.ProtoReflect.Descriptor instead. func (*HugepageLimit) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{50} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{54} } func (x *HugepageLimit) GetPageSize() string { @@ -4328,7 +4518,7 @@ type SELinuxOption struct { func (x *SELinuxOption) Reset() { *x = SELinuxOption{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[51] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4340,7 +4530,7 @@ func (x *SELinuxOption) String() string { func (*SELinuxOption) ProtoMessage() {} func (x *SELinuxOption) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[51] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4353,7 +4543,7 @@ func (x *SELinuxOption) ProtoReflect() protoreflect.Message { // Deprecated: Use SELinuxOption.ProtoReflect.Descriptor instead. func (*SELinuxOption) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{51} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{55} } func (x *SELinuxOption) GetUser() string { @@ -4406,7 +4596,7 @@ type Capability struct { func (x *Capability) Reset() { *x = Capability{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[52] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4418,7 +4608,7 @@ func (x *Capability) String() string { func (*Capability) ProtoMessage() {} func (x *Capability) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[52] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4431,7 +4621,7 @@ func (x *Capability) ProtoReflect() protoreflect.Message { // Deprecated: Use Capability.ProtoReflect.Descriptor instead. func (*Capability) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{52} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{56} } func (x *Capability) GetAddCapabilities() []string { @@ -4542,7 +4732,7 @@ type LinuxContainerSecurityContext struct { func (x *LinuxContainerSecurityContext) Reset() { *x = LinuxContainerSecurityContext{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[53] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4554,7 +4744,7 @@ func (x *LinuxContainerSecurityContext) String() string { func (*LinuxContainerSecurityContext) ProtoMessage() {} func (x *LinuxContainerSecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[53] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4567,7 +4757,7 @@ func (x *LinuxContainerSecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxContainerSecurityContext.ProtoReflect.Descriptor instead. func (*LinuxContainerSecurityContext) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{53} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{57} } func (x *LinuxContainerSecurityContext) GetCapabilities() *Capability { @@ -4705,7 +4895,7 @@ type LinuxContainerConfig struct { func (x *LinuxContainerConfig) Reset() { *x = LinuxContainerConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[54] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4717,7 +4907,7 @@ func (x *LinuxContainerConfig) String() string { func (*LinuxContainerConfig) ProtoMessage() {} func (x *LinuxContainerConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[54] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4730,7 +4920,7 @@ func (x *LinuxContainerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxContainerConfig.ProtoReflect.Descriptor instead. func (*LinuxContainerConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{54} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{58} } func (x *LinuxContainerConfig) GetResources() *LinuxContainerResources { @@ -4761,7 +4951,7 @@ type LinuxContainerUser struct { func (x *LinuxContainerUser) Reset() { *x = LinuxContainerUser{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[55] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4773,7 +4963,7 @@ func (x *LinuxContainerUser) String() string { func (*LinuxContainerUser) ProtoMessage() {} func (x *LinuxContainerUser) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[55] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4786,7 +4976,7 @@ func (x *LinuxContainerUser) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxContainerUser.ProtoReflect.Descriptor instead. func (*LinuxContainerUser) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{55} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{59} } func (x *LinuxContainerUser) GetUid() int64 { @@ -4822,7 +5012,7 @@ type WindowsNamespaceOption struct { func (x *WindowsNamespaceOption) Reset() { *x = WindowsNamespaceOption{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[56] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4834,7 +5024,7 @@ func (x *WindowsNamespaceOption) String() string { func (*WindowsNamespaceOption) ProtoMessage() {} func (x *WindowsNamespaceOption) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[56] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4847,7 +5037,7 @@ func (x *WindowsNamespaceOption) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsNamespaceOption.ProtoReflect.Descriptor instead. func (*WindowsNamespaceOption) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{56} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{60} } func (x *WindowsNamespaceOption) GetNetwork() NamespaceMode { @@ -4878,7 +5068,7 @@ type WindowsSandboxSecurityContext struct { func (x *WindowsSandboxSecurityContext) Reset() { *x = WindowsSandboxSecurityContext{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[57] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4890,7 +5080,7 @@ func (x *WindowsSandboxSecurityContext) String() string { func (*WindowsSandboxSecurityContext) ProtoMessage() {} func (x *WindowsSandboxSecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[57] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4903,7 +5093,7 @@ func (x *WindowsSandboxSecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsSandboxSecurityContext.ProtoReflect.Descriptor instead. func (*WindowsSandboxSecurityContext) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{57} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{61} } func (x *WindowsSandboxSecurityContext) GetRunAsUsername() string { @@ -4946,7 +5136,7 @@ type WindowsPodSandboxConfig struct { func (x *WindowsPodSandboxConfig) Reset() { *x = WindowsPodSandboxConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[58] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4958,7 +5148,7 @@ func (x *WindowsPodSandboxConfig) String() string { func (*WindowsPodSandboxConfig) ProtoMessage() {} func (x *WindowsPodSandboxConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[58] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4971,7 +5161,7 @@ func (x *WindowsPodSandboxConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsPodSandboxConfig.ProtoReflect.Descriptor instead. func (*WindowsPodSandboxConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{58} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{62} } func (x *WindowsPodSandboxConfig) GetSecurityContext() *WindowsSandboxSecurityContext { @@ -4998,7 +5188,7 @@ type WindowsContainerSecurityContext struct { func (x *WindowsContainerSecurityContext) Reset() { *x = WindowsContainerSecurityContext{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[59] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5010,7 +5200,7 @@ func (x *WindowsContainerSecurityContext) String() string { func (*WindowsContainerSecurityContext) ProtoMessage() {} func (x *WindowsContainerSecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[59] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5023,7 +5213,7 @@ func (x *WindowsContainerSecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsContainerSecurityContext.ProtoReflect.Descriptor instead. func (*WindowsContainerSecurityContext) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{59} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{63} } func (x *WindowsContainerSecurityContext) GetRunAsUsername() string { @@ -5061,7 +5251,7 @@ type WindowsContainerConfig struct { func (x *WindowsContainerConfig) Reset() { *x = WindowsContainerConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[60] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5073,7 +5263,7 @@ func (x *WindowsContainerConfig) String() string { func (*WindowsContainerConfig) ProtoMessage() {} func (x *WindowsContainerConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[60] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5086,7 +5276,7 @@ func (x *WindowsContainerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsContainerConfig.ProtoReflect.Descriptor instead. func (*WindowsContainerConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{60} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{64} } func (x *WindowsContainerConfig) GetResources() *WindowsContainerResources { @@ -5125,7 +5315,7 @@ type WindowsContainerResources struct { func (x *WindowsContainerResources) Reset() { *x = WindowsContainerResources{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[61] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5137,7 +5327,7 @@ func (x *WindowsContainerResources) String() string { func (*WindowsContainerResources) ProtoMessage() {} func (x *WindowsContainerResources) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[61] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5150,7 +5340,7 @@ func (x *WindowsContainerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsContainerResources.ProtoReflect.Descriptor instead. func (*WindowsContainerResources) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{61} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{65} } func (x *WindowsContainerResources) GetCpuShares() int64 { @@ -5211,7 +5401,7 @@ type WindowsCpuGroupAffinity struct { func (x *WindowsCpuGroupAffinity) Reset() { *x = WindowsCpuGroupAffinity{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[62] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5223,7 +5413,7 @@ func (x *WindowsCpuGroupAffinity) String() string { func (*WindowsCpuGroupAffinity) ProtoMessage() {} func (x *WindowsCpuGroupAffinity) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[62] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5236,7 +5426,7 @@ func (x *WindowsCpuGroupAffinity) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsCpuGroupAffinity.ProtoReflect.Descriptor instead. func (*WindowsCpuGroupAffinity) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{62} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{66} } func (x *WindowsCpuGroupAffinity) GetCpuMask() uint64 { @@ -5270,7 +5460,7 @@ type ContainerMetadata struct { func (x *ContainerMetadata) Reset() { *x = ContainerMetadata{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[63] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5282,7 +5472,7 @@ func (x *ContainerMetadata) String() string { func (*ContainerMetadata) ProtoMessage() {} func (x *ContainerMetadata) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[63] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5295,7 +5485,7 @@ func (x *ContainerMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerMetadata.ProtoReflect.Descriptor instead. func (*ContainerMetadata) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{63} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{67} } func (x *ContainerMetadata) GetName() string { @@ -5330,7 +5520,7 @@ type Device struct { func (x *Device) Reset() { *x = Device{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[64] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5342,7 +5532,7 @@ func (x *Device) String() string { func (*Device) ProtoMessage() {} func (x *Device) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[64] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5355,7 +5545,7 @@ func (x *Device) ProtoReflect() protoreflect.Message { // Deprecated: Use Device.ProtoReflect.Descriptor instead. func (*Device) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{64} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{68} } func (x *Device) GetContainerPath() string { @@ -5393,7 +5583,7 @@ type CDIDevice struct { func (x *CDIDevice) Reset() { *x = CDIDevice{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[65] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5405,7 +5595,7 @@ func (x *CDIDevice) String() string { func (*CDIDevice) ProtoMessage() {} func (x *CDIDevice) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[65] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5418,7 +5608,7 @@ func (x *CDIDevice) ProtoReflect() protoreflect.Message { // Deprecated: Use CDIDevice.ProtoReflect.Descriptor instead. func (*CDIDevice) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{65} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{69} } func (x *CDIDevice) GetName() string { @@ -5496,7 +5686,7 @@ type ContainerConfig struct { func (x *ContainerConfig) Reset() { *x = ContainerConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[66] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5508,7 +5698,7 @@ func (x *ContainerConfig) String() string { func (*ContainerConfig) ProtoMessage() {} func (x *ContainerConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[66] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5521,7 +5711,7 @@ func (x *ContainerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerConfig.ProtoReflect.Descriptor instead. func (*ContainerConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{66} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{70} } func (x *ContainerConfig) GetMetadata() *ContainerMetadata { @@ -5667,7 +5857,7 @@ type CreateContainerRequest struct { func (x *CreateContainerRequest) Reset() { *x = CreateContainerRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[67] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5679,7 +5869,7 @@ func (x *CreateContainerRequest) String() string { func (*CreateContainerRequest) ProtoMessage() {} func (x *CreateContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[67] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5692,7 +5882,7 @@ func (x *CreateContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateContainerRequest.ProtoReflect.Descriptor instead. func (*CreateContainerRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{67} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{71} } func (x *CreateContainerRequest) GetPodSandboxId() string { @@ -5726,7 +5916,7 @@ type CreateContainerResponse struct { func (x *CreateContainerResponse) Reset() { *x = CreateContainerResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[68] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5738,7 +5928,7 @@ func (x *CreateContainerResponse) String() string { func (*CreateContainerResponse) ProtoMessage() {} func (x *CreateContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[68] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5751,7 +5941,7 @@ func (x *CreateContainerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateContainerResponse.ProtoReflect.Descriptor instead. func (*CreateContainerResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{68} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{72} } func (x *CreateContainerResponse) GetContainerId() string { @@ -5771,7 +5961,7 @@ type StartContainerRequest struct { func (x *StartContainerRequest) Reset() { *x = StartContainerRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[69] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5783,7 +5973,7 @@ func (x *StartContainerRequest) String() string { func (*StartContainerRequest) ProtoMessage() {} func (x *StartContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[69] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5796,7 +5986,7 @@ func (x *StartContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartContainerRequest.ProtoReflect.Descriptor instead. func (*StartContainerRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{69} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{73} } func (x *StartContainerRequest) GetContainerId() string { @@ -5814,7 +6004,7 @@ type StartContainerResponse struct { func (x *StartContainerResponse) Reset() { *x = StartContainerResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[70] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5826,7 +6016,7 @@ func (x *StartContainerResponse) String() string { func (*StartContainerResponse) ProtoMessage() {} func (x *StartContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[70] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5839,7 +6029,7 @@ func (x *StartContainerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StartContainerResponse.ProtoReflect.Descriptor instead. func (*StartContainerResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{70} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{74} } type StopContainerRequest struct { @@ -5855,7 +6045,7 @@ type StopContainerRequest struct { func (x *StopContainerRequest) Reset() { *x = StopContainerRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[71] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5867,7 +6057,7 @@ func (x *StopContainerRequest) String() string { func (*StopContainerRequest) ProtoMessage() {} func (x *StopContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[71] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5880,7 +6070,7 @@ func (x *StopContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StopContainerRequest.ProtoReflect.Descriptor instead. func (*StopContainerRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{71} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{75} } func (x *StopContainerRequest) GetContainerId() string { @@ -5905,7 +6095,7 @@ type StopContainerResponse struct { func (x *StopContainerResponse) Reset() { *x = StopContainerResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[72] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5917,7 +6107,7 @@ func (x *StopContainerResponse) String() string { func (*StopContainerResponse) ProtoMessage() {} func (x *StopContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[72] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5930,7 +6120,7 @@ func (x *StopContainerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StopContainerResponse.ProtoReflect.Descriptor instead. func (*StopContainerResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{72} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{76} } type RemoveContainerRequest struct { @@ -5943,7 +6133,7 @@ type RemoveContainerRequest struct { func (x *RemoveContainerRequest) Reset() { *x = RemoveContainerRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[73] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5955,7 +6145,7 @@ func (x *RemoveContainerRequest) String() string { func (*RemoveContainerRequest) ProtoMessage() {} func (x *RemoveContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[73] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5968,7 +6158,7 @@ func (x *RemoveContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveContainerRequest.ProtoReflect.Descriptor instead. func (*RemoveContainerRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{73} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{77} } func (x *RemoveContainerRequest) GetContainerId() string { @@ -5986,7 +6176,7 @@ type RemoveContainerResponse struct { func (x *RemoveContainerResponse) Reset() { *x = RemoveContainerResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[74] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5998,7 +6188,7 @@ func (x *RemoveContainerResponse) String() string { func (*RemoveContainerResponse) ProtoMessage() {} func (x *RemoveContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[74] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6011,7 +6201,7 @@ func (x *RemoveContainerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveContainerResponse.ProtoReflect.Descriptor instead. func (*RemoveContainerResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{74} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{78} } // ContainerStateValue is the wrapper of ContainerState. @@ -6025,7 +6215,7 @@ type ContainerStateValue struct { func (x *ContainerStateValue) Reset() { *x = ContainerStateValue{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[75] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6037,7 +6227,7 @@ func (x *ContainerStateValue) String() string { func (*ContainerStateValue) ProtoMessage() {} func (x *ContainerStateValue) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[75] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6050,7 +6240,7 @@ func (x *ContainerStateValue) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStateValue.ProtoReflect.Descriptor instead. func (*ContainerStateValue) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{75} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{79} } func (x *ContainerStateValue) GetState() ContainerState { @@ -6080,7 +6270,7 @@ type ContainerFilter struct { func (x *ContainerFilter) Reset() { *x = ContainerFilter{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[76] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6092,7 +6282,7 @@ func (x *ContainerFilter) String() string { func (*ContainerFilter) ProtoMessage() {} func (x *ContainerFilter) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[76] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6105,7 +6295,7 @@ func (x *ContainerFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerFilter.ProtoReflect.Descriptor instead. func (*ContainerFilter) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{76} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{80} } func (x *ContainerFilter) GetId() string { @@ -6145,7 +6335,7 @@ type ListContainersRequest struct { func (x *ListContainersRequest) Reset() { *x = ListContainersRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[77] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6157,7 +6347,7 @@ func (x *ListContainersRequest) String() string { func (*ListContainersRequest) ProtoMessage() {} func (x *ListContainersRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[77] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6170,7 +6360,7 @@ func (x *ListContainersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListContainersRequest.ProtoReflect.Descriptor instead. func (*ListContainersRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{77} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{81} } func (x *ListContainersRequest) GetFilter() *ContainerFilter { @@ -6206,15 +6396,11 @@ type Container struct { // MUST be identical to that of the corresponding ContainerConfig used to // instantiate this Container. Annotations map[string]string `protobuf:"bytes,9,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - // Reference to the unique identifier of the image, on the node, as - // returned in the image service apis. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. // - // Note: The image_ref above has been historically used by container - // runtimes to reference images by digest. The image_ref has been also used - // in the kubelet image garbage collection, which does not work with - // digests at all. To separate and avoid possible misusage, we now - // introduce the image_id field, which should always refer to a unique - // image identifier on the node. + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. ImageId string `protobuf:"bytes,10,opt,name=image_id,json=imageId,proto3" json:"image_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -6222,7 +6408,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[78] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6234,7 +6420,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[78] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6247,7 +6433,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{78} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{82} } func (x *Container) GetId() string { @@ -6285,42 +6471,132 @@ func (x *Container) GetImageRef() string { return "" } -func (x *Container) GetState() ContainerState { - if x != nil { - return x.State - } - return ContainerState_CONTAINER_CREATED +func (x *Container) GetState() ContainerState { + if x != nil { + return x.State + } + return ContainerState_CONTAINER_CREATED +} + +func (x *Container) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *Container) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Container) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Container) GetImageId() string { + if x != nil { + return x.ImageId + } + return "" +} + +type ListContainersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of containers. + Containers []*Container `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListContainersResponse) Reset() { + *x = ListContainersResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListContainersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListContainersResponse) ProtoMessage() {} + +func (x *ListContainersResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[83] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListContainersResponse.ProtoReflect.Descriptor instead. +func (*ListContainersResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{83} +} + +func (x *ListContainersResponse) GetContainers() []*Container { + if x != nil { + return x.Containers + } + return nil +} + +type StreamContainersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Filter for the list request. + Filter *ContainerFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamContainersRequest) Reset() { + *x = StreamContainersRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamContainersRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *Container) GetCreatedAt() int64 { - if x != nil { - return x.CreatedAt - } - return 0 -} +func (*StreamContainersRequest) ProtoMessage() {} -func (x *Container) GetLabels() map[string]string { +func (x *StreamContainersRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[84] if x != nil { - return x.Labels + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *Container) GetAnnotations() map[string]string { - if x != nil { - return x.Annotations - } - return nil +// Deprecated: Use StreamContainersRequest.ProtoReflect.Descriptor instead. +func (*StreamContainersRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{84} } -func (x *Container) GetImageId() string { +func (x *StreamContainersRequest) GetFilter() *ContainerFilter { if x != nil { - return x.ImageId + return x.Filter } - return "" + return nil } -type ListContainersResponse struct { +type StreamContainersResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // List of containers. Containers []*Container `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` @@ -6328,21 +6604,21 @@ type ListContainersResponse struct { sizeCache protoimpl.SizeCache } -func (x *ListContainersResponse) Reset() { - *x = ListContainersResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[79] +func (x *StreamContainersResponse) Reset() { + *x = StreamContainersResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListContainersResponse) String() string { +func (x *StreamContainersResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListContainersResponse) ProtoMessage() {} +func (*StreamContainersResponse) ProtoMessage() {} -func (x *ListContainersResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[79] +func (x *StreamContainersResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6353,12 +6629,12 @@ func (x *ListContainersResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListContainersResponse.ProtoReflect.Descriptor instead. -func (*ListContainersResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{79} +// Deprecated: Use StreamContainersResponse.ProtoReflect.Descriptor instead. +func (*StreamContainersResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{85} } -func (x *ListContainersResponse) GetContainers() []*Container { +func (x *StreamContainersResponse) GetContainers() []*Container { if x != nil { return x.Containers } @@ -6377,7 +6653,7 @@ type ContainerStatusRequest struct { func (x *ContainerStatusRequest) Reset() { *x = ContainerStatusRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[80] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6389,7 +6665,7 @@ func (x *ContainerStatusRequest) String() string { func (*ContainerStatusRequest) ProtoMessage() {} func (x *ContainerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[80] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6402,7 +6678,7 @@ func (x *ContainerStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStatusRequest.ProtoReflect.Descriptor instead. func (*ContainerStatusRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{80} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{86} } func (x *ContainerStatusRequest) GetContainerId() string { @@ -6459,13 +6735,11 @@ type ContainerStatus struct { LogPath string `protobuf:"bytes,15,opt,name=log_path,json=logPath,proto3" json:"log_path,omitempty"` // Resource limits configuration of the container. Resources *ContainerResources `protobuf:"bytes,16,opt,name=resources,proto3" json:"resources,omitempty"` - // Reference to the unique identifier of the image, on the node, as - // returned in the image service apis. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. // - // Note: The image_ref above has been historically used by container - // runtimes to reference images by digest. To separate and avoid possible - // misusage, we now introduce the image_id field, which should always refer - // to a unique image identifier on the node. + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. ImageId string `protobuf:"bytes,17,opt,name=image_id,json=imageId,proto3" json:"image_id,omitempty"` // User identities initially attached to the container User *ContainerUser `protobuf:"bytes,18,opt,name=user,proto3" json:"user,omitempty"` @@ -6477,7 +6751,7 @@ type ContainerStatus struct { func (x *ContainerStatus) Reset() { *x = ContainerStatus{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[81] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6489,7 +6763,7 @@ func (x *ContainerStatus) String() string { func (*ContainerStatus) ProtoMessage() {} func (x *ContainerStatus) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[81] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6502,7 +6776,7 @@ func (x *ContainerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStatus.ProtoReflect.Descriptor instead. func (*ContainerStatus) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{81} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{87} } func (x *ContainerStatus) GetId() string { @@ -6653,7 +6927,7 @@ type ContainerStatusResponse struct { func (x *ContainerStatusResponse) Reset() { *x = ContainerStatusResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[82] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6665,7 +6939,7 @@ func (x *ContainerStatusResponse) String() string { func (*ContainerStatusResponse) ProtoMessage() {} func (x *ContainerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[82] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6678,7 +6952,7 @@ func (x *ContainerStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStatusResponse.ProtoReflect.Descriptor instead. func (*ContainerStatusResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{82} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{88} } func (x *ContainerStatusResponse) GetStatus() *ContainerStatus { @@ -6708,7 +6982,7 @@ type ContainerResources struct { func (x *ContainerResources) Reset() { *x = ContainerResources{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[83] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6720,7 +6994,7 @@ func (x *ContainerResources) String() string { func (*ContainerResources) ProtoMessage() {} func (x *ContainerResources) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[83] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6733,7 +7007,7 @@ func (x *ContainerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerResources.ProtoReflect.Descriptor instead. func (*ContainerResources) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{83} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{89} } func (x *ContainerResources) GetLinux() *LinuxContainerResources { @@ -6761,7 +7035,7 @@ type ContainerUser struct { func (x *ContainerUser) Reset() { *x = ContainerUser{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[84] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6773,7 +7047,7 @@ func (x *ContainerUser) String() string { func (*ContainerUser) ProtoMessage() {} func (x *ContainerUser) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[84] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6786,7 +7060,7 @@ func (x *ContainerUser) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerUser.ProtoReflect.Descriptor instead. func (*ContainerUser) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{84} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{90} } func (x *ContainerUser) GetLinux() *LinuxContainerUser { @@ -6814,7 +7088,7 @@ type UpdateContainerResourcesRequest struct { func (x *UpdateContainerResourcesRequest) Reset() { *x = UpdateContainerResourcesRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[85] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6826,7 +7100,7 @@ func (x *UpdateContainerResourcesRequest) String() string { func (*UpdateContainerResourcesRequest) ProtoMessage() {} func (x *UpdateContainerResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[85] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6839,7 +7113,7 @@ func (x *UpdateContainerResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateContainerResourcesRequest.ProtoReflect.Descriptor instead. func (*UpdateContainerResourcesRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{85} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{91} } func (x *UpdateContainerResourcesRequest) GetContainerId() string { @@ -6878,7 +7152,7 @@ type UpdateContainerResourcesResponse struct { func (x *UpdateContainerResourcesResponse) Reset() { *x = UpdateContainerResourcesResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[86] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6890,7 +7164,7 @@ func (x *UpdateContainerResourcesResponse) String() string { func (*UpdateContainerResourcesResponse) ProtoMessage() {} func (x *UpdateContainerResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[86] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6903,7 +7177,7 @@ func (x *UpdateContainerResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateContainerResourcesResponse.ProtoReflect.Descriptor instead. func (*UpdateContainerResourcesResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{86} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{92} } type ExecSyncRequest struct { @@ -6920,7 +7194,7 @@ type ExecSyncRequest struct { func (x *ExecSyncRequest) Reset() { *x = ExecSyncRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[87] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6932,7 +7206,7 @@ func (x *ExecSyncRequest) String() string { func (*ExecSyncRequest) ProtoMessage() {} func (x *ExecSyncRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[87] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6945,7 +7219,7 @@ func (x *ExecSyncRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSyncRequest.ProtoReflect.Descriptor instead. func (*ExecSyncRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{87} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{93} } func (x *ExecSyncRequest) GetContainerId() string { @@ -6991,7 +7265,7 @@ type ExecSyncResponse struct { func (x *ExecSyncResponse) Reset() { *x = ExecSyncResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[88] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7003,7 +7277,7 @@ func (x *ExecSyncResponse) String() string { func (*ExecSyncResponse) ProtoMessage() {} func (x *ExecSyncResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[88] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7016,7 +7290,7 @@ func (x *ExecSyncResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSyncResponse.ProtoReflect.Descriptor instead. func (*ExecSyncResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{88} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{94} } func (x *ExecSyncResponse) GetStdout() []byte { @@ -7066,7 +7340,7 @@ type ExecRequest struct { func (x *ExecRequest) Reset() { *x = ExecRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[89] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7078,7 +7352,7 @@ func (x *ExecRequest) String() string { func (*ExecRequest) ProtoMessage() {} func (x *ExecRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[89] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7091,7 +7365,7 @@ func (x *ExecRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecRequest.ProtoReflect.Descriptor instead. func (*ExecRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{89} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{95} } func (x *ExecRequest) GetContainerId() string { @@ -7146,7 +7420,7 @@ type ExecResponse struct { func (x *ExecResponse) Reset() { *x = ExecResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[90] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7158,7 +7432,7 @@ func (x *ExecResponse) String() string { func (*ExecResponse) ProtoMessage() {} func (x *ExecResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[90] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7171,7 +7445,7 @@ func (x *ExecResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecResponse.ProtoReflect.Descriptor instead. func (*ExecResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{90} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{96} } func (x *ExecResponse) GetUrl() string { @@ -7206,7 +7480,7 @@ type AttachRequest struct { func (x *AttachRequest) Reset() { *x = AttachRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[91] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7218,7 +7492,7 @@ func (x *AttachRequest) String() string { func (*AttachRequest) ProtoMessage() {} func (x *AttachRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[91] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7231,7 +7505,7 @@ func (x *AttachRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachRequest.ProtoReflect.Descriptor instead. func (*AttachRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{91} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{97} } func (x *AttachRequest) GetContainerId() string { @@ -7279,7 +7553,7 @@ type AttachResponse struct { func (x *AttachResponse) Reset() { *x = AttachResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[92] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7291,7 +7565,7 @@ func (x *AttachResponse) String() string { func (*AttachResponse) ProtoMessage() {} func (x *AttachResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[92] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7304,7 +7578,7 @@ func (x *AttachResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachResponse.ProtoReflect.Descriptor instead. func (*AttachResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{92} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{98} } func (x *AttachResponse) GetUrl() string { @@ -7326,7 +7600,7 @@ type PortForwardRequest struct { func (x *PortForwardRequest) Reset() { *x = PortForwardRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[93] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7338,7 +7612,7 @@ func (x *PortForwardRequest) String() string { func (*PortForwardRequest) ProtoMessage() {} func (x *PortForwardRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[93] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7351,7 +7625,7 @@ func (x *PortForwardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PortForwardRequest.ProtoReflect.Descriptor instead. func (*PortForwardRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{93} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{99} } func (x *PortForwardRequest) GetPodSandboxId() string { @@ -7378,7 +7652,7 @@ type PortForwardResponse struct { func (x *PortForwardResponse) Reset() { *x = PortForwardResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[94] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7390,7 +7664,7 @@ func (x *PortForwardResponse) String() string { func (*PortForwardResponse) ProtoMessage() {} func (x *PortForwardResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[94] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7403,7 +7677,7 @@ func (x *PortForwardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PortForwardResponse.ProtoReflect.Descriptor instead. func (*PortForwardResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{94} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{100} } func (x *PortForwardResponse) GetUrl() string { @@ -7423,7 +7697,7 @@ type ImageFilter struct { func (x *ImageFilter) Reset() { *x = ImageFilter{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[95] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7435,7 +7709,7 @@ func (x *ImageFilter) String() string { func (*ImageFilter) ProtoMessage() {} func (x *ImageFilter) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[95] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7448,7 +7722,7 @@ func (x *ImageFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageFilter.ProtoReflect.Descriptor instead. func (*ImageFilter) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{95} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{101} } func (x *ImageFilter) GetImage() *ImageSpec { @@ -7468,7 +7742,7 @@ type ListImagesRequest struct { func (x *ListImagesRequest) Reset() { *x = ListImagesRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[96] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7480,7 +7754,7 @@ func (x *ListImagesRequest) String() string { func (*ListImagesRequest) ProtoMessage() {} func (x *ListImagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[96] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7493,7 +7767,7 @@ func (x *ListImagesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListImagesRequest.ProtoReflect.Descriptor instead. func (*ListImagesRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{96} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{102} } func (x *ListImagesRequest) GetFilter() *ImageFilter { @@ -7506,7 +7780,11 @@ func (x *ListImagesRequest) GetFilter() *ImageFilter { // Basic information about a container image. type Image struct { state protoimpl.MessageState `protogen:"open.v1"` - // ID of the image. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. + // + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Other names by which this image is known. RepoTags []string `protobuf:"bytes,2,rep,name=repo_tags,json=repoTags,proto3" json:"repo_tags,omitempty"` @@ -7533,7 +7811,7 @@ type Image struct { func (x *Image) Reset() { *x = Image{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[97] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7545,7 +7823,7 @@ func (x *Image) String() string { func (*Image) ProtoMessage() {} func (x *Image) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[97] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7558,7 +7836,7 @@ func (x *Image) ProtoReflect() protoreflect.Message { // Deprecated: Use Image.ProtoReflect.Descriptor instead. func (*Image) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{97} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{103} } func (x *Image) GetId() string { @@ -7627,7 +7905,7 @@ type ListImagesResponse struct { func (x *ListImagesResponse) Reset() { *x = ListImagesResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[98] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7639,7 +7917,7 @@ func (x *ListImagesResponse) String() string { func (*ListImagesResponse) ProtoMessage() {} func (x *ListImagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[98] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7652,7 +7930,7 @@ func (x *ListImagesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListImagesResponse.ProtoReflect.Descriptor instead. func (*ListImagesResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{98} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{104} } func (x *ListImagesResponse) GetImages() []*Image { @@ -7662,6 +7940,96 @@ func (x *ListImagesResponse) GetImages() []*Image { return nil } +type StreamImagesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Filter to list images. + Filter *ImageFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamImagesRequest) Reset() { + *x = StreamImagesRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamImagesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamImagesRequest) ProtoMessage() {} + +func (x *StreamImagesRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamImagesRequest.ProtoReflect.Descriptor instead. +func (*StreamImagesRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{105} +} + +func (x *StreamImagesRequest) GetFilter() *ImageFilter { + if x != nil { + return x.Filter + } + return nil +} + +type StreamImagesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of images. + Images []*Image `protobuf:"bytes,1,rep,name=images,proto3" json:"images,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamImagesResponse) Reset() { + *x = StreamImagesResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamImagesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamImagesResponse) ProtoMessage() {} + +func (x *StreamImagesResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamImagesResponse.ProtoReflect.Descriptor instead. +func (*StreamImagesResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{106} +} + +func (x *StreamImagesResponse) GetImages() []*Image { + if x != nil { + return x.Images + } + return nil +} + type ImageStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Spec of the image. @@ -7674,7 +8042,7 @@ type ImageStatusRequest struct { func (x *ImageStatusRequest) Reset() { *x = ImageStatusRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[99] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7686,7 +8054,7 @@ func (x *ImageStatusRequest) String() string { func (*ImageStatusRequest) ProtoMessage() {} func (x *ImageStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[99] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7699,7 +8067,7 @@ func (x *ImageStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageStatusRequest.ProtoReflect.Descriptor instead. func (*ImageStatusRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{99} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{107} } func (x *ImageStatusRequest) GetImage() *ImageSpec { @@ -7731,7 +8099,7 @@ type ImageStatusResponse struct { func (x *ImageStatusResponse) Reset() { *x = ImageStatusResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[100] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7743,7 +8111,7 @@ func (x *ImageStatusResponse) String() string { func (*ImageStatusResponse) ProtoMessage() {} func (x *ImageStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[100] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7756,7 +8124,7 @@ func (x *ImageStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageStatusResponse.ProtoReflect.Descriptor instead. func (*ImageStatusResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{100} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{108} } func (x *ImageStatusResponse) GetImage() *Image { @@ -7791,7 +8159,7 @@ type AuthConfig struct { func (x *AuthConfig) Reset() { *x = AuthConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[101] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7803,7 +8171,7 @@ func (x *AuthConfig) String() string { func (*AuthConfig) ProtoMessage() {} func (x *AuthConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[101] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7816,7 +8184,7 @@ func (x *AuthConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthConfig.ProtoReflect.Descriptor instead. func (*AuthConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{101} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{109} } func (x *AuthConfig) GetUsername() string { @@ -7875,7 +8243,7 @@ type PullImageRequest struct { func (x *PullImageRequest) Reset() { *x = PullImageRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[102] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7887,7 +8255,7 @@ func (x *PullImageRequest) String() string { func (*PullImageRequest) ProtoMessage() {} func (x *PullImageRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[102] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7900,7 +8268,7 @@ func (x *PullImageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PullImageRequest.ProtoReflect.Descriptor instead. func (*PullImageRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{102} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{110} } func (x *PullImageRequest) GetImage() *ImageSpec { @@ -7926,8 +8294,20 @@ func (x *PullImageRequest) GetSandboxConfig() *PodSandboxConfig { type PullImageResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - // Reference to the image in use. For most runtimes, this should be an - // image ID or digest. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. + // + // When referring to the same image, the container runtime MUST always return + // the same value for: + // - Image.id + // - Container.image_id + // - ContainerStatus.image_id + // - PullImageResponse.image_ref + // + // Note: this field has a stricter meaning starting with v1.36. + // It used to be image ID OR digest, which are different values, + // and would not necessarily match other ID fields in the Container, + // ContainerStatus, and Image messages ImageRef string `protobuf:"bytes,1,opt,name=image_ref,json=imageRef,proto3" json:"image_ref,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -7935,7 +8315,7 @@ type PullImageResponse struct { func (x *PullImageResponse) Reset() { *x = PullImageResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[103] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7947,7 +8327,7 @@ func (x *PullImageResponse) String() string { func (*PullImageResponse) ProtoMessage() {} func (x *PullImageResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[103] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7960,7 +8340,7 @@ func (x *PullImageResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PullImageResponse.ProtoReflect.Descriptor instead. func (*PullImageResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{103} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{111} } func (x *PullImageResponse) GetImageRef() string { @@ -7980,7 +8360,7 @@ type RemoveImageRequest struct { func (x *RemoveImageRequest) Reset() { *x = RemoveImageRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[104] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7992,7 +8372,7 @@ func (x *RemoveImageRequest) String() string { func (*RemoveImageRequest) ProtoMessage() {} func (x *RemoveImageRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[104] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8005,7 +8385,7 @@ func (x *RemoveImageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveImageRequest.ProtoReflect.Descriptor instead. func (*RemoveImageRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{104} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{112} } func (x *RemoveImageRequest) GetImage() *ImageSpec { @@ -8023,7 +8403,7 @@ type RemoveImageResponse struct { func (x *RemoveImageResponse) Reset() { *x = RemoveImageResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[105] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8035,7 +8415,7 @@ func (x *RemoveImageResponse) String() string { func (*RemoveImageResponse) ProtoMessage() {} func (x *RemoveImageResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[105] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8048,7 +8428,7 @@ func (x *RemoveImageResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveImageResponse.ProtoReflect.Descriptor instead. func (*RemoveImageResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{105} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{113} } type NetworkConfig struct { @@ -8062,7 +8442,7 @@ type NetworkConfig struct { func (x *NetworkConfig) Reset() { *x = NetworkConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[106] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8074,7 +8454,7 @@ func (x *NetworkConfig) String() string { func (*NetworkConfig) ProtoMessage() {} func (x *NetworkConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[106] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8087,7 +8467,7 @@ func (x *NetworkConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkConfig.ProtoReflect.Descriptor instead. func (*NetworkConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{106} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{114} } func (x *NetworkConfig) GetPodCidr() string { @@ -8106,7 +8486,7 @@ type RuntimeConfig struct { func (x *RuntimeConfig) Reset() { *x = RuntimeConfig{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[107] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8118,7 +8498,7 @@ func (x *RuntimeConfig) String() string { func (*RuntimeConfig) ProtoMessage() {} func (x *RuntimeConfig) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[107] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8131,7 +8511,7 @@ func (x *RuntimeConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeConfig.ProtoReflect.Descriptor instead. func (*RuntimeConfig) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{107} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{115} } func (x *RuntimeConfig) GetNetworkConfig() *NetworkConfig { @@ -8150,7 +8530,7 @@ type UpdateRuntimeConfigRequest struct { func (x *UpdateRuntimeConfigRequest) Reset() { *x = UpdateRuntimeConfigRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[108] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8162,7 +8542,7 @@ func (x *UpdateRuntimeConfigRequest) String() string { func (*UpdateRuntimeConfigRequest) ProtoMessage() {} func (x *UpdateRuntimeConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[108] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8175,7 +8555,7 @@ func (x *UpdateRuntimeConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRuntimeConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateRuntimeConfigRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{108} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{116} } func (x *UpdateRuntimeConfigRequest) GetRuntimeConfig() *RuntimeConfig { @@ -8193,7 +8573,7 @@ type UpdateRuntimeConfigResponse struct { func (x *UpdateRuntimeConfigResponse) Reset() { *x = UpdateRuntimeConfigResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[109] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8205,7 +8585,7 @@ func (x *UpdateRuntimeConfigResponse) String() string { func (*UpdateRuntimeConfigResponse) ProtoMessage() {} func (x *UpdateRuntimeConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[109] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8218,7 +8598,7 @@ func (x *UpdateRuntimeConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRuntimeConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateRuntimeConfigResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{109} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{117} } // RuntimeCondition contains condition information for the runtime. @@ -8251,7 +8631,7 @@ type RuntimeCondition struct { func (x *RuntimeCondition) Reset() { *x = RuntimeCondition{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[110] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8263,7 +8643,7 @@ func (x *RuntimeCondition) String() string { func (*RuntimeCondition) ProtoMessage() {} func (x *RuntimeCondition) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[110] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8276,7 +8656,7 @@ func (x *RuntimeCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeCondition.ProtoReflect.Descriptor instead. func (*RuntimeCondition) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{110} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{118} } func (x *RuntimeCondition) GetType() string { @@ -8318,7 +8698,7 @@ type RuntimeStatus struct { func (x *RuntimeStatus) Reset() { *x = RuntimeStatus{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[111] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8330,7 +8710,7 @@ func (x *RuntimeStatus) String() string { func (*RuntimeStatus) ProtoMessage() {} func (x *RuntimeStatus) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[111] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8343,7 +8723,7 @@ func (x *RuntimeStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeStatus.ProtoReflect.Descriptor instead. func (*RuntimeStatus) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{111} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{119} } func (x *RuntimeStatus) GetConditions() []*RuntimeCondition { @@ -8363,7 +8743,7 @@ type StatusRequest struct { func (x *StatusRequest) Reset() { *x = StatusRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[112] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8375,7 +8755,7 @@ func (x *StatusRequest) String() string { func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[112] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8388,7 +8768,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. func (*StatusRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{112} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{120} } func (x *StatusRequest) GetVerbose() bool { @@ -8415,7 +8795,7 @@ type RuntimeHandlerFeatures struct { func (x *RuntimeHandlerFeatures) Reset() { *x = RuntimeHandlerFeatures{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[113] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8427,7 +8807,7 @@ func (x *RuntimeHandlerFeatures) String() string { func (*RuntimeHandlerFeatures) ProtoMessage() {} func (x *RuntimeHandlerFeatures) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[113] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8440,7 +8820,7 @@ func (x *RuntimeHandlerFeatures) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeHandlerFeatures.ProtoReflect.Descriptor instead. func (*RuntimeHandlerFeatures) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{113} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{121} } func (x *RuntimeHandlerFeatures) GetRecursiveReadOnlyMounts() bool { @@ -8470,7 +8850,7 @@ type RuntimeHandler struct { func (x *RuntimeHandler) Reset() { *x = RuntimeHandler{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[114] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8482,7 +8862,7 @@ func (x *RuntimeHandler) String() string { func (*RuntimeHandler) ProtoMessage() {} func (x *RuntimeHandler) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[114] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8495,7 +8875,7 @@ func (x *RuntimeHandler) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeHandler.ProtoReflect.Descriptor instead. func (*RuntimeHandler) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{114} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{122} } func (x *RuntimeHandler) GetName() string { @@ -8519,13 +8899,16 @@ type RuntimeFeatures struct { state protoimpl.MessageState `protogen:"open.v1"` // supplemental_groups_policy is set to true if the runtime supports SupplementalGroupsPolicy and ContainerUser. SupplementalGroupsPolicy bool `protobuf:"varint,1,opt,name=supplemental_groups_policy,json=supplementalGroupsPolicy,proto3" json:"supplemental_groups_policy,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // user_namespaces_host_network is set to true if the runtime supports containers using both + // host network and user namespace simultaneously. + UserNamespacesHostNetwork bool `protobuf:"varint,2,opt,name=user_namespaces_host_network,json=userNamespacesHostNetwork,proto3" json:"user_namespaces_host_network,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RuntimeFeatures) Reset() { *x = RuntimeFeatures{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[115] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8537,7 +8920,7 @@ func (x *RuntimeFeatures) String() string { func (*RuntimeFeatures) ProtoMessage() {} func (x *RuntimeFeatures) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[115] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8550,7 +8933,7 @@ func (x *RuntimeFeatures) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeFeatures.ProtoReflect.Descriptor instead. func (*RuntimeFeatures) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{115} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{123} } func (x *RuntimeFeatures) GetSupplementalGroupsPolicy() bool { @@ -8560,6 +8943,13 @@ func (x *RuntimeFeatures) GetSupplementalGroupsPolicy() bool { return false } +func (x *RuntimeFeatures) GetUserNamespacesHostNetwork() bool { + if x != nil { + return x.UserNamespacesHostNetwork + } + return false +} + type StatusResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // Status of the Runtime. @@ -8580,7 +8970,7 @@ type StatusResponse struct { func (x *StatusResponse) Reset() { *x = StatusResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[116] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8592,7 +8982,7 @@ func (x *StatusResponse) String() string { func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[116] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8605,7 +8995,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. func (*StatusResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{116} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{124} } func (x *StatusResponse) GetStatus() *RuntimeStatus { @@ -8644,7 +9034,7 @@ type ImageFsInfoRequest struct { func (x *ImageFsInfoRequest) Reset() { *x = ImageFsInfoRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[117] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8656,7 +9046,7 @@ func (x *ImageFsInfoRequest) String() string { func (*ImageFsInfoRequest) ProtoMessage() {} func (x *ImageFsInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[117] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8669,7 +9059,7 @@ func (x *ImageFsInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageFsInfoRequest.ProtoReflect.Descriptor instead. func (*ImageFsInfoRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{117} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{125} } // UInt64Value is the wrapper of uint64. @@ -8683,7 +9073,7 @@ type UInt64Value struct { func (x *UInt64Value) Reset() { *x = UInt64Value{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[118] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8695,7 +9085,7 @@ func (x *UInt64Value) String() string { func (*UInt64Value) ProtoMessage() {} func (x *UInt64Value) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[118] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8708,7 +9098,7 @@ func (x *UInt64Value) ProtoReflect() protoreflect.Message { // Deprecated: Use UInt64Value.ProtoReflect.Descriptor instead. func (*UInt64Value) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{118} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{126} } func (x *UInt64Value) GetValue() uint64 { @@ -8729,7 +9119,7 @@ type FilesystemIdentifier struct { func (x *FilesystemIdentifier) Reset() { *x = FilesystemIdentifier{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[119] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8741,7 +9131,7 @@ func (x *FilesystemIdentifier) String() string { func (*FilesystemIdentifier) ProtoMessage() {} func (x *FilesystemIdentifier) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[119] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8754,7 +9144,7 @@ func (x *FilesystemIdentifier) ProtoReflect() protoreflect.Message { // Deprecated: Use FilesystemIdentifier.ProtoReflect.Descriptor instead. func (*FilesystemIdentifier) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{119} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{127} } func (x *FilesystemIdentifier) GetMountpoint() string { @@ -8785,7 +9175,7 @@ type FilesystemUsage struct { func (x *FilesystemUsage) Reset() { *x = FilesystemUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[120] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8797,7 +9187,7 @@ func (x *FilesystemUsage) String() string { func (*FilesystemUsage) ProtoMessage() {} func (x *FilesystemUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[120] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8810,7 +9200,7 @@ func (x *FilesystemUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use FilesystemUsage.ProtoReflect.Descriptor instead. func (*FilesystemUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{120} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{128} } func (x *FilesystemUsage) GetTimestamp() int64 { @@ -8858,7 +9248,7 @@ type WindowsFilesystemUsage struct { func (x *WindowsFilesystemUsage) Reset() { *x = WindowsFilesystemUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[121] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8870,7 +9260,7 @@ func (x *WindowsFilesystemUsage) String() string { func (*WindowsFilesystemUsage) ProtoMessage() {} func (x *WindowsFilesystemUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[121] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8883,7 +9273,7 @@ func (x *WindowsFilesystemUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsFilesystemUsage.ProtoReflect.Descriptor instead. func (*WindowsFilesystemUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{121} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{129} } func (x *WindowsFilesystemUsage) GetTimestamp() int64 { @@ -8922,7 +9312,7 @@ type ImageFsInfoResponse struct { func (x *ImageFsInfoResponse) Reset() { *x = ImageFsInfoResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[122] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8934,7 +9324,7 @@ func (x *ImageFsInfoResponse) String() string { func (*ImageFsInfoResponse) ProtoMessage() {} func (x *ImageFsInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[122] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8947,7 +9337,7 @@ func (x *ImageFsInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageFsInfoResponse.ProtoReflect.Descriptor instead. func (*ImageFsInfoResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{122} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{130} } func (x *ImageFsInfoResponse) GetImageFilesystems() []*FilesystemUsage { @@ -8974,7 +9364,7 @@ type ContainerStatsRequest struct { func (x *ContainerStatsRequest) Reset() { *x = ContainerStatsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[123] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8986,7 +9376,7 @@ func (x *ContainerStatsRequest) String() string { func (*ContainerStatsRequest) ProtoMessage() {} func (x *ContainerStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[123] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8999,7 +9389,7 @@ func (x *ContainerStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStatsRequest.ProtoReflect.Descriptor instead. func (*ContainerStatsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{123} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{131} } func (x *ContainerStatsRequest) GetContainerId() string { @@ -9019,7 +9409,7 @@ type ContainerStatsResponse struct { func (x *ContainerStatsResponse) Reset() { *x = ContainerStatsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[124] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9031,7 +9421,7 @@ func (x *ContainerStatsResponse) String() string { func (*ContainerStatsResponse) ProtoMessage() {} func (x *ContainerStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[124] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9044,7 +9434,7 @@ func (x *ContainerStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStatsResponse.ProtoReflect.Descriptor instead. func (*ContainerStatsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{124} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{132} } func (x *ContainerStatsResponse) GetStats() *ContainerStats { @@ -9064,7 +9454,7 @@ type ListContainerStatsRequest struct { func (x *ListContainerStatsRequest) Reset() { *x = ListContainerStatsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[125] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9076,7 +9466,7 @@ func (x *ListContainerStatsRequest) String() string { func (*ListContainerStatsRequest) ProtoMessage() {} func (x *ListContainerStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[125] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9089,7 +9479,7 @@ func (x *ListContainerStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListContainerStatsRequest.ProtoReflect.Descriptor instead. func (*ListContainerStatsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{125} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{133} } func (x *ListContainerStatsRequest) GetFilter() *ContainerStatsFilter { @@ -9103,33 +9493,137 @@ func (x *ListContainerStatsRequest) GetFilter() *ContainerStatsFilter { // All those fields are combined with 'AND' type ContainerStatsFilter struct { state protoimpl.MessageState `protogen:"open.v1"` - // ID of the container. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // ID of the PodSandbox. - PodSandboxId string `protobuf:"bytes,2,opt,name=pod_sandbox_id,json=podSandboxId,proto3" json:"pod_sandbox_id,omitempty"` - // LabelSelector to select matches. - // Only api.MatchLabels is supported for now and the requirements - // are ANDed. MatchExpressions is not supported yet. - LabelSelector map[string]string `protobuf:"bytes,3,rep,name=label_selector,json=labelSelector,proto3" json:"label_selector,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // ID of the container. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // ID of the PodSandbox. + PodSandboxId string `protobuf:"bytes,2,opt,name=pod_sandbox_id,json=podSandboxId,proto3" json:"pod_sandbox_id,omitempty"` + // LabelSelector to select matches. + // Only api.MatchLabels is supported for now and the requirements + // are ANDed. MatchExpressions is not supported yet. + LabelSelector map[string]string `protobuf:"bytes,3,rep,name=label_selector,json=labelSelector,proto3" json:"label_selector,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContainerStatsFilter) Reset() { + *x = ContainerStatsFilter{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[134] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContainerStatsFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContainerStatsFilter) ProtoMessage() {} + +func (x *ContainerStatsFilter) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[134] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContainerStatsFilter.ProtoReflect.Descriptor instead. +func (*ContainerStatsFilter) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{134} +} + +func (x *ContainerStatsFilter) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ContainerStatsFilter) GetPodSandboxId() string { + if x != nil { + return x.PodSandboxId + } + return "" +} + +func (x *ContainerStatsFilter) GetLabelSelector() map[string]string { + if x != nil { + return x.LabelSelector + } + return nil +} + +type ListContainerStatsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Stats of the container. + Stats []*ContainerStats `protobuf:"bytes,1,rep,name=stats,proto3" json:"stats,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListContainerStatsResponse) Reset() { + *x = ListContainerStatsResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[135] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListContainerStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListContainerStatsResponse) ProtoMessage() {} + +func (x *ListContainerStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[135] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListContainerStatsResponse.ProtoReflect.Descriptor instead. +func (*ListContainerStatsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{135} +} + +func (x *ListContainerStatsResponse) GetStats() []*ContainerStats { + if x != nil { + return x.Stats + } + return nil +} + +type StreamContainerStatsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Filter for the list request. + Filter *ContainerStatsFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ContainerStatsFilter) Reset() { - *x = ContainerStatsFilter{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[126] +func (x *StreamContainerStatsRequest) Reset() { + *x = StreamContainerStatsRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ContainerStatsFilter) String() string { +func (x *StreamContainerStatsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerStatsFilter) ProtoMessage() {} +func (*StreamContainerStatsRequest) ProtoMessage() {} -func (x *ContainerStatsFilter) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[126] +func (x *StreamContainerStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9140,55 +9634,41 @@ func (x *ContainerStatsFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerStatsFilter.ProtoReflect.Descriptor instead. -func (*ContainerStatsFilter) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{126} -} - -func (x *ContainerStatsFilter) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ContainerStatsFilter) GetPodSandboxId() string { - if x != nil { - return x.PodSandboxId - } - return "" +// Deprecated: Use StreamContainerStatsRequest.ProtoReflect.Descriptor instead. +func (*StreamContainerStatsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{136} } -func (x *ContainerStatsFilter) GetLabelSelector() map[string]string { +func (x *StreamContainerStatsRequest) GetFilter() *ContainerStatsFilter { if x != nil { - return x.LabelSelector + return x.Filter } return nil } -type ListContainerStatsResponse struct { +type StreamContainerStatsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - // Stats of the container. - Stats []*ContainerStats `protobuf:"bytes,1,rep,name=stats,proto3" json:"stats,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // List of container stats. + ContainerStats []*ContainerStats `protobuf:"bytes,1,rep,name=container_stats,json=containerStats,proto3" json:"container_stats,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ListContainerStatsResponse) Reset() { - *x = ListContainerStatsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[127] +func (x *StreamContainerStatsResponse) Reset() { + *x = StreamContainerStatsResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListContainerStatsResponse) String() string { +func (x *StreamContainerStatsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListContainerStatsResponse) ProtoMessage() {} +func (*StreamContainerStatsResponse) ProtoMessage() {} -func (x *ListContainerStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[127] +func (x *StreamContainerStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9199,14 +9679,14 @@ func (x *ListContainerStatsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListContainerStatsResponse.ProtoReflect.Descriptor instead. -func (*ListContainerStatsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{127} +// Deprecated: Use StreamContainerStatsResponse.ProtoReflect.Descriptor instead. +func (*StreamContainerStatsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{137} } -func (x *ListContainerStatsResponse) GetStats() []*ContainerStats { +func (x *StreamContainerStatsResponse) GetContainerStats() []*ContainerStats { if x != nil { - return x.Stats + return x.ContainerStats } return nil } @@ -9231,7 +9711,7 @@ type ContainerAttributes struct { func (x *ContainerAttributes) Reset() { *x = ContainerAttributes{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[128] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9243,7 +9723,7 @@ func (x *ContainerAttributes) String() string { func (*ContainerAttributes) ProtoMessage() {} func (x *ContainerAttributes) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[128] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9256,7 +9736,7 @@ func (x *ContainerAttributes) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerAttributes.ProtoReflect.Descriptor instead. func (*ContainerAttributes) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{128} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{138} } func (x *ContainerAttributes) GetId() string { @@ -9308,7 +9788,7 @@ type ContainerStats struct { func (x *ContainerStats) Reset() { *x = ContainerStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[129] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9320,7 +9800,7 @@ func (x *ContainerStats) String() string { func (*ContainerStats) ProtoMessage() {} func (x *ContainerStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[129] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9333,7 +9813,7 @@ func (x *ContainerStats) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStats.ProtoReflect.Descriptor instead. func (*ContainerStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{129} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{139} } func (x *ContainerStats) GetAttributes() *ContainerAttributes { @@ -9395,7 +9875,7 @@ type WindowsContainerStats struct { func (x *WindowsContainerStats) Reset() { *x = WindowsContainerStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[130] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9407,7 +9887,7 @@ func (x *WindowsContainerStats) String() string { func (*WindowsContainerStats) ProtoMessage() {} func (x *WindowsContainerStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[130] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9420,7 +9900,7 @@ func (x *WindowsContainerStats) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsContainerStats.ProtoReflect.Descriptor instead. func (*WindowsContainerStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{130} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{140} } func (x *WindowsContainerStats) GetAttributes() *ContainerAttributes { @@ -9464,7 +9944,7 @@ type PsiStats struct { func (x *PsiStats) Reset() { *x = PsiStats{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[131] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9476,7 +9956,7 @@ func (x *PsiStats) String() string { func (*PsiStats) ProtoMessage() {} func (x *PsiStats) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[131] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9489,7 +9969,7 @@ func (x *PsiStats) ProtoReflect() protoreflect.Message { // Deprecated: Use PsiStats.ProtoReflect.Descriptor instead. func (*PsiStats) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{131} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{141} } func (x *PsiStats) GetFull() *PsiData { @@ -9524,7 +10004,7 @@ type PsiData struct { func (x *PsiData) Reset() { *x = PsiData{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[132] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9536,7 +10016,7 @@ func (x *PsiData) String() string { func (*PsiData) ProtoMessage() {} func (x *PsiData) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[132] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9549,7 +10029,7 @@ func (x *PsiData) ProtoReflect() protoreflect.Message { // Deprecated: Use PsiData.ProtoReflect.Descriptor instead. func (*PsiData) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{132} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{142} } func (x *PsiData) GetTotal() uint64 { @@ -9598,7 +10078,7 @@ type CpuUsage struct { func (x *CpuUsage) Reset() { *x = CpuUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[133] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9610,7 +10090,7 @@ func (x *CpuUsage) String() string { func (*CpuUsage) ProtoMessage() {} func (x *CpuUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[133] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9623,7 +10103,7 @@ func (x *CpuUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use CpuUsage.ProtoReflect.Descriptor instead. func (*CpuUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{133} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{143} } func (x *CpuUsage) GetTimestamp() int64 { @@ -9670,7 +10150,7 @@ type WindowsCpuUsage struct { func (x *WindowsCpuUsage) Reset() { *x = WindowsCpuUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[134] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9682,7 +10162,7 @@ func (x *WindowsCpuUsage) String() string { func (*WindowsCpuUsage) ProtoMessage() {} func (x *WindowsCpuUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[134] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9695,7 +10175,7 @@ func (x *WindowsCpuUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsCpuUsage.ProtoReflect.Descriptor instead. func (*WindowsCpuUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{134} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{144} } func (x *WindowsCpuUsage) GetTimestamp() int64 { @@ -9744,7 +10224,7 @@ type MemoryUsage struct { func (x *MemoryUsage) Reset() { *x = MemoryUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[135] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9756,7 +10236,7 @@ func (x *MemoryUsage) String() string { func (*MemoryUsage) ProtoMessage() {} func (x *MemoryUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[135] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9769,7 +10249,7 @@ func (x *MemoryUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use MemoryUsage.ProtoReflect.Descriptor instead. func (*MemoryUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{135} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{145} } func (x *MemoryUsage) GetTimestamp() int64 { @@ -9840,7 +10320,7 @@ type IoUsage struct { func (x *IoUsage) Reset() { *x = IoUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[136] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9852,7 +10332,7 @@ func (x *IoUsage) String() string { func (*IoUsage) ProtoMessage() {} func (x *IoUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[136] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9865,7 +10345,7 @@ func (x *IoUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use IoUsage.ProtoReflect.Descriptor instead. func (*IoUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{136} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{146} } func (x *IoUsage) GetTimestamp() int64 { @@ -9896,7 +10376,7 @@ type SwapUsage struct { func (x *SwapUsage) Reset() { *x = SwapUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[137] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9908,7 +10388,7 @@ func (x *SwapUsage) String() string { func (*SwapUsage) ProtoMessage() {} func (x *SwapUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[137] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9921,7 +10401,7 @@ func (x *SwapUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use SwapUsage.ProtoReflect.Descriptor instead. func (*SwapUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{137} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{147} } func (x *SwapUsage) GetTimestamp() int64 { @@ -9964,7 +10444,7 @@ type WindowsMemoryUsage struct { func (x *WindowsMemoryUsage) Reset() { *x = WindowsMemoryUsage{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[138] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9976,7 +10456,7 @@ func (x *WindowsMemoryUsage) String() string { func (*WindowsMemoryUsage) ProtoMessage() {} func (x *WindowsMemoryUsage) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[138] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9989,7 +10469,7 @@ func (x *WindowsMemoryUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use WindowsMemoryUsage.ProtoReflect.Descriptor instead. func (*WindowsMemoryUsage) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{138} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{148} } func (x *WindowsMemoryUsage) GetTimestamp() int64 { @@ -10037,7 +10517,7 @@ type ReopenContainerLogRequest struct { func (x *ReopenContainerLogRequest) Reset() { *x = ReopenContainerLogRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[139] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10049,7 +10529,7 @@ func (x *ReopenContainerLogRequest) String() string { func (*ReopenContainerLogRequest) ProtoMessage() {} func (x *ReopenContainerLogRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[139] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10062,7 +10542,7 @@ func (x *ReopenContainerLogRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReopenContainerLogRequest.ProtoReflect.Descriptor instead. func (*ReopenContainerLogRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{139} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{149} } func (x *ReopenContainerLogRequest) GetContainerId() string { @@ -10080,7 +10560,7 @@ type ReopenContainerLogResponse struct { func (x *ReopenContainerLogResponse) Reset() { *x = ReopenContainerLogResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[140] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10092,7 +10572,7 @@ func (x *ReopenContainerLogResponse) String() string { func (*ReopenContainerLogResponse) ProtoMessage() {} func (x *ReopenContainerLogResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[140] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10105,7 +10585,7 @@ func (x *ReopenContainerLogResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReopenContainerLogResponse.ProtoReflect.Descriptor instead. func (*ReopenContainerLogResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{140} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{150} } type CheckpointContainerRequest struct { @@ -10124,7 +10604,7 @@ type CheckpointContainerRequest struct { func (x *CheckpointContainerRequest) Reset() { *x = CheckpointContainerRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[141] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10136,7 +10616,7 @@ func (x *CheckpointContainerRequest) String() string { func (*CheckpointContainerRequest) ProtoMessage() {} func (x *CheckpointContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[141] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10149,7 +10629,7 @@ func (x *CheckpointContainerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointContainerRequest.ProtoReflect.Descriptor instead. func (*CheckpointContainerRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{141} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{151} } func (x *CheckpointContainerRequest) GetContainerId() string { @@ -10181,7 +10661,7 @@ type CheckpointContainerResponse struct { func (x *CheckpointContainerResponse) Reset() { *x = CheckpointContainerResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[142] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10193,7 +10673,7 @@ func (x *CheckpointContainerResponse) String() string { func (*CheckpointContainerResponse) ProtoMessage() {} func (x *CheckpointContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[142] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10206,7 +10686,7 @@ func (x *CheckpointContainerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointContainerResponse.ProtoReflect.Descriptor instead. func (*CheckpointContainerResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{142} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{152} } type GetEventsRequest struct { @@ -10217,7 +10697,7 @@ type GetEventsRequest struct { func (x *GetEventsRequest) Reset() { *x = GetEventsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[143] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10229,7 +10709,7 @@ func (x *GetEventsRequest) String() string { func (*GetEventsRequest) ProtoMessage() {} func (x *GetEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[143] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10242,7 +10722,7 @@ func (x *GetEventsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsRequest.ProtoReflect.Descriptor instead. func (*GetEventsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{143} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{153} } type ContainerEventResponse struct { @@ -10263,7 +10743,7 @@ type ContainerEventResponse struct { func (x *ContainerEventResponse) Reset() { *x = ContainerEventResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[144] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10275,7 +10755,7 @@ func (x *ContainerEventResponse) String() string { func (*ContainerEventResponse) ProtoMessage() {} func (x *ContainerEventResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[144] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10288,7 +10768,7 @@ func (x *ContainerEventResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerEventResponse.ProtoReflect.Descriptor instead. func (*ContainerEventResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{144} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{154} } func (x *ContainerEventResponse) GetContainerId() string { @@ -10334,7 +10814,7 @@ type ListMetricDescriptorsRequest struct { func (x *ListMetricDescriptorsRequest) Reset() { *x = ListMetricDescriptorsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[145] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10346,7 +10826,7 @@ func (x *ListMetricDescriptorsRequest) String() string { func (*ListMetricDescriptorsRequest) ProtoMessage() {} func (x *ListMetricDescriptorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[145] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10359,7 +10839,7 @@ func (x *ListMetricDescriptorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListMetricDescriptorsRequest.ProtoReflect.Descriptor instead. func (*ListMetricDescriptorsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{145} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{155} } type ListMetricDescriptorsResponse struct { @@ -10371,7 +10851,7 @@ type ListMetricDescriptorsResponse struct { func (x *ListMetricDescriptorsResponse) Reset() { *x = ListMetricDescriptorsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[146] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10383,7 +10863,7 @@ func (x *ListMetricDescriptorsResponse) String() string { func (*ListMetricDescriptorsResponse) ProtoMessage() {} func (x *ListMetricDescriptorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[146] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10396,7 +10876,7 @@ func (x *ListMetricDescriptorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListMetricDescriptorsResponse.ProtoReflect.Descriptor instead. func (*ListMetricDescriptorsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{146} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{156} } func (x *ListMetricDescriptorsResponse) GetDescriptors() []*MetricDescriptor { @@ -10423,7 +10903,7 @@ type MetricDescriptor struct { func (x *MetricDescriptor) Reset() { *x = MetricDescriptor{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[147] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10435,7 +10915,7 @@ func (x *MetricDescriptor) String() string { func (*MetricDescriptor) ProtoMessage() {} func (x *MetricDescriptor) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[147] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10448,7 +10928,7 @@ func (x *MetricDescriptor) ProtoReflect() protoreflect.Message { // Deprecated: Use MetricDescriptor.ProtoReflect.Descriptor instead. func (*MetricDescriptor) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{147} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{157} } func (x *MetricDescriptor) GetName() string { @@ -10465,34 +10945,114 @@ func (x *MetricDescriptor) GetHelp() string { return "" } -func (x *MetricDescriptor) GetLabelKeys() []string { +func (x *MetricDescriptor) GetLabelKeys() []string { + if x != nil { + return x.LabelKeys + } + return nil +} + +type ListPodSandboxMetricsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPodSandboxMetricsRequest) Reset() { + *x = ListPodSandboxMetricsRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[158] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPodSandboxMetricsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPodSandboxMetricsRequest) ProtoMessage() {} + +func (x *ListPodSandboxMetricsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[158] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPodSandboxMetricsRequest.ProtoReflect.Descriptor instead. +func (*ListPodSandboxMetricsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{158} +} + +type ListPodSandboxMetricsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + PodMetrics []*PodSandboxMetrics `protobuf:"bytes,1,rep,name=pod_metrics,json=podMetrics,proto3" json:"pod_metrics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPodSandboxMetricsResponse) Reset() { + *x = ListPodSandboxMetricsResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[159] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPodSandboxMetricsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPodSandboxMetricsResponse) ProtoMessage() {} + +func (x *ListPodSandboxMetricsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[159] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPodSandboxMetricsResponse.ProtoReflect.Descriptor instead. +func (*ListPodSandboxMetricsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{159} +} + +func (x *ListPodSandboxMetricsResponse) GetPodMetrics() []*PodSandboxMetrics { if x != nil { - return x.LabelKeys + return x.PodMetrics } return nil } -type ListPodSandboxMetricsRequest struct { +type StreamPodSandboxMetricsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ListPodSandboxMetricsRequest) Reset() { - *x = ListPodSandboxMetricsRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[148] +func (x *StreamPodSandboxMetricsRequest) Reset() { + *x = StreamPodSandboxMetricsRequest{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListPodSandboxMetricsRequest) String() string { +func (x *StreamPodSandboxMetricsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListPodSandboxMetricsRequest) ProtoMessage() {} +func (*StreamPodSandboxMetricsRequest) ProtoMessage() {} -func (x *ListPodSandboxMetricsRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[148] +func (x *StreamPodSandboxMetricsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10503,33 +11063,34 @@ func (x *ListPodSandboxMetricsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListPodSandboxMetricsRequest.ProtoReflect.Descriptor instead. -func (*ListPodSandboxMetricsRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{148} +// Deprecated: Use StreamPodSandboxMetricsRequest.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxMetricsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{160} } -type ListPodSandboxMetricsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - PodMetrics []*PodSandboxMetrics `protobuf:"bytes,1,rep,name=pod_metrics,json=podMetrics,proto3" json:"pod_metrics,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type StreamPodSandboxMetricsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of pod sandbox metrics. + PodSandboxMetrics []*PodSandboxMetrics `protobuf:"bytes,1,rep,name=pod_sandbox_metrics,json=podSandboxMetrics,proto3" json:"pod_sandbox_metrics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ListPodSandboxMetricsResponse) Reset() { - *x = ListPodSandboxMetricsResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[149] +func (x *StreamPodSandboxMetricsResponse) Reset() { + *x = StreamPodSandboxMetricsResponse{} + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListPodSandboxMetricsResponse) String() string { +func (x *StreamPodSandboxMetricsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListPodSandboxMetricsResponse) ProtoMessage() {} +func (*StreamPodSandboxMetricsResponse) ProtoMessage() {} -func (x *ListPodSandboxMetricsResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[149] +func (x *StreamPodSandboxMetricsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10540,14 +11101,14 @@ func (x *ListPodSandboxMetricsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListPodSandboxMetricsResponse.ProtoReflect.Descriptor instead. -func (*ListPodSandboxMetricsResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{149} +// Deprecated: Use StreamPodSandboxMetricsResponse.ProtoReflect.Descriptor instead. +func (*StreamPodSandboxMetricsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{161} } -func (x *ListPodSandboxMetricsResponse) GetPodMetrics() []*PodSandboxMetrics { +func (x *StreamPodSandboxMetricsResponse) GetPodSandboxMetrics() []*PodSandboxMetrics { if x != nil { - return x.PodMetrics + return x.PodSandboxMetrics } return nil } @@ -10563,7 +11124,7 @@ type PodSandboxMetrics struct { func (x *PodSandboxMetrics) Reset() { *x = PodSandboxMetrics{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[150] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10575,7 +11136,7 @@ func (x *PodSandboxMetrics) String() string { func (*PodSandboxMetrics) ProtoMessage() {} func (x *PodSandboxMetrics) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[150] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10588,7 +11149,7 @@ func (x *PodSandboxMetrics) ProtoReflect() protoreflect.Message { // Deprecated: Use PodSandboxMetrics.ProtoReflect.Descriptor instead. func (*PodSandboxMetrics) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{150} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{162} } func (x *PodSandboxMetrics) GetPodSandboxId() string { @@ -10622,7 +11183,7 @@ type ContainerMetrics struct { func (x *ContainerMetrics) Reset() { *x = ContainerMetrics{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[151] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10634,7 +11195,7 @@ func (x *ContainerMetrics) String() string { func (*ContainerMetrics) ProtoMessage() {} func (x *ContainerMetrics) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[151] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10647,7 +11208,7 @@ func (x *ContainerMetrics) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerMetrics.ProtoReflect.Descriptor instead. func (*ContainerMetrics) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{151} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{163} } func (x *ContainerMetrics) GetContainerId() string { @@ -10684,7 +11245,7 @@ type Metric struct { func (x *Metric) Reset() { *x = Metric{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[152] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10696,7 +11257,7 @@ func (x *Metric) String() string { func (*Metric) ProtoMessage() {} func (x *Metric) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[152] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10709,7 +11270,7 @@ func (x *Metric) ProtoReflect() protoreflect.Message { // Deprecated: Use Metric.ProtoReflect.Descriptor instead. func (*Metric) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{152} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{164} } func (x *Metric) GetName() string { @@ -10755,7 +11316,7 @@ type RuntimeConfigRequest struct { func (x *RuntimeConfigRequest) Reset() { *x = RuntimeConfigRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[153] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10767,7 +11328,7 @@ func (x *RuntimeConfigRequest) String() string { func (*RuntimeConfigRequest) ProtoMessage() {} func (x *RuntimeConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[153] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10780,7 +11341,7 @@ func (x *RuntimeConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeConfigRequest.ProtoReflect.Descriptor instead. func (*RuntimeConfigRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{153} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{165} } type RuntimeConfigResponse struct { @@ -10795,7 +11356,7 @@ type RuntimeConfigResponse struct { func (x *RuntimeConfigResponse) Reset() { *x = RuntimeConfigResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[154] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10807,7 +11368,7 @@ func (x *RuntimeConfigResponse) String() string { func (*RuntimeConfigResponse) ProtoMessage() {} func (x *RuntimeConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[154] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10820,7 +11381,7 @@ func (x *RuntimeConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeConfigResponse.ProtoReflect.Descriptor instead. func (*RuntimeConfigResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{154} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{166} } func (x *RuntimeConfigResponse) GetLinux() *LinuxRuntimeConfiguration { @@ -10846,7 +11407,7 @@ type LinuxRuntimeConfiguration struct { func (x *LinuxRuntimeConfiguration) Reset() { *x = LinuxRuntimeConfiguration{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[155] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10858,7 +11419,7 @@ func (x *LinuxRuntimeConfiguration) String() string { func (*LinuxRuntimeConfiguration) ProtoMessage() {} func (x *LinuxRuntimeConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[155] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[167] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10871,7 +11432,7 @@ func (x *LinuxRuntimeConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use LinuxRuntimeConfiguration.ProtoReflect.Descriptor instead. func (*LinuxRuntimeConfiguration) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{155} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{167} } func (x *LinuxRuntimeConfiguration) GetCgroupDriver() CgroupDriver { @@ -10895,7 +11456,7 @@ type UpdatePodSandboxResourcesRequest struct { func (x *UpdatePodSandboxResourcesRequest) Reset() { *x = UpdatePodSandboxResourcesRequest{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[156] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10907,7 +11468,7 @@ func (x *UpdatePodSandboxResourcesRequest) String() string { func (*UpdatePodSandboxResourcesRequest) ProtoMessage() {} func (x *UpdatePodSandboxResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[156] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[168] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10920,7 +11481,7 @@ func (x *UpdatePodSandboxResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdatePodSandboxResourcesRequest.ProtoReflect.Descriptor instead. func (*UpdatePodSandboxResourcesRequest) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{156} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{168} } func (x *UpdatePodSandboxResourcesRequest) GetPodSandboxId() string { @@ -10952,7 +11513,7 @@ type UpdatePodSandboxResourcesResponse struct { func (x *UpdatePodSandboxResourcesResponse) Reset() { *x = UpdatePodSandboxResourcesResponse{} - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[157] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10964,7 +11525,7 @@ func (x *UpdatePodSandboxResourcesResponse) String() string { func (*UpdatePodSandboxResourcesResponse) ProtoMessage() {} func (x *UpdatePodSandboxResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[157] + mi := &file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes[169] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10977,7 +11538,7 @@ func (x *UpdatePodSandboxResourcesResponse) ProtoReflect() protoreflect.Message // Deprecated: Use UpdatePodSandboxResourcesResponse.ProtoReflect.Descriptor instead. func (*UpdatePodSandboxResourcesResponse) Descriptor() ([]byte, []int) { - return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{157} + return file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP(), []int{169} } var File_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto protoreflect.FileDescriptor @@ -11369,209 +11930,234 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc = stri 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3e, - 0x0a, 0x16, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, - 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x4c, - 0x0a, 0x17, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0xc6, 0x01, 0x0a, - 0x15, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x5b, 0x0a, 0x0e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, - 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x51, + 0x0a, 0x19, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0x59, 0x0a, 0x1a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3b, 0x0a, 0x0d, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x0c, + 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x16, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x4c, 0x0a, 0x17, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x5b, 0x0a, 0x0e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x1a, 0x40, 0x0a, 0x12, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x39, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x1b, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x59, + 0x0a, 0x1c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, + 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x1a, 0x40, 0x0a, 0x12, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x50, - 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x22, 0xf8, 0x02, 0x0a, 0x14, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x44, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x53, 0x0a, 0x0b, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x31, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x0f, - 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, - 0x40, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x68, 0x0a, 0x1d, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x11, 0x70, 0x6f, + 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x0f, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x14, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3a, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x44, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x53, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x12, 0x36, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x3c, 0x0a, 0x07, 0x77, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, - 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x07, - 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x22, 0xb8, 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x6e, 0x75, - 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x70, 0x75, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x07, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x55, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x32, 0x0a, - 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, - 0x02, 0x69, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x02, - 0x69, 0x6f, 0x22, 0xb8, 0x02, 0x0a, 0x16, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2d, 0x0a, - 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, - 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x36, 0x0a, 0x06, - 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, - 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6d, 0x65, - 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, - 0x39, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x0a, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0xbf, 0x01, - 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x4e, 0x0a, 0x11, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x0a, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, + 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc9, + 0x01, 0x0a, 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x40, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x3c, 0x0a, 0x07, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x52, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x22, 0xb8, 0x02, 0x0a, 0x14, 0x4c, + 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x70, + 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x2f, 0x0a, 0x06, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x07, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x12, 0x32, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x12, 0x23, 0x0a, 0x02, 0x69, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6f, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x02, 0x69, 0x6f, 0x22, 0xb8, 0x02, 0x0a, 0x16, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x73, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x12, 0x2d, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, + 0x36, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x12, 0x39, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x41, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x22, 0xbf, 0x01, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x4e, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, + 0x41, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x55, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, + 0x48, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x22, 0xff, 0x01, 0x0a, 0x15, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x22, - 0xd4, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x55, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x22, 0xff, 0x01, 0x0a, 0x15, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x78, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x32, - 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x72, + 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0x12, 0x32, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x78, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x08, 0x74, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0xa8, 0x02, 0x0a, 0x1c, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x32, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x78, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x12, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, - 0x74, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0xa8, 0x02, 0x0a, 0x1c, 0x57, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, - 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, - 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x45, 0x0a, 0x12, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, - 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x72, 0x78, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x08, 0x74, + 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, - 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, - 0x73, 0x44, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x12, - 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x70, - 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x10, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x44, 0x72, 0x6f, 0x70, - 0x70, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, - 0x71, 0x0a, 0x13, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x45, 0x0a, 0x12, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x64, 0x72, + 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x44, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x22, 0x6a, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x86, 0x02, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, - 0x65, 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x61, - 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x1a, 0x3e, 0x0a, 0x10, 0x41, + 0x6e, 0x74, 0x22, 0x71, 0x0a, 0x13, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa3, 0x02, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x1b, + 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x32, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x95, 0x04, 0x0a, 0x17, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x70, 0x75, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, @@ -11945,292 +12531,315 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc = stri 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x73, 0x22, 0x55, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x95, 0x07, 0x0a, 0x0f, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, - 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6e, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, - 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, - 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, - 0x66, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x66, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0c, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0e, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, - 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, 0x09, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, - 0x65, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x0a, 0x73, 0x74, 0x6f, - 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x65, 0x72, 0x73, 0x22, 0x4e, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, + 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x35, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x55, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x95, 0x07, + 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x5f, 0x72, 0x65, 0x66, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, + 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x12, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x0a, + 0x73, 0x74, 0x6f, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x01, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x41, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, + 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0xca, 0x01, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x41, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, + 0x38, 0x01, 0x22, 0x90, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6e, + 0x75, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x6c, + 0x69, 0x6e, 0x75, 0x78, 0x12, 0x3f, 0x0a, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x07, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x22, 0x45, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x22, 0xe0, 0x02, 0x0a, + 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x3f, + 0x0a, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x12, + 0x5e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, + 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x90, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, - 0x78, 0x12, 0x3f, 0x0a, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x22, 0x45, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x22, 0xe0, 0x02, 0x0a, 0x1f, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x3f, 0x0a, 0x07, 0x77, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x07, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x12, 0x5e, 0x0a, 0x0b, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, - 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x22, 0x0a, 0x20, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x60, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x03, 0x63, 0x6d, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x22, 0x5f, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, - 0x6f, 0x64, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x03, 0x63, 0x6d, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, - 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, - 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, - 0x22, 0x20, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x22, 0x8a, 0x01, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x10, 0x0a, - 0x03, 0x74, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x74, 0x79, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, - 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x22, - 0x22, 0x0a, 0x0e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x75, 0x72, 0x6c, 0x22, 0x4e, 0x0a, 0x12, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, - 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x04, 0x70, - 0x6f, 0x72, 0x74, 0x22, 0x27, 0x0a, 0x13, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x3a, 0x0a, 0x0b, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x05, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x44, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, - 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x22, 0x0a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x60, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, 0x64, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x63, 0x6d, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x5f, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, + 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, + 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, + 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, 0x64, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x63, 0x6d, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x74, + 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x74, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, + 0x64, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, + 0x65, 0x72, 0x72, 0x22, 0x20, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x8a, 0x01, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, + 0x64, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, + 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, + 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x64, 0x65, 0x72, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, + 0x72, 0x72, 0x22, 0x22, 0x0a, 0x0e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x4e, 0x0a, 0x12, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, + 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, + 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x27, 0x0a, 0x13, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, + 0x3a, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, + 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0xf4, - 0x01, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, - 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, - 0x6f, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x70, - 0x6f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x28, 0x0a, 0x03, - 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, - 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, - 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x22, 0x3f, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x12, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, - 0x6f, 0x73, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x13, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, - 0x6e, 0x66, 0x6f, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe1, 0x01, 0x0a, - 0x0a, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, 0x04, 0x61, 0x75, 0x74, - 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, - 0x01, 0x52, 0x0d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0xb0, 0x01, 0x0a, 0x10, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, - 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x43, - 0x0a, 0x0e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x66, 0x22, 0x41, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, - 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x2a, 0x0a, 0x0d, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6f, 0x64, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x70, 0x6f, 0x64, 0x43, 0x69, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x0d, 0x52, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x0e, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x0d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5e, - 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x0d, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x1d, - 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, - 0x10, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x4d, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x3c, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x29, - 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x52, 0x75, 0x6e, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x44, 0x0a, 0x11, 0x4c, + 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0xf4, 0x01, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, + 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x72, 0x65, 0x70, 0x6f, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, + 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x72, 0x65, 0x70, 0x6f, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, + 0x28, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x12, 0x16, 0x0a, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x22, 0x3f, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, + 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x13, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2f, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0x41, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x12, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, + 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, + 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x13, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe1, 0x01, 0x0a, 0x0a, 0x41, + 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, 0x08, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, + 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0x80, 0x01, 0x01, 0x52, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0x80, 0x01, 0x01, 0x52, + 0x0d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xb0, + 0x01, 0x0a, 0x10, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x12, 0x2a, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x43, 0x0a, 0x0e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x0d, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, + 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x66, 0x22, 0x41, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, + 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, + 0x0d, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, + 0x0a, 0x08, 0x70, 0x6f, 0x64, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x6f, 0x64, 0x43, 0x69, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x0d, 0x52, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x0e, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5e, 0x0a, 0x1a, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x1d, 0x0a, 0x1b, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, 0x10, 0x52, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x4d, 0x0a, + 0x0d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3c, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x29, 0x0a, 0x0d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x72, + 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, + 0x52, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x27, + 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x46, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, - 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, - 0x76, 0x65, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0e, 0x52, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x3e, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x46, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, - 0x4f, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x1a, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x90, 0x01, + 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x12, 0x3c, 0x0a, 0x1a, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x3f, 0x0a, 0x1c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0x48, 0x6f, 0x73, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0xb6, 0x02, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, @@ -12327,152 +12936,118 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc = stri 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, - 0xf4, 0x02, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x52, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, - 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, - 0x70, 0x75, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x12, 0x42, 0x0a, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x77, 0x61, 0x70, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x73, 0x77, - 0x61, 0x70, 0x12, 0x23, 0x0a, 0x02, 0x69, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6f, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x02, 0x69, 0x6f, 0x22, 0x8a, 0x02, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x12, 0x3f, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, - 0x75, 0x12, 0x36, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x77, 0x72, 0x69, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, - 0x61, 0x79, 0x65, 0x72, 0x22, 0x5c, 0x0a, 0x08, 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x27, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x73, 0x69, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x12, 0x27, 0x0a, 0x04, 0x53, 0x6f, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x53, 0x6f, - 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x07, 0x50, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, - 0x05, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x54, 0x6f, - 0x74, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x76, 0x67, 0x31, 0x30, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x05, 0x41, 0x76, 0x67, 0x31, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x76, 0x67, - 0x36, 0x30, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x41, 0x76, 0x67, 0x36, 0x30, 0x12, - 0x16, 0x0a, 0x06, 0x41, 0x76, 0x67, 0x33, 0x30, 0x30, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x06, 0x41, 0x76, 0x67, 0x33, 0x30, 0x30, 0x22, 0xe3, 0x01, 0x0a, 0x08, 0x43, 0x70, 0x75, 0x55, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x4e, 0x0a, 0x17, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x72, 0x65, - 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x75, 0x73, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x53, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x12, 0x41, 0x0a, 0x10, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, - 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x75, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6e, 0x6f, - 0x43, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0xc2, 0x01, - 0x0a, 0x0f, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x4e, 0x0a, 0x17, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, - 0x6e, 0x6f, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x75, 0x73, 0x61, 0x67, 0x65, - 0x43, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, - 0x41, 0x0a, 0x10, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, - 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0e, 0x75, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x43, 0x6f, 0x72, - 0x65, 0x73, 0x22, 0xc9, 0x03, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, + 0x57, 0x0a, 0x1b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x63, 0x0a, 0x1c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xf4, 0x02, + 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x52, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3f, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, + 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x12, 0x42, 0x0a, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x04, 0x73, 0x77, 0x61, 0x70, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x73, 0x77, 0x61, 0x70, + 0x12, 0x23, 0x0a, 0x02, 0x69, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6f, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x02, 0x69, 0x6f, 0x22, 0x8a, 0x02, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x3f, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x12, 0x2d, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x73, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, + 0x36, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x22, 0x5c, 0x0a, 0x08, 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x27, + 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x73, 0x69, 0x44, 0x61, 0x74, + 0x61, 0x52, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x12, 0x27, 0x0a, 0x04, 0x53, 0x6f, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x53, 0x6f, 0x6d, 0x65, + 0x22, 0x63, 0x0a, 0x07, 0x50, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x54, + 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x54, 0x6f, 0x74, 0x61, + 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x76, 0x67, 0x31, 0x30, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x05, 0x41, 0x76, 0x67, 0x31, 0x30, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x76, 0x67, 0x36, 0x30, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x41, 0x76, 0x67, 0x36, 0x30, 0x12, 0x16, 0x0a, + 0x06, 0x41, 0x76, 0x67, 0x33, 0x30, 0x30, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x41, + 0x76, 0x67, 0x33, 0x30, 0x30, 0x22, 0xe3, 0x01, 0x0a, 0x08, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x43, 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x0f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x12, 0x4e, 0x0a, 0x17, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6e, + 0x61, 0x6e, 0x6f, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x75, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x12, 0x41, 0x0a, 0x10, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x63, + 0x6f, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x75, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x43, 0x6f, + 0x72, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x73, + 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0xc2, 0x01, 0x0a, 0x0f, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x43, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x4e, 0x0a, + 0x17, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, + 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, - 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x75, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x75, 0x73, 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x73, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, - 0x73, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x61, 0x67, 0x65, 0x5f, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x43, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, - 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0x4f, - 0x0a, 0x07, 0x49, 0x6f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, - 0xb7, 0x01, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x49, 0x0a, 0x14, 0x73, - 0x77, 0x61, 0x70, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x12, 0x73, 0x77, 0x61, 0x70, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, - 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x10, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75, - 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x73, 0x77, 0x61, 0x70, 0x55, - 0x73, 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xbc, 0x02, 0x0a, 0x12, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x75, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x72, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x41, 0x0a, + 0x10, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x63, 0x6f, 0x72, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0e, 0x75, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6e, 0x6f, 0x43, 0x6f, 0x72, 0x65, 0x73, + 0x22, 0xc9, 0x03, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x43, 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x62, 0x79, @@ -12483,444 +13058,539 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc = stri 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x75, 0x73, 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x34, 0x0a, 0x09, 0x72, 0x73, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, 0x73, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, - 0x47, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x19, 0x52, 0x65, 0x6f, 0x70, - 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6f, 0x70, - 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x1d, 0x0a, - 0x1b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0xc6, 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x50, - 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x12, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x4a, 0x0a, 0x12, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x70, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x13, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x59, 0x0a, 0x10, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x70, 0x6f, 0x64, 0x5f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0a, 0x70, 0x6f, 0x64, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x24, 0x0a, 0x0e, - 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x12, 0x49, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x63, 0x0a, 0x10, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x22, 0xc5, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x37, 0x0a, - 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x43, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0x4f, 0x0a, 0x07, + 0x49, 0x6f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x03, 0x70, 0x73, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x73, 0x69, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x03, 0x70, 0x73, 0x69, 0x22, 0xb7, 0x01, + 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x49, 0x0a, 0x14, 0x73, 0x77, 0x61, + 0x70, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x12, 0x73, 0x77, 0x61, 0x70, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x10, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x73, 0x77, 0x61, 0x70, 0x55, 0x73, 0x61, + 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xbc, 0x02, 0x0a, 0x12, 0x57, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x43, 0x0a, 0x11, + 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x40, 0x0a, 0x0f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x54, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x6c, 0x69, 0x6e, - 0x75, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x22, 0x5a, 0x0a, 0x19, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x64, 0x72, - 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x72, - 0x69, 0x76, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x72, 0x69, 0x76, - 0x65, 0x72, 0x22, 0xcc, 0x01, 0x0a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, 0x73, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x3f, 0x0a, - 0x08, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x12, 0x41, - 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x47, 0x0a, + 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x19, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc6, + 0x02, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x50, 0x0a, 0x14, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x4a, 0x0a, + 0x12, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x13, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x59, 0x0a, 0x10, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x68, 0x65, 0x6c, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x4b, + 0x65, 0x79, 0x73, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x70, 0x6f, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0a, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x70, 0x0a, 0x1f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x13, 0x70, 0x6f, 0x64, + 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x11, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x24, + 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x12, 0x49, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x10, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x63, 0x0a, + 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x37, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x54, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x6c, + 0x69, 0x6e, 0x75, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x22, 0x5a, 0x0a, 0x19, 0x4c, 0x69, 0x6e, 0x75, + 0x78, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x22, 0xcc, 0x01, 0x0a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, + 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, + 0x3f, 0x0a, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x22, 0x23, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x26, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, - 0x44, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x43, 0x54, 0x50, 0x10, 0x02, 0x2a, 0x6d, - 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x50, - 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x5f, - 0x54, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, - 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x49, - 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x2a, 0x3d, 0x0a, - 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, - 0x0a, 0x03, 0x50, 0x4f, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x54, 0x41, - 0x49, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x02, - 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0x03, 0x2a, 0x31, 0x0a, 0x18, - 0x53, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x10, 0x01, 0x2a, - 0x3a, 0x0a, 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x5f, 0x52, 0x45, - 0x41, 0x44, 0x59, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, - 0x5f, 0x4e, 0x4f, 0x54, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x01, 0x2a, 0xac, 0x08, 0x0a, 0x06, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, - 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x49, 0x47, 0x41, 0x42, 0x52, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x41, - 0x4c, 0x52, 0x4d, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x42, 0x55, 0x53, 0x10, - 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x43, 0x48, 0x4c, 0x44, 0x10, 0x04, 0x12, 0x0a, - 0x0a, 0x06, 0x53, 0x49, 0x47, 0x43, 0x4c, 0x44, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, - 0x47, 0x43, 0x4f, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x46, 0x50, - 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x48, 0x55, 0x50, 0x10, 0x08, 0x12, - 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x49, 0x4c, 0x4c, 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x53, - 0x49, 0x47, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x49, 0x47, 0x49, 0x4f, - 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x49, 0x4f, 0x54, 0x10, 0x0c, 0x12, 0x0b, - 0x0a, 0x07, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x0d, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x49, 0x47, 0x50, 0x49, 0x50, 0x45, 0x10, 0x0e, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x50, - 0x4f, 0x4c, 0x4c, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x50, 0x52, 0x4f, 0x46, - 0x10, 0x10, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x50, 0x57, 0x52, 0x10, 0x11, 0x12, 0x0b, - 0x0a, 0x07, 0x53, 0x49, 0x47, 0x51, 0x55, 0x49, 0x54, 0x10, 0x12, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x49, 0x47, 0x53, 0x45, 0x47, 0x56, 0x10, 0x13, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x49, 0x47, 0x53, - 0x54, 0x4b, 0x46, 0x4c, 0x54, 0x10, 0x14, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x53, 0x54, - 0x4f, 0x50, 0x10, 0x15, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x53, 0x59, 0x53, 0x10, 0x16, - 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x45, 0x52, 0x4d, 0x10, 0x17, 0x12, 0x0b, 0x0a, - 0x07, 0x53, 0x49, 0x47, 0x54, 0x52, 0x41, 0x50, 0x10, 0x18, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, - 0x47, 0x54, 0x53, 0x54, 0x50, 0x10, 0x19, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x54, - 0x49, 0x4e, 0x10, 0x1a, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x54, 0x4f, 0x55, 0x10, - 0x1b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x55, 0x52, 0x47, 0x10, 0x1c, 0x12, 0x0b, 0x0a, - 0x07, 0x53, 0x49, 0x47, 0x55, 0x53, 0x52, 0x31, 0x10, 0x1d, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, - 0x47, 0x55, 0x53, 0x52, 0x32, 0x10, 0x1e, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x49, 0x47, 0x56, 0x54, - 0x41, 0x4c, 0x52, 0x4d, 0x10, 0x1f, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x49, 0x47, 0x57, 0x49, 0x4e, - 0x43, 0x48, 0x10, 0x20, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x58, 0x43, 0x50, 0x55, 0x10, - 0x21, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x58, 0x46, 0x53, 0x5a, 0x10, 0x22, 0x12, 0x0c, - 0x0a, 0x08, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x10, 0x23, 0x12, 0x11, 0x0a, 0x0d, - 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x10, 0x24, 0x12, - 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x32, - 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, - 0x55, 0x53, 0x33, 0x10, 0x26, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, - 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x34, 0x10, 0x27, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, - 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x35, 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, 0x53, - 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x36, 0x10, 0x29, 0x12, 0x11, - 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x37, 0x10, - 0x2a, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, - 0x53, 0x38, 0x10, 0x2b, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, - 0x50, 0x4c, 0x55, 0x53, 0x39, 0x10, 0x2c, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, - 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x30, 0x10, 0x2d, 0x12, 0x12, 0x0a, 0x0e, 0x53, - 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x31, 0x10, 0x2e, 0x12, - 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, - 0x32, 0x10, 0x2f, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, - 0x4c, 0x55, 0x53, 0x31, 0x33, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, - 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x34, 0x10, 0x31, 0x12, 0x12, 0x0a, 0x0e, 0x53, - 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x35, 0x10, 0x32, 0x12, - 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, - 0x31, 0x34, 0x10, 0x33, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, - 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x33, 0x10, 0x34, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, - 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x32, 0x10, 0x35, 0x12, 0x13, - 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, - 0x31, 0x10, 0x36, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, - 0x49, 0x4e, 0x55, 0x53, 0x31, 0x30, 0x10, 0x37, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, - 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x39, 0x10, 0x38, 0x12, 0x12, 0x0a, 0x0e, - 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x38, 0x10, 0x39, - 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, - 0x53, 0x37, 0x10, 0x3a, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, - 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x36, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, - 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x35, 0x10, 0x3c, 0x12, 0x12, 0x0a, 0x0e, - 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x34, 0x10, 0x3d, - 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, - 0x53, 0x33, 0x10, 0x3e, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, - 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x32, 0x10, 0x3f, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, - 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x10, 0x40, 0x12, 0x0c, 0x0a, 0x08, - 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x10, 0x41, 0x2a, 0x6b, 0x0a, 0x0e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, - 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, - 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, - 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x45, 0x44, 0x10, 0x02, - 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x88, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, - 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x45, 0x41, - 0x54, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x43, - 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, - 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, - 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x5f, 0x45, 0x56, - 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, - 0x45, 0x52, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, - 0x10, 0x03, 0x2a, 0x24, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, - 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x01, 0x2a, 0x29, 0x0a, 0x0c, 0x43, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x59, 0x53, 0x54, - 0x45, 0x4d, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x46, - 0x53, 0x10, 0x01, 0x32, 0xfa, 0x15, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, - 0x52, 0x75, 0x6e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x20, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, - 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x64, 0x53, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x5f, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x64, 0x53, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x5f, 0x0a, 0x10, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x0f, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, - 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, + 0x12, 0x41, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x26, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, + 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x43, 0x54, 0x50, 0x10, 0x02, + 0x2a, 0x6d, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x21, 0x0a, + 0x1d, 0x50, 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x4f, 0x53, + 0x54, 0x5f, 0x54, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x01, + 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x50, 0x41, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x42, 0x49, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x2a, + 0x3d, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x07, 0x0a, 0x03, 0x50, 0x4f, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, + 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, + 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0x03, 0x2a, 0x31, + 0x0a, 0x18, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x10, + 0x01, 0x2a, 0x3a, 0x0a, 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x41, 0x4e, 0x44, 0x42, + 0x4f, 0x58, 0x5f, 0x4e, 0x4f, 0x54, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x01, 0x2a, 0xac, 0x08, + 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x55, 0x4e, 0x54, + 0x49, 0x4d, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x53, 0x49, 0x47, 0x41, 0x42, 0x52, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, + 0x47, 0x41, 0x4c, 0x52, 0x4d, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x42, 0x55, + 0x53, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x43, 0x48, 0x4c, 0x44, 0x10, 0x04, + 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x43, 0x4c, 0x44, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, + 0x53, 0x49, 0x47, 0x43, 0x4f, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, + 0x46, 0x50, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x48, 0x55, 0x50, 0x10, + 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x49, 0x4c, 0x4c, 0x10, 0x09, 0x12, 0x0a, 0x0a, + 0x06, 0x53, 0x49, 0x47, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x49, 0x47, + 0x49, 0x4f, 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x49, 0x4f, 0x54, 0x10, 0x0c, + 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x4b, 0x49, 0x4c, 0x4c, 0x10, 0x0d, 0x12, 0x0b, 0x0a, + 0x07, 0x53, 0x49, 0x47, 0x50, 0x49, 0x50, 0x45, 0x10, 0x0e, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, + 0x47, 0x50, 0x4f, 0x4c, 0x4c, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x50, 0x52, + 0x4f, 0x46, 0x10, 0x10, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x50, 0x57, 0x52, 0x10, 0x11, + 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x51, 0x55, 0x49, 0x54, 0x10, 0x12, 0x12, 0x0b, 0x0a, + 0x07, 0x53, 0x49, 0x47, 0x53, 0x45, 0x47, 0x56, 0x10, 0x13, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x49, + 0x47, 0x53, 0x54, 0x4b, 0x46, 0x4c, 0x54, 0x10, 0x14, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, + 0x53, 0x54, 0x4f, 0x50, 0x10, 0x15, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x53, 0x59, 0x53, + 0x10, 0x16, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x45, 0x52, 0x4d, 0x10, 0x17, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x52, 0x41, 0x50, 0x10, 0x18, 0x12, 0x0b, 0x0a, 0x07, + 0x53, 0x49, 0x47, 0x54, 0x53, 0x54, 0x50, 0x10, 0x19, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, + 0x54, 0x54, 0x49, 0x4e, 0x10, 0x1a, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x54, 0x54, 0x4f, + 0x55, 0x10, 0x1b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x47, 0x55, 0x52, 0x47, 0x10, 0x1c, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x55, 0x53, 0x52, 0x31, 0x10, 0x1d, 0x12, 0x0b, 0x0a, 0x07, + 0x53, 0x49, 0x47, 0x55, 0x53, 0x52, 0x32, 0x10, 0x1e, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x49, 0x47, + 0x56, 0x54, 0x41, 0x4c, 0x52, 0x4d, 0x10, 0x1f, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x49, 0x47, 0x57, + 0x49, 0x4e, 0x43, 0x48, 0x10, 0x20, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x58, 0x43, 0x50, + 0x55, 0x10, 0x21, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x49, 0x47, 0x58, 0x46, 0x53, 0x5a, 0x10, 0x22, + 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x10, 0x23, 0x12, 0x11, + 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x10, + 0x24, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, + 0x53, 0x32, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, + 0x50, 0x4c, 0x55, 0x53, 0x33, 0x10, 0x26, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, + 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x34, 0x10, 0x27, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, + 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x35, 0x10, 0x28, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x36, 0x10, 0x29, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, + 0x37, 0x10, 0x2a, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, + 0x4c, 0x55, 0x53, 0x38, 0x10, 0x2b, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, + 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x39, 0x10, 0x2c, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, + 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x30, 0x10, 0x2d, 0x12, 0x12, 0x0a, + 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x31, 0x10, + 0x2e, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, + 0x53, 0x31, 0x32, 0x10, 0x2f, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, + 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x33, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, + 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x34, 0x10, 0x31, 0x12, 0x12, 0x0a, + 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x49, 0x4e, 0x50, 0x4c, 0x55, 0x53, 0x31, 0x35, 0x10, + 0x32, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, + 0x55, 0x53, 0x31, 0x34, 0x10, 0x33, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, + 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x33, 0x10, 0x34, 0x12, 0x13, 0x0a, 0x0f, 0x53, + 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x32, 0x10, 0x35, + 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, + 0x53, 0x31, 0x31, 0x10, 0x36, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, + 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x30, 0x10, 0x37, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, + 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x39, 0x10, 0x38, 0x12, 0x12, + 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x38, + 0x10, 0x39, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, + 0x4e, 0x55, 0x53, 0x37, 0x10, 0x3a, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, + 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x36, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, + 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x35, 0x10, 0x3c, 0x12, 0x12, + 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x34, + 0x10, 0x3d, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, + 0x4e, 0x55, 0x53, 0x33, 0x10, 0x3e, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, + 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x32, 0x10, 0x3f, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x49, + 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x31, 0x10, 0x40, 0x12, 0x0c, + 0x0a, 0x08, 0x53, 0x49, 0x47, 0x52, 0x54, 0x4d, 0x41, 0x58, 0x10, 0x41, 0x2a, 0x6b, 0x0a, 0x0e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, + 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, + 0x45, 0x52, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, + 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, + 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x88, 0x01, 0x0a, 0x12, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x1b, 0x0a, + 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, + 0x45, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, + 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x5f, + 0x45, 0x56, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x41, + 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x5f, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x10, 0x03, 0x2a, 0x24, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, + 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x01, 0x2a, 0x29, 0x0a, 0x0c, 0x43, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x59, + 0x53, 0x54, 0x45, 0x4d, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x46, 0x53, 0x10, 0x01, 0x32, 0x9f, 0x1a, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, + 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, + 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x75, 0x6e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x5f, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x10, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, + 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x56, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x12, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, - 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x4c, - 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x77, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, - 0x12, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x4c, 0x6f, 0x67, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, - 0x12, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, - 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, - 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, - 0x04, 0x45, 0x78, 0x65, 0x63, 0x12, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x61, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x77, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2b, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x12, 0x52, + 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, + 0x67, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x47, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x41, 0x74, - 0x74, 0x61, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, - 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, - 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x59, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x12, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5c, 0x0a, 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x68, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x79, 0x6e, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x04, 0x45, + 0x78, 0x65, 0x63, 0x12, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x41, 0x74, 0x74, 0x61, + 0x63, 0x68, 0x12, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x50, + 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, + 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x6d, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5c, + 0x0a, 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x12, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x13, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x26, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x5a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x15, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x15, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x32, 0x9f, 0x03, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, - 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x41, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x5a, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x15, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x15, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x50, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, - 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x17, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x19, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xf6, 0x03, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x50, + 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4a, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, - 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x50, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x24, 0x5a, 0x22, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x63, 0x72, 0x69, - 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x46, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x24, 0x5a, 0x22, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x63, 0x72, 0x69, 0x2d, 0x61, + 0x70, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -12936,7 +13606,7 @@ func file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDescGZIP() } var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_enumTypes = make([]protoimpl.EnumInfo, 11) -var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 186) +var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 198) var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_goTypes = []any{ (Protocol)(0), // 0: runtime.v1.Protocol (MountPropagation)(0), // 1: runtime.v1.MountPropagation @@ -12981,167 +13651,179 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_goTypes = []an (*ListPodSandboxRequest)(nil), // 40: runtime.v1.ListPodSandboxRequest (*PodSandbox)(nil), // 41: runtime.v1.PodSandbox (*ListPodSandboxResponse)(nil), // 42: runtime.v1.ListPodSandboxResponse - (*PodSandboxStatsRequest)(nil), // 43: runtime.v1.PodSandboxStatsRequest - (*PodSandboxStatsResponse)(nil), // 44: runtime.v1.PodSandboxStatsResponse - (*PodSandboxStatsFilter)(nil), // 45: runtime.v1.PodSandboxStatsFilter - (*ListPodSandboxStatsRequest)(nil), // 46: runtime.v1.ListPodSandboxStatsRequest - (*ListPodSandboxStatsResponse)(nil), // 47: runtime.v1.ListPodSandboxStatsResponse - (*PodSandboxAttributes)(nil), // 48: runtime.v1.PodSandboxAttributes - (*PodSandboxStats)(nil), // 49: runtime.v1.PodSandboxStats - (*LinuxPodSandboxStats)(nil), // 50: runtime.v1.LinuxPodSandboxStats - (*WindowsPodSandboxStats)(nil), // 51: runtime.v1.WindowsPodSandboxStats - (*NetworkUsage)(nil), // 52: runtime.v1.NetworkUsage - (*WindowsNetworkUsage)(nil), // 53: runtime.v1.WindowsNetworkUsage - (*NetworkInterfaceUsage)(nil), // 54: runtime.v1.NetworkInterfaceUsage - (*WindowsNetworkInterfaceUsage)(nil), // 55: runtime.v1.WindowsNetworkInterfaceUsage - (*ProcessUsage)(nil), // 56: runtime.v1.ProcessUsage - (*WindowsProcessUsage)(nil), // 57: runtime.v1.WindowsProcessUsage - (*ImageSpec)(nil), // 58: runtime.v1.ImageSpec - (*KeyValue)(nil), // 59: runtime.v1.KeyValue - (*LinuxContainerResources)(nil), // 60: runtime.v1.LinuxContainerResources - (*HugepageLimit)(nil), // 61: runtime.v1.HugepageLimit - (*SELinuxOption)(nil), // 62: runtime.v1.SELinuxOption - (*Capability)(nil), // 63: runtime.v1.Capability - (*LinuxContainerSecurityContext)(nil), // 64: runtime.v1.LinuxContainerSecurityContext - (*LinuxContainerConfig)(nil), // 65: runtime.v1.LinuxContainerConfig - (*LinuxContainerUser)(nil), // 66: runtime.v1.LinuxContainerUser - (*WindowsNamespaceOption)(nil), // 67: runtime.v1.WindowsNamespaceOption - (*WindowsSandboxSecurityContext)(nil), // 68: runtime.v1.WindowsSandboxSecurityContext - (*WindowsPodSandboxConfig)(nil), // 69: runtime.v1.WindowsPodSandboxConfig - (*WindowsContainerSecurityContext)(nil), // 70: runtime.v1.WindowsContainerSecurityContext - (*WindowsContainerConfig)(nil), // 71: runtime.v1.WindowsContainerConfig - (*WindowsContainerResources)(nil), // 72: runtime.v1.WindowsContainerResources - (*WindowsCpuGroupAffinity)(nil), // 73: runtime.v1.WindowsCpuGroupAffinity - (*ContainerMetadata)(nil), // 74: runtime.v1.ContainerMetadata - (*Device)(nil), // 75: runtime.v1.Device - (*CDIDevice)(nil), // 76: runtime.v1.CDIDevice - (*ContainerConfig)(nil), // 77: runtime.v1.ContainerConfig - (*CreateContainerRequest)(nil), // 78: runtime.v1.CreateContainerRequest - (*CreateContainerResponse)(nil), // 79: runtime.v1.CreateContainerResponse - (*StartContainerRequest)(nil), // 80: runtime.v1.StartContainerRequest - (*StartContainerResponse)(nil), // 81: runtime.v1.StartContainerResponse - (*StopContainerRequest)(nil), // 82: runtime.v1.StopContainerRequest - (*StopContainerResponse)(nil), // 83: runtime.v1.StopContainerResponse - (*RemoveContainerRequest)(nil), // 84: runtime.v1.RemoveContainerRequest - (*RemoveContainerResponse)(nil), // 85: runtime.v1.RemoveContainerResponse - (*ContainerStateValue)(nil), // 86: runtime.v1.ContainerStateValue - (*ContainerFilter)(nil), // 87: runtime.v1.ContainerFilter - (*ListContainersRequest)(nil), // 88: runtime.v1.ListContainersRequest - (*Container)(nil), // 89: runtime.v1.Container - (*ListContainersResponse)(nil), // 90: runtime.v1.ListContainersResponse - (*ContainerStatusRequest)(nil), // 91: runtime.v1.ContainerStatusRequest - (*ContainerStatus)(nil), // 92: runtime.v1.ContainerStatus - (*ContainerStatusResponse)(nil), // 93: runtime.v1.ContainerStatusResponse - (*ContainerResources)(nil), // 94: runtime.v1.ContainerResources - (*ContainerUser)(nil), // 95: runtime.v1.ContainerUser - (*UpdateContainerResourcesRequest)(nil), // 96: runtime.v1.UpdateContainerResourcesRequest - (*UpdateContainerResourcesResponse)(nil), // 97: runtime.v1.UpdateContainerResourcesResponse - (*ExecSyncRequest)(nil), // 98: runtime.v1.ExecSyncRequest - (*ExecSyncResponse)(nil), // 99: runtime.v1.ExecSyncResponse - (*ExecRequest)(nil), // 100: runtime.v1.ExecRequest - (*ExecResponse)(nil), // 101: runtime.v1.ExecResponse - (*AttachRequest)(nil), // 102: runtime.v1.AttachRequest - (*AttachResponse)(nil), // 103: runtime.v1.AttachResponse - (*PortForwardRequest)(nil), // 104: runtime.v1.PortForwardRequest - (*PortForwardResponse)(nil), // 105: runtime.v1.PortForwardResponse - (*ImageFilter)(nil), // 106: runtime.v1.ImageFilter - (*ListImagesRequest)(nil), // 107: runtime.v1.ListImagesRequest - (*Image)(nil), // 108: runtime.v1.Image - (*ListImagesResponse)(nil), // 109: runtime.v1.ListImagesResponse - (*ImageStatusRequest)(nil), // 110: runtime.v1.ImageStatusRequest - (*ImageStatusResponse)(nil), // 111: runtime.v1.ImageStatusResponse - (*AuthConfig)(nil), // 112: runtime.v1.AuthConfig - (*PullImageRequest)(nil), // 113: runtime.v1.PullImageRequest - (*PullImageResponse)(nil), // 114: runtime.v1.PullImageResponse - (*RemoveImageRequest)(nil), // 115: runtime.v1.RemoveImageRequest - (*RemoveImageResponse)(nil), // 116: runtime.v1.RemoveImageResponse - (*NetworkConfig)(nil), // 117: runtime.v1.NetworkConfig - (*RuntimeConfig)(nil), // 118: runtime.v1.RuntimeConfig - (*UpdateRuntimeConfigRequest)(nil), // 119: runtime.v1.UpdateRuntimeConfigRequest - (*UpdateRuntimeConfigResponse)(nil), // 120: runtime.v1.UpdateRuntimeConfigResponse - (*RuntimeCondition)(nil), // 121: runtime.v1.RuntimeCondition - (*RuntimeStatus)(nil), // 122: runtime.v1.RuntimeStatus - (*StatusRequest)(nil), // 123: runtime.v1.StatusRequest - (*RuntimeHandlerFeatures)(nil), // 124: runtime.v1.RuntimeHandlerFeatures - (*RuntimeHandler)(nil), // 125: runtime.v1.RuntimeHandler - (*RuntimeFeatures)(nil), // 126: runtime.v1.RuntimeFeatures - (*StatusResponse)(nil), // 127: runtime.v1.StatusResponse - (*ImageFsInfoRequest)(nil), // 128: runtime.v1.ImageFsInfoRequest - (*UInt64Value)(nil), // 129: runtime.v1.UInt64Value - (*FilesystemIdentifier)(nil), // 130: runtime.v1.FilesystemIdentifier - (*FilesystemUsage)(nil), // 131: runtime.v1.FilesystemUsage - (*WindowsFilesystemUsage)(nil), // 132: runtime.v1.WindowsFilesystemUsage - (*ImageFsInfoResponse)(nil), // 133: runtime.v1.ImageFsInfoResponse - (*ContainerStatsRequest)(nil), // 134: runtime.v1.ContainerStatsRequest - (*ContainerStatsResponse)(nil), // 135: runtime.v1.ContainerStatsResponse - (*ListContainerStatsRequest)(nil), // 136: runtime.v1.ListContainerStatsRequest - (*ContainerStatsFilter)(nil), // 137: runtime.v1.ContainerStatsFilter - (*ListContainerStatsResponse)(nil), // 138: runtime.v1.ListContainerStatsResponse - (*ContainerAttributes)(nil), // 139: runtime.v1.ContainerAttributes - (*ContainerStats)(nil), // 140: runtime.v1.ContainerStats - (*WindowsContainerStats)(nil), // 141: runtime.v1.WindowsContainerStats - (*PsiStats)(nil), // 142: runtime.v1.PsiStats - (*PsiData)(nil), // 143: runtime.v1.PsiData - (*CpuUsage)(nil), // 144: runtime.v1.CpuUsage - (*WindowsCpuUsage)(nil), // 145: runtime.v1.WindowsCpuUsage - (*MemoryUsage)(nil), // 146: runtime.v1.MemoryUsage - (*IoUsage)(nil), // 147: runtime.v1.IoUsage - (*SwapUsage)(nil), // 148: runtime.v1.SwapUsage - (*WindowsMemoryUsage)(nil), // 149: runtime.v1.WindowsMemoryUsage - (*ReopenContainerLogRequest)(nil), // 150: runtime.v1.ReopenContainerLogRequest - (*ReopenContainerLogResponse)(nil), // 151: runtime.v1.ReopenContainerLogResponse - (*CheckpointContainerRequest)(nil), // 152: runtime.v1.CheckpointContainerRequest - (*CheckpointContainerResponse)(nil), // 153: runtime.v1.CheckpointContainerResponse - (*GetEventsRequest)(nil), // 154: runtime.v1.GetEventsRequest - (*ContainerEventResponse)(nil), // 155: runtime.v1.ContainerEventResponse - (*ListMetricDescriptorsRequest)(nil), // 156: runtime.v1.ListMetricDescriptorsRequest - (*ListMetricDescriptorsResponse)(nil), // 157: runtime.v1.ListMetricDescriptorsResponse - (*MetricDescriptor)(nil), // 158: runtime.v1.MetricDescriptor - (*ListPodSandboxMetricsRequest)(nil), // 159: runtime.v1.ListPodSandboxMetricsRequest - (*ListPodSandboxMetricsResponse)(nil), // 160: runtime.v1.ListPodSandboxMetricsResponse - (*PodSandboxMetrics)(nil), // 161: runtime.v1.PodSandboxMetrics - (*ContainerMetrics)(nil), // 162: runtime.v1.ContainerMetrics - (*Metric)(nil), // 163: runtime.v1.Metric - (*RuntimeConfigRequest)(nil), // 164: runtime.v1.RuntimeConfigRequest - (*RuntimeConfigResponse)(nil), // 165: runtime.v1.RuntimeConfigResponse - (*LinuxRuntimeConfiguration)(nil), // 166: runtime.v1.LinuxRuntimeConfiguration - (*UpdatePodSandboxResourcesRequest)(nil), // 167: runtime.v1.UpdatePodSandboxResourcesRequest - (*UpdatePodSandboxResourcesResponse)(nil), // 168: runtime.v1.UpdatePodSandboxResourcesResponse - nil, // 169: runtime.v1.LinuxPodSandboxConfig.SysctlsEntry - nil, // 170: runtime.v1.PodSandboxConfig.LabelsEntry - nil, // 171: runtime.v1.PodSandboxConfig.AnnotationsEntry - nil, // 172: runtime.v1.PodSandboxStatus.LabelsEntry - nil, // 173: runtime.v1.PodSandboxStatus.AnnotationsEntry - nil, // 174: runtime.v1.PodSandboxStatusResponse.InfoEntry - nil, // 175: runtime.v1.PodSandboxFilter.LabelSelectorEntry - nil, // 176: runtime.v1.PodSandbox.LabelsEntry - nil, // 177: runtime.v1.PodSandbox.AnnotationsEntry - nil, // 178: runtime.v1.PodSandboxStatsFilter.LabelSelectorEntry - nil, // 179: runtime.v1.PodSandboxAttributes.LabelsEntry - nil, // 180: runtime.v1.PodSandboxAttributes.AnnotationsEntry - nil, // 181: runtime.v1.ImageSpec.AnnotationsEntry - nil, // 182: runtime.v1.LinuxContainerResources.UnifiedEntry - nil, // 183: runtime.v1.ContainerConfig.LabelsEntry - nil, // 184: runtime.v1.ContainerConfig.AnnotationsEntry - nil, // 185: runtime.v1.ContainerFilter.LabelSelectorEntry - nil, // 186: runtime.v1.Container.LabelsEntry - nil, // 187: runtime.v1.Container.AnnotationsEntry - nil, // 188: runtime.v1.ContainerStatus.LabelsEntry - nil, // 189: runtime.v1.ContainerStatus.AnnotationsEntry - nil, // 190: runtime.v1.ContainerStatusResponse.InfoEntry - nil, // 191: runtime.v1.UpdateContainerResourcesRequest.AnnotationsEntry - nil, // 192: runtime.v1.ImageStatusResponse.InfoEntry - nil, // 193: runtime.v1.StatusResponse.InfoEntry - nil, // 194: runtime.v1.ContainerStatsFilter.LabelSelectorEntry - nil, // 195: runtime.v1.ContainerAttributes.LabelsEntry - nil, // 196: runtime.v1.ContainerAttributes.AnnotationsEntry + (*StreamPodSandboxesRequest)(nil), // 43: runtime.v1.StreamPodSandboxesRequest + (*StreamPodSandboxesResponse)(nil), // 44: runtime.v1.StreamPodSandboxesResponse + (*PodSandboxStatsRequest)(nil), // 45: runtime.v1.PodSandboxStatsRequest + (*PodSandboxStatsResponse)(nil), // 46: runtime.v1.PodSandboxStatsResponse + (*PodSandboxStatsFilter)(nil), // 47: runtime.v1.PodSandboxStatsFilter + (*ListPodSandboxStatsRequest)(nil), // 48: runtime.v1.ListPodSandboxStatsRequest + (*ListPodSandboxStatsResponse)(nil), // 49: runtime.v1.ListPodSandboxStatsResponse + (*StreamPodSandboxStatsRequest)(nil), // 50: runtime.v1.StreamPodSandboxStatsRequest + (*StreamPodSandboxStatsResponse)(nil), // 51: runtime.v1.StreamPodSandboxStatsResponse + (*PodSandboxAttributes)(nil), // 52: runtime.v1.PodSandboxAttributes + (*PodSandboxStats)(nil), // 53: runtime.v1.PodSandboxStats + (*LinuxPodSandboxStats)(nil), // 54: runtime.v1.LinuxPodSandboxStats + (*WindowsPodSandboxStats)(nil), // 55: runtime.v1.WindowsPodSandboxStats + (*NetworkUsage)(nil), // 56: runtime.v1.NetworkUsage + (*WindowsNetworkUsage)(nil), // 57: runtime.v1.WindowsNetworkUsage + (*NetworkInterfaceUsage)(nil), // 58: runtime.v1.NetworkInterfaceUsage + (*WindowsNetworkInterfaceUsage)(nil), // 59: runtime.v1.WindowsNetworkInterfaceUsage + (*ProcessUsage)(nil), // 60: runtime.v1.ProcessUsage + (*WindowsProcessUsage)(nil), // 61: runtime.v1.WindowsProcessUsage + (*ImageSpec)(nil), // 62: runtime.v1.ImageSpec + (*KeyValue)(nil), // 63: runtime.v1.KeyValue + (*LinuxContainerResources)(nil), // 64: runtime.v1.LinuxContainerResources + (*HugepageLimit)(nil), // 65: runtime.v1.HugepageLimit + (*SELinuxOption)(nil), // 66: runtime.v1.SELinuxOption + (*Capability)(nil), // 67: runtime.v1.Capability + (*LinuxContainerSecurityContext)(nil), // 68: runtime.v1.LinuxContainerSecurityContext + (*LinuxContainerConfig)(nil), // 69: runtime.v1.LinuxContainerConfig + (*LinuxContainerUser)(nil), // 70: runtime.v1.LinuxContainerUser + (*WindowsNamespaceOption)(nil), // 71: runtime.v1.WindowsNamespaceOption + (*WindowsSandboxSecurityContext)(nil), // 72: runtime.v1.WindowsSandboxSecurityContext + (*WindowsPodSandboxConfig)(nil), // 73: runtime.v1.WindowsPodSandboxConfig + (*WindowsContainerSecurityContext)(nil), // 74: runtime.v1.WindowsContainerSecurityContext + (*WindowsContainerConfig)(nil), // 75: runtime.v1.WindowsContainerConfig + (*WindowsContainerResources)(nil), // 76: runtime.v1.WindowsContainerResources + (*WindowsCpuGroupAffinity)(nil), // 77: runtime.v1.WindowsCpuGroupAffinity + (*ContainerMetadata)(nil), // 78: runtime.v1.ContainerMetadata + (*Device)(nil), // 79: runtime.v1.Device + (*CDIDevice)(nil), // 80: runtime.v1.CDIDevice + (*ContainerConfig)(nil), // 81: runtime.v1.ContainerConfig + (*CreateContainerRequest)(nil), // 82: runtime.v1.CreateContainerRequest + (*CreateContainerResponse)(nil), // 83: runtime.v1.CreateContainerResponse + (*StartContainerRequest)(nil), // 84: runtime.v1.StartContainerRequest + (*StartContainerResponse)(nil), // 85: runtime.v1.StartContainerResponse + (*StopContainerRequest)(nil), // 86: runtime.v1.StopContainerRequest + (*StopContainerResponse)(nil), // 87: runtime.v1.StopContainerResponse + (*RemoveContainerRequest)(nil), // 88: runtime.v1.RemoveContainerRequest + (*RemoveContainerResponse)(nil), // 89: runtime.v1.RemoveContainerResponse + (*ContainerStateValue)(nil), // 90: runtime.v1.ContainerStateValue + (*ContainerFilter)(nil), // 91: runtime.v1.ContainerFilter + (*ListContainersRequest)(nil), // 92: runtime.v1.ListContainersRequest + (*Container)(nil), // 93: runtime.v1.Container + (*ListContainersResponse)(nil), // 94: runtime.v1.ListContainersResponse + (*StreamContainersRequest)(nil), // 95: runtime.v1.StreamContainersRequest + (*StreamContainersResponse)(nil), // 96: runtime.v1.StreamContainersResponse + (*ContainerStatusRequest)(nil), // 97: runtime.v1.ContainerStatusRequest + (*ContainerStatus)(nil), // 98: runtime.v1.ContainerStatus + (*ContainerStatusResponse)(nil), // 99: runtime.v1.ContainerStatusResponse + (*ContainerResources)(nil), // 100: runtime.v1.ContainerResources + (*ContainerUser)(nil), // 101: runtime.v1.ContainerUser + (*UpdateContainerResourcesRequest)(nil), // 102: runtime.v1.UpdateContainerResourcesRequest + (*UpdateContainerResourcesResponse)(nil), // 103: runtime.v1.UpdateContainerResourcesResponse + (*ExecSyncRequest)(nil), // 104: runtime.v1.ExecSyncRequest + (*ExecSyncResponse)(nil), // 105: runtime.v1.ExecSyncResponse + (*ExecRequest)(nil), // 106: runtime.v1.ExecRequest + (*ExecResponse)(nil), // 107: runtime.v1.ExecResponse + (*AttachRequest)(nil), // 108: runtime.v1.AttachRequest + (*AttachResponse)(nil), // 109: runtime.v1.AttachResponse + (*PortForwardRequest)(nil), // 110: runtime.v1.PortForwardRequest + (*PortForwardResponse)(nil), // 111: runtime.v1.PortForwardResponse + (*ImageFilter)(nil), // 112: runtime.v1.ImageFilter + (*ListImagesRequest)(nil), // 113: runtime.v1.ListImagesRequest + (*Image)(nil), // 114: runtime.v1.Image + (*ListImagesResponse)(nil), // 115: runtime.v1.ListImagesResponse + (*StreamImagesRequest)(nil), // 116: runtime.v1.StreamImagesRequest + (*StreamImagesResponse)(nil), // 117: runtime.v1.StreamImagesResponse + (*ImageStatusRequest)(nil), // 118: runtime.v1.ImageStatusRequest + (*ImageStatusResponse)(nil), // 119: runtime.v1.ImageStatusResponse + (*AuthConfig)(nil), // 120: runtime.v1.AuthConfig + (*PullImageRequest)(nil), // 121: runtime.v1.PullImageRequest + (*PullImageResponse)(nil), // 122: runtime.v1.PullImageResponse + (*RemoveImageRequest)(nil), // 123: runtime.v1.RemoveImageRequest + (*RemoveImageResponse)(nil), // 124: runtime.v1.RemoveImageResponse + (*NetworkConfig)(nil), // 125: runtime.v1.NetworkConfig + (*RuntimeConfig)(nil), // 126: runtime.v1.RuntimeConfig + (*UpdateRuntimeConfigRequest)(nil), // 127: runtime.v1.UpdateRuntimeConfigRequest + (*UpdateRuntimeConfigResponse)(nil), // 128: runtime.v1.UpdateRuntimeConfigResponse + (*RuntimeCondition)(nil), // 129: runtime.v1.RuntimeCondition + (*RuntimeStatus)(nil), // 130: runtime.v1.RuntimeStatus + (*StatusRequest)(nil), // 131: runtime.v1.StatusRequest + (*RuntimeHandlerFeatures)(nil), // 132: runtime.v1.RuntimeHandlerFeatures + (*RuntimeHandler)(nil), // 133: runtime.v1.RuntimeHandler + (*RuntimeFeatures)(nil), // 134: runtime.v1.RuntimeFeatures + (*StatusResponse)(nil), // 135: runtime.v1.StatusResponse + (*ImageFsInfoRequest)(nil), // 136: runtime.v1.ImageFsInfoRequest + (*UInt64Value)(nil), // 137: runtime.v1.UInt64Value + (*FilesystemIdentifier)(nil), // 138: runtime.v1.FilesystemIdentifier + (*FilesystemUsage)(nil), // 139: runtime.v1.FilesystemUsage + (*WindowsFilesystemUsage)(nil), // 140: runtime.v1.WindowsFilesystemUsage + (*ImageFsInfoResponse)(nil), // 141: runtime.v1.ImageFsInfoResponse + (*ContainerStatsRequest)(nil), // 142: runtime.v1.ContainerStatsRequest + (*ContainerStatsResponse)(nil), // 143: runtime.v1.ContainerStatsResponse + (*ListContainerStatsRequest)(nil), // 144: runtime.v1.ListContainerStatsRequest + (*ContainerStatsFilter)(nil), // 145: runtime.v1.ContainerStatsFilter + (*ListContainerStatsResponse)(nil), // 146: runtime.v1.ListContainerStatsResponse + (*StreamContainerStatsRequest)(nil), // 147: runtime.v1.StreamContainerStatsRequest + (*StreamContainerStatsResponse)(nil), // 148: runtime.v1.StreamContainerStatsResponse + (*ContainerAttributes)(nil), // 149: runtime.v1.ContainerAttributes + (*ContainerStats)(nil), // 150: runtime.v1.ContainerStats + (*WindowsContainerStats)(nil), // 151: runtime.v1.WindowsContainerStats + (*PsiStats)(nil), // 152: runtime.v1.PsiStats + (*PsiData)(nil), // 153: runtime.v1.PsiData + (*CpuUsage)(nil), // 154: runtime.v1.CpuUsage + (*WindowsCpuUsage)(nil), // 155: runtime.v1.WindowsCpuUsage + (*MemoryUsage)(nil), // 156: runtime.v1.MemoryUsage + (*IoUsage)(nil), // 157: runtime.v1.IoUsage + (*SwapUsage)(nil), // 158: runtime.v1.SwapUsage + (*WindowsMemoryUsage)(nil), // 159: runtime.v1.WindowsMemoryUsage + (*ReopenContainerLogRequest)(nil), // 160: runtime.v1.ReopenContainerLogRequest + (*ReopenContainerLogResponse)(nil), // 161: runtime.v1.ReopenContainerLogResponse + (*CheckpointContainerRequest)(nil), // 162: runtime.v1.CheckpointContainerRequest + (*CheckpointContainerResponse)(nil), // 163: runtime.v1.CheckpointContainerResponse + (*GetEventsRequest)(nil), // 164: runtime.v1.GetEventsRequest + (*ContainerEventResponse)(nil), // 165: runtime.v1.ContainerEventResponse + (*ListMetricDescriptorsRequest)(nil), // 166: runtime.v1.ListMetricDescriptorsRequest + (*ListMetricDescriptorsResponse)(nil), // 167: runtime.v1.ListMetricDescriptorsResponse + (*MetricDescriptor)(nil), // 168: runtime.v1.MetricDescriptor + (*ListPodSandboxMetricsRequest)(nil), // 169: runtime.v1.ListPodSandboxMetricsRequest + (*ListPodSandboxMetricsResponse)(nil), // 170: runtime.v1.ListPodSandboxMetricsResponse + (*StreamPodSandboxMetricsRequest)(nil), // 171: runtime.v1.StreamPodSandboxMetricsRequest + (*StreamPodSandboxMetricsResponse)(nil), // 172: runtime.v1.StreamPodSandboxMetricsResponse + (*PodSandboxMetrics)(nil), // 173: runtime.v1.PodSandboxMetrics + (*ContainerMetrics)(nil), // 174: runtime.v1.ContainerMetrics + (*Metric)(nil), // 175: runtime.v1.Metric + (*RuntimeConfigRequest)(nil), // 176: runtime.v1.RuntimeConfigRequest + (*RuntimeConfigResponse)(nil), // 177: runtime.v1.RuntimeConfigResponse + (*LinuxRuntimeConfiguration)(nil), // 178: runtime.v1.LinuxRuntimeConfiguration + (*UpdatePodSandboxResourcesRequest)(nil), // 179: runtime.v1.UpdatePodSandboxResourcesRequest + (*UpdatePodSandboxResourcesResponse)(nil), // 180: runtime.v1.UpdatePodSandboxResourcesResponse + nil, // 181: runtime.v1.LinuxPodSandboxConfig.SysctlsEntry + nil, // 182: runtime.v1.PodSandboxConfig.LabelsEntry + nil, // 183: runtime.v1.PodSandboxConfig.AnnotationsEntry + nil, // 184: runtime.v1.PodSandboxStatus.LabelsEntry + nil, // 185: runtime.v1.PodSandboxStatus.AnnotationsEntry + nil, // 186: runtime.v1.PodSandboxStatusResponse.InfoEntry + nil, // 187: runtime.v1.PodSandboxFilter.LabelSelectorEntry + nil, // 188: runtime.v1.PodSandbox.LabelsEntry + nil, // 189: runtime.v1.PodSandbox.AnnotationsEntry + nil, // 190: runtime.v1.PodSandboxStatsFilter.LabelSelectorEntry + nil, // 191: runtime.v1.PodSandboxAttributes.LabelsEntry + nil, // 192: runtime.v1.PodSandboxAttributes.AnnotationsEntry + nil, // 193: runtime.v1.ImageSpec.AnnotationsEntry + nil, // 194: runtime.v1.LinuxContainerResources.UnifiedEntry + nil, // 195: runtime.v1.ContainerConfig.LabelsEntry + nil, // 196: runtime.v1.ContainerConfig.AnnotationsEntry + nil, // 197: runtime.v1.ContainerFilter.LabelSelectorEntry + nil, // 198: runtime.v1.Container.LabelsEntry + nil, // 199: runtime.v1.Container.AnnotationsEntry + nil, // 200: runtime.v1.ContainerStatus.LabelsEntry + nil, // 201: runtime.v1.ContainerStatus.AnnotationsEntry + nil, // 202: runtime.v1.ContainerStatusResponse.InfoEntry + nil, // 203: runtime.v1.UpdateContainerResourcesRequest.AnnotationsEntry + nil, // 204: runtime.v1.ImageStatusResponse.InfoEntry + nil, // 205: runtime.v1.StatusResponse.InfoEntry + nil, // 206: runtime.v1.ContainerStatsFilter.LabelSelectorEntry + nil, // 207: runtime.v1.ContainerAttributes.LabelsEntry + nil, // 208: runtime.v1.ContainerAttributes.AnnotationsEntry } var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_depIdxs = []int32{ 0, // 0: runtime.v1.PortMapping.protocol:type_name -> runtime.v1.Protocol 1, // 1: runtime.v1.Mount.propagation:type_name -> runtime.v1.MountPropagation 16, // 2: runtime.v1.Mount.uidMappings:type_name -> runtime.v1.IDMapping 16, // 3: runtime.v1.Mount.gidMappings:type_name -> runtime.v1.IDMapping - 58, // 4: runtime.v1.Mount.image:type_name -> runtime.v1.ImageSpec + 62, // 4: runtime.v1.Mount.image:type_name -> runtime.v1.ImageSpec 2, // 5: runtime.v1.UserNamespace.mode:type_name -> runtime.v1.NamespaceMode 16, // 6: runtime.v1.UserNamespace.uids:type_name -> runtime.v1.IDMapping 16, // 7: runtime.v1.UserNamespace.gids:type_name -> runtime.v1.IDMapping @@ -13150,7 +13832,7 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_depIdxs = []in 2, // 10: runtime.v1.NamespaceOption.ipc:type_name -> runtime.v1.NamespaceMode 17, // 11: runtime.v1.NamespaceOption.userns_options:type_name -> runtime.v1.UserNamespace 18, // 12: runtime.v1.LinuxSandboxSecurityContext.namespace_options:type_name -> runtime.v1.NamespaceOption - 62, // 13: runtime.v1.LinuxSandboxSecurityContext.selinux_options:type_name -> runtime.v1.SELinuxOption + 66, // 13: runtime.v1.LinuxSandboxSecurityContext.selinux_options:type_name -> runtime.v1.SELinuxOption 19, // 14: runtime.v1.LinuxSandboxSecurityContext.run_as_user:type_name -> runtime.v1.Int64Value 19, // 15: runtime.v1.LinuxSandboxSecurityContext.run_as_group:type_name -> runtime.v1.Int64Value 3, // 16: runtime.v1.LinuxSandboxSecurityContext.supplemental_groups_policy:type_name -> runtime.v1.SupplementalGroupsPolicy @@ -13158,16 +13840,16 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_depIdxs = []in 21, // 18: runtime.v1.LinuxSandboxSecurityContext.apparmor:type_name -> runtime.v1.SecurityProfile 10, // 19: runtime.v1.SecurityProfile.profile_type:type_name -> runtime.v1.SecurityProfile.ProfileType 20, // 20: runtime.v1.LinuxPodSandboxConfig.security_context:type_name -> runtime.v1.LinuxSandboxSecurityContext - 169, // 21: runtime.v1.LinuxPodSandboxConfig.sysctls:type_name -> runtime.v1.LinuxPodSandboxConfig.SysctlsEntry - 60, // 22: runtime.v1.LinuxPodSandboxConfig.overhead:type_name -> runtime.v1.LinuxContainerResources - 60, // 23: runtime.v1.LinuxPodSandboxConfig.resources:type_name -> runtime.v1.LinuxContainerResources + 181, // 21: runtime.v1.LinuxPodSandboxConfig.sysctls:type_name -> runtime.v1.LinuxPodSandboxConfig.SysctlsEntry + 64, // 22: runtime.v1.LinuxPodSandboxConfig.overhead:type_name -> runtime.v1.LinuxContainerResources + 64, // 23: runtime.v1.LinuxPodSandboxConfig.resources:type_name -> runtime.v1.LinuxContainerResources 23, // 24: runtime.v1.PodSandboxConfig.metadata:type_name -> runtime.v1.PodSandboxMetadata 13, // 25: runtime.v1.PodSandboxConfig.dns_config:type_name -> runtime.v1.DNSConfig 14, // 26: runtime.v1.PodSandboxConfig.port_mappings:type_name -> runtime.v1.PortMapping - 170, // 27: runtime.v1.PodSandboxConfig.labels:type_name -> runtime.v1.PodSandboxConfig.LabelsEntry - 171, // 28: runtime.v1.PodSandboxConfig.annotations:type_name -> runtime.v1.PodSandboxConfig.AnnotationsEntry + 182, // 27: runtime.v1.PodSandboxConfig.labels:type_name -> runtime.v1.PodSandboxConfig.LabelsEntry + 183, // 28: runtime.v1.PodSandboxConfig.annotations:type_name -> runtime.v1.PodSandboxConfig.AnnotationsEntry 22, // 29: runtime.v1.PodSandboxConfig.linux:type_name -> runtime.v1.LinuxPodSandboxConfig - 69, // 30: runtime.v1.PodSandboxConfig.windows:type_name -> runtime.v1.WindowsPodSandboxConfig + 73, // 30: runtime.v1.PodSandboxConfig.windows:type_name -> runtime.v1.WindowsPodSandboxConfig 24, // 31: runtime.v1.RunPodSandboxRequest.config:type_name -> runtime.v1.PodSandboxConfig 32, // 32: runtime.v1.PodSandboxNetworkStatus.additional_ips:type_name -> runtime.v1.PodIP 18, // 33: runtime.v1.Namespace.options:type_name -> runtime.v1.NamespaceOption @@ -13176,268 +13858,291 @@ var file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_depIdxs = []in 4, // 36: runtime.v1.PodSandboxStatus.state:type_name -> runtime.v1.PodSandboxState 33, // 37: runtime.v1.PodSandboxStatus.network:type_name -> runtime.v1.PodSandboxNetworkStatus 35, // 38: runtime.v1.PodSandboxStatus.linux:type_name -> runtime.v1.LinuxPodSandboxStatus - 172, // 39: runtime.v1.PodSandboxStatus.labels:type_name -> runtime.v1.PodSandboxStatus.LabelsEntry - 173, // 40: runtime.v1.PodSandboxStatus.annotations:type_name -> runtime.v1.PodSandboxStatus.AnnotationsEntry + 184, // 39: runtime.v1.PodSandboxStatus.labels:type_name -> runtime.v1.PodSandboxStatus.LabelsEntry + 185, // 40: runtime.v1.PodSandboxStatus.annotations:type_name -> runtime.v1.PodSandboxStatus.AnnotationsEntry 36, // 41: runtime.v1.PodSandboxStatusResponse.status:type_name -> runtime.v1.PodSandboxStatus - 174, // 42: runtime.v1.PodSandboxStatusResponse.info:type_name -> runtime.v1.PodSandboxStatusResponse.InfoEntry - 92, // 43: runtime.v1.PodSandboxStatusResponse.containers_statuses:type_name -> runtime.v1.ContainerStatus + 186, // 42: runtime.v1.PodSandboxStatusResponse.info:type_name -> runtime.v1.PodSandboxStatusResponse.InfoEntry + 98, // 43: runtime.v1.PodSandboxStatusResponse.containers_statuses:type_name -> runtime.v1.ContainerStatus 4, // 44: runtime.v1.PodSandboxStateValue.state:type_name -> runtime.v1.PodSandboxState 38, // 45: runtime.v1.PodSandboxFilter.state:type_name -> runtime.v1.PodSandboxStateValue - 175, // 46: runtime.v1.PodSandboxFilter.label_selector:type_name -> runtime.v1.PodSandboxFilter.LabelSelectorEntry + 187, // 46: runtime.v1.PodSandboxFilter.label_selector:type_name -> runtime.v1.PodSandboxFilter.LabelSelectorEntry 39, // 47: runtime.v1.ListPodSandboxRequest.filter:type_name -> runtime.v1.PodSandboxFilter 23, // 48: runtime.v1.PodSandbox.metadata:type_name -> runtime.v1.PodSandboxMetadata 4, // 49: runtime.v1.PodSandbox.state:type_name -> runtime.v1.PodSandboxState - 176, // 50: runtime.v1.PodSandbox.labels:type_name -> runtime.v1.PodSandbox.LabelsEntry - 177, // 51: runtime.v1.PodSandbox.annotations:type_name -> runtime.v1.PodSandbox.AnnotationsEntry + 188, // 50: runtime.v1.PodSandbox.labels:type_name -> runtime.v1.PodSandbox.LabelsEntry + 189, // 51: runtime.v1.PodSandbox.annotations:type_name -> runtime.v1.PodSandbox.AnnotationsEntry 41, // 52: runtime.v1.ListPodSandboxResponse.items:type_name -> runtime.v1.PodSandbox - 49, // 53: runtime.v1.PodSandboxStatsResponse.stats:type_name -> runtime.v1.PodSandboxStats - 178, // 54: runtime.v1.PodSandboxStatsFilter.label_selector:type_name -> runtime.v1.PodSandboxStatsFilter.LabelSelectorEntry - 45, // 55: runtime.v1.ListPodSandboxStatsRequest.filter:type_name -> runtime.v1.PodSandboxStatsFilter - 49, // 56: runtime.v1.ListPodSandboxStatsResponse.stats:type_name -> runtime.v1.PodSandboxStats - 23, // 57: runtime.v1.PodSandboxAttributes.metadata:type_name -> runtime.v1.PodSandboxMetadata - 179, // 58: runtime.v1.PodSandboxAttributes.labels:type_name -> runtime.v1.PodSandboxAttributes.LabelsEntry - 180, // 59: runtime.v1.PodSandboxAttributes.annotations:type_name -> runtime.v1.PodSandboxAttributes.AnnotationsEntry - 48, // 60: runtime.v1.PodSandboxStats.attributes:type_name -> runtime.v1.PodSandboxAttributes - 50, // 61: runtime.v1.PodSandboxStats.linux:type_name -> runtime.v1.LinuxPodSandboxStats - 51, // 62: runtime.v1.PodSandboxStats.windows:type_name -> runtime.v1.WindowsPodSandboxStats - 144, // 63: runtime.v1.LinuxPodSandboxStats.cpu:type_name -> runtime.v1.CpuUsage - 146, // 64: runtime.v1.LinuxPodSandboxStats.memory:type_name -> runtime.v1.MemoryUsage - 52, // 65: runtime.v1.LinuxPodSandboxStats.network:type_name -> runtime.v1.NetworkUsage - 56, // 66: runtime.v1.LinuxPodSandboxStats.process:type_name -> runtime.v1.ProcessUsage - 140, // 67: runtime.v1.LinuxPodSandboxStats.containers:type_name -> runtime.v1.ContainerStats - 147, // 68: runtime.v1.LinuxPodSandboxStats.io:type_name -> runtime.v1.IoUsage - 145, // 69: runtime.v1.WindowsPodSandboxStats.cpu:type_name -> runtime.v1.WindowsCpuUsage - 149, // 70: runtime.v1.WindowsPodSandboxStats.memory:type_name -> runtime.v1.WindowsMemoryUsage - 53, // 71: runtime.v1.WindowsPodSandboxStats.network:type_name -> runtime.v1.WindowsNetworkUsage - 57, // 72: runtime.v1.WindowsPodSandboxStats.process:type_name -> runtime.v1.WindowsProcessUsage - 141, // 73: runtime.v1.WindowsPodSandboxStats.containers:type_name -> runtime.v1.WindowsContainerStats - 54, // 74: runtime.v1.NetworkUsage.default_interface:type_name -> runtime.v1.NetworkInterfaceUsage - 54, // 75: runtime.v1.NetworkUsage.interfaces:type_name -> runtime.v1.NetworkInterfaceUsage - 55, // 76: runtime.v1.WindowsNetworkUsage.default_interface:type_name -> runtime.v1.WindowsNetworkInterfaceUsage - 55, // 77: runtime.v1.WindowsNetworkUsage.interfaces:type_name -> runtime.v1.WindowsNetworkInterfaceUsage - 129, // 78: runtime.v1.NetworkInterfaceUsage.rx_bytes:type_name -> runtime.v1.UInt64Value - 129, // 79: runtime.v1.NetworkInterfaceUsage.rx_errors:type_name -> runtime.v1.UInt64Value - 129, // 80: runtime.v1.NetworkInterfaceUsage.tx_bytes:type_name -> runtime.v1.UInt64Value - 129, // 81: runtime.v1.NetworkInterfaceUsage.tx_errors:type_name -> runtime.v1.UInt64Value - 129, // 82: runtime.v1.WindowsNetworkInterfaceUsage.rx_bytes:type_name -> runtime.v1.UInt64Value - 129, // 83: runtime.v1.WindowsNetworkInterfaceUsage.rx_packets_dropped:type_name -> runtime.v1.UInt64Value - 129, // 84: runtime.v1.WindowsNetworkInterfaceUsage.tx_bytes:type_name -> runtime.v1.UInt64Value - 129, // 85: runtime.v1.WindowsNetworkInterfaceUsage.tx_packets_dropped:type_name -> runtime.v1.UInt64Value - 129, // 86: runtime.v1.ProcessUsage.process_count:type_name -> runtime.v1.UInt64Value - 129, // 87: runtime.v1.WindowsProcessUsage.process_count:type_name -> runtime.v1.UInt64Value - 181, // 88: runtime.v1.ImageSpec.annotations:type_name -> runtime.v1.ImageSpec.AnnotationsEntry - 61, // 89: runtime.v1.LinuxContainerResources.hugepage_limits:type_name -> runtime.v1.HugepageLimit - 182, // 90: runtime.v1.LinuxContainerResources.unified:type_name -> runtime.v1.LinuxContainerResources.UnifiedEntry - 63, // 91: runtime.v1.LinuxContainerSecurityContext.capabilities:type_name -> runtime.v1.Capability - 18, // 92: runtime.v1.LinuxContainerSecurityContext.namespace_options:type_name -> runtime.v1.NamespaceOption - 62, // 93: runtime.v1.LinuxContainerSecurityContext.selinux_options:type_name -> runtime.v1.SELinuxOption - 19, // 94: runtime.v1.LinuxContainerSecurityContext.run_as_user:type_name -> runtime.v1.Int64Value - 19, // 95: runtime.v1.LinuxContainerSecurityContext.run_as_group:type_name -> runtime.v1.Int64Value - 3, // 96: runtime.v1.LinuxContainerSecurityContext.supplemental_groups_policy:type_name -> runtime.v1.SupplementalGroupsPolicy - 21, // 97: runtime.v1.LinuxContainerSecurityContext.seccomp:type_name -> runtime.v1.SecurityProfile - 21, // 98: runtime.v1.LinuxContainerSecurityContext.apparmor:type_name -> runtime.v1.SecurityProfile - 60, // 99: runtime.v1.LinuxContainerConfig.resources:type_name -> runtime.v1.LinuxContainerResources - 64, // 100: runtime.v1.LinuxContainerConfig.security_context:type_name -> runtime.v1.LinuxContainerSecurityContext - 2, // 101: runtime.v1.WindowsNamespaceOption.network:type_name -> runtime.v1.NamespaceMode - 67, // 102: runtime.v1.WindowsSandboxSecurityContext.namespace_options:type_name -> runtime.v1.WindowsNamespaceOption - 68, // 103: runtime.v1.WindowsPodSandboxConfig.security_context:type_name -> runtime.v1.WindowsSandboxSecurityContext - 72, // 104: runtime.v1.WindowsContainerConfig.resources:type_name -> runtime.v1.WindowsContainerResources - 70, // 105: runtime.v1.WindowsContainerConfig.security_context:type_name -> runtime.v1.WindowsContainerSecurityContext - 73, // 106: runtime.v1.WindowsContainerResources.affinity_cpus:type_name -> runtime.v1.WindowsCpuGroupAffinity - 74, // 107: runtime.v1.ContainerConfig.metadata:type_name -> runtime.v1.ContainerMetadata - 58, // 108: runtime.v1.ContainerConfig.image:type_name -> runtime.v1.ImageSpec - 59, // 109: runtime.v1.ContainerConfig.envs:type_name -> runtime.v1.KeyValue - 15, // 110: runtime.v1.ContainerConfig.mounts:type_name -> runtime.v1.Mount - 75, // 111: runtime.v1.ContainerConfig.devices:type_name -> runtime.v1.Device - 183, // 112: runtime.v1.ContainerConfig.labels:type_name -> runtime.v1.ContainerConfig.LabelsEntry - 184, // 113: runtime.v1.ContainerConfig.annotations:type_name -> runtime.v1.ContainerConfig.AnnotationsEntry - 65, // 114: runtime.v1.ContainerConfig.linux:type_name -> runtime.v1.LinuxContainerConfig - 71, // 115: runtime.v1.ContainerConfig.windows:type_name -> runtime.v1.WindowsContainerConfig - 76, // 116: runtime.v1.ContainerConfig.CDI_devices:type_name -> runtime.v1.CDIDevice - 5, // 117: runtime.v1.ContainerConfig.stop_signal:type_name -> runtime.v1.Signal - 77, // 118: runtime.v1.CreateContainerRequest.config:type_name -> runtime.v1.ContainerConfig - 24, // 119: runtime.v1.CreateContainerRequest.sandbox_config:type_name -> runtime.v1.PodSandboxConfig - 6, // 120: runtime.v1.ContainerStateValue.state:type_name -> runtime.v1.ContainerState - 86, // 121: runtime.v1.ContainerFilter.state:type_name -> runtime.v1.ContainerStateValue - 185, // 122: runtime.v1.ContainerFilter.label_selector:type_name -> runtime.v1.ContainerFilter.LabelSelectorEntry - 87, // 123: runtime.v1.ListContainersRequest.filter:type_name -> runtime.v1.ContainerFilter - 74, // 124: runtime.v1.Container.metadata:type_name -> runtime.v1.ContainerMetadata - 58, // 125: runtime.v1.Container.image:type_name -> runtime.v1.ImageSpec - 6, // 126: runtime.v1.Container.state:type_name -> runtime.v1.ContainerState - 186, // 127: runtime.v1.Container.labels:type_name -> runtime.v1.Container.LabelsEntry - 187, // 128: runtime.v1.Container.annotations:type_name -> runtime.v1.Container.AnnotationsEntry - 89, // 129: runtime.v1.ListContainersResponse.containers:type_name -> runtime.v1.Container - 74, // 130: runtime.v1.ContainerStatus.metadata:type_name -> runtime.v1.ContainerMetadata - 6, // 131: runtime.v1.ContainerStatus.state:type_name -> runtime.v1.ContainerState - 58, // 132: runtime.v1.ContainerStatus.image:type_name -> runtime.v1.ImageSpec - 188, // 133: runtime.v1.ContainerStatus.labels:type_name -> runtime.v1.ContainerStatus.LabelsEntry - 189, // 134: runtime.v1.ContainerStatus.annotations:type_name -> runtime.v1.ContainerStatus.AnnotationsEntry - 15, // 135: runtime.v1.ContainerStatus.mounts:type_name -> runtime.v1.Mount - 94, // 136: runtime.v1.ContainerStatus.resources:type_name -> runtime.v1.ContainerResources - 95, // 137: runtime.v1.ContainerStatus.user:type_name -> runtime.v1.ContainerUser - 5, // 138: runtime.v1.ContainerStatus.stop_signal:type_name -> runtime.v1.Signal - 92, // 139: runtime.v1.ContainerStatusResponse.status:type_name -> runtime.v1.ContainerStatus - 190, // 140: runtime.v1.ContainerStatusResponse.info:type_name -> runtime.v1.ContainerStatusResponse.InfoEntry - 60, // 141: runtime.v1.ContainerResources.linux:type_name -> runtime.v1.LinuxContainerResources - 72, // 142: runtime.v1.ContainerResources.windows:type_name -> runtime.v1.WindowsContainerResources - 66, // 143: runtime.v1.ContainerUser.linux:type_name -> runtime.v1.LinuxContainerUser - 60, // 144: runtime.v1.UpdateContainerResourcesRequest.linux:type_name -> runtime.v1.LinuxContainerResources - 72, // 145: runtime.v1.UpdateContainerResourcesRequest.windows:type_name -> runtime.v1.WindowsContainerResources - 191, // 146: runtime.v1.UpdateContainerResourcesRequest.annotations:type_name -> runtime.v1.UpdateContainerResourcesRequest.AnnotationsEntry - 58, // 147: runtime.v1.ImageFilter.image:type_name -> runtime.v1.ImageSpec - 106, // 148: runtime.v1.ListImagesRequest.filter:type_name -> runtime.v1.ImageFilter - 19, // 149: runtime.v1.Image.uid:type_name -> runtime.v1.Int64Value - 58, // 150: runtime.v1.Image.spec:type_name -> runtime.v1.ImageSpec - 108, // 151: runtime.v1.ListImagesResponse.images:type_name -> runtime.v1.Image - 58, // 152: runtime.v1.ImageStatusRequest.image:type_name -> runtime.v1.ImageSpec - 108, // 153: runtime.v1.ImageStatusResponse.image:type_name -> runtime.v1.Image - 192, // 154: runtime.v1.ImageStatusResponse.info:type_name -> runtime.v1.ImageStatusResponse.InfoEntry - 58, // 155: runtime.v1.PullImageRequest.image:type_name -> runtime.v1.ImageSpec - 112, // 156: runtime.v1.PullImageRequest.auth:type_name -> runtime.v1.AuthConfig - 24, // 157: runtime.v1.PullImageRequest.sandbox_config:type_name -> runtime.v1.PodSandboxConfig - 58, // 158: runtime.v1.RemoveImageRequest.image:type_name -> runtime.v1.ImageSpec - 117, // 159: runtime.v1.RuntimeConfig.network_config:type_name -> runtime.v1.NetworkConfig - 118, // 160: runtime.v1.UpdateRuntimeConfigRequest.runtime_config:type_name -> runtime.v1.RuntimeConfig - 121, // 161: runtime.v1.RuntimeStatus.conditions:type_name -> runtime.v1.RuntimeCondition - 124, // 162: runtime.v1.RuntimeHandler.features:type_name -> runtime.v1.RuntimeHandlerFeatures - 122, // 163: runtime.v1.StatusResponse.status:type_name -> runtime.v1.RuntimeStatus - 193, // 164: runtime.v1.StatusResponse.info:type_name -> runtime.v1.StatusResponse.InfoEntry - 125, // 165: runtime.v1.StatusResponse.runtime_handlers:type_name -> runtime.v1.RuntimeHandler - 126, // 166: runtime.v1.StatusResponse.features:type_name -> runtime.v1.RuntimeFeatures - 130, // 167: runtime.v1.FilesystemUsage.fs_id:type_name -> runtime.v1.FilesystemIdentifier - 129, // 168: runtime.v1.FilesystemUsage.used_bytes:type_name -> runtime.v1.UInt64Value - 129, // 169: runtime.v1.FilesystemUsage.inodes_used:type_name -> runtime.v1.UInt64Value - 130, // 170: runtime.v1.WindowsFilesystemUsage.fs_id:type_name -> runtime.v1.FilesystemIdentifier - 129, // 171: runtime.v1.WindowsFilesystemUsage.used_bytes:type_name -> runtime.v1.UInt64Value - 131, // 172: runtime.v1.ImageFsInfoResponse.image_filesystems:type_name -> runtime.v1.FilesystemUsage - 131, // 173: runtime.v1.ImageFsInfoResponse.container_filesystems:type_name -> runtime.v1.FilesystemUsage - 140, // 174: runtime.v1.ContainerStatsResponse.stats:type_name -> runtime.v1.ContainerStats - 137, // 175: runtime.v1.ListContainerStatsRequest.filter:type_name -> runtime.v1.ContainerStatsFilter - 194, // 176: runtime.v1.ContainerStatsFilter.label_selector:type_name -> runtime.v1.ContainerStatsFilter.LabelSelectorEntry - 140, // 177: runtime.v1.ListContainerStatsResponse.stats:type_name -> runtime.v1.ContainerStats - 74, // 178: runtime.v1.ContainerAttributes.metadata:type_name -> runtime.v1.ContainerMetadata - 195, // 179: runtime.v1.ContainerAttributes.labels:type_name -> runtime.v1.ContainerAttributes.LabelsEntry - 196, // 180: runtime.v1.ContainerAttributes.annotations:type_name -> runtime.v1.ContainerAttributes.AnnotationsEntry - 139, // 181: runtime.v1.ContainerStats.attributes:type_name -> runtime.v1.ContainerAttributes - 144, // 182: runtime.v1.ContainerStats.cpu:type_name -> runtime.v1.CpuUsage - 146, // 183: runtime.v1.ContainerStats.memory:type_name -> runtime.v1.MemoryUsage - 131, // 184: runtime.v1.ContainerStats.writable_layer:type_name -> runtime.v1.FilesystemUsage - 148, // 185: runtime.v1.ContainerStats.swap:type_name -> runtime.v1.SwapUsage - 147, // 186: runtime.v1.ContainerStats.io:type_name -> runtime.v1.IoUsage - 139, // 187: runtime.v1.WindowsContainerStats.attributes:type_name -> runtime.v1.ContainerAttributes - 145, // 188: runtime.v1.WindowsContainerStats.cpu:type_name -> runtime.v1.WindowsCpuUsage - 149, // 189: runtime.v1.WindowsContainerStats.memory:type_name -> runtime.v1.WindowsMemoryUsage - 132, // 190: runtime.v1.WindowsContainerStats.writable_layer:type_name -> runtime.v1.WindowsFilesystemUsage - 143, // 191: runtime.v1.PsiStats.Full:type_name -> runtime.v1.PsiData - 143, // 192: runtime.v1.PsiStats.Some:type_name -> runtime.v1.PsiData - 129, // 193: runtime.v1.CpuUsage.usage_core_nano_seconds:type_name -> runtime.v1.UInt64Value - 129, // 194: runtime.v1.CpuUsage.usage_nano_cores:type_name -> runtime.v1.UInt64Value - 142, // 195: runtime.v1.CpuUsage.psi:type_name -> runtime.v1.PsiStats - 129, // 196: runtime.v1.WindowsCpuUsage.usage_core_nano_seconds:type_name -> runtime.v1.UInt64Value - 129, // 197: runtime.v1.WindowsCpuUsage.usage_nano_cores:type_name -> runtime.v1.UInt64Value - 129, // 198: runtime.v1.MemoryUsage.working_set_bytes:type_name -> runtime.v1.UInt64Value - 129, // 199: runtime.v1.MemoryUsage.available_bytes:type_name -> runtime.v1.UInt64Value - 129, // 200: runtime.v1.MemoryUsage.usage_bytes:type_name -> runtime.v1.UInt64Value - 129, // 201: runtime.v1.MemoryUsage.rss_bytes:type_name -> runtime.v1.UInt64Value - 129, // 202: runtime.v1.MemoryUsage.page_faults:type_name -> runtime.v1.UInt64Value - 129, // 203: runtime.v1.MemoryUsage.major_page_faults:type_name -> runtime.v1.UInt64Value - 142, // 204: runtime.v1.MemoryUsage.psi:type_name -> runtime.v1.PsiStats - 142, // 205: runtime.v1.IoUsage.psi:type_name -> runtime.v1.PsiStats - 129, // 206: runtime.v1.SwapUsage.swap_available_bytes:type_name -> runtime.v1.UInt64Value - 129, // 207: runtime.v1.SwapUsage.swap_usage_bytes:type_name -> runtime.v1.UInt64Value - 129, // 208: runtime.v1.WindowsMemoryUsage.working_set_bytes:type_name -> runtime.v1.UInt64Value - 129, // 209: runtime.v1.WindowsMemoryUsage.available_bytes:type_name -> runtime.v1.UInt64Value - 129, // 210: runtime.v1.WindowsMemoryUsage.page_faults:type_name -> runtime.v1.UInt64Value - 129, // 211: runtime.v1.WindowsMemoryUsage.commit_memory_bytes:type_name -> runtime.v1.UInt64Value - 7, // 212: runtime.v1.ContainerEventResponse.container_event_type:type_name -> runtime.v1.ContainerEventType - 36, // 213: runtime.v1.ContainerEventResponse.pod_sandbox_status:type_name -> runtime.v1.PodSandboxStatus - 92, // 214: runtime.v1.ContainerEventResponse.containers_statuses:type_name -> runtime.v1.ContainerStatus - 158, // 215: runtime.v1.ListMetricDescriptorsResponse.descriptors:type_name -> runtime.v1.MetricDescriptor - 161, // 216: runtime.v1.ListPodSandboxMetricsResponse.pod_metrics:type_name -> runtime.v1.PodSandboxMetrics - 163, // 217: runtime.v1.PodSandboxMetrics.metrics:type_name -> runtime.v1.Metric - 162, // 218: runtime.v1.PodSandboxMetrics.container_metrics:type_name -> runtime.v1.ContainerMetrics - 163, // 219: runtime.v1.ContainerMetrics.metrics:type_name -> runtime.v1.Metric - 8, // 220: runtime.v1.Metric.metric_type:type_name -> runtime.v1.MetricType - 129, // 221: runtime.v1.Metric.value:type_name -> runtime.v1.UInt64Value - 166, // 222: runtime.v1.RuntimeConfigResponse.linux:type_name -> runtime.v1.LinuxRuntimeConfiguration - 9, // 223: runtime.v1.LinuxRuntimeConfiguration.cgroup_driver:type_name -> runtime.v1.CgroupDriver - 60, // 224: runtime.v1.UpdatePodSandboxResourcesRequest.overhead:type_name -> runtime.v1.LinuxContainerResources - 60, // 225: runtime.v1.UpdatePodSandboxResourcesRequest.resources:type_name -> runtime.v1.LinuxContainerResources - 11, // 226: runtime.v1.RuntimeService.Version:input_type -> runtime.v1.VersionRequest - 25, // 227: runtime.v1.RuntimeService.RunPodSandbox:input_type -> runtime.v1.RunPodSandboxRequest - 27, // 228: runtime.v1.RuntimeService.StopPodSandbox:input_type -> runtime.v1.StopPodSandboxRequest - 29, // 229: runtime.v1.RuntimeService.RemovePodSandbox:input_type -> runtime.v1.RemovePodSandboxRequest - 31, // 230: runtime.v1.RuntimeService.PodSandboxStatus:input_type -> runtime.v1.PodSandboxStatusRequest - 40, // 231: runtime.v1.RuntimeService.ListPodSandbox:input_type -> runtime.v1.ListPodSandboxRequest - 78, // 232: runtime.v1.RuntimeService.CreateContainer:input_type -> runtime.v1.CreateContainerRequest - 80, // 233: runtime.v1.RuntimeService.StartContainer:input_type -> runtime.v1.StartContainerRequest - 82, // 234: runtime.v1.RuntimeService.StopContainer:input_type -> runtime.v1.StopContainerRequest - 84, // 235: runtime.v1.RuntimeService.RemoveContainer:input_type -> runtime.v1.RemoveContainerRequest - 88, // 236: runtime.v1.RuntimeService.ListContainers:input_type -> runtime.v1.ListContainersRequest - 91, // 237: runtime.v1.RuntimeService.ContainerStatus:input_type -> runtime.v1.ContainerStatusRequest - 96, // 238: runtime.v1.RuntimeService.UpdateContainerResources:input_type -> runtime.v1.UpdateContainerResourcesRequest - 150, // 239: runtime.v1.RuntimeService.ReopenContainerLog:input_type -> runtime.v1.ReopenContainerLogRequest - 98, // 240: runtime.v1.RuntimeService.ExecSync:input_type -> runtime.v1.ExecSyncRequest - 100, // 241: runtime.v1.RuntimeService.Exec:input_type -> runtime.v1.ExecRequest - 102, // 242: runtime.v1.RuntimeService.Attach:input_type -> runtime.v1.AttachRequest - 104, // 243: runtime.v1.RuntimeService.PortForward:input_type -> runtime.v1.PortForwardRequest - 134, // 244: runtime.v1.RuntimeService.ContainerStats:input_type -> runtime.v1.ContainerStatsRequest - 136, // 245: runtime.v1.RuntimeService.ListContainerStats:input_type -> runtime.v1.ListContainerStatsRequest - 43, // 246: runtime.v1.RuntimeService.PodSandboxStats:input_type -> runtime.v1.PodSandboxStatsRequest - 46, // 247: runtime.v1.RuntimeService.ListPodSandboxStats:input_type -> runtime.v1.ListPodSandboxStatsRequest - 119, // 248: runtime.v1.RuntimeService.UpdateRuntimeConfig:input_type -> runtime.v1.UpdateRuntimeConfigRequest - 123, // 249: runtime.v1.RuntimeService.Status:input_type -> runtime.v1.StatusRequest - 152, // 250: runtime.v1.RuntimeService.CheckpointContainer:input_type -> runtime.v1.CheckpointContainerRequest - 154, // 251: runtime.v1.RuntimeService.GetContainerEvents:input_type -> runtime.v1.GetEventsRequest - 156, // 252: runtime.v1.RuntimeService.ListMetricDescriptors:input_type -> runtime.v1.ListMetricDescriptorsRequest - 159, // 253: runtime.v1.RuntimeService.ListPodSandboxMetrics:input_type -> runtime.v1.ListPodSandboxMetricsRequest - 164, // 254: runtime.v1.RuntimeService.RuntimeConfig:input_type -> runtime.v1.RuntimeConfigRequest - 167, // 255: runtime.v1.RuntimeService.UpdatePodSandboxResources:input_type -> runtime.v1.UpdatePodSandboxResourcesRequest - 107, // 256: runtime.v1.ImageService.ListImages:input_type -> runtime.v1.ListImagesRequest - 110, // 257: runtime.v1.ImageService.ImageStatus:input_type -> runtime.v1.ImageStatusRequest - 113, // 258: runtime.v1.ImageService.PullImage:input_type -> runtime.v1.PullImageRequest - 115, // 259: runtime.v1.ImageService.RemoveImage:input_type -> runtime.v1.RemoveImageRequest - 128, // 260: runtime.v1.ImageService.ImageFsInfo:input_type -> runtime.v1.ImageFsInfoRequest - 12, // 261: runtime.v1.RuntimeService.Version:output_type -> runtime.v1.VersionResponse - 26, // 262: runtime.v1.RuntimeService.RunPodSandbox:output_type -> runtime.v1.RunPodSandboxResponse - 28, // 263: runtime.v1.RuntimeService.StopPodSandbox:output_type -> runtime.v1.StopPodSandboxResponse - 30, // 264: runtime.v1.RuntimeService.RemovePodSandbox:output_type -> runtime.v1.RemovePodSandboxResponse - 37, // 265: runtime.v1.RuntimeService.PodSandboxStatus:output_type -> runtime.v1.PodSandboxStatusResponse - 42, // 266: runtime.v1.RuntimeService.ListPodSandbox:output_type -> runtime.v1.ListPodSandboxResponse - 79, // 267: runtime.v1.RuntimeService.CreateContainer:output_type -> runtime.v1.CreateContainerResponse - 81, // 268: runtime.v1.RuntimeService.StartContainer:output_type -> runtime.v1.StartContainerResponse - 83, // 269: runtime.v1.RuntimeService.StopContainer:output_type -> runtime.v1.StopContainerResponse - 85, // 270: runtime.v1.RuntimeService.RemoveContainer:output_type -> runtime.v1.RemoveContainerResponse - 90, // 271: runtime.v1.RuntimeService.ListContainers:output_type -> runtime.v1.ListContainersResponse - 93, // 272: runtime.v1.RuntimeService.ContainerStatus:output_type -> runtime.v1.ContainerStatusResponse - 97, // 273: runtime.v1.RuntimeService.UpdateContainerResources:output_type -> runtime.v1.UpdateContainerResourcesResponse - 151, // 274: runtime.v1.RuntimeService.ReopenContainerLog:output_type -> runtime.v1.ReopenContainerLogResponse - 99, // 275: runtime.v1.RuntimeService.ExecSync:output_type -> runtime.v1.ExecSyncResponse - 101, // 276: runtime.v1.RuntimeService.Exec:output_type -> runtime.v1.ExecResponse - 103, // 277: runtime.v1.RuntimeService.Attach:output_type -> runtime.v1.AttachResponse - 105, // 278: runtime.v1.RuntimeService.PortForward:output_type -> runtime.v1.PortForwardResponse - 135, // 279: runtime.v1.RuntimeService.ContainerStats:output_type -> runtime.v1.ContainerStatsResponse - 138, // 280: runtime.v1.RuntimeService.ListContainerStats:output_type -> runtime.v1.ListContainerStatsResponse - 44, // 281: runtime.v1.RuntimeService.PodSandboxStats:output_type -> runtime.v1.PodSandboxStatsResponse - 47, // 282: runtime.v1.RuntimeService.ListPodSandboxStats:output_type -> runtime.v1.ListPodSandboxStatsResponse - 120, // 283: runtime.v1.RuntimeService.UpdateRuntimeConfig:output_type -> runtime.v1.UpdateRuntimeConfigResponse - 127, // 284: runtime.v1.RuntimeService.Status:output_type -> runtime.v1.StatusResponse - 153, // 285: runtime.v1.RuntimeService.CheckpointContainer:output_type -> runtime.v1.CheckpointContainerResponse - 155, // 286: runtime.v1.RuntimeService.GetContainerEvents:output_type -> runtime.v1.ContainerEventResponse - 157, // 287: runtime.v1.RuntimeService.ListMetricDescriptors:output_type -> runtime.v1.ListMetricDescriptorsResponse - 160, // 288: runtime.v1.RuntimeService.ListPodSandboxMetrics:output_type -> runtime.v1.ListPodSandboxMetricsResponse - 165, // 289: runtime.v1.RuntimeService.RuntimeConfig:output_type -> runtime.v1.RuntimeConfigResponse - 168, // 290: runtime.v1.RuntimeService.UpdatePodSandboxResources:output_type -> runtime.v1.UpdatePodSandboxResourcesResponse - 109, // 291: runtime.v1.ImageService.ListImages:output_type -> runtime.v1.ListImagesResponse - 111, // 292: runtime.v1.ImageService.ImageStatus:output_type -> runtime.v1.ImageStatusResponse - 114, // 293: runtime.v1.ImageService.PullImage:output_type -> runtime.v1.PullImageResponse - 116, // 294: runtime.v1.ImageService.RemoveImage:output_type -> runtime.v1.RemoveImageResponse - 133, // 295: runtime.v1.ImageService.ImageFsInfo:output_type -> runtime.v1.ImageFsInfoResponse - 261, // [261:296] is the sub-list for method output_type - 226, // [226:261] is the sub-list for method input_type - 226, // [226:226] is the sub-list for extension type_name - 226, // [226:226] is the sub-list for extension extendee - 0, // [0:226] is the sub-list for field type_name + 39, // 53: runtime.v1.StreamPodSandboxesRequest.filter:type_name -> runtime.v1.PodSandboxFilter + 41, // 54: runtime.v1.StreamPodSandboxesResponse.pod_sandboxes:type_name -> runtime.v1.PodSandbox + 53, // 55: runtime.v1.PodSandboxStatsResponse.stats:type_name -> runtime.v1.PodSandboxStats + 190, // 56: runtime.v1.PodSandboxStatsFilter.label_selector:type_name -> runtime.v1.PodSandboxStatsFilter.LabelSelectorEntry + 47, // 57: runtime.v1.ListPodSandboxStatsRequest.filter:type_name -> runtime.v1.PodSandboxStatsFilter + 53, // 58: runtime.v1.ListPodSandboxStatsResponse.stats:type_name -> runtime.v1.PodSandboxStats + 47, // 59: runtime.v1.StreamPodSandboxStatsRequest.filter:type_name -> runtime.v1.PodSandboxStatsFilter + 53, // 60: runtime.v1.StreamPodSandboxStatsResponse.pod_sandbox_stats:type_name -> runtime.v1.PodSandboxStats + 23, // 61: runtime.v1.PodSandboxAttributes.metadata:type_name -> runtime.v1.PodSandboxMetadata + 191, // 62: runtime.v1.PodSandboxAttributes.labels:type_name -> runtime.v1.PodSandboxAttributes.LabelsEntry + 192, // 63: runtime.v1.PodSandboxAttributes.annotations:type_name -> runtime.v1.PodSandboxAttributes.AnnotationsEntry + 52, // 64: runtime.v1.PodSandboxStats.attributes:type_name -> runtime.v1.PodSandboxAttributes + 54, // 65: runtime.v1.PodSandboxStats.linux:type_name -> runtime.v1.LinuxPodSandboxStats + 55, // 66: runtime.v1.PodSandboxStats.windows:type_name -> runtime.v1.WindowsPodSandboxStats + 154, // 67: runtime.v1.LinuxPodSandboxStats.cpu:type_name -> runtime.v1.CpuUsage + 156, // 68: runtime.v1.LinuxPodSandboxStats.memory:type_name -> runtime.v1.MemoryUsage + 56, // 69: runtime.v1.LinuxPodSandboxStats.network:type_name -> runtime.v1.NetworkUsage + 60, // 70: runtime.v1.LinuxPodSandboxStats.process:type_name -> runtime.v1.ProcessUsage + 150, // 71: runtime.v1.LinuxPodSandboxStats.containers:type_name -> runtime.v1.ContainerStats + 157, // 72: runtime.v1.LinuxPodSandboxStats.io:type_name -> runtime.v1.IoUsage + 155, // 73: runtime.v1.WindowsPodSandboxStats.cpu:type_name -> runtime.v1.WindowsCpuUsage + 159, // 74: runtime.v1.WindowsPodSandboxStats.memory:type_name -> runtime.v1.WindowsMemoryUsage + 57, // 75: runtime.v1.WindowsPodSandboxStats.network:type_name -> runtime.v1.WindowsNetworkUsage + 61, // 76: runtime.v1.WindowsPodSandboxStats.process:type_name -> runtime.v1.WindowsProcessUsage + 151, // 77: runtime.v1.WindowsPodSandboxStats.containers:type_name -> runtime.v1.WindowsContainerStats + 58, // 78: runtime.v1.NetworkUsage.default_interface:type_name -> runtime.v1.NetworkInterfaceUsage + 58, // 79: runtime.v1.NetworkUsage.interfaces:type_name -> runtime.v1.NetworkInterfaceUsage + 59, // 80: runtime.v1.WindowsNetworkUsage.default_interface:type_name -> runtime.v1.WindowsNetworkInterfaceUsage + 59, // 81: runtime.v1.WindowsNetworkUsage.interfaces:type_name -> runtime.v1.WindowsNetworkInterfaceUsage + 137, // 82: runtime.v1.NetworkInterfaceUsage.rx_bytes:type_name -> runtime.v1.UInt64Value + 137, // 83: runtime.v1.NetworkInterfaceUsage.rx_errors:type_name -> runtime.v1.UInt64Value + 137, // 84: runtime.v1.NetworkInterfaceUsage.tx_bytes:type_name -> runtime.v1.UInt64Value + 137, // 85: runtime.v1.NetworkInterfaceUsage.tx_errors:type_name -> runtime.v1.UInt64Value + 137, // 86: runtime.v1.WindowsNetworkInterfaceUsage.rx_bytes:type_name -> runtime.v1.UInt64Value + 137, // 87: runtime.v1.WindowsNetworkInterfaceUsage.rx_packets_dropped:type_name -> runtime.v1.UInt64Value + 137, // 88: runtime.v1.WindowsNetworkInterfaceUsage.tx_bytes:type_name -> runtime.v1.UInt64Value + 137, // 89: runtime.v1.WindowsNetworkInterfaceUsage.tx_packets_dropped:type_name -> runtime.v1.UInt64Value + 137, // 90: runtime.v1.ProcessUsage.process_count:type_name -> runtime.v1.UInt64Value + 137, // 91: runtime.v1.WindowsProcessUsage.process_count:type_name -> runtime.v1.UInt64Value + 193, // 92: runtime.v1.ImageSpec.annotations:type_name -> runtime.v1.ImageSpec.AnnotationsEntry + 65, // 93: runtime.v1.LinuxContainerResources.hugepage_limits:type_name -> runtime.v1.HugepageLimit + 194, // 94: runtime.v1.LinuxContainerResources.unified:type_name -> runtime.v1.LinuxContainerResources.UnifiedEntry + 67, // 95: runtime.v1.LinuxContainerSecurityContext.capabilities:type_name -> runtime.v1.Capability + 18, // 96: runtime.v1.LinuxContainerSecurityContext.namespace_options:type_name -> runtime.v1.NamespaceOption + 66, // 97: runtime.v1.LinuxContainerSecurityContext.selinux_options:type_name -> runtime.v1.SELinuxOption + 19, // 98: runtime.v1.LinuxContainerSecurityContext.run_as_user:type_name -> runtime.v1.Int64Value + 19, // 99: runtime.v1.LinuxContainerSecurityContext.run_as_group:type_name -> runtime.v1.Int64Value + 3, // 100: runtime.v1.LinuxContainerSecurityContext.supplemental_groups_policy:type_name -> runtime.v1.SupplementalGroupsPolicy + 21, // 101: runtime.v1.LinuxContainerSecurityContext.seccomp:type_name -> runtime.v1.SecurityProfile + 21, // 102: runtime.v1.LinuxContainerSecurityContext.apparmor:type_name -> runtime.v1.SecurityProfile + 64, // 103: runtime.v1.LinuxContainerConfig.resources:type_name -> runtime.v1.LinuxContainerResources + 68, // 104: runtime.v1.LinuxContainerConfig.security_context:type_name -> runtime.v1.LinuxContainerSecurityContext + 2, // 105: runtime.v1.WindowsNamespaceOption.network:type_name -> runtime.v1.NamespaceMode + 71, // 106: runtime.v1.WindowsSandboxSecurityContext.namespace_options:type_name -> runtime.v1.WindowsNamespaceOption + 72, // 107: runtime.v1.WindowsPodSandboxConfig.security_context:type_name -> runtime.v1.WindowsSandboxSecurityContext + 76, // 108: runtime.v1.WindowsContainerConfig.resources:type_name -> runtime.v1.WindowsContainerResources + 74, // 109: runtime.v1.WindowsContainerConfig.security_context:type_name -> runtime.v1.WindowsContainerSecurityContext + 77, // 110: runtime.v1.WindowsContainerResources.affinity_cpus:type_name -> runtime.v1.WindowsCpuGroupAffinity + 78, // 111: runtime.v1.ContainerConfig.metadata:type_name -> runtime.v1.ContainerMetadata + 62, // 112: runtime.v1.ContainerConfig.image:type_name -> runtime.v1.ImageSpec + 63, // 113: runtime.v1.ContainerConfig.envs:type_name -> runtime.v1.KeyValue + 15, // 114: runtime.v1.ContainerConfig.mounts:type_name -> runtime.v1.Mount + 79, // 115: runtime.v1.ContainerConfig.devices:type_name -> runtime.v1.Device + 195, // 116: runtime.v1.ContainerConfig.labels:type_name -> runtime.v1.ContainerConfig.LabelsEntry + 196, // 117: runtime.v1.ContainerConfig.annotations:type_name -> runtime.v1.ContainerConfig.AnnotationsEntry + 69, // 118: runtime.v1.ContainerConfig.linux:type_name -> runtime.v1.LinuxContainerConfig + 75, // 119: runtime.v1.ContainerConfig.windows:type_name -> runtime.v1.WindowsContainerConfig + 80, // 120: runtime.v1.ContainerConfig.CDI_devices:type_name -> runtime.v1.CDIDevice + 5, // 121: runtime.v1.ContainerConfig.stop_signal:type_name -> runtime.v1.Signal + 81, // 122: runtime.v1.CreateContainerRequest.config:type_name -> runtime.v1.ContainerConfig + 24, // 123: runtime.v1.CreateContainerRequest.sandbox_config:type_name -> runtime.v1.PodSandboxConfig + 6, // 124: runtime.v1.ContainerStateValue.state:type_name -> runtime.v1.ContainerState + 90, // 125: runtime.v1.ContainerFilter.state:type_name -> runtime.v1.ContainerStateValue + 197, // 126: runtime.v1.ContainerFilter.label_selector:type_name -> runtime.v1.ContainerFilter.LabelSelectorEntry + 91, // 127: runtime.v1.ListContainersRequest.filter:type_name -> runtime.v1.ContainerFilter + 78, // 128: runtime.v1.Container.metadata:type_name -> runtime.v1.ContainerMetadata + 62, // 129: runtime.v1.Container.image:type_name -> runtime.v1.ImageSpec + 6, // 130: runtime.v1.Container.state:type_name -> runtime.v1.ContainerState + 198, // 131: runtime.v1.Container.labels:type_name -> runtime.v1.Container.LabelsEntry + 199, // 132: runtime.v1.Container.annotations:type_name -> runtime.v1.Container.AnnotationsEntry + 93, // 133: runtime.v1.ListContainersResponse.containers:type_name -> runtime.v1.Container + 91, // 134: runtime.v1.StreamContainersRequest.filter:type_name -> runtime.v1.ContainerFilter + 93, // 135: runtime.v1.StreamContainersResponse.containers:type_name -> runtime.v1.Container + 78, // 136: runtime.v1.ContainerStatus.metadata:type_name -> runtime.v1.ContainerMetadata + 6, // 137: runtime.v1.ContainerStatus.state:type_name -> runtime.v1.ContainerState + 62, // 138: runtime.v1.ContainerStatus.image:type_name -> runtime.v1.ImageSpec + 200, // 139: runtime.v1.ContainerStatus.labels:type_name -> runtime.v1.ContainerStatus.LabelsEntry + 201, // 140: runtime.v1.ContainerStatus.annotations:type_name -> runtime.v1.ContainerStatus.AnnotationsEntry + 15, // 141: runtime.v1.ContainerStatus.mounts:type_name -> runtime.v1.Mount + 100, // 142: runtime.v1.ContainerStatus.resources:type_name -> runtime.v1.ContainerResources + 101, // 143: runtime.v1.ContainerStatus.user:type_name -> runtime.v1.ContainerUser + 5, // 144: runtime.v1.ContainerStatus.stop_signal:type_name -> runtime.v1.Signal + 98, // 145: runtime.v1.ContainerStatusResponse.status:type_name -> runtime.v1.ContainerStatus + 202, // 146: runtime.v1.ContainerStatusResponse.info:type_name -> runtime.v1.ContainerStatusResponse.InfoEntry + 64, // 147: runtime.v1.ContainerResources.linux:type_name -> runtime.v1.LinuxContainerResources + 76, // 148: runtime.v1.ContainerResources.windows:type_name -> runtime.v1.WindowsContainerResources + 70, // 149: runtime.v1.ContainerUser.linux:type_name -> runtime.v1.LinuxContainerUser + 64, // 150: runtime.v1.UpdateContainerResourcesRequest.linux:type_name -> runtime.v1.LinuxContainerResources + 76, // 151: runtime.v1.UpdateContainerResourcesRequest.windows:type_name -> runtime.v1.WindowsContainerResources + 203, // 152: runtime.v1.UpdateContainerResourcesRequest.annotations:type_name -> runtime.v1.UpdateContainerResourcesRequest.AnnotationsEntry + 62, // 153: runtime.v1.ImageFilter.image:type_name -> runtime.v1.ImageSpec + 112, // 154: runtime.v1.ListImagesRequest.filter:type_name -> runtime.v1.ImageFilter + 19, // 155: runtime.v1.Image.uid:type_name -> runtime.v1.Int64Value + 62, // 156: runtime.v1.Image.spec:type_name -> runtime.v1.ImageSpec + 114, // 157: runtime.v1.ListImagesResponse.images:type_name -> runtime.v1.Image + 112, // 158: runtime.v1.StreamImagesRequest.filter:type_name -> runtime.v1.ImageFilter + 114, // 159: runtime.v1.StreamImagesResponse.images:type_name -> runtime.v1.Image + 62, // 160: runtime.v1.ImageStatusRequest.image:type_name -> runtime.v1.ImageSpec + 114, // 161: runtime.v1.ImageStatusResponse.image:type_name -> runtime.v1.Image + 204, // 162: runtime.v1.ImageStatusResponse.info:type_name -> runtime.v1.ImageStatusResponse.InfoEntry + 62, // 163: runtime.v1.PullImageRequest.image:type_name -> runtime.v1.ImageSpec + 120, // 164: runtime.v1.PullImageRequest.auth:type_name -> runtime.v1.AuthConfig + 24, // 165: runtime.v1.PullImageRequest.sandbox_config:type_name -> runtime.v1.PodSandboxConfig + 62, // 166: runtime.v1.RemoveImageRequest.image:type_name -> runtime.v1.ImageSpec + 125, // 167: runtime.v1.RuntimeConfig.network_config:type_name -> runtime.v1.NetworkConfig + 126, // 168: runtime.v1.UpdateRuntimeConfigRequest.runtime_config:type_name -> runtime.v1.RuntimeConfig + 129, // 169: runtime.v1.RuntimeStatus.conditions:type_name -> runtime.v1.RuntimeCondition + 132, // 170: runtime.v1.RuntimeHandler.features:type_name -> runtime.v1.RuntimeHandlerFeatures + 130, // 171: runtime.v1.StatusResponse.status:type_name -> runtime.v1.RuntimeStatus + 205, // 172: runtime.v1.StatusResponse.info:type_name -> runtime.v1.StatusResponse.InfoEntry + 133, // 173: runtime.v1.StatusResponse.runtime_handlers:type_name -> runtime.v1.RuntimeHandler + 134, // 174: runtime.v1.StatusResponse.features:type_name -> runtime.v1.RuntimeFeatures + 138, // 175: runtime.v1.FilesystemUsage.fs_id:type_name -> runtime.v1.FilesystemIdentifier + 137, // 176: runtime.v1.FilesystemUsage.used_bytes:type_name -> runtime.v1.UInt64Value + 137, // 177: runtime.v1.FilesystemUsage.inodes_used:type_name -> runtime.v1.UInt64Value + 138, // 178: runtime.v1.WindowsFilesystemUsage.fs_id:type_name -> runtime.v1.FilesystemIdentifier + 137, // 179: runtime.v1.WindowsFilesystemUsage.used_bytes:type_name -> runtime.v1.UInt64Value + 139, // 180: runtime.v1.ImageFsInfoResponse.image_filesystems:type_name -> runtime.v1.FilesystemUsage + 139, // 181: runtime.v1.ImageFsInfoResponse.container_filesystems:type_name -> runtime.v1.FilesystemUsage + 150, // 182: runtime.v1.ContainerStatsResponse.stats:type_name -> runtime.v1.ContainerStats + 145, // 183: runtime.v1.ListContainerStatsRequest.filter:type_name -> runtime.v1.ContainerStatsFilter + 206, // 184: runtime.v1.ContainerStatsFilter.label_selector:type_name -> runtime.v1.ContainerStatsFilter.LabelSelectorEntry + 150, // 185: runtime.v1.ListContainerStatsResponse.stats:type_name -> runtime.v1.ContainerStats + 145, // 186: runtime.v1.StreamContainerStatsRequest.filter:type_name -> runtime.v1.ContainerStatsFilter + 150, // 187: runtime.v1.StreamContainerStatsResponse.container_stats:type_name -> runtime.v1.ContainerStats + 78, // 188: runtime.v1.ContainerAttributes.metadata:type_name -> runtime.v1.ContainerMetadata + 207, // 189: runtime.v1.ContainerAttributes.labels:type_name -> runtime.v1.ContainerAttributes.LabelsEntry + 208, // 190: runtime.v1.ContainerAttributes.annotations:type_name -> runtime.v1.ContainerAttributes.AnnotationsEntry + 149, // 191: runtime.v1.ContainerStats.attributes:type_name -> runtime.v1.ContainerAttributes + 154, // 192: runtime.v1.ContainerStats.cpu:type_name -> runtime.v1.CpuUsage + 156, // 193: runtime.v1.ContainerStats.memory:type_name -> runtime.v1.MemoryUsage + 139, // 194: runtime.v1.ContainerStats.writable_layer:type_name -> runtime.v1.FilesystemUsage + 158, // 195: runtime.v1.ContainerStats.swap:type_name -> runtime.v1.SwapUsage + 157, // 196: runtime.v1.ContainerStats.io:type_name -> runtime.v1.IoUsage + 149, // 197: runtime.v1.WindowsContainerStats.attributes:type_name -> runtime.v1.ContainerAttributes + 155, // 198: runtime.v1.WindowsContainerStats.cpu:type_name -> runtime.v1.WindowsCpuUsage + 159, // 199: runtime.v1.WindowsContainerStats.memory:type_name -> runtime.v1.WindowsMemoryUsage + 140, // 200: runtime.v1.WindowsContainerStats.writable_layer:type_name -> runtime.v1.WindowsFilesystemUsage + 153, // 201: runtime.v1.PsiStats.Full:type_name -> runtime.v1.PsiData + 153, // 202: runtime.v1.PsiStats.Some:type_name -> runtime.v1.PsiData + 137, // 203: runtime.v1.CpuUsage.usage_core_nano_seconds:type_name -> runtime.v1.UInt64Value + 137, // 204: runtime.v1.CpuUsage.usage_nano_cores:type_name -> runtime.v1.UInt64Value + 152, // 205: runtime.v1.CpuUsage.psi:type_name -> runtime.v1.PsiStats + 137, // 206: runtime.v1.WindowsCpuUsage.usage_core_nano_seconds:type_name -> runtime.v1.UInt64Value + 137, // 207: runtime.v1.WindowsCpuUsage.usage_nano_cores:type_name -> runtime.v1.UInt64Value + 137, // 208: runtime.v1.MemoryUsage.working_set_bytes:type_name -> runtime.v1.UInt64Value + 137, // 209: runtime.v1.MemoryUsage.available_bytes:type_name -> runtime.v1.UInt64Value + 137, // 210: runtime.v1.MemoryUsage.usage_bytes:type_name -> runtime.v1.UInt64Value + 137, // 211: runtime.v1.MemoryUsage.rss_bytes:type_name -> runtime.v1.UInt64Value + 137, // 212: runtime.v1.MemoryUsage.page_faults:type_name -> runtime.v1.UInt64Value + 137, // 213: runtime.v1.MemoryUsage.major_page_faults:type_name -> runtime.v1.UInt64Value + 152, // 214: runtime.v1.MemoryUsage.psi:type_name -> runtime.v1.PsiStats + 152, // 215: runtime.v1.IoUsage.psi:type_name -> runtime.v1.PsiStats + 137, // 216: runtime.v1.SwapUsage.swap_available_bytes:type_name -> runtime.v1.UInt64Value + 137, // 217: runtime.v1.SwapUsage.swap_usage_bytes:type_name -> runtime.v1.UInt64Value + 137, // 218: runtime.v1.WindowsMemoryUsage.working_set_bytes:type_name -> runtime.v1.UInt64Value + 137, // 219: runtime.v1.WindowsMemoryUsage.available_bytes:type_name -> runtime.v1.UInt64Value + 137, // 220: runtime.v1.WindowsMemoryUsage.page_faults:type_name -> runtime.v1.UInt64Value + 137, // 221: runtime.v1.WindowsMemoryUsage.commit_memory_bytes:type_name -> runtime.v1.UInt64Value + 7, // 222: runtime.v1.ContainerEventResponse.container_event_type:type_name -> runtime.v1.ContainerEventType + 36, // 223: runtime.v1.ContainerEventResponse.pod_sandbox_status:type_name -> runtime.v1.PodSandboxStatus + 98, // 224: runtime.v1.ContainerEventResponse.containers_statuses:type_name -> runtime.v1.ContainerStatus + 168, // 225: runtime.v1.ListMetricDescriptorsResponse.descriptors:type_name -> runtime.v1.MetricDescriptor + 173, // 226: runtime.v1.ListPodSandboxMetricsResponse.pod_metrics:type_name -> runtime.v1.PodSandboxMetrics + 173, // 227: runtime.v1.StreamPodSandboxMetricsResponse.pod_sandbox_metrics:type_name -> runtime.v1.PodSandboxMetrics + 175, // 228: runtime.v1.PodSandboxMetrics.metrics:type_name -> runtime.v1.Metric + 174, // 229: runtime.v1.PodSandboxMetrics.container_metrics:type_name -> runtime.v1.ContainerMetrics + 175, // 230: runtime.v1.ContainerMetrics.metrics:type_name -> runtime.v1.Metric + 8, // 231: runtime.v1.Metric.metric_type:type_name -> runtime.v1.MetricType + 137, // 232: runtime.v1.Metric.value:type_name -> runtime.v1.UInt64Value + 178, // 233: runtime.v1.RuntimeConfigResponse.linux:type_name -> runtime.v1.LinuxRuntimeConfiguration + 9, // 234: runtime.v1.LinuxRuntimeConfiguration.cgroup_driver:type_name -> runtime.v1.CgroupDriver + 64, // 235: runtime.v1.UpdatePodSandboxResourcesRequest.overhead:type_name -> runtime.v1.LinuxContainerResources + 64, // 236: runtime.v1.UpdatePodSandboxResourcesRequest.resources:type_name -> runtime.v1.LinuxContainerResources + 11, // 237: runtime.v1.RuntimeService.Version:input_type -> runtime.v1.VersionRequest + 25, // 238: runtime.v1.RuntimeService.RunPodSandbox:input_type -> runtime.v1.RunPodSandboxRequest + 27, // 239: runtime.v1.RuntimeService.StopPodSandbox:input_type -> runtime.v1.StopPodSandboxRequest + 29, // 240: runtime.v1.RuntimeService.RemovePodSandbox:input_type -> runtime.v1.RemovePodSandboxRequest + 31, // 241: runtime.v1.RuntimeService.PodSandboxStatus:input_type -> runtime.v1.PodSandboxStatusRequest + 40, // 242: runtime.v1.RuntimeService.ListPodSandbox:input_type -> runtime.v1.ListPodSandboxRequest + 43, // 243: runtime.v1.RuntimeService.StreamPodSandboxes:input_type -> runtime.v1.StreamPodSandboxesRequest + 82, // 244: runtime.v1.RuntimeService.CreateContainer:input_type -> runtime.v1.CreateContainerRequest + 84, // 245: runtime.v1.RuntimeService.StartContainer:input_type -> runtime.v1.StartContainerRequest + 86, // 246: runtime.v1.RuntimeService.StopContainer:input_type -> runtime.v1.StopContainerRequest + 88, // 247: runtime.v1.RuntimeService.RemoveContainer:input_type -> runtime.v1.RemoveContainerRequest + 92, // 248: runtime.v1.RuntimeService.ListContainers:input_type -> runtime.v1.ListContainersRequest + 95, // 249: runtime.v1.RuntimeService.StreamContainers:input_type -> runtime.v1.StreamContainersRequest + 97, // 250: runtime.v1.RuntimeService.ContainerStatus:input_type -> runtime.v1.ContainerStatusRequest + 102, // 251: runtime.v1.RuntimeService.UpdateContainerResources:input_type -> runtime.v1.UpdateContainerResourcesRequest + 160, // 252: runtime.v1.RuntimeService.ReopenContainerLog:input_type -> runtime.v1.ReopenContainerLogRequest + 104, // 253: runtime.v1.RuntimeService.ExecSync:input_type -> runtime.v1.ExecSyncRequest + 106, // 254: runtime.v1.RuntimeService.Exec:input_type -> runtime.v1.ExecRequest + 108, // 255: runtime.v1.RuntimeService.Attach:input_type -> runtime.v1.AttachRequest + 110, // 256: runtime.v1.RuntimeService.PortForward:input_type -> runtime.v1.PortForwardRequest + 142, // 257: runtime.v1.RuntimeService.ContainerStats:input_type -> runtime.v1.ContainerStatsRequest + 144, // 258: runtime.v1.RuntimeService.ListContainerStats:input_type -> runtime.v1.ListContainerStatsRequest + 147, // 259: runtime.v1.RuntimeService.StreamContainerStats:input_type -> runtime.v1.StreamContainerStatsRequest + 45, // 260: runtime.v1.RuntimeService.PodSandboxStats:input_type -> runtime.v1.PodSandboxStatsRequest + 48, // 261: runtime.v1.RuntimeService.ListPodSandboxStats:input_type -> runtime.v1.ListPodSandboxStatsRequest + 50, // 262: runtime.v1.RuntimeService.StreamPodSandboxStats:input_type -> runtime.v1.StreamPodSandboxStatsRequest + 127, // 263: runtime.v1.RuntimeService.UpdateRuntimeConfig:input_type -> runtime.v1.UpdateRuntimeConfigRequest + 131, // 264: runtime.v1.RuntimeService.Status:input_type -> runtime.v1.StatusRequest + 162, // 265: runtime.v1.RuntimeService.CheckpointContainer:input_type -> runtime.v1.CheckpointContainerRequest + 164, // 266: runtime.v1.RuntimeService.GetContainerEvents:input_type -> runtime.v1.GetEventsRequest + 166, // 267: runtime.v1.RuntimeService.ListMetricDescriptors:input_type -> runtime.v1.ListMetricDescriptorsRequest + 169, // 268: runtime.v1.RuntimeService.ListPodSandboxMetrics:input_type -> runtime.v1.ListPodSandboxMetricsRequest + 171, // 269: runtime.v1.RuntimeService.StreamPodSandboxMetrics:input_type -> runtime.v1.StreamPodSandboxMetricsRequest + 176, // 270: runtime.v1.RuntimeService.RuntimeConfig:input_type -> runtime.v1.RuntimeConfigRequest + 179, // 271: runtime.v1.RuntimeService.UpdatePodSandboxResources:input_type -> runtime.v1.UpdatePodSandboxResourcesRequest + 113, // 272: runtime.v1.ImageService.ListImages:input_type -> runtime.v1.ListImagesRequest + 116, // 273: runtime.v1.ImageService.StreamImages:input_type -> runtime.v1.StreamImagesRequest + 118, // 274: runtime.v1.ImageService.ImageStatus:input_type -> runtime.v1.ImageStatusRequest + 121, // 275: runtime.v1.ImageService.PullImage:input_type -> runtime.v1.PullImageRequest + 123, // 276: runtime.v1.ImageService.RemoveImage:input_type -> runtime.v1.RemoveImageRequest + 136, // 277: runtime.v1.ImageService.ImageFsInfo:input_type -> runtime.v1.ImageFsInfoRequest + 12, // 278: runtime.v1.RuntimeService.Version:output_type -> runtime.v1.VersionResponse + 26, // 279: runtime.v1.RuntimeService.RunPodSandbox:output_type -> runtime.v1.RunPodSandboxResponse + 28, // 280: runtime.v1.RuntimeService.StopPodSandbox:output_type -> runtime.v1.StopPodSandboxResponse + 30, // 281: runtime.v1.RuntimeService.RemovePodSandbox:output_type -> runtime.v1.RemovePodSandboxResponse + 37, // 282: runtime.v1.RuntimeService.PodSandboxStatus:output_type -> runtime.v1.PodSandboxStatusResponse + 42, // 283: runtime.v1.RuntimeService.ListPodSandbox:output_type -> runtime.v1.ListPodSandboxResponse + 44, // 284: runtime.v1.RuntimeService.StreamPodSandboxes:output_type -> runtime.v1.StreamPodSandboxesResponse + 83, // 285: runtime.v1.RuntimeService.CreateContainer:output_type -> runtime.v1.CreateContainerResponse + 85, // 286: runtime.v1.RuntimeService.StartContainer:output_type -> runtime.v1.StartContainerResponse + 87, // 287: runtime.v1.RuntimeService.StopContainer:output_type -> runtime.v1.StopContainerResponse + 89, // 288: runtime.v1.RuntimeService.RemoveContainer:output_type -> runtime.v1.RemoveContainerResponse + 94, // 289: runtime.v1.RuntimeService.ListContainers:output_type -> runtime.v1.ListContainersResponse + 96, // 290: runtime.v1.RuntimeService.StreamContainers:output_type -> runtime.v1.StreamContainersResponse + 99, // 291: runtime.v1.RuntimeService.ContainerStatus:output_type -> runtime.v1.ContainerStatusResponse + 103, // 292: runtime.v1.RuntimeService.UpdateContainerResources:output_type -> runtime.v1.UpdateContainerResourcesResponse + 161, // 293: runtime.v1.RuntimeService.ReopenContainerLog:output_type -> runtime.v1.ReopenContainerLogResponse + 105, // 294: runtime.v1.RuntimeService.ExecSync:output_type -> runtime.v1.ExecSyncResponse + 107, // 295: runtime.v1.RuntimeService.Exec:output_type -> runtime.v1.ExecResponse + 109, // 296: runtime.v1.RuntimeService.Attach:output_type -> runtime.v1.AttachResponse + 111, // 297: runtime.v1.RuntimeService.PortForward:output_type -> runtime.v1.PortForwardResponse + 143, // 298: runtime.v1.RuntimeService.ContainerStats:output_type -> runtime.v1.ContainerStatsResponse + 146, // 299: runtime.v1.RuntimeService.ListContainerStats:output_type -> runtime.v1.ListContainerStatsResponse + 148, // 300: runtime.v1.RuntimeService.StreamContainerStats:output_type -> runtime.v1.StreamContainerStatsResponse + 46, // 301: runtime.v1.RuntimeService.PodSandboxStats:output_type -> runtime.v1.PodSandboxStatsResponse + 49, // 302: runtime.v1.RuntimeService.ListPodSandboxStats:output_type -> runtime.v1.ListPodSandboxStatsResponse + 51, // 303: runtime.v1.RuntimeService.StreamPodSandboxStats:output_type -> runtime.v1.StreamPodSandboxStatsResponse + 128, // 304: runtime.v1.RuntimeService.UpdateRuntimeConfig:output_type -> runtime.v1.UpdateRuntimeConfigResponse + 135, // 305: runtime.v1.RuntimeService.Status:output_type -> runtime.v1.StatusResponse + 163, // 306: runtime.v1.RuntimeService.CheckpointContainer:output_type -> runtime.v1.CheckpointContainerResponse + 165, // 307: runtime.v1.RuntimeService.GetContainerEvents:output_type -> runtime.v1.ContainerEventResponse + 167, // 308: runtime.v1.RuntimeService.ListMetricDescriptors:output_type -> runtime.v1.ListMetricDescriptorsResponse + 170, // 309: runtime.v1.RuntimeService.ListPodSandboxMetrics:output_type -> runtime.v1.ListPodSandboxMetricsResponse + 172, // 310: runtime.v1.RuntimeService.StreamPodSandboxMetrics:output_type -> runtime.v1.StreamPodSandboxMetricsResponse + 177, // 311: runtime.v1.RuntimeService.RuntimeConfig:output_type -> runtime.v1.RuntimeConfigResponse + 180, // 312: runtime.v1.RuntimeService.UpdatePodSandboxResources:output_type -> runtime.v1.UpdatePodSandboxResourcesResponse + 115, // 313: runtime.v1.ImageService.ListImages:output_type -> runtime.v1.ListImagesResponse + 117, // 314: runtime.v1.ImageService.StreamImages:output_type -> runtime.v1.StreamImagesResponse + 119, // 315: runtime.v1.ImageService.ImageStatus:output_type -> runtime.v1.ImageStatusResponse + 122, // 316: runtime.v1.ImageService.PullImage:output_type -> runtime.v1.PullImageResponse + 124, // 317: runtime.v1.ImageService.RemoveImage:output_type -> runtime.v1.RemoveImageResponse + 141, // 318: runtime.v1.ImageService.ImageFsInfo:output_type -> runtime.v1.ImageFsInfoResponse + 278, // [278:319] is the sub-list for method output_type + 237, // [237:278] is the sub-list for method input_type + 237, // [237:237] is the sub-list for extension type_name + 237, // [237:237] is the sub-list for extension extendee + 0, // [0:237] is the sub-list for field type_name } func init() { file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_init() } @@ -13451,7 +14156,7 @@ func file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc), len(file_staging_src_k8s_io_cri_api_pkg_apis_runtime_v1_api_proto_rawDesc)), NumEnums: 11, - NumMessages: 186, + NumMessages: 198, NumExtensions: 0, NumServices: 2, }, diff --git a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto index 9e7b26aa72..f05a5e05fd 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto +++ b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto @@ -48,6 +48,19 @@ service RuntimeService { rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {} // ListPodSandbox returns a list of PodSandboxes. rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {} + // StreamPodSandboxes returns a stream of PodSandboxes. + // This is an alternative to ListPodSandbox that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many pods. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamPodSandboxes(StreamPodSandboxesRequest) returns (stream StreamPodSandboxesResponse) {} // CreateContainer creates a new container in specified PodSandbox rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {} @@ -66,6 +79,19 @@ service RuntimeService { rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {} // ListContainers lists all containers by filters. rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {} + // StreamContainers returns a stream of containers. + // This is an alternative to ListContainers that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many containers. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamContainers(StreamContainersRequest) returns (stream StreamContainersResponse) {} // ContainerStatus returns status of the container. If the container is not // present, returns an error. rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {} @@ -93,12 +119,40 @@ service RuntimeService { rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {} // ListContainerStats returns stats of all running containers. rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {} + // StreamContainerStats returns a stream of container stats. + // This is an alternative to ListContainerStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many containers. The number of items per list may vary + // depending on the container runtime. Each item must appear in exactly one + // response and must not be duplicated across responses in the same stream. + // The server must close the stream with EOF after all items have been sent. + // The kubelet collects all items from the stream and processes them all at + // once after the stream completes. The kubelet enforces a timeout on the + // entire stream and will discard partial results if the stream is not + // completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamContainerStats(StreamContainerStatsRequest) returns (stream StreamContainerStatsResponse) {} // PodSandboxStats returns stats of the pod sandbox. If the pod sandbox does not // exist, the call returns an error. rpc PodSandboxStats(PodSandboxStatsRequest) returns (PodSandboxStatsResponse) {} // ListPodSandboxStats returns stats of the pod sandboxes matching a filter. rpc ListPodSandboxStats(ListPodSandboxStatsRequest) returns (ListPodSandboxStatsResponse) {} + // StreamPodSandboxStats returns a stream of pod sandbox stats. + // This is an alternative to ListPodSandboxStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamPodSandboxStats(StreamPodSandboxStatsRequest) returns (stream StreamPodSandboxStatsResponse) {} // UpdateRuntimeConfig updates the runtime configuration based on the given request. rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {} @@ -121,6 +175,20 @@ service RuntimeService { // ListPodSandboxMetrics gets pod sandbox metrics from CRI Runtime rpc ListPodSandboxMetrics(ListPodSandboxMetricsRequest) returns (ListPodSandboxMetricsResponse) {} + // StreamPodSandboxMetrics returns a stream of pod sandbox metrics. + // This is an alternative to ListPodSandboxMetrics that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamPodSandboxMetrics(StreamPodSandboxMetricsRequest) returns (stream StreamPodSandboxMetricsResponse) {} // RuntimeConfig returns configuration information of the runtime. // A couple of notes: @@ -143,6 +211,19 @@ service RuntimeService { service ImageService { // ListImages lists existing images. rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {} + // StreamImages returns a stream of images. + // This is an alternative to ListImages that streams results in lists of at + // least one item, avoiding the gRPC message size limit for nodes with many + // images. The number of items per list may vary depending on the container + // runtime. Each item must appear in exactly one response and must not be + // duplicated across responses in the same stream. The server must close the + // stream with EOF after all items have been sent. The kubelet collects all + // items from the stream and processes them all at once after the stream + // completes. The kubelet enforces a timeout on the entire stream and will + // discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + rpc StreamImages(StreamImagesRequest) returns (stream StreamImagesResponse) {} // ImageStatus returns the status of the image. If the image is not // present, returns a response with ImageStatusResponse.Image set to // nil. @@ -152,8 +233,16 @@ service ImageService { // RemoveImage removes the image. // This call is idempotent, and must not return an error if the image has // already been removed. + // Note that if the image is referenced by multiple tags (even across different repositories + // if they resolve to the same image digest), removing the image by a single tag + // will remove all of its tags. For example, if `repo/image:v1` and `another_repo/image:latest` + // point to the same image, removing `repo/image:v1` will also remove `another_repo/image:latest`. + // The next call to ListImages, ImageStatus, ImageFsInfo will not return this image. + // The resources (e.g. disk space) may be cleaned asynchronously + // and not guaranteed to be cleaned up by the time this method returns. rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {} // ImageFSInfo returns information of the filesystem that is used to store images. + // Usage information may include images that were removed, but are still being cleaned up. rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {} } @@ -255,7 +344,7 @@ message Mount { // Mount an image reference (image ID, with or without digest), which is a // special use case for image volume mounts. If this field is set, then // host_path should be unset. All image mounts are per feature definition - // readonly (noexec). The kubelet does an PullImage RPC and evaluates the returned + // readonly. The kubelet does an PullImage RPC and evaluates the returned // PullImageResponse.image_ref value, which is then set to the // ImageSpec.image field. Runtimes are expected to mount the image as // required. @@ -670,6 +759,16 @@ message ListPodSandboxResponse { repeated PodSandbox items = 1; } +message StreamPodSandboxesRequest { + // Filter for the list request. + PodSandboxFilter filter = 1; +} + +message StreamPodSandboxesResponse { + // List of PodSandboxes. + repeated PodSandbox pod_sandboxes = 1; +} + message PodSandboxStatsRequest { // ID of the pod sandbox for which to retrieve stats. string pod_sandbox_id = 1; @@ -700,6 +799,16 @@ message ListPodSandboxStatsResponse { repeated PodSandboxStats stats = 1; } +message StreamPodSandboxStatsRequest { + // Filter for the list request. + PodSandboxStatsFilter filter = 1; +} + +message StreamPodSandboxStatsResponse { + // List of pod sandbox stats. + repeated PodSandboxStats pod_sandbox_stats = 1; +} + // PodSandboxAttributes provides basic information of the pod sandbox. message PodSandboxAttributes { // ID of the pod sandbox. @@ -835,11 +944,14 @@ message ImageSpec { // If the runtime handler is unknown, the request should be rejected. // An empty string would select the default runtime handler. string runtime_handler = 19; + // The digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + string image_ref = 20; } message KeyValue { string key = 1; - string value = 2; + bytes value = 2; } // LinuxContainerResources specifies Linux specific configuration for @@ -1350,15 +1462,11 @@ message Container { // MUST be identical to that of the corresponding ContainerConfig used to // instantiate this Container. map annotations = 9; - // Reference to the unique identifier of the image, on the node, as - // returned in the image service apis. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. // - // Note: The image_ref above has been historically used by container - // runtimes to reference images by digest. The image_ref has been also used - // in the kubelet image garbage collection, which does not work with - // digests at all. To separate and avoid possible misusage, we now - // introduce the image_id field, which should always refer to a unique - // image identifier on the node. + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. string image_id = 10; } @@ -1367,6 +1475,16 @@ message ListContainersResponse { repeated Container containers = 1; } +message StreamContainersRequest { + // Filter for the list request. + ContainerFilter filter = 1; +} + +message StreamContainersResponse { + // List of containers. + repeated Container containers = 1; +} + message ContainerStatusRequest { // ID of the container for which to retrieve status. string container_id = 1; @@ -1413,13 +1531,11 @@ message ContainerStatus { string log_path = 15; // Resource limits configuration of the container. ContainerResources resources = 16; - // Reference to the unique identifier of the image, on the node, as - // returned in the image service apis. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. // - // Note: The image_ref above has been historically used by container - // runtimes to reference images by digest. To separate and avoid possible - // misusage, we now introduce the image_id field, which should always refer - // to a unique image identifier on the node. + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. string image_id = 17; // User identities initially attached to the container ContainerUser user = 18; @@ -1573,7 +1689,11 @@ message ListImagesRequest { // Basic information about a container image. message Image { - // ID of the image. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. + // + // This value MUST always match `PullImageResponse.image_ref` when referring + // to the same image. string id = 1; // Other names by which this image is known. repeated string repo_tags = 2; @@ -1601,6 +1721,16 @@ message ListImagesResponse { repeated Image images = 1; } +message StreamImagesRequest { + // Filter to list images. + ImageFilter filter = 1; +} + +message StreamImagesResponse { + // List of images. + repeated Image images = 1; +} + message ImageStatusRequest { // Spec of the image. ImageSpec image = 1; @@ -1641,8 +1771,19 @@ message PullImageRequest { } message PullImageResponse { - // Reference to the image in use. For most runtimes, this should be an - // image ID or digest. + // Reference to the unique identifier of the image on the node, as + // returned in the image and runtime service apis. + // + // When referring to the same image, the container runtime MUST always return + // the same value for: + // - Image.id + // - Container.image_id + // - ContainerStatus.image_id + // - PullImageResponse.image_ref + // Note: this field has a stricter meaning starting with v1.36. + // It used to be image ID OR digest, which are different values, + // and would not necessarily match other ID fields in the Container, + // ContainerStatus, and Image messages string image_ref = 1; } @@ -1731,6 +1872,9 @@ message RuntimeHandler { message RuntimeFeatures { // supplemental_groups_policy is set to true if the runtime supports SupplementalGroupsPolicy and ContainerUser. bool supplemental_groups_policy = 1; + // user_namespaces_host_network is set to true if the runtime supports containers using both + // host network and user namespace simultaneously. + bool user_namespaces_host_network = 2; } message StatusResponse { @@ -1833,6 +1977,16 @@ message ListContainerStatsResponse { repeated ContainerStats stats = 1; } +message StreamContainerStatsRequest { + // Filter for the list request. + ContainerStatsFilter filter = 1; +} + +message StreamContainerStatsResponse { + // List of container stats. + repeated ContainerStats container_stats = 1; +} + // ContainerAttributes provides basic information of the container. message ContainerAttributes { // ID of the container. @@ -2049,6 +2203,13 @@ message ListPodSandboxMetricsResponse { repeated PodSandboxMetrics pod_metrics = 1; } +message StreamPodSandboxMetricsRequest {} + +message StreamPodSandboxMetricsResponse { + // List of pod sandbox metrics. + repeated PodSandboxMetrics pod_sandbox_metrics = 1; +} + message PodSandboxMetrics { string pod_sandbox_id = 1; repeated Metric metrics = 2; diff --git a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api_grpc.pb.go b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api_grpc.pb.go index ace6e12069..61f5750da5 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api_grpc.pb.go +++ b/vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api_grpc.pb.go @@ -58,11 +58,13 @@ const ( RuntimeService_RemovePodSandbox_FullMethodName = "/runtime.v1.RuntimeService/RemovePodSandbox" RuntimeService_PodSandboxStatus_FullMethodName = "/runtime.v1.RuntimeService/PodSandboxStatus" RuntimeService_ListPodSandbox_FullMethodName = "/runtime.v1.RuntimeService/ListPodSandbox" + RuntimeService_StreamPodSandboxes_FullMethodName = "/runtime.v1.RuntimeService/StreamPodSandboxes" RuntimeService_CreateContainer_FullMethodName = "/runtime.v1.RuntimeService/CreateContainer" RuntimeService_StartContainer_FullMethodName = "/runtime.v1.RuntimeService/StartContainer" RuntimeService_StopContainer_FullMethodName = "/runtime.v1.RuntimeService/StopContainer" RuntimeService_RemoveContainer_FullMethodName = "/runtime.v1.RuntimeService/RemoveContainer" RuntimeService_ListContainers_FullMethodName = "/runtime.v1.RuntimeService/ListContainers" + RuntimeService_StreamContainers_FullMethodName = "/runtime.v1.RuntimeService/StreamContainers" RuntimeService_ContainerStatus_FullMethodName = "/runtime.v1.RuntimeService/ContainerStatus" RuntimeService_UpdateContainerResources_FullMethodName = "/runtime.v1.RuntimeService/UpdateContainerResources" RuntimeService_ReopenContainerLog_FullMethodName = "/runtime.v1.RuntimeService/ReopenContainerLog" @@ -72,14 +74,17 @@ const ( RuntimeService_PortForward_FullMethodName = "/runtime.v1.RuntimeService/PortForward" RuntimeService_ContainerStats_FullMethodName = "/runtime.v1.RuntimeService/ContainerStats" RuntimeService_ListContainerStats_FullMethodName = "/runtime.v1.RuntimeService/ListContainerStats" + RuntimeService_StreamContainerStats_FullMethodName = "/runtime.v1.RuntimeService/StreamContainerStats" RuntimeService_PodSandboxStats_FullMethodName = "/runtime.v1.RuntimeService/PodSandboxStats" RuntimeService_ListPodSandboxStats_FullMethodName = "/runtime.v1.RuntimeService/ListPodSandboxStats" + RuntimeService_StreamPodSandboxStats_FullMethodName = "/runtime.v1.RuntimeService/StreamPodSandboxStats" RuntimeService_UpdateRuntimeConfig_FullMethodName = "/runtime.v1.RuntimeService/UpdateRuntimeConfig" RuntimeService_Status_FullMethodName = "/runtime.v1.RuntimeService/Status" RuntimeService_CheckpointContainer_FullMethodName = "/runtime.v1.RuntimeService/CheckpointContainer" RuntimeService_GetContainerEvents_FullMethodName = "/runtime.v1.RuntimeService/GetContainerEvents" RuntimeService_ListMetricDescriptors_FullMethodName = "/runtime.v1.RuntimeService/ListMetricDescriptors" RuntimeService_ListPodSandboxMetrics_FullMethodName = "/runtime.v1.RuntimeService/ListPodSandboxMetrics" + RuntimeService_StreamPodSandboxMetrics_FullMethodName = "/runtime.v1.RuntimeService/StreamPodSandboxMetrics" RuntimeService_RuntimeConfig_FullMethodName = "/runtime.v1.RuntimeService/RuntimeConfig" RuntimeService_UpdatePodSandboxResources_FullMethodName = "/runtime.v1.RuntimeService/UpdatePodSandboxResources" ) @@ -115,6 +120,19 @@ type RuntimeServiceClient interface { PodSandboxStatus(ctx context.Context, in *PodSandboxStatusRequest, opts ...grpc.CallOption) (*PodSandboxStatusResponse, error) // ListPodSandbox returns a list of PodSandboxes. ListPodSandbox(ctx context.Context, in *ListPodSandboxRequest, opts ...grpc.CallOption) (*ListPodSandboxResponse, error) + // StreamPodSandboxes returns a stream of PodSandboxes. + // This is an alternative to ListPodSandbox that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many pods. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxes(ctx context.Context, in *StreamPodSandboxesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxesResponse], error) // CreateContainer creates a new container in specified PodSandbox CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) // StartContainer starts the container. @@ -132,6 +150,19 @@ type RuntimeServiceClient interface { RemoveContainer(ctx context.Context, in *RemoveContainerRequest, opts ...grpc.CallOption) (*RemoveContainerResponse, error) // ListContainers lists all containers by filters. ListContainers(ctx context.Context, in *ListContainersRequest, opts ...grpc.CallOption) (*ListContainersResponse, error) + // StreamContainers returns a stream of containers. + // This is an alternative to ListContainers that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many containers. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamContainers(ctx context.Context, in *StreamContainersRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamContainersResponse], error) // ContainerStatus returns status of the container. If the container is not // present, returns an error. ContainerStatus(ctx context.Context, in *ContainerStatusRequest, opts ...grpc.CallOption) (*ContainerStatusResponse, error) @@ -157,11 +188,39 @@ type RuntimeServiceClient interface { ContainerStats(ctx context.Context, in *ContainerStatsRequest, opts ...grpc.CallOption) (*ContainerStatsResponse, error) // ListContainerStats returns stats of all running containers. ListContainerStats(ctx context.Context, in *ListContainerStatsRequest, opts ...grpc.CallOption) (*ListContainerStatsResponse, error) + // StreamContainerStats returns a stream of container stats. + // This is an alternative to ListContainerStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many containers. The number of items per list may vary + // depending on the container runtime. Each item must appear in exactly one + // response and must not be duplicated across responses in the same stream. + // The server must close the stream with EOF after all items have been sent. + // The kubelet collects all items from the stream and processes them all at + // once after the stream completes. The kubelet enforces a timeout on the + // entire stream and will discard partial results if the stream is not + // completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamContainerStats(ctx context.Context, in *StreamContainerStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamContainerStatsResponse], error) // PodSandboxStats returns stats of the pod sandbox. If the pod sandbox does not // exist, the call returns an error. PodSandboxStats(ctx context.Context, in *PodSandboxStatsRequest, opts ...grpc.CallOption) (*PodSandboxStatsResponse, error) // ListPodSandboxStats returns stats of the pod sandboxes matching a filter. ListPodSandboxStats(ctx context.Context, in *ListPodSandboxStatsRequest, opts ...grpc.CallOption) (*ListPodSandboxStatsResponse, error) + // StreamPodSandboxStats returns a stream of pod sandbox stats. + // This is an alternative to ListPodSandboxStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxStats(ctx context.Context, in *StreamPodSandboxStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxStatsResponse], error) // UpdateRuntimeConfig updates the runtime configuration based on the given request. UpdateRuntimeConfig(ctx context.Context, in *UpdateRuntimeConfigRequest, opts ...grpc.CallOption) (*UpdateRuntimeConfigResponse, error) // Status returns the status of the runtime. @@ -178,6 +237,20 @@ type RuntimeServiceClient interface { ListMetricDescriptors(ctx context.Context, in *ListMetricDescriptorsRequest, opts ...grpc.CallOption) (*ListMetricDescriptorsResponse, error) // ListPodSandboxMetrics gets pod sandbox metrics from CRI Runtime ListPodSandboxMetrics(ctx context.Context, in *ListPodSandboxMetricsRequest, opts ...grpc.CallOption) (*ListPodSandboxMetricsResponse, error) + // StreamPodSandboxMetrics returns a stream of pod sandbox metrics. + // This is an alternative to ListPodSandboxMetrics that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxMetrics(ctx context.Context, in *StreamPodSandboxMetricsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxMetricsResponse], error) // RuntimeConfig returns configuration information of the runtime. // A couple of notes: // - The RuntimeConfigRequest object is not to be confused with the contents of UpdateRuntimeConfigRequest. @@ -262,6 +335,25 @@ func (c *runtimeServiceClient) ListPodSandbox(ctx context.Context, in *ListPodSa return out, nil } +func (c *runtimeServiceClient) StreamPodSandboxes(ctx context.Context, in *StreamPodSandboxesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxesResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[0], RuntimeService_StreamPodSandboxes_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamPodSandboxesRequest, StreamPodSandboxesResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxesClient = grpc.ServerStreamingClient[StreamPodSandboxesResponse] + func (c *runtimeServiceClient) CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateContainerResponse) @@ -312,6 +404,25 @@ func (c *runtimeServiceClient) ListContainers(ctx context.Context, in *ListConta return out, nil } +func (c *runtimeServiceClient) StreamContainers(ctx context.Context, in *StreamContainersRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamContainersResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[1], RuntimeService_StreamContainers_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamContainersRequest, StreamContainersResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamContainersClient = grpc.ServerStreamingClient[StreamContainersResponse] + func (c *runtimeServiceClient) ContainerStatus(ctx context.Context, in *ContainerStatusRequest, opts ...grpc.CallOption) (*ContainerStatusResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ContainerStatusResponse) @@ -402,6 +513,25 @@ func (c *runtimeServiceClient) ListContainerStats(ctx context.Context, in *ListC return out, nil } +func (c *runtimeServiceClient) StreamContainerStats(ctx context.Context, in *StreamContainerStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamContainerStatsResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[2], RuntimeService_StreamContainerStats_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamContainerStatsRequest, StreamContainerStatsResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamContainerStatsClient = grpc.ServerStreamingClient[StreamContainerStatsResponse] + func (c *runtimeServiceClient) PodSandboxStats(ctx context.Context, in *PodSandboxStatsRequest, opts ...grpc.CallOption) (*PodSandboxStatsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(PodSandboxStatsResponse) @@ -422,6 +552,25 @@ func (c *runtimeServiceClient) ListPodSandboxStats(ctx context.Context, in *List return out, nil } +func (c *runtimeServiceClient) StreamPodSandboxStats(ctx context.Context, in *StreamPodSandboxStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxStatsResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[3], RuntimeService_StreamPodSandboxStats_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamPodSandboxStatsRequest, StreamPodSandboxStatsResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxStatsClient = grpc.ServerStreamingClient[StreamPodSandboxStatsResponse] + func (c *runtimeServiceClient) UpdateRuntimeConfig(ctx context.Context, in *UpdateRuntimeConfigRequest, opts ...grpc.CallOption) (*UpdateRuntimeConfigResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UpdateRuntimeConfigResponse) @@ -454,7 +603,7 @@ func (c *runtimeServiceClient) CheckpointContainer(ctx context.Context, in *Chec func (c *runtimeServiceClient) GetContainerEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ContainerEventResponse], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[0], RuntimeService_GetContainerEvents_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[4], RuntimeService_GetContainerEvents_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -491,6 +640,25 @@ func (c *runtimeServiceClient) ListPodSandboxMetrics(ctx context.Context, in *Li return out, nil } +func (c *runtimeServiceClient) StreamPodSandboxMetrics(ctx context.Context, in *StreamPodSandboxMetricsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamPodSandboxMetricsResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &RuntimeService_ServiceDesc.Streams[5], RuntimeService_StreamPodSandboxMetrics_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamPodSandboxMetricsRequest, StreamPodSandboxMetricsResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxMetricsClient = grpc.ServerStreamingClient[StreamPodSandboxMetricsResponse] + func (c *runtimeServiceClient) RuntimeConfig(ctx context.Context, in *RuntimeConfigRequest, opts ...grpc.CallOption) (*RuntimeConfigResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RuntimeConfigResponse) @@ -542,6 +710,19 @@ type RuntimeServiceServer interface { PodSandboxStatus(context.Context, *PodSandboxStatusRequest) (*PodSandboxStatusResponse, error) // ListPodSandbox returns a list of PodSandboxes. ListPodSandbox(context.Context, *ListPodSandboxRequest) (*ListPodSandboxResponse, error) + // StreamPodSandboxes returns a stream of PodSandboxes. + // This is an alternative to ListPodSandbox that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many pods. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxes(*StreamPodSandboxesRequest, grpc.ServerStreamingServer[StreamPodSandboxesResponse]) error // CreateContainer creates a new container in specified PodSandbox CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) // StartContainer starts the container. @@ -559,6 +740,19 @@ type RuntimeServiceServer interface { RemoveContainer(context.Context, *RemoveContainerRequest) (*RemoveContainerResponse, error) // ListContainers lists all containers by filters. ListContainers(context.Context, *ListContainersRequest) (*ListContainersResponse, error) + // StreamContainers returns a stream of containers. + // This is an alternative to ListContainers that streams results in lists + // of at least one item, avoiding the gRPC message size limit for nodes with + // many containers. The number of items per list may vary depending on the + // container runtime. Each item must appear in exactly one response and must + // not be duplicated across responses in the same stream. The server must + // close the stream with EOF after all items have been sent. The kubelet + // collects all items from the stream and processes them all at once after + // the stream completes. The kubelet enforces a timeout on the entire stream + // and will discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamContainers(*StreamContainersRequest, grpc.ServerStreamingServer[StreamContainersResponse]) error // ContainerStatus returns status of the container. If the container is not // present, returns an error. ContainerStatus(context.Context, *ContainerStatusRequest) (*ContainerStatusResponse, error) @@ -584,11 +778,39 @@ type RuntimeServiceServer interface { ContainerStats(context.Context, *ContainerStatsRequest) (*ContainerStatsResponse, error) // ListContainerStats returns stats of all running containers. ListContainerStats(context.Context, *ListContainerStatsRequest) (*ListContainerStatsResponse, error) + // StreamContainerStats returns a stream of container stats. + // This is an alternative to ListContainerStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many containers. The number of items per list may vary + // depending on the container runtime. Each item must appear in exactly one + // response and must not be duplicated across responses in the same stream. + // The server must close the stream with EOF after all items have been sent. + // The kubelet collects all items from the stream and processes them all at + // once after the stream completes. The kubelet enforces a timeout on the + // entire stream and will discard partial results if the stream is not + // completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamContainerStats(*StreamContainerStatsRequest, grpc.ServerStreamingServer[StreamContainerStatsResponse]) error // PodSandboxStats returns stats of the pod sandbox. If the pod sandbox does not // exist, the call returns an error. PodSandboxStats(context.Context, *PodSandboxStatsRequest) (*PodSandboxStatsResponse, error) // ListPodSandboxStats returns stats of the pod sandboxes matching a filter. ListPodSandboxStats(context.Context, *ListPodSandboxStatsRequest) (*ListPodSandboxStatsResponse, error) + // StreamPodSandboxStats returns a stream of pod sandbox stats. + // This is an alternative to ListPodSandboxStats that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxStats(*StreamPodSandboxStatsRequest, grpc.ServerStreamingServer[StreamPodSandboxStatsResponse]) error // UpdateRuntimeConfig updates the runtime configuration based on the given request. UpdateRuntimeConfig(context.Context, *UpdateRuntimeConfigRequest) (*UpdateRuntimeConfigResponse, error) // Status returns the status of the runtime. @@ -605,6 +827,20 @@ type RuntimeServiceServer interface { ListMetricDescriptors(context.Context, *ListMetricDescriptorsRequest) (*ListMetricDescriptorsResponse, error) // ListPodSandboxMetrics gets pod sandbox metrics from CRI Runtime ListPodSandboxMetrics(context.Context, *ListPodSandboxMetricsRequest) (*ListPodSandboxMetricsResponse, error) + // StreamPodSandboxMetrics returns a stream of pod sandbox metrics. + // This is an alternative to ListPodSandboxMetrics that streams results in + // lists of at least one item, avoiding the gRPC message size limit for + // nodes with many pods. The number of items per list may vary depending on + // the container runtime. Each item must appear in exactly one response and + // must not be duplicated across responses in the same stream. The server + // must close the stream with EOF after all items have been sent. The + // kubelet collects all items from the stream and processes them all at once + // after the stream completes. The kubelet enforces a timeout on the entire + // stream and will discard partial results if the stream is not completed + // in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamPodSandboxMetrics(*StreamPodSandboxMetricsRequest, grpc.ServerStreamingServer[StreamPodSandboxMetricsResponse]) error // RuntimeConfig returns configuration information of the runtime. // A couple of notes: // - The RuntimeConfigRequest object is not to be confused with the contents of UpdateRuntimeConfigRequest. @@ -647,6 +883,9 @@ func (UnimplementedRuntimeServiceServer) PodSandboxStatus(context.Context, *PodS func (UnimplementedRuntimeServiceServer) ListPodSandbox(context.Context, *ListPodSandboxRequest) (*ListPodSandboxResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPodSandbox not implemented") } +func (UnimplementedRuntimeServiceServer) StreamPodSandboxes(*StreamPodSandboxesRequest, grpc.ServerStreamingServer[StreamPodSandboxesResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamPodSandboxes not implemented") +} func (UnimplementedRuntimeServiceServer) CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateContainer not implemented") } @@ -662,6 +901,9 @@ func (UnimplementedRuntimeServiceServer) RemoveContainer(context.Context, *Remov func (UnimplementedRuntimeServiceServer) ListContainers(context.Context, *ListContainersRequest) (*ListContainersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListContainers not implemented") } +func (UnimplementedRuntimeServiceServer) StreamContainers(*StreamContainersRequest, grpc.ServerStreamingServer[StreamContainersResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamContainers not implemented") +} func (UnimplementedRuntimeServiceServer) ContainerStatus(context.Context, *ContainerStatusRequest) (*ContainerStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ContainerStatus not implemented") } @@ -689,12 +931,18 @@ func (UnimplementedRuntimeServiceServer) ContainerStats(context.Context, *Contai func (UnimplementedRuntimeServiceServer) ListContainerStats(context.Context, *ListContainerStatsRequest) (*ListContainerStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListContainerStats not implemented") } +func (UnimplementedRuntimeServiceServer) StreamContainerStats(*StreamContainerStatsRequest, grpc.ServerStreamingServer[StreamContainerStatsResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamContainerStats not implemented") +} func (UnimplementedRuntimeServiceServer) PodSandboxStats(context.Context, *PodSandboxStatsRequest) (*PodSandboxStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PodSandboxStats not implemented") } func (UnimplementedRuntimeServiceServer) ListPodSandboxStats(context.Context, *ListPodSandboxStatsRequest) (*ListPodSandboxStatsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPodSandboxStats not implemented") } +func (UnimplementedRuntimeServiceServer) StreamPodSandboxStats(*StreamPodSandboxStatsRequest, grpc.ServerStreamingServer[StreamPodSandboxStatsResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamPodSandboxStats not implemented") +} func (UnimplementedRuntimeServiceServer) UpdateRuntimeConfig(context.Context, *UpdateRuntimeConfigRequest) (*UpdateRuntimeConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRuntimeConfig not implemented") } @@ -713,6 +961,9 @@ func (UnimplementedRuntimeServiceServer) ListMetricDescriptors(context.Context, func (UnimplementedRuntimeServiceServer) ListPodSandboxMetrics(context.Context, *ListPodSandboxMetricsRequest) (*ListPodSandboxMetricsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPodSandboxMetrics not implemented") } +func (UnimplementedRuntimeServiceServer) StreamPodSandboxMetrics(*StreamPodSandboxMetricsRequest, grpc.ServerStreamingServer[StreamPodSandboxMetricsResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamPodSandboxMetrics not implemented") +} func (UnimplementedRuntimeServiceServer) RuntimeConfig(context.Context, *RuntimeConfigRequest) (*RuntimeConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RuntimeConfig not implemented") } @@ -848,6 +1099,17 @@ func _RuntimeService_ListPodSandbox_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _RuntimeService_StreamPodSandboxes_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamPodSandboxesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(RuntimeServiceServer).StreamPodSandboxes(m, &grpc.GenericServerStream[StreamPodSandboxesRequest, StreamPodSandboxesResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxesServer = grpc.ServerStreamingServer[StreamPodSandboxesResponse] + func _RuntimeService_CreateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateContainerRequest) if err := dec(in); err != nil { @@ -938,6 +1200,17 @@ func _RuntimeService_ListContainers_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _RuntimeService_StreamContainers_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamContainersRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(RuntimeServiceServer).StreamContainers(m, &grpc.GenericServerStream[StreamContainersRequest, StreamContainersResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamContainersServer = grpc.ServerStreamingServer[StreamContainersResponse] + func _RuntimeService_ContainerStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ContainerStatusRequest) if err := dec(in); err != nil { @@ -1100,6 +1373,17 @@ func _RuntimeService_ListContainerStats_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } +func _RuntimeService_StreamContainerStats_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamContainerStatsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(RuntimeServiceServer).StreamContainerStats(m, &grpc.GenericServerStream[StreamContainerStatsRequest, StreamContainerStatsResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamContainerStatsServer = grpc.ServerStreamingServer[StreamContainerStatsResponse] + func _RuntimeService_PodSandboxStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PodSandboxStatsRequest) if err := dec(in); err != nil { @@ -1136,6 +1420,17 @@ func _RuntimeService_ListPodSandboxStats_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _RuntimeService_StreamPodSandboxStats_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamPodSandboxStatsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(RuntimeServiceServer).StreamPodSandboxStats(m, &grpc.GenericServerStream[StreamPodSandboxStatsRequest, StreamPodSandboxStatsResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxStatsServer = grpc.ServerStreamingServer[StreamPodSandboxStatsResponse] + func _RuntimeService_UpdateRuntimeConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateRuntimeConfigRequest) if err := dec(in); err != nil { @@ -1237,6 +1532,17 @@ func _RuntimeService_ListPodSandboxMetrics_Handler(srv interface{}, ctx context. return interceptor(ctx, in, info, handler) } +func _RuntimeService_StreamPodSandboxMetrics_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamPodSandboxMetricsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(RuntimeServiceServer).StreamPodSandboxMetrics(m, &grpc.GenericServerStream[StreamPodSandboxMetricsRequest, StreamPodSandboxMetricsResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type RuntimeService_StreamPodSandboxMetricsServer = grpc.ServerStreamingServer[StreamPodSandboxMetricsResponse] + func _RuntimeService_RuntimeConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RuntimeConfigRequest) if err := dec(in); err != nil { @@ -1398,21 +1704,47 @@ var RuntimeService_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{ + { + StreamName: "StreamPodSandboxes", + Handler: _RuntimeService_StreamPodSandboxes_Handler, + ServerStreams: true, + }, + { + StreamName: "StreamContainers", + Handler: _RuntimeService_StreamContainers_Handler, + ServerStreams: true, + }, + { + StreamName: "StreamContainerStats", + Handler: _RuntimeService_StreamContainerStats_Handler, + ServerStreams: true, + }, + { + StreamName: "StreamPodSandboxStats", + Handler: _RuntimeService_StreamPodSandboxStats_Handler, + ServerStreams: true, + }, { StreamName: "GetContainerEvents", Handler: _RuntimeService_GetContainerEvents_Handler, ServerStreams: true, }, + { + StreamName: "StreamPodSandboxMetrics", + Handler: _RuntimeService_StreamPodSandboxMetrics_Handler, + ServerStreams: true, + }, }, Metadata: "staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto", } const ( - ImageService_ListImages_FullMethodName = "/runtime.v1.ImageService/ListImages" - ImageService_ImageStatus_FullMethodName = "/runtime.v1.ImageService/ImageStatus" - ImageService_PullImage_FullMethodName = "/runtime.v1.ImageService/PullImage" - ImageService_RemoveImage_FullMethodName = "/runtime.v1.ImageService/RemoveImage" - ImageService_ImageFsInfo_FullMethodName = "/runtime.v1.ImageService/ImageFsInfo" + ImageService_ListImages_FullMethodName = "/runtime.v1.ImageService/ListImages" + ImageService_StreamImages_FullMethodName = "/runtime.v1.ImageService/StreamImages" + ImageService_ImageStatus_FullMethodName = "/runtime.v1.ImageService/ImageStatus" + ImageService_PullImage_FullMethodName = "/runtime.v1.ImageService/PullImage" + ImageService_RemoveImage_FullMethodName = "/runtime.v1.ImageService/RemoveImage" + ImageService_ImageFsInfo_FullMethodName = "/runtime.v1.ImageService/ImageFsInfo" ) // ImageServiceClient is the client API for ImageService service. @@ -1423,6 +1755,19 @@ const ( type ImageServiceClient interface { // ListImages lists existing images. ListImages(ctx context.Context, in *ListImagesRequest, opts ...grpc.CallOption) (*ListImagesResponse, error) + // StreamImages returns a stream of images. + // This is an alternative to ListImages that streams results in lists of at + // least one item, avoiding the gRPC message size limit for nodes with many + // images. The number of items per list may vary depending on the container + // runtime. Each item must appear in exactly one response and must not be + // duplicated across responses in the same stream. The server must close the + // stream with EOF after all items have been sent. The kubelet collects all + // items from the stream and processes them all at once after the stream + // completes. The kubelet enforces a timeout on the entire stream and will + // discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamImages(ctx context.Context, in *StreamImagesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamImagesResponse], error) // ImageStatus returns the status of the image. If the image is not // present, returns a response with ImageStatusResponse.Image set to // nil. @@ -1432,8 +1777,16 @@ type ImageServiceClient interface { // RemoveImage removes the image. // This call is idempotent, and must not return an error if the image has // already been removed. + // Note that if the image is referenced by multiple tags (even across different repositories + // if they resolve to the same image digest), removing the image by a single tag + // will remove all of its tags. For example, if `repo/image:v1` and `another_repo/image:latest` + // point to the same image, removing `repo/image:v1` will also remove `another_repo/image:latest`. + // The next call to ListImages, ImageStatus, ImageFsInfo will not return this image. + // The resources (e.g. disk space) may be cleaned asynchronously + // and not guaranteed to be cleaned up by the time this method returns. RemoveImage(ctx context.Context, in *RemoveImageRequest, opts ...grpc.CallOption) (*RemoveImageResponse, error) // ImageFSInfo returns information of the filesystem that is used to store images. + // Usage information may include images that were removed, but are still being cleaned up. ImageFsInfo(ctx context.Context, in *ImageFsInfoRequest, opts ...grpc.CallOption) (*ImageFsInfoResponse, error) } @@ -1455,6 +1808,25 @@ func (c *imageServiceClient) ListImages(ctx context.Context, in *ListImagesReque return out, nil } +func (c *imageServiceClient) StreamImages(ctx context.Context, in *StreamImagesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamImagesResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ImageService_ServiceDesc.Streams[0], ImageService_StreamImages_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamImagesRequest, StreamImagesResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ImageService_StreamImagesClient = grpc.ServerStreamingClient[StreamImagesResponse] + func (c *imageServiceClient) ImageStatus(ctx context.Context, in *ImageStatusRequest, opts ...grpc.CallOption) (*ImageStatusResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ImageStatusResponse) @@ -1503,6 +1875,19 @@ func (c *imageServiceClient) ImageFsInfo(ctx context.Context, in *ImageFsInfoReq type ImageServiceServer interface { // ListImages lists existing images. ListImages(context.Context, *ListImagesRequest) (*ListImagesResponse, error) + // StreamImages returns a stream of images. + // This is an alternative to ListImages that streams results in lists of at + // least one item, avoiding the gRPC message size limit for nodes with many + // images. The number of items per list may vary depending on the container + // runtime. Each item must appear in exactly one response and must not be + // duplicated across responses in the same stream. The server must close the + // stream with EOF after all items have been sent. The kubelet collects all + // items from the stream and processes them all at once after the stream + // completes. The kubelet enforces a timeout on the entire stream and will + // discard partial results if the stream is not completed in time. + // Feature gate: CRIListStreaming + // See https://kep.k8s.io/5825 for more details. + StreamImages(*StreamImagesRequest, grpc.ServerStreamingServer[StreamImagesResponse]) error // ImageStatus returns the status of the image. If the image is not // present, returns a response with ImageStatusResponse.Image set to // nil. @@ -1512,8 +1897,16 @@ type ImageServiceServer interface { // RemoveImage removes the image. // This call is idempotent, and must not return an error if the image has // already been removed. + // Note that if the image is referenced by multiple tags (even across different repositories + // if they resolve to the same image digest), removing the image by a single tag + // will remove all of its tags. For example, if `repo/image:v1` and `another_repo/image:latest` + // point to the same image, removing `repo/image:v1` will also remove `another_repo/image:latest`. + // The next call to ListImages, ImageStatus, ImageFsInfo will not return this image. + // The resources (e.g. disk space) may be cleaned asynchronously + // and not guaranteed to be cleaned up by the time this method returns. RemoveImage(context.Context, *RemoveImageRequest) (*RemoveImageResponse, error) // ImageFSInfo returns information of the filesystem that is used to store images. + // Usage information may include images that were removed, but are still being cleaned up. ImageFsInfo(context.Context, *ImageFsInfoRequest) (*ImageFsInfoResponse, error) mustEmbedUnimplementedImageServiceServer() } @@ -1528,6 +1921,9 @@ type UnimplementedImageServiceServer struct{} func (UnimplementedImageServiceServer) ListImages(context.Context, *ListImagesRequest) (*ListImagesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListImages not implemented") } +func (UnimplementedImageServiceServer) StreamImages(*StreamImagesRequest, grpc.ServerStreamingServer[StreamImagesResponse]) error { + return status.Errorf(codes.Unimplemented, "method StreamImages not implemented") +} func (UnimplementedImageServiceServer) ImageStatus(context.Context, *ImageStatusRequest) (*ImageStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ImageStatus not implemented") } @@ -1579,6 +1975,17 @@ func _ImageService_ListImages_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ImageService_StreamImages_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamImagesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ImageServiceServer).StreamImages(m, &grpc.GenericServerStream[StreamImagesRequest, StreamImagesResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ImageService_StreamImagesServer = grpc.ServerStreamingServer[StreamImagesResponse] + func _ImageService_ImageStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ImageStatusRequest) if err := dec(in); err != nil { @@ -1679,6 +2086,12 @@ var ImageService_ServiceDesc = grpc.ServiceDesc{ Handler: _ImageService_ImageFsInfo_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamImages", + Handler: _ImageService_StreamImages_Handler, + ServerStreams: true, + }, + }, Metadata: "staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto", } diff --git a/vendor/k8s.io/cri-api/pkg/apis/services.go b/vendor/k8s.io/cri-api/pkg/apis/services.go index 2bbd35b2d4..6618e36121 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/services.go +++ b/vendor/k8s.io/cri-api/pkg/apis/services.go @@ -124,7 +124,7 @@ type RuntimeService interface { // RuntimeConfig returns the configuration information of the runtime. RuntimeConfig(ctx context.Context) (*runtimeapi.RuntimeConfigResponse, error) // Close will shutdown the internal gRPC client connection. - Close() error + Close(ctx context.Context) error } // ImageManagerService interface should be implemented by a container image @@ -142,5 +142,5 @@ type ImageManagerService interface { // ImageFsInfo returns information of the filesystem(s) used to store the read-only layers and the writeable layer. ImageFsInfo(ctx context.Context) (*runtimeapi.ImageFsInfoResponse, error) // Close will shutdown the internal gRPC client connection. - Close() error + Close(ctx context.Context) error } diff --git a/vendor/k8s.io/cri-api/pkg/apis/testing/fake_image_service.go b/vendor/k8s.io/cri-api/pkg/apis/testing/fake_image_service.go index b83b57f8ca..1381661727 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/testing/fake_image_service.go +++ b/vendor/k8s.io/cri-api/pkg/apis/testing/fake_image_service.go @@ -256,7 +256,7 @@ type pulledImage struct { } // Close will shutdown the internal gRPC client connection. -func (r *FakeImageService) Close() error { +func (r *FakeImageService) Close(_ context.Context) error { r.Lock() defer r.Unlock() diff --git a/vendor/k8s.io/cri-api/pkg/apis/testing/fake_runtime_service.go b/vendor/k8s.io/cri-api/pkg/apis/testing/fake_runtime_service.go index f4e808d7aa..4e1456e6b2 100644 --- a/vendor/k8s.io/cri-api/pkg/apis/testing/fake_runtime_service.go +++ b/vendor/k8s.io/cri-api/pkg/apis/testing/fake_runtime_service.go @@ -810,7 +810,7 @@ func (r *FakeRuntimeService) UpdatePodSandboxResources(context.Context, *runtime } // Close will shutdown the internal gRPC client connection. -func (r *FakeRuntimeService) Close() error { +func (r *FakeRuntimeService) Close(_ context.Context) error { r.Lock() defer r.Unlock() diff --git a/vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go b/vendor/k8s.io/cri-client/pkg/connection_target.go similarity index 52% rename from vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go rename to vendor/k8s.io/cri-client/pkg/connection_target.go index 35fe0d2a8a..207b83c6a9 100644 --- a/vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go +++ b/vendor/k8s.io/cri-client/pkg/connection_target.go @@ -1,6 +1,3 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - /* Copyright The Kubernetes Authors. @@ -17,16 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v2 - -func (*APIGroupDiscovery) ProtoMessage() {} - -func (*APIGroupDiscoveryList) ProtoMessage() {} +package cri -func (*APIResourceDiscovery) ProtoMessage() {} +import "strings" -func (*APISubresourceDiscovery) ProtoMessage() {} +func clientTargetForAddress(addr string) string { + // Defensive: normalize callers that pass a unix endpoint instead of the + // parsed socket path. + if strings.HasPrefix(addr, "unix:///") { + addr = strings.TrimPrefix(addr, "unix://") + } -func (*APIVersionDiscovery) ProtoMessage() {} + // grpc defaults to the DNS resolver for bare targets. Use the passthrough + // resolver for socket-style addresses so the custom dialer gets the raw path. + if strings.HasPrefix(addr, "/") { + return "passthrough:///" + addr + } + return addr +} diff --git a/vendor/k8s.io/cri-client/pkg/logs/logs.go b/vendor/k8s.io/cri-client/pkg/logs/logs.go index bbfc2b6033..ffa3bb37e6 100644 --- a/vendor/k8s.io/cri-client/pkg/logs/logs.go +++ b/vendor/k8s.io/cri-client/pkg/logs/logs.go @@ -33,13 +33,11 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - v1 "k8s.io/api/core/v1" internalapi "k8s.io/cri-api/pkg/apis" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" remote "k8s.io/cri-client/pkg" - "k8s.io/cri-client/pkg/internal" ) // Notice that the current CRI logs implementation doesn't handle @@ -89,34 +87,28 @@ func (l *logMessage) reset() { // LogOptions is the CRI internal type of all log options. type LogOptions struct { - tail int64 - bytes int64 - since time.Time - follow bool - timestamp bool -} - -// NewLogOptions convert the v1.PodLogOptions to CRI internal LogOptions. -func NewLogOptions(apiOpts *v1.PodLogOptions, now time.Time) *LogOptions { - opts := &LogOptions{ - tail: -1, // -1 by default which means read all logs. - bytes: -1, // -1 by default which means read all logs. - follow: apiOpts.Follow, - timestamp: apiOpts.Timestamps, - } - if apiOpts.TailLines != nil { - opts.tail = *apiOpts.TailLines - } - if apiOpts.LimitBytes != nil { - opts.bytes = *apiOpts.LimitBytes - } - if apiOpts.SinceSeconds != nil { - opts.since = now.Add(-time.Duration(*apiOpts.SinceSeconds) * time.Second) - } - if apiOpts.SinceTime != nil && apiOpts.SinceTime.After(opts.since) { - opts.since = apiOpts.SinceTime.Time - } - return opts + // TailLines is the number of lines to show from the end of the logs. + // If it is nil, it means all log lines will be shown. + // If it is 0, no log lines will be shown. + // This corresponds to the TailLines field in v1.PodLogOptions. + TailLines *int64 + // LimitBytes is the maximum number of bytes to read from the logs. + // If it is nil, it means all bytes will be read. + // If it is 0, no bytes will be read. + // This corresponds to the LimitBytes field in v1.PodLogOptions. + LimitBytes *int64 + // Since is the absolute time from which to show logs. + // Only logs with a timestamp after this time will be returned. + // This can be derived from either SinceSeconds or SinceTime in v1.PodLogOptions. + Since time.Time + // Follow indicates whether the logs should be followed. + // If true, the read will continue until the container is stopped or the context is cancelled. + // This corresponds to the Follow field in v1.PodLogOptions. + Follow bool + // Timestamp indicates whether to include timestamps in the log output. + // If true, each log line will be prefixed with its RFC3339 timestamp. + // This corresponds to the Timestamps field in v1.PodLogOptions. + Timestamp bool } // parseFunc is a function parsing one log line to the internal log type. @@ -236,20 +228,20 @@ func newLogWriter(stdout io.Writer, stderr io.Writer, opts *LogOptions) *logWrit opts: opts, remain: math.MaxInt64, // initialize it as infinity } - if opts.bytes >= 0 { - w.remain = opts.bytes + if opts.LimitBytes != nil { + w.remain = *opts.LimitBytes } return w } // writeLogs writes logs into stdout, stderr. func (w *logWriter) write(msg *logMessage, addPrefix bool) error { - if msg.timestamp.Before(w.opts.since) { + if msg.timestamp.Before(w.opts.Since) { // Skip the line because it's older than since return nil } line := msg.log - if w.opts.timestamp && addPrefix { + if w.opts.Timestamp && addPrefix { prefix := append([]byte(msg.timestamp.Format(timeFormatOut)), delimiter[0]) line = append(prefix, line...) } @@ -291,7 +283,7 @@ func (w *logWriter) write(msg *logMessage, addPrefix bool) error { // ReadLogs read the container log and redirect into stdout and stderr. // Note that containerID is only needed when following the log, or else // just pass in empty string "". -func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string, opts *LogOptions, runtimeService internalapi.RuntimeService, stdout, stderr io.Writer) error { +func ReadLogs(ctx context.Context, path, containerID string, opts *LogOptions, runtimeService internalapi.RuntimeService, stdout, stderr io.Writer) error { // fsnotify has different behavior for symlinks in different platform, // for example it follows symlink on Linux, but not on Windows, // so we explicitly resolve symlinks before reading the logs. @@ -309,16 +301,20 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string defer f.Close() // Search start point based on tail line. - start, err := findTailLineStartIndex(f, opts.tail) + var tail int64 = -1 + if opts.TailLines != nil { + tail = *opts.TailLines + } + start, err := findTailLineStartIndex(f, tail) if err != nil { - return fmt.Errorf("failed to tail %d lines of log file %q: %v", opts.tail, path, err) + return fmt.Errorf("failed to tail %d lines of log file %q: %w", tail, path, err) } if _, err := f.Seek(start, io.SeekStart); err != nil { - return fmt.Errorf("failed to seek %d in log file %q: %v", start, path, err) + return fmt.Errorf("failed to seek %d in log file %q: %w", start, path, err) } - limitedMode := (opts.tail >= 0) && (!opts.follow) - limitedNum := opts.tail + limitedMode := (opts.TailLines != nil) && (!opts.Follow) + limitedNum := tail // Start parsing the logs. r := bufio.NewReader(f) // Do not create watcher here because it is not needed if `Follow` is false. @@ -331,9 +327,11 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string msg := &logMessage{} baseName := filepath.Base(path) dir := filepath.Dir(path) + logger := klog.FromContext(ctx) + for { if stop || (limitedMode && limitedNum == 0) { - internal.Log(logger, 2, "Finished parsing log file", "path", path) + logger.V(2).Info("Finished parsing log file", "path", path) return nil } l, err := r.ReadBytes(eol[0]) @@ -341,7 +339,7 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string if err != io.EOF { // This is an real error return fmt.Errorf("failed to read log file %q: %v", path, err) } - if opts.follow { + if opts.Follow { // The container is not running, we got to the end of the log. if !found { return nil @@ -366,7 +364,7 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string } var recreated bool // Wait until the next log change. - found, recreated, err = waitLogs(ctx, logger, containerID, baseName, watcher, runtimeService) + found, recreated, err = waitLogs(ctx, containerID, baseName, watcher, runtimeService) if err != nil { return err } @@ -391,7 +389,7 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string if len(l) == 0 { continue } - internal.Log(logger, 0, "Incomplete line in log file", "path", path, "line", l) + logger.Info("Incomplete line in log file", "path", path, "line", l) } if parse == nil { // Initialize the log parsing function. @@ -403,16 +401,20 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string // Parse the log line. msg.reset() if err := parse(l, msg); err != nil { - internal.LogErr(logger, err, "Failed when parsing line in log file", "path", path, "line", l) + logger.Error(err, "Failed when parsing line in log file", "path", path, "line", l) continue } // Write the log line into the stream. if err := writer.write(msg, isNewLine); err != nil { if err == errMaximumWrite { - internal.Log(logger, 2, "Finished parsing log file, hit bytes limit", "path", path, "limit", opts.bytes) + var bytes int64 = -1 + if opts.LimitBytes != nil { + bytes = *opts.LimitBytes + } + logger.V(2).Info("Finished parsing log file, hit bytes limit", "path", path, "limit", bytes) return nil } - internal.LogErr(logger, err, "Failed when writing line to log file", "path", path, "line", msg) + logger.Error(err, "Failed when writing line to log file", "path", path, "line", msg) return err } if limitedMode { @@ -426,7 +428,7 @@ func ReadLogs(ctx context.Context, logger *klog.Logger, path, containerID string } } -func isContainerRunning(ctx context.Context, logger *klog.Logger, id string, r internalapi.RuntimeService) (bool, error) { +func isContainerRunning(ctx context.Context, id string, r internalapi.RuntimeService) (bool, error) { resp, err := r.ContainerStatus(ctx, id, false) if err != nil { // Assume that the container is still running when the runtime is @@ -442,9 +444,10 @@ func isContainerRunning(ctx context.Context, logger *klog.Logger, id string, r i if status == nil { return false, remote.ErrContainerStatusNil } + logger := klog.FromContext(ctx) // Only keep following container log when it is running. if status.State != runtimeapi.ContainerState_CONTAINER_RUNNING { - internal.Log(logger, 5, "Container is not running", "containerId", id, "state", status.State) + logger.V(5).Info("Container is not running", "containerId", id, "state", status.State) // Do not return error because it's normal that the container stops // during waiting. return false, nil @@ -455,9 +458,10 @@ func isContainerRunning(ctx context.Context, logger *klog.Logger, id string, r i // waitLogs wait for the next log write. It returns two booleans and an error. The first boolean // indicates whether a new log is found; the second boolean if the log file was recreated; // the error is error happens during waiting new logs. -func waitLogs(ctx context.Context, logger *klog.Logger, id string, logName string, w *fsnotify.Watcher, runtimeService internalapi.RuntimeService) (bool, bool, error) { +func waitLogs(ctx context.Context, id string, logName string, w *fsnotify.Watcher, runtimeService internalapi.RuntimeService) (bool, bool, error) { + logger := klog.FromContext(ctx) // no need to wait if the pod is not running - if running, err := isContainerRunning(ctx, logger, id, runtimeService); !running { + if running, err := isContainerRunning(ctx, id, runtimeService); !running { return false, false, err } errRetry := 5 @@ -472,10 +476,10 @@ func waitLogs(ctx context.Context, logger *klog.Logger, id string, logName strin case fsnotify.Create: return true, filepath.Base(e.Name) == logName, nil default: - internal.LogErr(logger, nil, "Received unexpected fsnotify event, retrying", "event", e) + logger.Error(nil, "Received unexpected fsnotify event, retrying", "event", e) } case err := <-w.Errors: - internal.LogErr(logger, err, "Received fsnotify watch error, retrying unless no more retries left", "retries", errRetry) + logger.Error(err, "Received fsnotify watch error, retrying unless no more retries left", "retries", errRetry) if errRetry == 0 { return false, false, err } diff --git a/vendor/k8s.io/cri-client/pkg/logs/logs_other.go b/vendor/k8s.io/cri-client/pkg/logs/logs_other.go index 4aa17b4a20..cc477e553a 100644 --- a/vendor/k8s.io/cri-client/pkg/logs/logs_other.go +++ b/vendor/k8s.io/cri-client/pkg/logs/logs_other.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/cri-client/pkg/logs/logs_windows.go b/vendor/k8s.io/cri-client/pkg/logs/logs_windows.go index 83d07d8df7..479c76572a 100644 --- a/vendor/k8s.io/cri-client/pkg/logs/logs_windows.go +++ b/vendor/k8s.io/cri-client/pkg/logs/logs_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/cri-client/pkg/remote_image.go b/vendor/k8s.io/cri-client/pkg/remote_image.go index ca27143a0e..e56a54c170 100644 --- a/vendor/k8s.io/cri-client/pkg/remote_image.go +++ b/vendor/k8s.io/cri-client/pkg/remote_image.go @@ -20,9 +20,12 @@ import ( "context" "errors" "fmt" + "io" + "sync/atomic" "time" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/backoff" @@ -30,12 +33,10 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" - tracing "k8s.io/component-base/tracing" internalapi "k8s.io/cri-api/pkg/apis" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" - "k8s.io/cri-client/pkg/internal" "k8s.io/cri-client/pkg/util" ) @@ -43,19 +44,31 @@ import ( type remoteImageService struct { timeout time.Duration imageClient runtimeapi.ImageServiceClient - logger *klog.Logger conn *grpc.ClientConn + // useStreaming indicates whether to use streaming RPCs for list operations + // when the CRIListStreaming feature gate is enabled. It falls back to false + // if a streaming RPC returns Unimplemented. Multiple goroutines may + // concurrently observe Unimplemented and store false, but that is harmless + // because the store is idempotent. + useStreaming atomic.Bool } // NewRemoteImageService creates a new internalapi.ImageManagerService. -func NewRemoteImageService(endpoint string, connectionTimeout time.Duration, tp trace.TracerProvider, logger *klog.Logger) (internalapi.ImageManagerService, error) { - internal.Log(logger, 3, "Connecting to image service", "endpoint", endpoint) +// If useStreaming is true, streaming RPCs will be used for list operations +// instead of unary RPCs. If the runtime returns an Unimplemented error, +// the client automatically falls back to unary RPCs. +// NOTE: useStreaming is supposed to be gated by the CRIListStreaming feature +// gate and is expected to default to true once the feature graduates to GA, +// at which point this parameter may be removed. +func NewRemoteImageService(ctx context.Context, endpoint string, connectionTimeout time.Duration, tp trace.TracerProvider, useStreaming bool) (internalapi.ImageManagerService, error) { + logger := klog.FromContext(ctx) + logger.V(3).Info("Connecting to image service", "endpoint", endpoint) addr, dialer, err := util.GetAddressAndDialer(endpoint) if err != nil { return nil, err } - ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + ctx, cancel := context.WithTimeout(ctx, connectionTimeout) defer cancel() var dialOpts []grpc.DialOption @@ -67,7 +80,7 @@ func NewRemoteImageService(endpoint string, connectionTimeout time.Duration, tp if tp != nil { tracingOpts := []otelgrpc.Option{ otelgrpc.WithMessageEvents(otelgrpc.ReceivedEvents, otelgrpc.SentEvents), - otelgrpc.WithPropagators(tracing.Propagators()), + otelgrpc.WithPropagators(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})), otelgrpc.WithTracerProvider(tp), } // Even if there is no TracerProvider, the otelgrpc still handles context propagation. @@ -86,17 +99,18 @@ func NewRemoteImageService(endpoint string, connectionTimeout time.Duration, tp grpc.WithConnectParams(connParams), ) - conn, err := grpc.DialContext(ctx, addr, dialOpts...) + conn, err := grpc.NewClient(clientTargetForAddress(addr), dialOpts...) if err != nil { - internal.LogErr(logger, err, "Connect remote image service failed", "address", addr) + logger.Error(err, "Connect remote image service failed", "address", addr) return nil, err } service := &remoteImageService{ timeout: connectionTimeout, - logger: logger, conn: conn, } + service.useStreaming.Store(useStreaming) + if err := service.validateServiceConnection(ctx, conn, endpoint); err != nil { return nil, fmt.Errorf("validate service connection: %w", err) } @@ -106,30 +120,24 @@ func NewRemoteImageService(endpoint string, connectionTimeout time.Duration, tp } // Close will shutdown the internal gRPC client connection. -func (r *remoteImageService) Close() error { - r.log(3, "Closing image service connection") +func (r *remoteImageService) Close(ctx context.Context) error { + logger := klog.FromContext(ctx) + logger.V(3).Info("Closing image service connection") return r.conn.Close() } -func (r *remoteImageService) log(level int, msg string, keyAndValues ...any) { - internal.Log(r.logger, level, msg, keyAndValues...) -} - -func (r *remoteImageService) logErr(err error, msg string, keyAndValues ...any) { - internal.LogErr(r.logger, err, msg, keyAndValues...) -} - // validateServiceConnection tries to connect to the remote image service by // using the CRI v1 API version and fails if that's not possible. func (r *remoteImageService) validateServiceConnection(ctx context.Context, conn *grpc.ClientConn, endpoint string) error { - r.log(4, "Validating the CRI v1 API image version") + logger := klog.FromContext(ctx) + logger.V(4).Info("Validating the CRI v1 API image version") r.imageClient = runtimeapi.NewImageServiceClient(conn) if _, err := r.imageClient.ImageFsInfo(ctx, &runtimeapi.ImageFsInfoRequest{}); err != nil { return fmt.Errorf("validate CRI v1 image API for endpoint %q: %w", endpoint, err) } - r.log(2, "Validated CRI v1 image API") + logger.V(2).Info("Validated CRI v1 image API") return nil } @@ -138,6 +146,9 @@ func (r *remoteImageService) ListImages(ctx context.Context, filter *runtimeapi. ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamImagesV1(ctx, filter) + } return r.listImagesV1(ctx, filter) } @@ -146,13 +157,48 @@ func (r *remoteImageService) listImagesV1(ctx context.Context, filter *runtimeap Filter: filter, }) if err != nil { - r.logErr(err, "ListImages with filter from image service failed", "filter", filter) + logger := klog.FromContext(ctx) + logger.Error(err, "ListImages with filter from image service failed", "filter", filter) return nil, err } return resp.Images, nil } +func (r *remoteImageService) streamImagesV1(ctx context.Context, filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) { + logger := klog.FromContext(ctx) + stream, err := r.imageClient.StreamImages(ctx, &runtimeapi.StreamImagesRequest{ + Filter: filter, + }) + if err != nil { + logger.Error(err, "StreamImages from image service failed", "filter", filter) + return nil, err + } + + var images []*runtimeapi.Image + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamImages not implemented, falling back to ListImages", "filter", filter) + r.useStreaming.Store(false) + return r.listImagesV1(ctx, filter) + } + logger.Error(err, "StreamImages recv failed", "filter", filter, "itemsReceived", len(images)) + return nil, err + } + images = append(images, resp.Images...) + } + + return images, nil +} + // ImageStatus returns the status of the image. func (r *remoteImageService) ImageStatus(ctx context.Context, image *runtimeapi.ImageSpec, verbose bool) (*runtimeapi.ImageStatusResponse, error) { ctx, cancel := context.WithTimeout(ctx, r.timeout) @@ -167,7 +213,8 @@ func (r *remoteImageService) imageStatusV1(ctx context.Context, image *runtimeap Verbose: verbose, }) if err != nil { - r.logErr(err, "Get ImageStatus from image service failed", "image", image.Image) + logger := klog.FromContext(ctx) + logger.Error(err, "Get ImageStatus from image service failed", "image", image.Image) return nil, err } @@ -175,7 +222,8 @@ func (r *remoteImageService) imageStatusV1(ctx context.Context, image *runtimeap if resp.Image.Id == "" || resp.Image.Size == 0 { errorMessage := fmt.Sprintf("Id or size of image %q is not set", image.Image) err := errors.New(errorMessage) - r.logErr(err, "ImageStatus failed", "image", image.Image) + logger := klog.FromContext(ctx) + logger.Error(err, "ImageStatus failed", "image", image.Image) return nil, err } } @@ -198,7 +246,8 @@ func (r *remoteImageService) pullImageV1(ctx context.Context, image *runtimeapi. SandboxConfig: podSandboxConfig, }) if err != nil { - r.logErr(err, "PullImage from image service failed", "image", image.Image) + logger := klog.FromContext(ctx) + logger.Error(err, "PullImage from image service failed", "image", image.Image) // We can strip the code from unknown status errors since they add no value // and will make them easier to read in the logs/events. @@ -214,7 +263,8 @@ func (r *remoteImageService) pullImageV1(ctx context.Context, image *runtimeapi. } if resp.ImageRef == "" { - r.logErr(errors.New("PullImage failed"), "ImageRef of image is not set", "image", image.Image) + logger := klog.FromContext(ctx) + logger.Error(errors.New("PullImage failed"), "ImageRef of image is not set", "image", image.Image) errorMessage := fmt.Sprintf("imageRef of image %q is not set", image.Image) return "", errors.New(errorMessage) } @@ -230,7 +280,8 @@ func (r *remoteImageService) RemoveImage(ctx context.Context, image *runtimeapi. if _, err = r.imageClient.RemoveImage(ctx, &runtimeapi.RemoveImageRequest{ Image: image, }); err != nil { - r.logErr(err, "RemoveImage from image service failed", "image", image.Image) + logger := klog.FromContext(ctx) + logger.Error(err, "RemoveImage from image service failed", "image", image.Image) return err } @@ -248,7 +299,8 @@ func (r *remoteImageService) ImageFsInfo(ctx context.Context) (*runtimeapi.Image func (r *remoteImageService) imageFsInfoV1(ctx context.Context) (*runtimeapi.ImageFsInfoResponse, error) { resp, err := r.imageClient.ImageFsInfo(ctx, &runtimeapi.ImageFsInfoRequest{}) if err != nil { - r.logErr(err, "ImageFsInfo from image service failed") + logger := klog.FromContext(ctx) + logger.Error(err, "ImageFsInfo from image service failed") return nil, err } return resp, nil diff --git a/vendor/k8s.io/cri-client/pkg/remote_runtime.go b/vendor/k8s.io/cri-client/pkg/remote_runtime.go index 6afa04f2c8..9e80b1a20f 100644 --- a/vendor/k8s.io/cri-client/pkg/remote_runtime.go +++ b/vendor/k8s.io/cri-client/pkg/remote_runtime.go @@ -22,9 +22,11 @@ import ( "fmt" "io" "strings" + "sync/atomic" "time" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/backoff" @@ -33,13 +35,11 @@ import ( "google.golang.org/grpc/status" "k8s.io/component-base/logs/logreduction" - tracing "k8s.io/component-base/tracing" internalapi "k8s.io/cri-api/pkg/apis" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" utilexec "k8s.io/utils/exec" - "k8s.io/cri-client/pkg/internal" "k8s.io/cri-client/pkg/util" ) @@ -49,8 +49,13 @@ type remoteRuntimeService struct { runtimeClient runtimeapi.RuntimeServiceClient // Cache last per-container error message to reduce log spam logReduction *logreduction.LogReduction - logger *klog.Logger conn *grpc.ClientConn + // useStreaming indicates whether to use streaming RPCs for list operations + // when the CRIListStreaming feature gate is enabled. It falls back to false + // if a streaming RPC returns Unimplemented. Multiple goroutines may + // concurrently observe Unimplemented and store false, but that is harmless + // because the store is idempotent. + useStreaming atomic.Bool } const ( @@ -81,13 +86,20 @@ const ( ) // NewRemoteRuntimeService creates a new internalapi.RuntimeService. -func NewRemoteRuntimeService(endpoint string, connectionTimeout time.Duration, tp trace.TracerProvider, logger *klog.Logger) (internalapi.RuntimeService, error) { - internal.Log(logger, 3, "Connecting to runtime service", "endpoint", endpoint) +// If useStreaming is true, streaming RPCs will be used for list operations +// instead of unary RPCs. If the runtime returns an Unimplemented error, +// the client automatically falls back to unary RPCs. +// NOTE: useStreaming is supposed to be gated by the CRIListStreaming feature +// gate and is expected to default to true once the feature graduates to GA, +// at which point this parameter may be removed. +func NewRemoteRuntimeService(ctx context.Context, endpoint string, connectionTimeout time.Duration, tp trace.TracerProvider, useStreaming bool) (internalapi.RuntimeService, error) { + logger := klog.FromContext(ctx) + logger.V(3).Info("Connecting to runtime service", "endpoint", endpoint) addr, dialer, err := util.GetAddressAndDialer(endpoint) if err != nil { return nil, err } - ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + ctx, cancel := context.WithTimeout(ctx, connectionTimeout) defer cancel() var dialOpts []grpc.DialOption @@ -99,7 +111,7 @@ func NewRemoteRuntimeService(endpoint string, connectionTimeout time.Duration, t if tp != nil { tracingOpts := []otelgrpc.Option{ otelgrpc.WithMessageEvents(otelgrpc.ReceivedEvents, otelgrpc.SentEvents), - otelgrpc.WithPropagators(tracing.Propagators()), + otelgrpc.WithPropagators(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})), otelgrpc.WithTracerProvider(tp), } // Even if there is no TracerProvider, the otelgrpc still handles context propagation. @@ -118,18 +130,18 @@ func NewRemoteRuntimeService(endpoint string, connectionTimeout time.Duration, t grpc.WithConnectParams(connParams), ) - conn, err := grpc.DialContext(ctx, addr, dialOpts...) + conn, err := grpc.NewClient(clientTargetForAddress(addr), dialOpts...) if err != nil { - internal.LogErr(logger, err, "Connect remote runtime failed", "address", addr) + logger.Error(err, "Connect remote runtime service failed", "address", addr) return nil, err } service := &remoteRuntimeService{ timeout: connectionTimeout, logReduction: logreduction.NewLogReduction(identicalErrorDelay), - logger: logger, conn: conn, } + service.useStreaming.Store(useStreaming) if err := service.validateServiceConnection(ctx, conn, endpoint); err != nil { return nil, fmt.Errorf("validate service connection: %w", err) @@ -139,36 +151,31 @@ func NewRemoteRuntimeService(endpoint string, connectionTimeout time.Duration, t } // Close will shutdown the internal gRPC client connection. -func (r *remoteRuntimeService) Close() error { - r.log(3, "Closing runtime service connection") +func (r *remoteRuntimeService) Close(ctx context.Context) error { + logger := klog.FromContext(ctx) + logger.V(3).Info("Closing runtime service connection") return r.conn.Close() } -func (r *remoteRuntimeService) log(level int, msg string, keyAndValues ...any) { - internal.Log(r.logger, level, msg, keyAndValues...) -} - -func (r *remoteRuntimeService) logErr(err error, msg string, keyAndValues ...any) { - internal.LogErr(r.logger, err, msg, keyAndValues...) -} - // validateServiceConnection tries to connect to the remote runtime service by // using the CRI v1 API version and fails if that's not possible. func (r *remoteRuntimeService) validateServiceConnection(ctx context.Context, conn *grpc.ClientConn, endpoint string) error { - r.log(4, "Validating the CRI v1 API runtime version") + logger := klog.FromContext(ctx) + logger.V(4).Info("Validating the CRI v1 API runtime version") r.runtimeClient = runtimeapi.NewRuntimeServiceClient(conn) if _, err := r.runtimeClient.Version(ctx, &runtimeapi.VersionRequest{}); err != nil { return fmt.Errorf("validate CRI v1 runtime API for endpoint %q: %w", endpoint, err) } - r.log(2, "Validated CRI v1 runtime API") + logger.V(2).Info("Validated CRI v1 runtime API") return nil } // Version returns the runtime name, runtime version and runtime API version. func (r *remoteRuntimeService) Version(ctx context.Context, apiVersion string) (*runtimeapi.VersionResponse, error) { - r.log(10, "[RemoteRuntimeService] Version", "apiVersion", apiVersion, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] Version", "apiVersion", apiVersion, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -180,12 +187,13 @@ func (r *remoteRuntimeService) versionV1(ctx context.Context, apiVersion string) typedVersion, err := r.runtimeClient.Version(ctx, &runtimeapi.VersionRequest{ Version: apiVersion, }) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "Version from runtime service failed") + logger.Error(err, "Version from runtime service failed") return nil, err } - r.log(10, "[RemoteRuntimeService] Version Response", "apiVersion", typedVersion) + logger.V(10).Info("[RemoteRuntimeService] Version Response", "apiVersion", typedVersion) var missingFields []string if typedVersion.Version == "" { @@ -214,7 +222,8 @@ func (r *remoteRuntimeService) RunPodSandbox(ctx context.Context, config *runtim // TODO: Make the pod sandbox timeout configurable. timeout := r.timeout * 2 - r.log(10, "[RemoteRuntimeService] RunPodSandbox", "config", config, "runtimeHandler", runtimeHandler, "timeout", timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] RunPodSandbox", "config", config, "runtimeHandler", runtimeHandler, "timeout", timeout) ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() @@ -225,7 +234,7 @@ func (r *remoteRuntimeService) RunPodSandbox(ctx context.Context, config *runtim }) if err != nil { - r.logErr(err, "RunPodSandbox from runtime service failed") + logger.Error(err, "RunPodSandbox from runtime service failed") return "", err } @@ -234,11 +243,11 @@ func (r *remoteRuntimeService) RunPodSandbox(ctx context.Context, config *runtim if podSandboxID == "" { errorMessage := fmt.Sprintf("PodSandboxId is not set for sandbox %q", config.Metadata) err := errors.New(errorMessage) - r.logErr(err, "RunPodSandbox failed") + logger.Error(err, "RunPodSandbox failed") return "", err } - r.log(10, "[RemoteRuntimeService] RunPodSandbox Response", "podSandboxID", podSandboxID) + logger.V(10).Info("[RemoteRuntimeService] RunPodSandbox Response", "podSandboxID", podSandboxID) return podSandboxID, nil } @@ -246,7 +255,8 @@ func (r *remoteRuntimeService) RunPodSandbox(ctx context.Context, config *runtim // StopPodSandbox stops the sandbox. If there are any running containers in the // sandbox, they should be forced to termination. func (r *remoteRuntimeService) StopPodSandbox(ctx context.Context, podSandBoxID string) (err error) { - r.log(10, "[RemoteRuntimeService] StopPodSandbox", "podSandboxID", podSandBoxID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] StopPodSandbox", "podSandboxID", podSandBoxID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -254,11 +264,11 @@ func (r *remoteRuntimeService) StopPodSandbox(ctx context.Context, podSandBoxID if _, err := r.runtimeClient.StopPodSandbox(ctx, &runtimeapi.StopPodSandboxRequest{ PodSandboxId: podSandBoxID, }); err != nil { - r.logErr(err, "StopPodSandbox from runtime service failed", "podSandboxID", podSandBoxID) + logger.Error(err, "StopPodSandbox from runtime service failed", "podSandboxID", podSandBoxID) return err } - r.log(10, "[RemoteRuntimeService] StopPodSandbox Response", "podSandboxID", podSandBoxID) + logger.V(10).Info("[RemoteRuntimeService] StopPodSandbox Response", "podSandboxID", podSandBoxID) return nil } @@ -266,25 +276,27 @@ func (r *remoteRuntimeService) StopPodSandbox(ctx context.Context, podSandBoxID // RemovePodSandbox removes the sandbox. If there are any containers in the // sandbox, they should be forcibly removed. func (r *remoteRuntimeService) RemovePodSandbox(ctx context.Context, podSandBoxID string) (err error) { - r.log(10, "[RemoteRuntimeService] RemovePodSandbox", "podSandboxID", podSandBoxID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] RemovePodSandbox", "podSandboxID", podSandBoxID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() if _, err := r.runtimeClient.RemovePodSandbox(ctx, &runtimeapi.RemovePodSandboxRequest{ PodSandboxId: podSandBoxID, }); err != nil { - r.logErr(err, "RemovePodSandbox from runtime service failed", "podSandboxID", podSandBoxID) + logger.Error(err, "RemovePodSandbox from runtime service failed", "podSandboxID", podSandBoxID) return err } - r.log(10, "[RemoteRuntimeService] RemovePodSandbox Response", "podSandboxID", podSandBoxID) + logger.V(10).Info("[RemoteRuntimeService] RemovePodSandbox Response", "podSandboxID", podSandBoxID) return nil } // PodSandboxStatus returns the status of the PodSandbox. func (r *remoteRuntimeService) PodSandboxStatus(ctx context.Context, podSandBoxID string, verbose bool) (*runtimeapi.PodSandboxStatusResponse, error) { - r.log(10, "[RemoteRuntimeService] PodSandboxStatus", "podSandboxID", podSandBoxID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] PodSandboxStatus", "podSandboxID", podSandBoxID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -300,7 +312,8 @@ func (r *remoteRuntimeService) podSandboxStatusV1(ctx context.Context, podSandBo return nil, err } - r.log(10, "[RemoteRuntimeService] PodSandboxStatus Response", "podSandboxID", podSandBoxID, "status", resp.Status) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] PodSandboxStatus Response", "podSandboxID", podSandBoxID, "status", resp.Status) status := resp.Status if resp.Status != nil { @@ -314,10 +327,14 @@ func (r *remoteRuntimeService) podSandboxStatusV1(ctx context.Context, podSandBo // ListPodSandbox returns a list of PodSandboxes. func (r *remoteRuntimeService) ListPodSandbox(ctx context.Context, filter *runtimeapi.PodSandboxFilter) ([]*runtimeapi.PodSandbox, error) { - r.log(10, "[RemoteRuntimeService] ListPodSandbox", "filter", filter, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ListPodSandbox", "filter", filter, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamPodSandboxesV1(ctx, filter) + } return r.listPodSandboxV1(ctx, filter) } @@ -325,19 +342,57 @@ func (r *remoteRuntimeService) listPodSandboxV1(ctx context.Context, filter *run resp, err := r.runtimeClient.ListPodSandbox(ctx, &runtimeapi.ListPodSandboxRequest{ Filter: filter, }) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListPodSandbox with filter from runtime service failed", "filter", filter) + logger.Error(err, "ListPodSandbox with filter from runtime service failed", "filter", filter) return nil, err } - r.log(10, "[RemoteRuntimeService] ListPodSandbox Response", "filter", filter, "items", resp.Items) + logger.V(10).Info("[RemoteRuntimeService] ListPodSandbox Response", "filter", filter, "items", resp.Items) return resp.Items, nil } +func (r *remoteRuntimeService) streamPodSandboxesV1(ctx context.Context, filter *runtimeapi.PodSandboxFilter) ([]*runtimeapi.PodSandbox, error) { + logger := klog.FromContext(ctx) + stream, err := r.runtimeClient.StreamPodSandboxes(ctx, &runtimeapi.StreamPodSandboxesRequest{ + Filter: filter, + }) + if err != nil { + logger.Error(err, "StreamPodSandboxes from runtime service failed", "filter", filter) + return nil, err + } + + var items []*runtimeapi.PodSandbox + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamPodSandboxes not implemented, falling back to ListPodSandbox", "filter", filter) + r.useStreaming.Store(false) + return r.listPodSandboxV1(ctx, filter) + } + logger.Error(err, "StreamPodSandboxes recv failed", "filter", filter, "itemsReceived", len(items)) + return nil, err + } + items = append(items, resp.PodSandboxes...) + } + + logger.V(10).Info("[RemoteRuntimeService] StreamPodSandboxes Response", "filter", filter, "items", items) + + return items, nil +} + // CreateContainer creates a new container in the specified PodSandbox. func (r *remoteRuntimeService) CreateContainer(ctx context.Context, podSandBoxID string, config *runtimeapi.ContainerConfig, sandboxConfig *runtimeapi.PodSandboxConfig) (string, error) { - r.log(10, "[RemoteRuntimeService] CreateContainer", "podSandboxID", podSandBoxID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] CreateContainer", "podSandboxID", podSandBoxID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -345,21 +400,22 @@ func (r *remoteRuntimeService) CreateContainer(ctx context.Context, podSandBoxID } func (r *remoteRuntimeService) createContainerV1(ctx context.Context, podSandBoxID string, config *runtimeapi.ContainerConfig, sandboxConfig *runtimeapi.PodSandboxConfig) (string, error) { + logger := klog.FromContext(ctx) resp, err := r.runtimeClient.CreateContainer(ctx, &runtimeapi.CreateContainerRequest{ PodSandboxId: podSandBoxID, Config: config, SandboxConfig: sandboxConfig, }) if err != nil { - r.logErr(err, "CreateContainer in sandbox from runtime service failed", "podSandboxID", podSandBoxID) + logger.Error(err, "CreateContainer in sandbox from runtime service failed", "podSandboxID", podSandBoxID) return "", err } - r.log(10, "[RemoteRuntimeService] CreateContainer", "podSandboxID", podSandBoxID, "containerID", resp.ContainerId) + logger.V(10).Info("[RemoteRuntimeService] CreateContainer", "podSandboxID", podSandBoxID, "containerID", resp.ContainerId) if resp.ContainerId == "" { errorMessage := fmt.Sprintf("ContainerId is not set for container %q", config.Metadata) err := errors.New(errorMessage) - r.logErr(err, "CreateContainer failed") + logger.Error(err, "CreateContainer failed") return "", err } @@ -368,24 +424,26 @@ func (r *remoteRuntimeService) createContainerV1(ctx context.Context, podSandBox // StartContainer starts the container. func (r *remoteRuntimeService) StartContainer(ctx context.Context, containerID string) (err error) { - r.log(10, "[RemoteRuntimeService] StartContainer", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] StartContainer", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() if _, err := r.runtimeClient.StartContainer(ctx, &runtimeapi.StartContainerRequest{ ContainerId: containerID, }); err != nil { - r.logErr(err, "StartContainer from runtime service failed", "containerID", containerID) + logger.Error(err, "StartContainer from runtime service failed", "containerID", containerID) return err } - r.log(10, "[RemoteRuntimeService] StartContainer Response", "containerID", containerID) + logger.V(10).Info("[RemoteRuntimeService] StartContainer Response", "containerID", containerID) return nil } // StopContainer stops a running container with a grace period (i.e., timeout). func (r *remoteRuntimeService) StopContainer(ctx context.Context, containerID string, timeout int64) (err error) { - r.log(10, "[RemoteRuntimeService] StopContainer", "containerID", containerID, "timeout", timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] StopContainer", "containerID", containerID, "timeout", timeout) // Use timeout + default timeout (2 minutes) as timeout to leave extra time // for SIGKILL container and request latency. t := r.timeout + time.Duration(timeout)*time.Second @@ -398,10 +456,10 @@ func (r *remoteRuntimeService) StopContainer(ctx context.Context, containerID st ContainerId: containerID, Timeout: timeout, }); err != nil { - r.logErr(err, "StopContainer from runtime service failed", "containerID", containerID) + logger.Error(err, "StopContainer from runtime service failed", "containerID", containerID) return err } - r.log(10, "[RemoteRuntimeService] StopContainer Response", "containerID", containerID) + logger.V(10).Info("[RemoteRuntimeService] StopContainer Response", "containerID", containerID) return nil } @@ -409,7 +467,8 @@ func (r *remoteRuntimeService) StopContainer(ctx context.Context, containerID st // RemoveContainer removes the container. If the container is running, the container // should be forced to removal. func (r *remoteRuntimeService) RemoveContainer(ctx context.Context, containerID string) (err error) { - r.log(10, "[RemoteRuntimeService] RemoveContainer", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] RemoveContainer", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -417,20 +476,24 @@ func (r *remoteRuntimeService) RemoveContainer(ctx context.Context, containerID if _, err := r.runtimeClient.RemoveContainer(ctx, &runtimeapi.RemoveContainerRequest{ ContainerId: containerID, }); err != nil { - r.logErr(err, "RemoveContainer from runtime service failed", "containerID", containerID) + logger.Error(err, "RemoveContainer from runtime service failed", "containerID", containerID) return err } - r.log(10, "[RemoteRuntimeService] RemoveContainer Response", "containerID", containerID) + logger.V(10).Info("[RemoteRuntimeService] RemoveContainer Response", "containerID", containerID) return nil } // ListContainers lists containers by filters. func (r *remoteRuntimeService) ListContainers(ctx context.Context, filter *runtimeapi.ContainerFilter) ([]*runtimeapi.Container, error) { - r.log(10, "[RemoteRuntimeService] ListContainers", "filter", filter, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ListContainers", "filter", filter, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamContainersV1(ctx, filter) + } return r.listContainersV1(ctx, filter) } @@ -438,18 +501,56 @@ func (r *remoteRuntimeService) listContainersV1(ctx context.Context, filter *run resp, err := r.runtimeClient.ListContainers(ctx, &runtimeapi.ListContainersRequest{ Filter: filter, }) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListContainers with filter from runtime service failed", "filter", filter) + logger.Error(err, "ListContainers with filter from runtime service failed", "filter", filter) return nil, err } - r.log(10, "[RemoteRuntimeService] ListContainers Response", "filter", filter, "containers", resp.Containers) + logger.V(10).Info("[RemoteRuntimeService] ListContainers Response", "filter", filter, "containers", resp.Containers) return resp.Containers, nil } +func (r *remoteRuntimeService) streamContainersV1(ctx context.Context, filter *runtimeapi.ContainerFilter) ([]*runtimeapi.Container, error) { + logger := klog.FromContext(ctx) + stream, err := r.runtimeClient.StreamContainers(ctx, &runtimeapi.StreamContainersRequest{ + Filter: filter, + }) + if err != nil { + logger.Error(err, "StreamContainers from runtime service failed", "filter", filter) + return nil, err + } + + var containers []*runtimeapi.Container + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamContainers not implemented, falling back to ListContainers", "filter", filter) + r.useStreaming.Store(false) + return r.listContainersV1(ctx, filter) + } + logger.Error(err, "StreamContainers recv failed", "filter", filter, "itemsReceived", len(containers)) + return nil, err + } + containers = append(containers, resp.Containers...) + } + + logger.V(10).Info("[RemoteRuntimeService] StreamContainers Response", "filter", filter, "containers", containers) + + return containers, nil +} + // ContainerStatus returns the container status. func (r *remoteRuntimeService) ContainerStatus(ctx context.Context, containerID string, verbose bool) (*runtimeapi.ContainerStatusResponse, error) { - r.log(10, "[RemoteRuntimeService] ContainerStatus", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ContainerStatus", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -461,20 +562,21 @@ func (r *remoteRuntimeService) containerStatusV1(ctx context.Context, containerI ContainerId: containerID, Verbose: verbose, }) + logger := klog.FromContext(ctx) if err != nil { // Don't spam the log with endless messages about the same failure. if r.logReduction.ShouldMessageBePrinted(err.Error(), containerID) { - r.logErr(err, "ContainerStatus from runtime service failed", "containerID", containerID) + logger.Error(err, "ContainerStatus from runtime service failed", "containerID", containerID) } return nil, err } r.logReduction.ClearID(containerID) - r.log(10, "[RemoteRuntimeService] ContainerStatus Response", "containerID", containerID, "status", resp.Status) + logger.V(10).Info("[RemoteRuntimeService] ContainerStatus Response", "containerID", containerID, "status", resp.Status) status := resp.Status if resp.Status != nil { if err := verifyContainerStatus(status); err != nil { - r.logErr(err, "verify ContainerStatus failed", "containerID", containerID) + logger.Error(err, "verify ContainerStatus failed", "containerID", containerID) return nil, err } } @@ -484,7 +586,8 @@ func (r *remoteRuntimeService) containerStatusV1(ctx context.Context, containerI // UpdateContainerResources updates a containers resource config func (r *remoteRuntimeService) UpdateContainerResources(ctx context.Context, containerID string, resources *runtimeapi.ContainerResources) (err error) { - r.log(10, "[RemoteRuntimeService] UpdateContainerResources", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] UpdateContainerResources", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -493,10 +596,10 @@ func (r *remoteRuntimeService) UpdateContainerResources(ctx context.Context, con Linux: resources.GetLinux(), Windows: resources.GetWindows(), }); err != nil { - r.logErr(err, "UpdateContainerResources from runtime service failed", "containerID", containerID) + logger.Error(err, "UpdateContainerResources from runtime service failed", "containerID", containerID) return err } - r.log(10, "[RemoteRuntimeService] UpdateContainerResources Response", "containerID", containerID) + logger.V(10).Info("[RemoteRuntimeService] UpdateContainerResources Response", "containerID", containerID) return nil } @@ -504,7 +607,8 @@ func (r *remoteRuntimeService) UpdateContainerResources(ctx context.Context, con // ExecSync executes a command in the container, and returns the stdout output. // If command exits with a non-zero exit code, an error is returned. func (r *remoteRuntimeService) ExecSync(ctx context.Context, containerID string, cmd []string, timeout time.Duration) (stdout []byte, stderr []byte, err error) { - r.log(10, "[RemoteRuntimeService] ExecSync", "containerID", containerID, "timeout", timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ExecSync", "containerID", containerID, "timeout", timeout) // Do not set timeout when timeout is 0. var cancel context.CancelFunc if timeout != 0 { @@ -527,8 +631,9 @@ func (r *remoteRuntimeService) execSyncV1(ctx context.Context, containerID strin Timeout: timeoutSeconds, } resp, err := r.runtimeClient.ExecSync(ctx, req) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ExecSync cmd from runtime service failed", "containerID", containerID, "cmd", cmd) + logger.Error(err, "ExecSync cmd from runtime service failed", "containerID", containerID, "cmd", cmd) // interpret DeadlineExceeded gRPC errors as timedout errors if status.Code(err) == codes.DeadlineExceeded { @@ -538,7 +643,7 @@ func (r *remoteRuntimeService) execSyncV1(ctx context.Context, containerID strin return nil, nil, err } - r.log(10, "[RemoteRuntimeService] ExecSync Response", "containerID", containerID, "exitCode", resp.ExitCode) + logger.V(10).Info("[RemoteRuntimeService] ExecSync Response", "containerID", containerID, "exitCode", resp.ExitCode) err = nil if resp.ExitCode != 0 { err = utilexec.CodeExitError{ @@ -552,7 +657,8 @@ func (r *remoteRuntimeService) execSyncV1(ctx context.Context, containerID strin // Exec prepares a streaming endpoint to execute a command in the container, and returns the address. func (r *remoteRuntimeService) Exec(ctx context.Context, req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) { - r.log(10, "[RemoteRuntimeService] Exec", "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] Exec", "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -561,16 +667,17 @@ func (r *remoteRuntimeService) Exec(ctx context.Context, req *runtimeapi.ExecReq func (r *remoteRuntimeService) execV1(ctx context.Context, req *runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error) { resp, err := r.runtimeClient.Exec(ctx, req) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "Exec cmd from runtime service failed", "containerID", req.ContainerId, "cmd", req.Cmd) + logger.Error(err, "Exec cmd from runtime service failed", "containerID", req.ContainerId, "cmd", req.Cmd) return nil, err } - r.log(10, "[RemoteRuntimeService] Exec Response") + logger.V(10).Info("[RemoteRuntimeService] Exec Response") if resp.Url == "" { errorMessage := "URL is not set" err := errors.New(errorMessage) - r.logErr(err, "Exec failed") + logger.Error(err, "Exec failed") return nil, err } @@ -579,7 +686,8 @@ func (r *remoteRuntimeService) execV1(ctx context.Context, req *runtimeapi.ExecR // Attach prepares a streaming endpoint to attach to a running container, and returns the address. func (r *remoteRuntimeService) Attach(ctx context.Context, req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) { - r.log(10, "[RemoteRuntimeService] Attach", "containerID", req.ContainerId, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] Attach", "containerID", req.ContainerId, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -587,17 +695,18 @@ func (r *remoteRuntimeService) Attach(ctx context.Context, req *runtimeapi.Attac } func (r *remoteRuntimeService) attachV1(ctx context.Context, req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error) { + logger := klog.FromContext(ctx) resp, err := r.runtimeClient.Attach(ctx, req) if err != nil { - r.logErr(err, "Attach container from runtime service failed", "containerID", req.ContainerId) + logger.Error(err, "Attach container from runtime service failed", "containerID", req.ContainerId) return nil, err } - r.log(10, "[RemoteRuntimeService] Attach Response", "containerID", req.ContainerId) + logger.V(10).Info("[RemoteRuntimeService] Attach Response", "containerID", req.ContainerId) if resp.Url == "" { errorMessage := "URL is not set" err := errors.New(errorMessage) - r.logErr(err, "Attach failed") + logger.Error(err, "Attach failed") return nil, err } return resp, nil @@ -605,7 +714,8 @@ func (r *remoteRuntimeService) attachV1(ctx context.Context, req *runtimeapi.Att // PortForward prepares a streaming endpoint to forward ports from a PodSandbox, and returns the address. func (r *remoteRuntimeService) PortForward(ctx context.Context, req *runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error) { - r.log(10, "[RemoteRuntimeService] PortForward", "podSandboxID", req.PodSandboxId, "port", req.Port, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] PortForward", "podSandboxID", req.PodSandboxId, "port", req.Port, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -614,16 +724,18 @@ func (r *remoteRuntimeService) PortForward(ctx context.Context, req *runtimeapi. func (r *remoteRuntimeService) portForwardV1(ctx context.Context, req *runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error) { resp, err := r.runtimeClient.PortForward(ctx, req) + + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "PortForward from runtime service failed", "podSandboxID", req.PodSandboxId) + logger.Error(err, "PortForward from runtime service failed", "podSandboxID", req.PodSandboxId) return nil, err } - r.log(10, "[RemoteRuntimeService] PortForward Response", "podSandboxID", req.PodSandboxId) + logger.V(10).Info("[RemoteRuntimeService] PortForward Response", "podSandboxID", req.PodSandboxId) if resp.Url == "" { errorMessage := "URL is not set" err := errors.New(errorMessage) - r.logErr(err, "PortForward failed") + logger.Error(err, "PortForward failed") return nil, err } @@ -633,16 +745,17 @@ func (r *remoteRuntimeService) portForwardV1(ctx context.Context, req *runtimeap // UpdatePodSandboxResources synchronously updates the PodSandboxConfig with // the pod-level resource configuration. func (r *remoteRuntimeService) UpdatePodSandboxResources(ctx context.Context, req *runtimeapi.UpdatePodSandboxResourcesRequest) (*runtimeapi.UpdatePodSandboxResourcesResponse, error) { - r.log(10, "[RemoteRuntimeService] UpdatePodSandboxResources", "PodSandboxId", req.PodSandboxId, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] UpdatePodSandboxResources", "PodSandboxId", req.PodSandboxId, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() resp, err := r.runtimeClient.UpdatePodSandboxResources(ctx, req) if err != nil { - r.logErr(err, "UpdatePodSandboxResources from runtime service failed", "podSandboxID", req.PodSandboxId) + logger.Error(err, "UpdatePodSandboxResources from runtime service failed", "podSandboxID", req.PodSandboxId) return nil, err } - r.log(10, "[RemoteRuntimeService] UpdatePodSandboxResources Response", "podSandboxID", req.PodSandboxId) + logger.V(10).Info("[RemoteRuntimeService] UpdatePodSandboxResources Response", "podSandboxID", req.PodSandboxId) return resp, nil } @@ -651,7 +764,8 @@ func (r *remoteRuntimeService) UpdatePodSandboxResources(ctx context.Context, re // update payload currently supported is the pod CIDR assigned to a node, // and the runtime service just proxies it down to the network plugin. func (r *remoteRuntimeService) UpdateRuntimeConfig(ctx context.Context, runtimeConfig *runtimeapi.RuntimeConfig) (err error) { - r.log(10, "[RemoteRuntimeService] UpdateRuntimeConfig", "runtimeConfig", runtimeConfig, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] UpdateRuntimeConfig", "runtimeConfig", runtimeConfig, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -663,14 +777,15 @@ func (r *remoteRuntimeService) UpdateRuntimeConfig(ctx context.Context, runtimeC }); err != nil { return err } - r.log(10, "[RemoteRuntimeService] UpdateRuntimeConfig Response", "runtimeConfig", runtimeConfig) + logger.V(10).Info("[RemoteRuntimeService] UpdateRuntimeConfig Response", "runtimeConfig", runtimeConfig) return nil } // Status returns the status of the runtime. func (r *remoteRuntimeService) Status(ctx context.Context, verbose bool) (*runtimeapi.StatusResponse, error) { - r.log(10, "[RemoteRuntimeService] Status", "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] Status", "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -678,20 +793,21 @@ func (r *remoteRuntimeService) Status(ctx context.Context, verbose bool) (*runti } func (r *remoteRuntimeService) statusV1(ctx context.Context, verbose bool) (*runtimeapi.StatusResponse, error) { + logger := klog.FromContext(ctx) resp, err := r.runtimeClient.Status(ctx, &runtimeapi.StatusRequest{ Verbose: verbose, }) if err != nil { - r.logErr(err, "Status from runtime service failed") + logger.Error(err, "Status from runtime service failed") return nil, err } - r.log(10, "[RemoteRuntimeService] Status Response", "status", resp.Status) + logger.V(10).Info("[RemoteRuntimeService] Status Response", "status", resp.Status) if resp.Status == nil || len(resp.Status.Conditions) < 2 { errorMessage := "RuntimeReady or NetworkReady condition are not set" err := errors.New(errorMessage) - r.logErr(err, "Status failed") + logger.Error(err, "Status failed") return nil, err } @@ -700,7 +816,8 @@ func (r *remoteRuntimeService) statusV1(ctx context.Context, verbose bool) (*run // ContainerStats returns the stats of the container. func (r *remoteRuntimeService) ContainerStats(ctx context.Context, containerID string) (*runtimeapi.ContainerStats, error) { - r.log(10, "[RemoteRuntimeService] ContainerStats", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ContainerStats", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -708,27 +825,32 @@ func (r *remoteRuntimeService) ContainerStats(ctx context.Context, containerID s } func (r *remoteRuntimeService) containerStatsV1(ctx context.Context, containerID string) (*runtimeapi.ContainerStats, error) { + logger := klog.FromContext(ctx) resp, err := r.runtimeClient.ContainerStats(ctx, &runtimeapi.ContainerStatsRequest{ ContainerId: containerID, }) if err != nil { if r.logReduction.ShouldMessageBePrinted(err.Error(), containerID) { - r.logErr(err, "ContainerStats from runtime service failed", "containerID", containerID) + logger.Error(err, "ContainerStats from runtime service failed", "containerID", containerID) } return nil, err } r.logReduction.ClearID(containerID) - r.log(10, "[RemoteRuntimeService] ContainerStats Response", "containerID", containerID, "stats", resp.GetStats()) + logger.V(10).Info("[RemoteRuntimeService] ContainerStats Response", "containerID", containerID, "stats", resp.GetStats()) return resp.GetStats(), nil } // ListContainerStats returns the list of ContainerStats given the filter. func (r *remoteRuntimeService) ListContainerStats(ctx context.Context, filter *runtimeapi.ContainerStatsFilter) ([]*runtimeapi.ContainerStats, error) { - r.log(10, "[RemoteRuntimeService] ListContainerStats", "filter", filter) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ListContainerStats", "filter", filter) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamContainerStatsV1(ctx, filter) + } return r.listContainerStatsV1(ctx, filter) } @@ -736,18 +858,56 @@ func (r *remoteRuntimeService) listContainerStatsV1(ctx context.Context, filter resp, err := r.runtimeClient.ListContainerStats(ctx, &runtimeapi.ListContainerStatsRequest{ Filter: filter, }) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListContainerStats with filter from runtime service failed", "filter", filter) + logger.Error(err, "ListContainerStats with filter from runtime service failed", "filter", filter) return nil, err } - r.log(10, "[RemoteRuntimeService] ListContainerStats Response", "filter", filter, "stats", resp.GetStats()) + logger.V(10).Info("[RemoteRuntimeService] ListContainerStats Response", "filter", filter, "stats", resp.GetStats()) return resp.GetStats(), nil } +func (r *remoteRuntimeService) streamContainerStatsV1(ctx context.Context, filter *runtimeapi.ContainerStatsFilter) ([]*runtimeapi.ContainerStats, error) { + logger := klog.FromContext(ctx) + stream, err := r.runtimeClient.StreamContainerStats(ctx, &runtimeapi.StreamContainerStatsRequest{ + Filter: filter, + }) + if err != nil { + logger.Error(err, "StreamContainerStats from runtime service failed", "filter", filter) + return nil, err + } + + var stats []*runtimeapi.ContainerStats + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamContainerStats not implemented, falling back to ListContainerStats", "filter", filter) + r.useStreaming.Store(false) + return r.listContainerStatsV1(ctx, filter) + } + logger.Error(err, "StreamContainerStats recv failed", "filter", filter, "itemsReceived", len(stats)) + return nil, err + } + stats = append(stats, resp.ContainerStats...) + } + + logger.V(10).Info("[RemoteRuntimeService] StreamContainerStats Response", "filter", filter, "stats", stats) + + return stats, nil +} + // PodSandboxStats returns the stats of the pod. func (r *remoteRuntimeService) PodSandboxStats(ctx context.Context, podSandboxID string) (*runtimeapi.PodSandboxStats, error) { - r.log(10, "[RemoteRuntimeService] PodSandboxStats", "podSandboxID", podSandboxID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] PodSandboxStats", "podSandboxID", podSandboxID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() @@ -755,28 +915,33 @@ func (r *remoteRuntimeService) PodSandboxStats(ctx context.Context, podSandboxID } func (r *remoteRuntimeService) podSandboxStatsV1(ctx context.Context, podSandboxID string) (*runtimeapi.PodSandboxStats, error) { + logger := klog.FromContext(ctx) resp, err := r.runtimeClient.PodSandboxStats(ctx, &runtimeapi.PodSandboxStatsRequest{ PodSandboxId: podSandboxID, }) if err != nil { if r.logReduction.ShouldMessageBePrinted(err.Error(), podSandboxID) { - r.logErr(err, "PodSandbox from runtime service failed", "podSandboxID", podSandboxID) + logger.Error(err, "PodSandbox from runtime service failed", "podSandboxID", podSandboxID) } return nil, err } r.logReduction.ClearID(podSandboxID) - r.log(10, "[RemoteRuntimeService] PodSandbox Response", "podSandboxID", podSandboxID, "stats", resp.GetStats()) + logger.V(10).Info("[RemoteRuntimeService] PodSandbox Response", "podSandboxID", podSandboxID, "stats", resp.GetStats()) return resp.GetStats(), nil } // ListPodSandboxStats returns the list of pod sandbox stats given the filter func (r *remoteRuntimeService) ListPodSandboxStats(ctx context.Context, filter *runtimeapi.PodSandboxStatsFilter) ([]*runtimeapi.PodSandboxStats, error) { - r.log(10, "[RemoteRuntimeService] ListPodSandboxStats", "filter", filter) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ListPodSandboxStats", "filter", filter) // Set timeout, because runtimes are able to cache disk stats results ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamPodSandboxStatsV1(ctx, filter) + } return r.listPodSandboxStatsV1(ctx, filter) } @@ -784,33 +949,72 @@ func (r *remoteRuntimeService) listPodSandboxStatsV1(ctx context.Context, filter resp, err := r.runtimeClient.ListPodSandboxStats(ctx, &runtimeapi.ListPodSandboxStatsRequest{ Filter: filter, }) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListPodSandboxStats with filter from runtime service failed", "filter", filter) + logger.Error(err, "ListPodSandboxStats with filter from runtime service failed", "filter", filter) return nil, err } - r.log(10, "[RemoteRuntimeService] ListPodSandboxStats Response", "filter", filter, "stats", resp.GetStats()) + logger.V(10).Info("[RemoteRuntimeService] ListPodSandboxStats Response", "filter", filter, "stats", resp.GetStats()) return resp.GetStats(), nil } +func (r *remoteRuntimeService) streamPodSandboxStatsV1(ctx context.Context, filter *runtimeapi.PodSandboxStatsFilter) ([]*runtimeapi.PodSandboxStats, error) { + logger := klog.FromContext(ctx) + stream, err := r.runtimeClient.StreamPodSandboxStats(ctx, &runtimeapi.StreamPodSandboxStatsRequest{ + Filter: filter, + }) + if err != nil { + logger.Error(err, "StreamPodSandboxStats from runtime service failed", "filter", filter) + return nil, err + } + + var stats []*runtimeapi.PodSandboxStats + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamPodSandboxStats not implemented, falling back to ListPodSandboxStats", "filter", filter) + r.useStreaming.Store(false) + return r.listPodSandboxStatsV1(ctx, filter) + } + logger.Error(err, "StreamPodSandboxStats recv failed", "filter", filter, "itemsReceived", len(stats)) + return nil, err + } + stats = append(stats, resp.PodSandboxStats...) + } + + logger.V(10).Info("[RemoteRuntimeService] StreamPodSandboxStats Response", "filter", filter, "stats", stats) + + return stats, nil +} + // ReopenContainerLog reopens the container log file. func (r *remoteRuntimeService) ReopenContainerLog(ctx context.Context, containerID string) (err error) { - r.log(10, "[RemoteRuntimeService] ReopenContainerLog", "containerID", containerID, "timeout", r.timeout) + logger := klog.FromContext(ctx) + logger.V(10).Info("[RemoteRuntimeService] ReopenContainerLog", "containerID", containerID, "timeout", r.timeout) ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() if _, err := r.runtimeClient.ReopenContainerLog(ctx, &runtimeapi.ReopenContainerLogRequest{ContainerId: containerID}); err != nil { - r.logErr(err, "ReopenContainerLog from runtime service failed", "containerID", containerID) + logger.Error(err, "ReopenContainerLog from runtime service failed", "containerID", containerID) return err } - r.log(10, "[RemoteRuntimeService] ReopenContainerLog Response", "containerID", containerID) + logger.V(10).Info("[RemoteRuntimeService] ReopenContainerLog Response", "containerID", containerID) return nil } // CheckpointContainer triggers a checkpoint of the given CheckpointContainerRequest func (r *remoteRuntimeService) CheckpointContainer(ctx context.Context, options *runtimeapi.CheckpointContainerRequest) error { - r.log(10, + logger := klog.FromContext(ctx) + logger.V(10).Info( "[RemoteRuntimeService] CheckpointContainer", "options", options, @@ -842,7 +1046,7 @@ func (r *remoteRuntimeService) CheckpointContainer(ctx context.Context, options ) if err != nil { - r.logErr( + logger.Error( err, "CheckpointContainer from runtime service failed", "containerID", @@ -850,7 +1054,7 @@ func (r *remoteRuntimeService) CheckpointContainer(ctx context.Context, options ) return err } - r.log(10, + logger.V(10).Info( "[RemoteRuntimeService] CheckpointContainer Response", "containerID", options.ContainerId, @@ -861,8 +1065,9 @@ func (r *remoteRuntimeService) CheckpointContainer(ctx context.Context, options func (r *remoteRuntimeService) GetContainerEvents(ctx context.Context, containerEventsCh chan *runtimeapi.ContainerEventResponse, connectionEstablishedCallback func(runtimeapi.RuntimeService_GetContainerEventsClient)) error { containerEventsStreamingClient, err := r.runtimeClient.GetContainerEvents(ctx, &runtimeapi.GetEventsRequest{}) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "GetContainerEvents failed to get streaming client") + logger.Error(err, "GetContainerEvents failed to get streaming client") return err } @@ -873,17 +1078,17 @@ func (r *remoteRuntimeService) GetContainerEvents(ctx context.Context, container for { resp, err := containerEventsStreamingClient.Recv() - if err == io.EOF { - r.logErr(err, "container events stream is closed") + if errors.Is(err, io.EOF) { + logger.Error(err, "container events stream is closed") return err } if err != nil { - r.logErr(err, "failed to receive streaming container event") + logger.Error(err, "failed to receive streaming container event") return err } if resp != nil { containerEventsCh <- resp - r.log(4, "container event received", "resp", resp) + logger.V(4).Info("container event received", "resp", resp) } } } @@ -894,11 +1099,12 @@ func (r *remoteRuntimeService) ListMetricDescriptors(ctx context.Context) ([]*ru defer cancel() resp, err := r.runtimeClient.ListMetricDescriptors(ctx, &runtimeapi.ListMetricDescriptorsRequest{}) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListMetricDescriptors from runtime service failed") + logger.Error(err, "ListMetricDescriptors from runtime service failed") return nil, err } - r.log(10, "[RemoteRuntimeService] ListMetricDescriptors Response", "stats", resp.GetDescriptors()) + logger.V(10).Info("[RemoteRuntimeService] ListMetricDescriptors Response", "stats", resp.GetDescriptors()) return resp.GetDescriptors(), nil } @@ -908,27 +1114,70 @@ func (r *remoteRuntimeService) ListPodSandboxMetrics(ctx context.Context) ([]*ru ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() + if r.useStreaming.Load() { + return r.streamPodSandboxMetricsV1(ctx) + } + return r.listPodSandboxMetricsV1(ctx) +} + +func (r *remoteRuntimeService) listPodSandboxMetricsV1(ctx context.Context) ([]*runtimeapi.PodSandboxMetrics, error) { resp, err := r.runtimeClient.ListPodSandboxMetrics(ctx, &runtimeapi.ListPodSandboxMetricsRequest{}) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "ListPodSandboxMetrics from runtime service failed") + logger.Error(err, "ListPodSandboxMetrics from runtime service failed") return nil, err } - r.log(10, "[RemoteRuntimeService] ListPodSandboxMetrics Response", "stats", resp.GetPodMetrics()) + logger.V(10).Info("[RemoteRuntimeService] ListPodSandboxMetrics Response", "stats", resp.GetPodMetrics()) return resp.GetPodMetrics(), nil } +func (r *remoteRuntimeService) streamPodSandboxMetricsV1(ctx context.Context) ([]*runtimeapi.PodSandboxMetrics, error) { + logger := klog.FromContext(ctx) + stream, err := r.runtimeClient.StreamPodSandboxMetrics(ctx, &runtimeapi.StreamPodSandboxMetricsRequest{}) + if err != nil { + logger.Error(err, "StreamPodSandboxMetrics from runtime service failed") + return nil, err + } + + var metrics []*runtimeapi.PodSandboxMetrics + for { + resp, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + // If the RPC is unimplemented, disable streaming and fall back to the unary RPC. + // The Unimplemented status is not returned when creating the stream, + // but when calling Recv() on the stream. + if status.Code(err) == codes.Unimplemented { + logger.Info("StreamPodSandboxMetrics not implemented, falling back to ListPodSandboxMetrics") + r.useStreaming.Store(false) + return r.listPodSandboxMetricsV1(ctx) + } + logger.Error(err, "StreamPodSandboxMetrics recv failed", "itemsReceived", len(metrics)) + return nil, err + } + metrics = append(metrics, resp.PodSandboxMetrics...) + } + + logger.V(10).Info("[RemoteRuntimeService] StreamPodSandboxMetrics Response", "metrics", metrics) + + return metrics, nil +} + // RuntimeConfig returns the configuration information of the runtime. func (r *remoteRuntimeService) RuntimeConfig(ctx context.Context) (*runtimeapi.RuntimeConfigResponse, error) { ctx, cancel := context.WithTimeout(ctx, r.timeout) defer cancel() resp, err := r.runtimeClient.RuntimeConfig(ctx, &runtimeapi.RuntimeConfigRequest{}) + logger := klog.FromContext(ctx) if err != nil { - r.logErr(err, "RuntimeConfig from runtime service failed") + logger.Error(err, "RuntimeConfig from runtime service failed") return nil, err } - r.log(10, "[RemoteRuntimeService] RuntimeConfigResponse", "linuxConfig", resp.GetLinux()) + logger.V(10).Info("[RemoteRuntimeService] RuntimeConfigResponse", "linuxConfig", resp.GetLinux()) return resp, nil } diff --git a/vendor/k8s.io/cri-client/pkg/util/util_unix.go b/vendor/k8s.io/cri-client/pkg/util/util_unix.go index 73df89045f..3310590384 100644 --- a/vendor/k8s.io/cri-client/pkg/util/util_unix.go +++ b/vendor/k8s.io/cri-client/pkg/util/util_unix.go @@ -1,5 +1,4 @@ //go:build freebsd || linux || darwin -// +build freebsd linux darwin /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/cri-client/pkg/util/util_unsupported.go b/vendor/k8s.io/cri-client/pkg/util/util_unsupported.go index bfb729897b..21c2a5b7ff 100644 --- a/vendor/k8s.io/cri-client/pkg/util/util_unsupported.go +++ b/vendor/k8s.io/cri-client/pkg/util/util_unsupported.go @@ -1,5 +1,4 @@ //go:build !freebsd && !linux && !windows && !darwin -// +build !freebsd,!linux,!windows,!darwin /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/cri-client/pkg/util/util_windows.go b/vendor/k8s.io/cri-client/pkg/util/util_windows.go index 96d0634ef0..e83119e8c9 100644 --- a/vendor/k8s.io/cri-client/pkg/util/util_windows.go +++ b/vendor/k8s.io/cri-client/pkg/util/util_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/github.com/aws/aws-sdk-go/LICENSE.txt b/vendor/k8s.io/cri-streaming/LICENSE similarity index 100% rename from vendor/github.com/aws/aws-sdk-go/LICENSE.txt rename to vendor/k8s.io/cri-streaming/LICENSE diff --git a/vendor/k8s.io/cri-streaming/pkg/streaming/.import-restrictions b/vendor/k8s.io/cri-streaming/pkg/streaming/.import-restrictions new file mode 100644 index 0000000000..87723dcfc8 --- /dev/null +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/.import-restrictions @@ -0,0 +1,5 @@ +rules: + # prevent import of k8s.io/kubernetes + - selectorRegexp: k8s[.]io/kubernetes + forbiddenPrefixes: + - '' diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/generated_expansion.go b/vendor/k8s.io/cri-streaming/pkg/streaming/doc.go similarity index 83% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/generated_expansion.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/doc.go index 822e062872..9d5d0df0c2 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/generated_expansion.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/doc.go @@ -14,8 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -package v2beta2 - -type HorizontalPodAutoscalerExpansion interface{} +// Package streaming contains CRI server-side streaming interfaces and implementations. +package streaming diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/errors.go b/vendor/k8s.io/cri-streaming/pkg/streaming/errors.go similarity index 100% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/errors.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/errors.go diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go b/vendor/k8s.io/cri-streaming/pkg/streaming/internal/httpresponse/writer.go similarity index 56% rename from vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/internal/httpresponse/writer.go index 0998c461bb..832b59a845 100644 --- a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/internal/httpresponse/writer.go @@ -1,6 +1,3 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - /* Copyright The Kubernetes Authors. @@ -17,16 +14,25 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v2beta1 - -func (*APIGroupDiscovery) ProtoMessage() {} - -func (*APIGroupDiscoveryList) ProtoMessage() {} - -func (*APIResourceDiscovery) ProtoMessage() {} - -func (*APISubresourceDiscovery) ProtoMessage() {} - -func (*APIVersionDiscovery) ProtoMessage() {} +package httpresponse + +import "net/http" + +type wrapper interface { + Unwrap() http.ResponseWriter +} + +// GetOriginal walks any response writer wrapper chain and returns the first writer. +func GetOriginal(w http.ResponseWriter) http.ResponseWriter { + for { + decorator, ok := w.(wrapper) + if !ok { + return w + } + inner := decorator.Unwrap() + if inner == w { + panic("http.ResponseWriter decorator chain has a cycle") + } + w = inner + } +} diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/constants.go b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/constants.go similarity index 68% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/constants.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/portforward/constants.go index 62b14f2051..6a060e241c 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/constants.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/constants.go @@ -22,3 +22,17 @@ const ProtocolV1Name = "portforward.k8s.io" // SupportedProtocols are the supported port forwarding protocols. var SupportedProtocols = []string{ProtocolV1Name} + +const ( + PortForwardV1Name = ProtocolV1Name + WebsocketsSPDYTunnelingPrefix = "SPDY/3.1+" + KubernetesSuffix = ".k8s.io" + WebsocketsSPDYTunnelingPortForwardV1 = WebsocketsSPDYTunnelingPrefix + PortForwardV1Name + + PortHeader = "port" + PortForwardRequestIDHeader = "requestID" + + StreamType = "streamType" + StreamTypeData = "data" + StreamTypeError = "error" +) diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/httpstream.go b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/httpstream.go similarity index 90% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/httpstream.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/portforward/httpstream.go index 9e2bd8ec8d..9ed58561a9 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/httpstream.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/httpstream.go @@ -25,16 +25,14 @@ import ( "sync" "time" - api "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/httpstream/spdy" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/httpstream/spdy" + utilruntime "k8s.io/streaming/pkg/runtime" "k8s.io/klog/v2" ) -func handleHTTPStreams(req *http.Request, w http.ResponseWriter, portForwarder PortForwarder, podName string, uid types.UID, supportedPortForwardProtocols []string, idleTimeout, streamCreationTimeout time.Duration) error { +func handleHTTPStreams(req *http.Request, w http.ResponseWriter, portForwarder PortForwarder, podName string, uid string, supportedPortForwardProtocols []string, idleTimeout, streamCreationTimeout time.Duration) error { _, err := httpstream.Handshake(req, w, supportedPortForwardProtocols) // negotiated protocol isn't currently used server side, but could be in the future if err != nil { @@ -75,9 +73,9 @@ func handleHTTPStreams(req *http.Request, w http.ResponseWriter, portForwarder P func httpStreamReceived(streams chan httpstream.Stream) func(httpstream.Stream, <-chan struct{}) error { return func(stream httpstream.Stream, replySent <-chan struct{}) error { // make sure it has a valid port header - portString := stream.Headers().Get(api.PortHeader) + portString := stream.Headers().Get(PortHeader) if len(portString) == 0 { - return fmt.Errorf("%q header is required", api.PortHeader) + return fmt.Errorf("%q header is required", PortHeader) } port, err := strconv.ParseUint(portString, 10, 16) if err != nil { @@ -88,11 +86,11 @@ func httpStreamReceived(streams chan httpstream.Stream) func(httpstream.Stream, } // make sure it has a valid stream type header - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) if len(streamType) == 0 { - return fmt.Errorf("%q header is required", api.StreamType) + return fmt.Errorf("%q header is required", StreamType) } - if streamType != api.StreamTypeError && streamType != api.StreamTypeData { + if streamType != StreamTypeError && streamType != StreamTypeData { return fmt.Errorf("invalid stream type %q", streamType) } @@ -110,7 +108,7 @@ type httpStreamHandler struct { streamPairs map[string]*httpStreamPair streamCreationTimeout time.Duration pod string - uid types.UID + uid string forwarder PortForwarder } @@ -173,7 +171,7 @@ func (h *httpStreamHandler) removeStreamPair(requestID string) { // requestID returns the request id for stream. func (h *httpStreamHandler) requestID(stream httpstream.Stream) string { - requestID := stream.Headers().Get(api.PortForwardRequestIDHeader) + requestID := stream.Headers().Get(PortForwardRequestIDHeader) if len(requestID) == 0 { klog.V(5).InfoS("Connection stream received without requestID header", "connection", h.conn) // If we get here, it's because the connection came from an older client @@ -194,11 +192,11 @@ func (h *httpStreamHandler) requestID(stream httpstream.Stream) string { // old clients that don't generate request ids. If there are concurrent // new connections, it's possible that 1 connection gets streams whose IDs // are not consecutive (e.g. 5 and 9 instead of 5 and 7). - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) switch streamType { - case api.StreamTypeError: + case StreamTypeError: requestID = strconv.Itoa(int(stream.Identifier())) - case api.StreamTypeData: + case StreamTypeData: requestID = strconv.Itoa(int(stream.Identifier()) - 2) } @@ -220,7 +218,7 @@ Loop: break Loop case stream := <-h.streamChan: requestID := h.requestID(stream) - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) klog.V(5).InfoS("Connection request received new type of stream", "connection", h.conn, "request", requestID, "streamType", streamType) p, created := h.getStreamPair(requestID) @@ -245,7 +243,7 @@ func (h *httpStreamHandler) portForward(p *httpStreamPair) { defer p.dataStream.Close() defer p.errorStream.Close() - portString := p.dataStream.Headers().Get(api.PortHeader) + portString := p.dataStream.Headers().Get(PortHeader) port, _ := strconv.ParseInt(portString, 10, 32) klog.V(5).InfoS("Connection request invoking forwarder.PortForward for port", "connection", h.conn, "request", p.requestID, "port", portString) @@ -291,13 +289,13 @@ func (p *httpStreamPair) add(stream httpstream.Stream) (bool, error) { p.lock.Lock() defer p.lock.Unlock() - switch stream.Headers().Get(api.StreamType) { - case api.StreamTypeError: + switch stream.Headers().Get(StreamType) { + case StreamTypeError: if p.errorStream != nil { return false, errors.New("error stream already assigned") } p.errorStream = stream - case api.StreamTypeData: + case StreamTypeData: if p.dataStream != nil { return false, errors.New("data stream already assigned") } diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/portforward.go b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/portforward.go similarity index 79% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/portforward.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/portforward/portforward.go index 7aa668ca4d..ac4508d86f 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/portforward.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/portforward.go @@ -22,16 +22,15 @@ import ( "net/http" "time" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" - "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/streaming/pkg/httpstream/wsstream" + "k8s.io/streaming/pkg/runtime" ) // PortForwarder knows how to forward content from a data stream to/from a port // in a pod. type PortForwarder interface { // PortForwarder copies data between a data stream and a port in a pod. - PortForward(ctx context.Context, name string, uid types.UID, port int32, stream io.ReadWriteCloser) error + PortForward(ctx context.Context, name string, uid string, port int32, stream io.ReadWriteCloser) error } // ServePortForward handles a port forwarding request. A single request is @@ -39,7 +38,7 @@ type PortForwarder interface { // been timed out due to idleness. This function handles multiple forwarded // connections; i.e., multiple `curl http://localhost:8888/` requests will be // handled by a single invocation of ServePortForward. -func ServePortForward(w http.ResponseWriter, req *http.Request, portForwarder PortForwarder, podName string, uid types.UID, portForwardOptions *V4Options, idleTimeout time.Duration, streamCreationTimeout time.Duration, supportedProtocols []string) { +func ServePortForward(w http.ResponseWriter, req *http.Request, portForwarder PortForwarder, podName string, uid string, portForwardOptions *V4Options, idleTimeout time.Duration, streamCreationTimeout time.Duration, supportedProtocols []string) { var err error if wsstream.IsWebSocketRequest(req) { err = handleWebSocketStreams(req, w, portForwarder, podName, uid, portForwardOptions, supportedProtocols, idleTimeout, streamCreationTimeout) diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/websocket.go b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/websocket.go similarity index 89% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/websocket.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/portforward/websocket.go index 3700a7e22a..93efffc6c6 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/portforward/websocket.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/portforward/websocket.go @@ -29,11 +29,9 @@ import ( "k8s.io/klog/v2" - api "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apiserver/pkg/endpoints/responsewriter" + "k8s.io/cri-streaming/pkg/streaming/internal/httpresponse" + "k8s.io/streaming/pkg/httpstream/wsstream" + "k8s.io/streaming/pkg/runtime" ) const ( @@ -58,15 +56,15 @@ func NewV4Options(req *http.Request) (*V4Options, error) { return &V4Options{}, nil } - portStrings := req.URL.Query()[api.PortHeader] + portStrings := req.URL.Query()[PortHeader] if len(portStrings) == 0 { - return nil, fmt.Errorf("query parameter %q is required", api.PortHeader) + return nil, fmt.Errorf("query parameter %q is required", PortHeader) } ports := make([]int32, 0, len(portStrings)) for _, portString := range portStrings { if len(portString) == 0 { - return nil, fmt.Errorf("query parameter %q cannot be empty", api.PortHeader) + return nil, fmt.Errorf("query parameter %q cannot be empty", PortHeader) } for _, p := range strings.Split(portString, ",") { port, err := strconv.ParseUint(p, 10, 16) @@ -94,7 +92,7 @@ func BuildV4Options(ports []int32) (*V4Options, error) { // a PortForwarder. A pair of streams are created per port (DATA n, // ERROR n+1). The associated port is written to each stream as a unsigned 16 // bit integer in little endian format. -func handleWebSocketStreams(req *http.Request, w http.ResponseWriter, portForwarder PortForwarder, podName string, uid types.UID, opts *V4Options, supportedPortForwardProtocols []string, idleTimeout, streamCreationTimeout time.Duration) error { +func handleWebSocketStreams(req *http.Request, w http.ResponseWriter, portForwarder PortForwarder, podName string, uid string, opts *V4Options, supportedPortForwardProtocols []string, idleTimeout, streamCreationTimeout time.Duration) error { channels := make([]wsstream.ChannelType, 0, len(opts.Ports)*2) for i := 0; i < len(opts.Ports); i++ { channels = append(channels, wsstream.ReadWriteChannel, wsstream.WriteChannel) @@ -114,7 +112,7 @@ func handleWebSocketStreams(req *http.Request, w http.ResponseWriter, portForwar }, }) conn.SetIdleTimeout(idleTimeout) - _, streams, err := conn.Open(responsewriter.GetOriginal(w), req) + _, streams, err := conn.Open(httpresponse.GetOriginal(w), req) if err != nil { err = fmt.Errorf("unable to upgrade websocket connection: %v", err) return err @@ -161,7 +159,7 @@ type websocketStreamHandler struct { conn *wsstream.Conn streamPairs []*websocketStreamPair pod string - uid types.UID + uid string forwarder PortForwarder } diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/attach.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/attach.go similarity index 69% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/attach.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/attach.go index aa638499a9..7b1c6dd661 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/attach.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/attach.go @@ -23,23 +23,19 @@ import ( "net/http" "time" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/client-go/tools/remotecommand" + "k8s.io/streaming/pkg/runtime" ) // Attacher knows how to attach to a running container in a pod. type Attacher interface { // AttachContainer attaches to the running container in the pod, copying data between in/out/err // and the container's stdin/stdout/stderr. - AttachContainer(ctx context.Context, name string, uid types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error + AttachContainer(ctx context.Context, name string, uid string, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan TerminalSize) error } // ServeAttach handles requests to attach to a container. After creating/receiving the required // streams, it delegates the actual attaching to attacher. -func ServeAttach(w http.ResponseWriter, req *http.Request, attacher Attacher, podName string, uid types.UID, container string, streamOpts *Options, idleTimeout, streamCreationTimeout time.Duration, supportedProtocols []string) { +func ServeAttach(w http.ResponseWriter, req *http.Request, attacher Attacher, podName string, uid string, container string, streamOpts *Options, idleTimeout, streamCreationTimeout time.Duration, supportedProtocols []string) { ctx, ok := createStreams(req, w, streamOpts, supportedProtocols, idleTimeout, streamCreationTimeout) if !ok { // error is handled by createStreams @@ -51,10 +47,10 @@ func ServeAttach(w http.ResponseWriter, req *http.Request, attacher Attacher, po if err != nil { err = fmt.Errorf("error attaching to container: %v", err) runtime.HandleError(err) - ctx.writeStatus(apierrors.NewInternalError(err)) + ctx.writeStatus(newInternalError(err)) } else { - ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{ - Status: metav1.StatusSuccess, + ctx.writeStatus(&streamStatusError{ErrStatus: streamStatus{ + Status: statusSuccess, }}) } } diff --git a/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/constants.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/constants.go new file mode 100644 index 0000000000..9deb2b7d74 --- /dev/null +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/constants.go @@ -0,0 +1,75 @@ +/* +Copyright 2016 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 remotecommand + +import "time" + +const ( + DefaultStreamCreationTimeout = 30 * time.Second + + ExecStdinParam = "input" + ExecStdoutParam = "output" + ExecStderrParam = "error" + ExecTTYParam = "tty" + + StreamType = "streamType" + StreamTypeStdin = "stdin" + StreamTypeStdout = "stdout" + StreamTypeStderr = "stderr" + StreamTypeError = "error" + StreamTypeResize = "resize" + + // The SPDY subprotocol "channel.k8s.io" is used for remote command + // attachment/execution. This represents the initial unversioned subprotocol, + // which has the known bugs https://issues.k8s.io/13394 and + // https://issues.k8s.io/13395. + StreamProtocolV1Name = "channel.k8s.io" + + // The SPDY subprotocol "v2.channel.k8s.io" is used for remote command + // attachment/execution. It is the second version of the subprotocol and + // resolves the issues present in the first version. + StreamProtocolV2Name = "v2.channel.k8s.io" + + // The SPDY subprotocol "v3.channel.k8s.io" is used for remote command + // attachment/execution. It is the third version of the subprotocol and + // adds support for resizing container terminals. + StreamProtocolV3Name = "v3.channel.k8s.io" + + // The SPDY subprotocol "v4.channel.k8s.io" is used for remote command + // attachment/execution. It is the 4th version of the subprotocol and + // adds support for exit codes. + StreamProtocolV4Name = "v4.channel.k8s.io" + + // The subprotocol "v5.channel.k8s.io" is used for remote command + // attachment/execution. It is the 5th version of the subprotocol and + // adds support for a CLOSE signal. + StreamProtocolV5Name = "v5.channel.k8s.io" + + NonZeroExitCodeReason = "NonZeroExitCode" + ExitCodeCauseType = "ExitCode" + + // RemoteCommand stream identifiers. The first three identifiers (for STDIN, + // STDOUT, STDERR) are the same as their file descriptors. + StreamStdIn = 0 + StreamStdOut = 1 + StreamStdErr = 2 + StreamErr = 3 + StreamResize = 4 + StreamClose = 255 +) + +var SupportedStreamingProtocols = []string{StreamProtocolV4Name, StreamProtocolV3Name, StreamProtocolV2Name, StreamProtocolV1Name} diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/doc.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/doc.go similarity index 100% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/doc.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/doc.go diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/exec.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/exec.go similarity index 63% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/exec.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/exec.go index 5ec6b86a8d..7b600955a8 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/exec.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/exec.go @@ -23,12 +23,7 @@ import ( "net/http" "time" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/client-go/tools/remotecommand" + "k8s.io/streaming/pkg/runtime" utilexec "k8s.io/utils/exec" ) @@ -36,13 +31,13 @@ import ( type Executor interface { // ExecInContainer executes a command in a container in the pod, copying data // between in/out/err and the container's stdin/stdout/stderr. - ExecInContainer(ctx context.Context, name string, uid types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error + ExecInContainer(ctx context.Context, name string, uid string, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan TerminalSize, timeout time.Duration) error } // ServeExec handles requests to execute a command in a container. After // creating/receiving the required streams, it delegates the actual execution // to the executor. -func ServeExec(w http.ResponseWriter, req *http.Request, executor Executor, podName string, uid types.UID, container string, cmd []string, streamOpts *Options, idleTimeout, streamCreationTimeout time.Duration, supportedProtocols []string) { +func ServeExec(w http.ResponseWriter, req *http.Request, executor Executor, podName string, uid string, container string, cmd []string, streamOpts *Options, idleTimeout, streamCreationTimeout time.Duration, supportedProtocols []string) { ctx, ok := createStreams(req, w, streamOpts, supportedProtocols, idleTimeout, streamCreationTimeout) if !ok { // error is handled by createStreams @@ -54,13 +49,13 @@ func ServeExec(w http.ResponseWriter, req *http.Request, executor Executor, podN if err != nil { if exitErr, ok := err.(utilexec.ExitError); ok && exitErr.Exited() { rc := exitErr.ExitStatus() - ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{ - Status: metav1.StatusFailure, - Reason: remotecommandconsts.NonZeroExitCodeReason, - Details: &metav1.StatusDetails{ - Causes: []metav1.StatusCause{ + ctx.writeStatus(&streamStatusError{ErrStatus: streamStatus{ + Status: statusFailure, + Reason: NonZeroExitCodeReason, + Details: &streamStatusDetails{ + Causes: []streamStatusCause{ { - Type: remotecommandconsts.ExitCodeCauseType, + Type: ExitCodeCauseType, Message: fmt.Sprintf("%d", rc), }, }, @@ -70,11 +65,11 @@ func ServeExec(w http.ResponseWriter, req *http.Request, executor Executor, podN } else { err = fmt.Errorf("error executing command in container: %v", err) runtime.HandleError(err) - ctx.writeStatus(apierrors.NewInternalError(err)) + ctx.writeStatus(newInternalError(err)) } } else { - ctx.writeStatus(&apierrors.StatusError{ErrStatus: metav1.Status{ - Status: metav1.StatusSuccess, + ctx.writeStatus(&streamStatusError{ErrStatus: streamStatus{ + Status: statusSuccess, }}) } } diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/httpstream.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/httpstream.go similarity index 83% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/httpstream.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/httpstream.go index 185a3db627..d463bb51af 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/httpstream.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/httpstream.go @@ -25,15 +25,10 @@ import ( "net/http" "time" - api "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/httpstream/spdy" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" - remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/client-go/tools/remotecommand" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/httpstream/spdy" + "k8s.io/streaming/pkg/httpstream/wsstream" + "k8s.io/streaming/pkg/runtime" "k8s.io/klog/v2" ) @@ -49,10 +44,10 @@ type Options struct { // NewOptions creates a new Options from the Request. func NewOptions(req *http.Request) (*Options, error) { - tty := req.FormValue(api.ExecTTYParam) == "1" - stdin := req.FormValue(api.ExecStdinParam) == "1" - stdout := req.FormValue(api.ExecStdoutParam) == "1" - stderr := req.FormValue(api.ExecStderrParam) == "1" + tty := req.FormValue(ExecTTYParam) == "1" + stdin := req.FormValue(ExecStdinParam) == "1" + stdout := req.FormValue(ExecStdoutParam) == "1" + stderr := req.FormValue(ExecStderrParam) == "1" if tty && stderr { // TODO: make this an error before we reach this method klog.V(4).InfoS("Access to exec with tty and stderr is not supported, bypassing stderr") @@ -78,9 +73,9 @@ type connectionContext struct { stdinStream io.ReadCloser stdoutStream io.WriteCloser stderrStream io.WriteCloser - writeStatus func(status *apierrors.StatusError) error + writeStatus func(status *streamStatusError) error resizeStream io.ReadCloser - resizeChan chan remotecommand.TerminalSize + resizeChan chan TerminalSize tty bool } @@ -116,7 +111,7 @@ func createStreams(req *http.Request, w http.ResponseWriter, opts *Options, supp } if ctx.resizeStream != nil { - ctx.resizeChan = make(chan remotecommand.TerminalSize) + ctx.resizeChan = make(chan TerminalSize) go handleResizeEvents(req.Context(), ctx.resizeStream, ctx.resizeChan) } @@ -149,16 +144,16 @@ func createHTTPStreamStreams(req *http.Request, w http.ResponseWriter, opts *Opt var handler protocolHandler switch protocol { - case remotecommandconsts.StreamProtocolV4Name: + case StreamProtocolV4Name: handler = &v4ProtocolHandler{} - case remotecommandconsts.StreamProtocolV3Name: + case StreamProtocolV3Name: handler = &v3ProtocolHandler{} - case remotecommandconsts.StreamProtocolV2Name: + case StreamProtocolV2Name: handler = &v2ProtocolHandler{} case "": - klog.V(4).InfoS("Client did not request protocol negotiation. Falling back", "protocol", remotecommandconsts.StreamProtocolV1Name) + klog.V(4).InfoS("Client did not request protocol negotiation. Falling back", "protocol", StreamProtocolV1Name) fallthrough - case remotecommandconsts.StreamProtocolV1Name: + case StreamProtocolV1Name: handler = &v1ProtocolHandler{} } @@ -201,7 +196,7 @@ type protocolHandler interface { } // v4ProtocolHandler implements the V4 protocol version for streaming command execution. It only differs -// in from v3 in the error stream format using an json-marshaled metav1.Status which carries +// in from v3 in the error stream format using a json-marshaled status object which carries // the process' exit code. type v4ProtocolHandler struct{} @@ -215,21 +210,21 @@ WaitForStreams: for { select { case stream := <-streams: - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) switch streamType { - case api.StreamTypeError: + case StreamTypeError: ctx.writeStatus = v4WriteStatusFunc(stream) // write json errors go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdin: + case StreamTypeStdin: ctx.stdinStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdout: + case StreamTypeStdout: ctx.stdoutStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStderr: + case StreamTypeStderr: ctx.stderrStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeResize: + case StreamTypeResize: ctx.resizeStream = stream go waitStreamReply(stream.replySent, replyChan, stop) default: @@ -266,21 +261,21 @@ WaitForStreams: for { select { case stream := <-streams: - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) switch streamType { - case api.StreamTypeError: + case StreamTypeError: ctx.writeStatus = v1WriteStatusFunc(stream) go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdin: + case StreamTypeStdin: ctx.stdinStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdout: + case StreamTypeStdout: ctx.stdoutStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStderr: + case StreamTypeStderr: ctx.stderrStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeResize: + case StreamTypeResize: ctx.resizeStream = stream go waitStreamReply(stream.replySent, replyChan, stop) default: @@ -317,18 +312,18 @@ WaitForStreams: for { select { case stream := <-streams: - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) switch streamType { - case api.StreamTypeError: + case StreamTypeError: ctx.writeStatus = v1WriteStatusFunc(stream) go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdin: + case StreamTypeStdin: ctx.stdinStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdout: + case StreamTypeStdout: ctx.stdoutStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStderr: + case StreamTypeStderr: ctx.stderrStream = stream go waitStreamReply(stream.replySent, replyChan, stop) default: @@ -365,9 +360,9 @@ WaitForStreams: for { select { case stream := <-streams: - streamType := stream.Headers().Get(api.StreamType) + streamType := stream.Headers().Get(StreamType) switch streamType { - case api.StreamTypeError: + case StreamTypeError: ctx.writeStatus = v1WriteStatusFunc(stream) // This defer statement shouldn't be here, but due to previous refactoring, it ended up in @@ -376,13 +371,13 @@ WaitForStreams: defer stream.Reset() go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdin: + case StreamTypeStdin: ctx.stdinStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStdout: + case StreamTypeStdout: ctx.stdoutStream = stream go waitStreamReply(stream.replySent, replyChan, stop) - case api.StreamTypeStderr: + case StreamTypeStderr: ctx.stderrStream = stream go waitStreamReply(stream.replySent, replyChan, stop) default: @@ -410,13 +405,13 @@ WaitForStreams: // supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it. func (*v1ProtocolHandler) supportsTerminalResizing() bool { return false } -func handleResizeEvents(reqctx context.Context, stream io.Reader, channel chan<- remotecommand.TerminalSize) { +func handleResizeEvents(reqctx context.Context, stream io.Reader, channel chan<- TerminalSize) { defer runtime.HandleCrash() defer close(channel) decoder := json.NewDecoder(stream) for { - size := remotecommand.TerminalSize{} + size := TerminalSize{} if err := decoder.Decode(&size); err != nil { break } @@ -429,9 +424,9 @@ func handleResizeEvents(reqctx context.Context, stream io.Reader, channel chan<- } } -func v1WriteStatusFunc(stream io.Writer) func(status *apierrors.StatusError) error { - return func(status *apierrors.StatusError) error { - if status.Status().Status == metav1.StatusSuccess { +func v1WriteStatusFunc(stream io.Writer) func(status *streamStatusError) error { + return func(status *streamStatusError) error { + if status.status().Status == statusSuccess { return nil // send error messages } _, err := stream.Write([]byte(status.Error())) @@ -439,11 +434,11 @@ func v1WriteStatusFunc(stream io.Writer) func(status *apierrors.StatusError) err } } -// v4WriteStatusFunc returns a WriteStatusFunc that marshals a given api Status +// v4WriteStatusFunc returns a WriteStatusFunc that marshals a status object // as json in the error channel. -func v4WriteStatusFunc(stream io.Writer) func(status *apierrors.StatusError) error { - return func(status *apierrors.StatusError) error { - bs, err := json.Marshal(status.Status()) +func v4WriteStatusFunc(stream io.Writer) func(status *streamStatusError) error { + return func(status *streamStatusError) error { + bs, err := json.Marshal(status.status()) if err != nil { return err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/doc.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/resize.go similarity index 79% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/doc.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/resize.go index 16f4439906..25cbe71bfc 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/doc.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/resize.go @@ -14,7 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. +package remotecommand -// Package fake has the automatically generated clients. -package fake +// TerminalSize represents the width and height of a terminal. +type TerminalSize struct { + Width uint16 + Height uint16 +} diff --git a/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/status.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/status.go new file mode 100644 index 0000000000..004dc3f438 --- /dev/null +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/status.go @@ -0,0 +1,71 @@ +/* +Copyright 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 remotecommand + +import ( + "fmt" + "net/http" +) + +const ( + statusSuccess = "Success" + statusFailure = "Failure" + + statusReasonInternalError = "InternalError" +) + +// streamStatusError carries status details written to the error stream. +type streamStatusError struct { + ErrStatus streamStatus +} + +func (e *streamStatusError) Error() string { + return e.ErrStatus.Message +} + +func (e *streamStatusError) status() streamStatus { + return e.ErrStatus +} + +func newInternalError(err error) *streamStatusError { + return &streamStatusError{ + ErrStatus: streamStatus{ + Status: statusFailure, + Reason: statusReasonInternalError, + Message: fmt.Sprintf("Internal error occurred: %v", err), + Code: http.StatusInternalServerError, + }, + } +} + +type streamStatus struct { + Status string `json:"status,omitempty"` + Message string `json:"message,omitempty"` + Reason string `json:"reason,omitempty"` + Details *streamStatusDetails `json:"details,omitempty"` + Code int32 `json:"code,omitempty"` +} + +type streamStatusDetails struct { + Causes []streamStatusCause `json:"causes,omitempty"` +} + +// streamStatusCause uses "reason" on the wire to match metav1.StatusCause. +type streamStatusCause struct { + Type string `json:"reason,omitempty"` + Message string `json:"message,omitempty"` +} diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/websocket.go b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/websocket.go similarity index 94% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/websocket.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/websocket.go index 2590088852..3bbeeddb3e 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/remotecommand/websocket.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/remotecommand/websocket.go @@ -21,9 +21,9 @@ import ( "net/http" "time" - "k8s.io/apimachinery/pkg/util/httpstream/wsstream" - "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apiserver/pkg/endpoints/responsewriter" + "k8s.io/cri-streaming/pkg/streaming/internal/httpresponse" + "k8s.io/streaming/pkg/httpstream/wsstream" + "k8s.io/streaming/pkg/runtime" ) const ( @@ -95,7 +95,7 @@ func createWebSocketStreams(req *http.Request, w http.ResponseWriter, opts *Opti }, }) conn.SetIdleTimeout(idleTimeout) - negotiatedProtocol, streams, err := conn.Open(responsewriter.GetOriginal(w), req) + negotiatedProtocol, streams, err := conn.Open(httpresponse.GetOriginal(w), req) if err != nil { runtime.HandleError(fmt.Errorf("unable to upgrade websocket connection: %v", err)) return nil, false diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/request_cache.go b/vendor/k8s.io/cri-streaming/pkg/streaming/request_cache.go similarity index 100% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/request_cache.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/request_cache.go diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/server.go b/vendor/k8s.io/cri-streaming/pkg/streaming/server.go similarity index 92% rename from vendor/k8s.io/kubelet/pkg/cri/streaming/server.go rename to vendor/k8s.io/cri-streaming/pkg/streaming/server.go index fe5c22b049..97ecb02828 100644 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/server.go +++ b/vendor/k8s.io/cri-streaming/pkg/streaming/server.go @@ -32,12 +32,9 @@ import ( restful "github.com/emicklei/go-restful/v3" - "k8s.io/apimachinery/pkg/types" - remotecommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" - "k8s.io/client-go/tools/remotecommand" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/kubelet/pkg/cri/streaming/portforward" - remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand" + "k8s.io/cri-streaming/pkg/streaming/portforward" + remotecommandserver "k8s.io/cri-streaming/pkg/streaming/remotecommand" ) // Server is the library interface to serve the stream requests. @@ -62,8 +59,8 @@ type Server interface { // Runtime is the interface to execute the commands and provide the streams. type Runtime interface { - Exec(ctx context.Context, containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error - Attach(ctx context.Context, containerID string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error + Exec(ctx context.Context, containerID string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommandserver.TerminalSize) error + Attach(ctx context.Context, containerID string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommandserver.TerminalSize) error PortForward(ctx context.Context, podSandboxID string, port int32, stream io.ReadWriteCloser) error } @@ -99,8 +96,8 @@ type Config struct { // some fields like Addr must still be provided. var DefaultConfig = Config{ StreamIdleTimeout: 4 * time.Hour, - StreamCreationTimeout: remotecommandconsts.DefaultStreamCreationTimeout, - SupportedRemoteCommandProtocols: remotecommandconsts.SupportedStreamingProtocols, + StreamCreationTimeout: remotecommandserver.DefaultStreamCreationTimeout, + SupportedRemoteCommandProtocols: remotecommandserver.SupportedStreamingProtocols, SupportedPortForwardProtocols: portforward.SupportedProtocols, } @@ -370,14 +367,14 @@ var _ remotecommandserver.Executor = &criAdapter{} var _ remotecommandserver.Attacher = &criAdapter{} var _ portforward.PortForwarder = &criAdapter{} -func (a *criAdapter) ExecInContainer(ctx context.Context, podName string, podUID types.UID, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize, timeout time.Duration) error { +func (a *criAdapter) ExecInContainer(ctx context.Context, podName string, podUID string, container string, cmd []string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommandserver.TerminalSize, timeout time.Duration) error { return a.Runtime.Exec(ctx, container, cmd, in, out, err, tty, resize) } -func (a *criAdapter) AttachContainer(ctx context.Context, podName string, podUID types.UID, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error { +func (a *criAdapter) AttachContainer(ctx context.Context, podName string, podUID string, container string, in io.Reader, out, err io.WriteCloser, tty bool, resize <-chan remotecommandserver.TerminalSize) error { return a.Runtime.Attach(ctx, container, in, out, err, tty, resize) } -func (a *criAdapter) PortForward(ctx context.Context, podName string, podUID types.UID, port int32, stream io.ReadWriteCloser) error { +func (a *criAdapter) PortForward(ctx context.Context, podName string, podUID string, port int32, stream io.ReadWriteCloser) error { return a.Runtime.PortForward(ctx, podName, port, stream) } diff --git a/vendor/k8s.io/dynamic-resource-allocation/api/OWNERS b/vendor/k8s.io/dynamic-resource-allocation/api/OWNERS index 6e4993d003..72e9dce52c 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/api/OWNERS +++ b/vendor/k8s.io/dynamic-resource-allocation/api/OWNERS @@ -9,6 +9,7 @@ reviewers: - bart0sh - klueska - pohly + - sig-node-reviewers labels: - sig/node - wg/device-management diff --git a/vendor/k8s.io/dynamic-resource-allocation/api/types.go b/vendor/k8s.io/dynamic-resource-allocation/api/types.go index 1d26a81e01..db168486b3 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/api/types.go +++ b/vendor/k8s.io/dynamic-resource-allocation/api/types.go @@ -60,18 +60,19 @@ type ResourcePool struct { } type Device struct { - Name UniqueString - Attributes map[resourceapi.QualifiedName]resourceapi.DeviceAttribute `json:",omitempty"` - Capacity map[resourceapi.QualifiedName]resourceapi.DeviceCapacity `json:",omitempty"` - ConsumesCounters []DeviceCounterConsumption `json:",omitempty"` - NodeName *string `json:",omitempty"` - NodeSelector *v1.NodeSelector `json:",omitempty"` - AllNodes *bool `json:",omitempty"` - Taints []resourceapi.DeviceTaint `json:",omitempty"` - BindsToNode bool `json:",omitempty"` - BindingConditions []string `json:",omitempty"` - BindingFailureConditions []string `json:",omitempty"` - AllowMultipleAllocations *bool `json:",omitempty"` + Name UniqueString + Attributes map[resourceapi.QualifiedName]resourceapi.DeviceAttribute `json:",omitempty"` + Capacity map[resourceapi.QualifiedName]resourceapi.DeviceCapacity `json:",omitempty"` + ConsumesCounters []DeviceCounterConsumption `json:",omitempty"` + NodeName *string `json:",omitempty"` + NodeSelector *v1.NodeSelector `json:",omitempty"` + AllNodes *bool `json:",omitempty"` + Taints []resourceapi.DeviceTaint `json:",omitempty"` + BindsToNode bool `json:",omitempty"` + BindingConditions []string `json:",omitempty"` + BindingFailureConditions []string `json:",omitempty"` + AllowMultipleAllocations *bool `json:",omitempty"` + NodeAllocatableResourceMappings map[v1.ResourceName]resourceapi.NodeAllocatableResourceMapping `json:",omitempty"` } type DeviceCounterConsumption struct { diff --git a/vendor/k8s.io/dynamic-resource-allocation/api/zz_generated.conversion.go b/vendor/k8s.io/dynamic-resource-allocation/api/zz_generated.conversion.go index cac65c36c3..44235a2bab 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/api/zz_generated.conversion.go +++ b/vendor/k8s.io/dynamic-resource-allocation/api/zz_generated.conversion.go @@ -164,6 +164,7 @@ func autoConvert_api_Device_To_v1_Device(in *Device, out *v1.Device, s conversio out.BindingConditions = *(*[]string)(unsafe.Pointer(&in.BindingConditions)) out.BindingFailureConditions = *(*[]string)(unsafe.Pointer(&in.BindingFailureConditions)) out.AllowMultipleAllocations = (*bool)(unsafe.Pointer(in.AllowMultipleAllocations)) + out.NodeAllocatableResourceMappings = *(*map[corev1.ResourceName]v1.NodeAllocatableResourceMapping)(unsafe.Pointer(&in.NodeAllocatableResourceMappings)) return nil } @@ -199,6 +200,7 @@ func autoConvert_v1_Device_To_api_Device(in *v1.Device, out *Device, s conversio out.BindingConditions = *(*[]string)(unsafe.Pointer(&in.BindingConditions)) out.BindingFailureConditions = *(*[]string)(unsafe.Pointer(&in.BindingFailureConditions)) out.AllowMultipleAllocations = (*bool)(unsafe.Pointer(in.AllowMultipleAllocations)) + out.NodeAllocatableResourceMappings = *(*map[corev1.ResourceName]v1.NodeAllocatableResourceMapping)(unsafe.Pointer(&in.NodeAllocatableResourceMappings)) return nil } diff --git a/vendor/k8s.io/dynamic-resource-allocation/cel/compile.go b/vendor/k8s.io/dynamic-resource-allocation/cel/compile.go index 7d34a4a17f..db9dd114e9 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/cel/compile.go +++ b/vendor/k8s.io/dynamic-resource-allocation/cel/compile.go @@ -56,10 +56,6 @@ var ( lazyCompiler *compiler lazyFeatures Features - // A variant of AnyType = https://github.com/kubernetes/kubernetes/blob/ec2e0de35a298363872897e5904501b029817af3/staging/src/k8s.io/apiserver/pkg/cel/types.go#L550: - // unknown actual type (could be bool, int, string, etc.) but with a known maximum size. - attributeType = withMaxElements(apiservercel.AnyType, resourceapi.DeviceAttributeMaxValueLength) - // Other strings also have a known maximum size. domainType = withMaxElements(apiservercel.StringType, resourceapi.DeviceMaxDomainLength) idType = withMaxElements(apiservercel.StringType, resourceapi.DeviceMaxIDLength) @@ -70,10 +66,6 @@ var ( // actual cost in compile_test.go). multiAllocType = withMaxElements(apiservercel.BoolType, 1) - // Each map is bound by the maximum number of different attributes. - innerAttributesMapType = apiservercel.NewMapType(idType, attributeType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) - outerAttributesMapType = apiservercel.NewMapType(domainType, innerAttributesMapType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) - // Same for capacity. innerCapacityMapType = apiservercel.NewMapType(idType, apiservercel.QuantityDeclType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) outerCapacityMapType = apiservercel.NewMapType(domainType, innerCapacityMapType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) @@ -82,6 +74,7 @@ var ( // Features contains feature gates supported by the package. type Features struct { EnableConsumableCapacity bool + EnableListTypeAttributes bool } func GetCompiler(features Features) *compiler { @@ -110,6 +103,8 @@ type CompilationResult struct { MaxCost uint64 emptyMapVal ref.Val + + features Features } // Device defines the input values for a CEL selector expression. @@ -131,6 +126,13 @@ type compiler struct { // cost estimates version-dependent. deviceType *apiservercel.DeclType envset *environment.EnvSet + + // A variant of AnyType = https://github.com/kubernetes/kubernetes/blob/ec2e0de35a298363872897e5904501b029817af3/staging/src/k8s.io/apiserver/pkg/cel/types.go#L550: + // unknown actual type (could be bool, int, string, etc.) but with a known maximum size. + // If DRAListTypeAttributes is enabled, this also applies to list attributes, so that the cost estimator can take into account the size of the list. + attributeType *apiservercel.DeclType + + features Features } // Options contains several additional parameters @@ -160,6 +162,7 @@ func (c compiler) CompileCELExpression(expression string, options Options) Compi }, Expression: expression, MaxCost: math.MaxUint64, + features: c.features, } } @@ -172,11 +175,24 @@ func (c compiler) CompileCELExpression(expression string, options Options) Compi if issues != nil { return resultError("compilation failed: "+issues.String(), apiservercel.ErrorTypeInvalid) } + + // When the DRAListTypeAttributes feature is enabled, + // we use DynType instead of AnyType for the attributes + // so that standard iterate functions(e.g., exists, all etc.) + // and overridden includes function can work (See newCompiler() for details). + // Thus, the unknown return type can also be DynType, not just AnyType as before. + // + // This has to be valid because the end result of a CEL expression might be + // a boolean attribute, which then has AnyType/DynType. expectedReturnType := cel.BoolType - if ast.OutputType() != expectedReturnType && - ast.OutputType() != cel.AnyType { + if ast.OutputType() == expectedReturnType || + ast.OutputType() == cel.AnyType || + c.features.EnableListTypeAttributes && ast.OutputType() == cel.DynType { + // Okay, is one of the acceptable types. + } else { return resultError(fmt.Sprintf("must evaluate to %v or the unknown type, not %v", expectedReturnType.String(), ast.OutputType().String()), apiservercel.ErrorTypeInvalid) } + _, err = cel.AstToCheckedExpr(ast) if err != nil { // should be impossible since env.Compile returned no issues @@ -200,6 +216,7 @@ func (c compiler) CompileCELExpression(expression string, options Options) Compi Environment: env, emptyMapVal: env.CELTypeAdapter().NativeToValue(map[string]any{}), MaxCost: math.MaxUint64, + features: c.features, } if !options.DisableCostEstimation { @@ -217,14 +234,42 @@ func (c compiler) CompileCELExpression(expression string, options Options) Compi return compilationResult } -func (c *compiler) newCostEstimator() *library.CostEstimator { - return &library.CostEstimator{SizeEstimator: &sizeEstimator{compiler: c}} +func (c *compiler) newCostEstimator() checker.CostEstimator { + base := &library.CostEstimator{SizeEstimator: &sizeEstimator{compiler: c}} + return &draCostEstimator{base: base} } // getAttributeValue returns the native representation of the one value that // should be stored in the attribute, otherwise an error. An error is // also returned when there is no supported value. -func getAttributeValue(attr resourceapi.DeviceAttribute) (any, error) { +// +// If the DRAListTypeAttributes feature is disabled and an attribute +// contains a list value, then we fall through to returning the +// "unsupported attribute value" error below. +// This failure then aborts scheduling until ResourceSlices get updated. +// This is better than incorrectly scheduling a pod +// because that is harder to correct. +func (c CompilationResult) getAttributeValue(attr resourceapi.DeviceAttribute) (any, error) { + if c.features.EnableListTypeAttributes { + switch { + case attr.IntValues != nil: + return attr.IntValues, nil + case attr.BoolValues != nil: + return attr.BoolValues, nil + case attr.StringValues != nil: + return attr.StringValues, nil + case attr.VersionValues != nil: + semVers := make([]apiservercel.Semver, len(attr.VersionValues)) + for i, versionStr := range attr.VersionValues { + v, err := semver.Parse(versionStr) + if err != nil { + return nil, fmt.Errorf("parse semantic version: %w", err) + } + semVers[i] = apiservercel.Semver{Version: v} + } + return semVers, nil + } + } switch { case attr.IntValue != nil: return *attr.IntValue, nil @@ -250,7 +295,7 @@ func (c CompilationResult) DeviceMatches(ctx context.Context, input Device) (boo // which wraps the underlying maps and directly looks up values. attributes := make(map[string]any) for name, attr := range input.Attributes { - value, err := getAttributeValue(attr) + value, err := c.getAttributeValue(attr) if err != nil { return false, nil, fmt.Errorf("attribute %s: %w", name, err) } @@ -312,6 +357,24 @@ func newCompiler(features Features) *compiler { return result } + attributeType := withMaxElements(apiservercel.AnyType, resourceapi.DeviceAttributeMaxValueLength) + if features.EnableListTypeAttributes { + attributeType = withMaxElements( + // use DynType instead of AnyType so that iterate functions can work(e.g., exists, all, etc.) + apiservercel.DynType, + // When DRAListTypeAttributes feature gate is enabled, we cannot + // determine statically whether an attribute will be a scalar or a list + // at compile time. MaxElements should describe + // - the max number of items when it's a list. + // - the max length of the string representation when it's a scalar. + // Thus, we set it to the larger one of the two cases. + uint64(max(resourceapi.DeviceAttributeMaxValueLength, resourceapi.ResourceSliceMaxAttributeValuesPerDevice)), + ) + } + // Each map is bound by the maximum number of different attributes. + innerAttributesMapType := apiservercel.NewMapType(idType, attributeType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) + outerAttributesMapType := apiservercel.NewMapType(domainType, innerAttributesMapType, resourceapi.ResourceSliceMaxAttributesAndCapacitiesPerDevice) + fieldsV131 := []*apiservercel.DeclField{ field(driverVar, driverType, true), field(attributesVar, outerAttributesMapType, true), @@ -363,13 +426,60 @@ func newCompiler(features Features) *compiler { deviceTypeV134ConsumableCapacity, }, }, + { + IntroducedVersion: version.MajorMinor(1, 36), + FeatureEnabled: func() bool { + return features.EnableListTypeAttributes + }, + EnvOptions: []cel.EnvOption{ + cel.Function("includes", + cel.MemberOverload("dra_includes_dyn_dyn", + []*cel.Type{cel.DynType, cel.DynType}, + cel.BoolType, + cel.BinaryBinding(includesFunc), + ), + ), + }, + }, } envset, err := envset.Extend(versioned...) if err != nil { panic(fmt.Errorf("internal error building CEL environment: %w", err)) } // return with newest deviceType - return &compiler{envset: envset, deviceType: deviceTypeV134ConsumableCapacity} + return &compiler{envset: envset, deviceType: deviceTypeV134ConsumableCapacity, features: features, attributeType: attributeType} +} + +// includesFunc implements the "includes" function for CEL (.includes()), +// which checks whether the target includes the argument. +// It supports both singular values and lists. +// +// WARNING: includes is not applicable to lists longer than +// resourceapi.ResourceSliceMaxAttributeValuesPerDevice. A runtime error gets +// returned in that case to prevent unbounded execution cost. +// The target is expected to be a scalar or list attribute, but users can +// technically call "includes" on any value. +func includesFunc(target, arg ref.Val) ref.Val { + if list, ok := target.(traits.Lister); ok { + i := 0 + it := list.Iterator() + for it.HasNext() == types.True { + if i >= resourceapi.ResourceSliceMaxAttributeValuesPerDevice { + return types.NewErr("'includes' function cannot be applied to lists longer than %d values", resourceapi.ResourceSliceMaxAttributeValuesPerDevice) + } + item := it.Next() + if item.Equal(arg) == types.True { + return types.True + } + i++ + } + return types.False + } + + if target.Equal(arg) == types.True { + return types.True + } + return types.False } func withMaxElements(in *apiservercel.DeclType, maxElements uint64) *apiservercel.DeclType { @@ -414,7 +524,29 @@ func (m mapper) Find(key ref.Val) (ref.Val, bool) { return m.defaultValue, true } -// sizeEstimator tells the cost estimator the maximum size of maps or strings accessible through the `device` variable. +// draCostEstimator is a wrapper around the base CEL CostEstimator to provide custom cost estimates for DRA-specific functions and types. +type draCostEstimator struct { + base *library.CostEstimator +} + +func (e *draCostEstimator) EstimateSize(element checker.AstNode) *checker.SizeEstimate { + return e.base.EstimateSize(element) +} + +func (e *draCostEstimator) EstimateCallCost(function, overloadID string, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate { + if function == "includes" && overloadID == "dra_includes_dyn_dyn" { + // ".includes()" is equivalent with " in " + // whose complexity is linear with the size of the target. + if target != nil { + targetSizeEstimate := checker.SizeEstimate{Min: 0, Max: resourceapi.ResourceSliceMaxAttributeValuesPerDevice} + return &checker.CallEstimate{CostEstimate: targetSizeEstimate.MultiplyByCost(checker.CostEstimate{Min: 1, Max: 1})} + } + } + + return e.base.EstimateCallCost(function, overloadID, target, args) +} + +// sizeEstimator tells the cost estimator the maximum size of maps, strings, or lists accessible through the `device` variable. // Without this, the maximum string size of e.g. `device.attributes["dra.example.com"].services` would be unknown. // // sizeEstimator is derived from the sizeEstimator in k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel. @@ -459,8 +591,8 @@ func (s *sizeEstimator) EstimateSize(element checker.AstNode) *checker.SizeEstim // If this is an attribute map, then we know that all elements // have the same maximum size as set in attributeType, regardless // of their name. - if currentNode.ElemType == attributeType { - currentNode = attributeType + if currentNode.ElemType == s.compiler.attributeType { + currentNode = s.compiler.attributeType continue } return nil diff --git a/vendor/k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache/extendedresourcecache.go b/vendor/k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache/extendedresourcecache.go index f70124fd34..96d27fc433 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache/extendedresourcecache.go +++ b/vendor/k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache/extendedresourcecache.go @@ -102,6 +102,7 @@ func (c *ExtendedResourceCache) OnAdd(obj interface{}, isInInitialList bool) { utilruntime.HandleErrorWithLogger(c.logger, nil, "Expected DeviceClass", "actual", fmt.Sprintf("%T", obj)) return } + c.logger.V(5).Info("DeviceClass added", "deviceClass", klog.KObj(deviceClass)) c.updateResourceName2class(deviceClass, nil) c.updateClass2ResourceName(deviceClass) @@ -122,6 +123,7 @@ func (c *ExtendedResourceCache) OnUpdate(oldObj, newObj interface{}) { utilruntime.HandleErrorWithLogger(c.logger, nil, "Expected DeviceClass", "actual", fmt.Sprintf("%T", oldObj)) return } + c.logger.V(5).Info("DeviceClass updated", "deviceClass", klog.KObj(deviceClass)) c.updateResourceName2class(deviceClass, oldDeviceClass) c.updateClass2ResourceName(deviceClass) @@ -140,6 +142,7 @@ func (c *ExtendedResourceCache) OnDelete(obj interface{}) { utilruntime.HandleErrorWithLogger(c.logger, nil, "Expected DeviceClass", "actual", fmt.Sprintf("%T", obj)) return } + c.logger.V(5).Info("DeviceClass deleted", "deviceClass", klog.KObj(deviceClass)) c.removeResourceName2class(deviceClass) c.removeClass2ResourceName(deviceClass) diff --git a/vendor/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go b/vendor/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go index 97ff1a4b4a..e31e223b16 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go +++ b/vendor/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go @@ -31,9 +31,13 @@ import ( v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" ) +const schedulingAPIGroupPrefix = schedulingapi.GroupName + "/" + var ( // ErrAPIUnsupported is wrapped by the actual errors returned by Name and // indicates that none of the required fields are set. @@ -78,27 +82,116 @@ func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) (name *string, mustCheckOw } } -// IsForPod checks that the ResourceClaim is the one that -// was created for the Pod. It returns an error that is informative +// NameFromPodGroup returns the name of the ResourceClaim object that gets +// referenced by or created for the PodGroupResourceClaim. Three different +// results are possible: +// +// - An error is returned when some field is not set as expected (either the +// input is invalid or the API got extended and the library and the client +// using it need to be updated) or the claim hasn't been created yet. +// +// The error includes PodGroup and PodGroup claim name and the unexpected +// field and is derived from one of the pre-defined errors in this package. +// +// - A nil string pointer and no error when the ResourceClaim intentionally +// didn't get created and the PodGroupResourceClaim can be ignored. +// +// - A pointer to the name and no error when the ResourceClaim got created. +// In this case the boolean determines whether IsForPodGroup must be called +// after retrieving the ResourceClaim and before using it. +func NameFromPodGroup(podGroup *schedulingapi.PodGroup, podGroupClaim *schedulingapi.PodGroupResourceClaim) (name *string, mustCheckOwner bool, err error) { + switch { + case podGroupClaim.ResourceClaimName != nil: + return podGroupClaim.ResourceClaimName, false, nil + case podGroupClaim.ResourceClaimTemplateName != nil: + for _, status := range podGroup.Status.ResourceClaimStatuses { + if status.Name == podGroupClaim.Name { + return status.ResourceClaimName, true, nil + } + } + return nil, false, fmt.Errorf("PodGroup %s/%s: %w", podGroup.Namespace, podGroup.Name, ErrClaimNotFound) + default: + return nil, false, fmt.Errorf("PodGroup %s/%s, spec.resourceClaim %s: %w", podGroup.Namespace, podGroup.Name, podGroupClaim.Name, ErrAPIUnsupported) + } +} + +// IsForPod checks that the ResourceClaim is the one that was created for the +// Pod or, if acceptPodGroupOwner is true, its PodGroup. PodGroup owners should +// only be considered when the DRAWorkloadResourceClaims feature gate is +// enabled. It returns an error that is informative enough to be returned by the +// caller without adding further details about the Pod or ResourceClaim. +func IsForPod(pod *v1.Pod, claim *resourceapi.ResourceClaim, acceptPodGroupOwner bool) error { + // Checking the namespaces is just a precaution. The caller should + // never pass in a ResourceClaim that isn't from the same namespace as the + // Pod. + if claim.Namespace != pod.Namespace { + return fmt.Errorf("ResourceClaim %s/%s is not in the same namespace as Pod %s/%s", claim.Namespace, claim.Name, pod.Namespace, pod.Name) + } + if !metav1.IsControlledBy(claim, pod) { + if acceptPodGroupOwner { + if !isForPodGroupByPod(pod, claim) { + return fmt.Errorf("ResourceClaim %s/%s was not created for Pod %s/%s (neither Pod nor PodGroup %s is the owner)", claim.Namespace, claim.Name, pod.Namespace, pod.Name, *pod.Spec.SchedulingGroup.PodGroupName) + } + return nil + } + return fmt.Errorf("ResourceClaim %s/%s was not created for Pod %s/%s (Pod is not owner)", claim.Namespace, claim.Name, pod.Namespace, pod.Name) + } + return nil +} + +// IsForPodGroup checks that the ResourceClaim is the one that +// was created for the PodGroup. It returns an error that is informative // enough to be returned by the caller without adding further details // about the Pod or ResourceClaim. -func IsForPod(pod *v1.Pod, claim *resourceapi.ResourceClaim) error { +func IsForPodGroup(podGroup *schedulingapi.PodGroup, claim *resourceapi.ResourceClaim) error { // Checking the namespaces is just a precaution. The caller should // never pass in a ResourceClaim that isn't from the same namespace as the // Pod. - if claim.Namespace != pod.Namespace || !metav1.IsControlledBy(claim, pod) { - return fmt.Errorf("ResourceClaim %s/%s was not created for pod %s/%s (pod is not owner)", claim.Namespace, claim.Name, pod.Namespace, pod.Name) + if claim.Namespace != podGroup.Namespace { + return fmt.Errorf("ResourceClaim %s/%s is not in the same namespace as PodGroup %s/%s", claim.Namespace, claim.Name, podGroup.Namespace, podGroup.Name) + } + if !metav1.IsControlledBy(claim, podGroup) { + return fmt.Errorf("ResourceClaim %s/%s was not created for PodGroup %s/%s (PodGroup is not owner)", claim.Namespace, claim.Name, podGroup.Namespace, podGroup.Name) } return nil } -// IsReservedForPod checks whether a claim lists the pod as one of the objects -// that the claim was reserved for. -func IsReservedForPod(pod *v1.Pod, claim *resourceapi.ResourceClaim) bool { +// isForPodGroupByPod performs the same function as [IsForPodGroup] by checking +// for the API group, kind, and name of the PodGroup in the claim's +// Status.ReservedFor instead of its UID, which is not known to the Pod. +func isForPodGroupByPod(pod *v1.Pod, claim *resourceapi.ResourceClaim) bool { + if pod.Spec.SchedulingGroup == nil || pod.Spec.SchedulingGroup.PodGroupName == nil { + return false + } + controller := metav1.GetControllerOfNoCopy(claim) + return controller != nil && + controller.Name == *pod.Spec.SchedulingGroup.PodGroupName && + controller.Kind == "PodGroup" && + // The version component of the APIVersion is ignored because that + // may change. The group component is still checked. + strings.HasPrefix(controller.APIVersion, schedulingAPIGroupPrefix) +} + +// IsReservedForPod checks whether a claim lists the Pod as one +// of the objects that the claim was reserved for. When the +// acceptPodGroupReservation parameter is true, it also returns true when the +// claim lists the Pod's PodGroup as one of the objects that the claim was +// reserved for. The acceptPodGroupReservation parameter should only be set when +// the DRAWorkloadResourceClaims feature is enabled. +func IsReservedForPod(pod *v1.Pod, claim *resourceapi.ResourceClaim, acceptPodGroupReservation bool) bool { for _, reserved := range claim.Status.ReservedFor { if reserved.UID == pod.UID { return true } + // Pods don't know the UID of their PodGroup, so we check all the + // other fields of the reservation that it does know. + if acceptPodGroupReservation && reserved.APIGroup == schedulingapi.GroupName && + reserved.Resource == "podgroups" && + pod.Spec.SchedulingGroup != nil && + pod.Spec.SchedulingGroup.PodGroupName != nil && + reserved.Name == *pod.Spec.SchedulingGroup.PodGroupName { + return true + } } return false } @@ -109,6 +202,46 @@ func CanBeReserved(claim *resourceapi.ResourceClaim) bool { return true } +// BindTo constructs a consumer reference for the claim that refers to the +// object to which the claim should be bound. When the PodResourceClaim Name, +// ResourceClaimName, and ResourceClaimTemplateName match those of one of the +// PodGroup's PodGroupResourceClaims, the claim is bound to the PodGroup. +// Otherwise, the claim is bound to the Pod. The podGroup parameter should only +// be non-nil when the DRAWorkloadResourceClaims feature gate is enabled. +func BindTo(pod *v1.Pod, podGroup *schedulingapi.PodGroup, podClaim *v1.PodResourceClaim) (resourceapi.ResourceClaimConsumerReference, error) { + if podClaim.ResourceClaimName == nil && + podClaim.ResourceClaimTemplateName == nil { + return resourceapi.ResourceClaimConsumerReference{}, fmt.Errorf("Pod %s/%s claim %s: %w", pod.Namespace, pod.Name, podClaim.Name, ErrAPIUnsupported) + } + if podGroup != nil { + if err := podMatchesPodGroup(pod, podGroup); err != nil { + return resourceapi.ResourceClaimConsumerReference{}, err + } + for _, podGroupClaim := range podGroup.Spec.ResourceClaims { + if podGroupClaim.ResourceClaimName == nil && + podGroupClaim.ResourceClaimTemplateName == nil { + return resourceapi.ResourceClaimConsumerReference{}, fmt.Errorf("PodGroup %s/%s claim %s: %w", podGroup.Namespace, podGroup.Name, podGroupClaim.Name, ErrAPIUnsupported) + } + if podGroupClaim.Name == podClaim.Name && + ptr.Equal(podGroupClaim.ResourceClaimName, podClaim.ResourceClaimName) && + ptr.Equal(podGroupClaim.ResourceClaimTemplateName, podClaim.ResourceClaimTemplateName) { + return resourceapi.ResourceClaimConsumerReference{ + APIGroup: schedulingapi.GroupName, + Resource: "podgroups", + Name: podGroup.Name, + UID: podGroup.UID, + }, nil + } + } + } + return resourceapi.ResourceClaimConsumerReference{ + APIGroup: v1.GroupName, + Resource: "pods", + Name: pod.Name, + UID: pod.UID, + }, nil +} + // BaseRequestRef returns the request name if the reference is to a top-level // request and the name of the parent request if the reference is to a subrequest. func BaseRequestRef(requestRef string) string { @@ -154,3 +287,13 @@ func isMatch(requests []string, requestRef string) bool { baseRequestRef := BaseRequestRef(requestRef) return slices.Contains(requests, baseRequestRef) } + +func podMatchesPodGroup(pod *v1.Pod, podGroup *schedulingapi.PodGroup) error { + if pod.Spec.SchedulingGroup == nil || pod.Spec.SchedulingGroup.PodGroupName == nil { + return fmt.Errorf("Pod %s/%s does not belong to a PodGroup", pod.Namespace, pod.Name) + } + if schedGroupPodGroup := *pod.Spec.SchedulingGroup.PodGroupName; pod.Namespace != podGroup.Namespace || schedGroupPodGroup != podGroup.Name { + return fmt.Errorf("Pod %s/%s belongs to PodGroup %s/%s, not PodGroup %s/%s", pod.Namespace, pod.Name, pod.Namespace, schedGroupPodGroup, podGroup.Namespace, podGroup.Name) + } + return nil +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/resourceslice/tracker/tracker.go b/vendor/k8s.io/dynamic-resource-allocation/resourceslice/tracker/tracker.go index 5ca9719b28..9941a38c3f 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/resourceslice/tracker/tracker.go +++ b/vendor/k8s.io/dynamic-resource-allocation/resourceslice/tracker/tracker.go @@ -31,7 +31,7 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" resourceinformers "k8s.io/client-go/informers/resource/v1" - resourcealphainformers "k8s.io/client-go/informers/resource/v1alpha3" + resourcebetainformers "k8s.io/client-go/informers/resource/v1beta2" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" v1core "k8s.io/client-go/kubernetes/typed/core/v1" @@ -71,8 +71,16 @@ type Tracker struct { // may be overridden in tests. handleError func(context.Context, error, string, ...any) + // wg and cancel track resp. kill goroutines. + wg sync.WaitGroup + cancel func(error) + // Synchronizes updates to these fields related to event handlers. rwMutex sync.RWMutex + + // synced gets closed once all the tracker's event handlers are synced. + synced chan struct{} + // All registered event handlers. eventHandlers []cache.ResourceEventHandler // The eventQueue contains functions which deliver an event to one @@ -111,7 +119,7 @@ type Options struct { EnableConsumableCapacity bool SliceInformer resourceinformers.ResourceSliceInformer - TaintInformer resourcealphainformers.DeviceTaintRuleInformer + TaintInformer resourcebetainformers.DeviceTaintRuleInformer ClassInformer resourceinformers.DeviceClassInformer // KubeClient is used to generate Events when CEL expressions @@ -155,6 +163,8 @@ func newTracker(ctx context.Context, opts Options) (finalT *Tracker, finalErr er deviceClasses: opts.ClassInformer.Informer(), patchedResourceSlices: cache.NewStore(cache.MetaNamespaceKeyFunc), handleError: utilruntime.HandleErrorWithContext, + synced: make(chan struct{}), + cancel: func(error) {}, // Real function set in initInformers. eventQueue: *buffer.NewRing[func()](buffer.RingOptions{InitialSize: 0, NormalSize: 4}), } defer func() { @@ -212,6 +222,22 @@ func (t *Tracker) initInformers(ctx context.Context) error { return fmt.Errorf("add event handler for DeviceClasses: %w", err) } + // This usually short-lived goroutines monitors our upstream event handlers and + // closes our own synced channel when they are synced. + monitorCtx, cancel := context.WithCancelCause(ctx) + t.cancel = cancel + t.wg.Go(func() { + for _, handle := range []cache.ResourceEventHandlerRegistration{t.resourceSlicesHandle, t.deviceTaintsHandle, t.deviceClassesHandle} { + select { + case <-handle.HasSyncedChecker().Done(): + case <-monitorCtx.Done(): + // Abort without closing our synced channel. + return + } + } + close(t.synced) + }) + return nil } @@ -220,21 +246,28 @@ func (t *Tracker) initInformers(ctx context.Context) error { // point is possible and will emit events with up-to-date ResourceSlice // objects. func (t *Tracker) HasSynced() bool { - if !t.enableDeviceTaintRules { - return t.resourceSlices.HasSynced() - } - - if t.resourceSlicesHandle != nil && !t.resourceSlicesHandle.HasSynced() { - return false - } - if t.deviceTaintsHandle != nil && !t.deviceTaintsHandle.HasSynced() { + select { + case <-t.HasSyncedChecker().Done(): + return true + default: return false } - if t.deviceClassesHandle != nil && !t.deviceClassesHandle.HasSynced() { - return false +} + +func (t *Tracker) HasSyncedChecker() cache.DoneChecker { + if !t.enableDeviceTaintRules { + return t.resourceSlices.HasSyncedChecker() } - return true + return trackerHasSynced{t} +} + +type trackerHasSynced struct{ t *Tracker } + +func (s trackerHasSynced) Name() string { return "ResourceSlice tracker" } + +func (s trackerHasSynced) Done() <-chan struct{} { + return s.t.synced } // Stop ends all background activity and blocks until that shutdown is complete. @@ -243,12 +276,16 @@ func (t *Tracker) Stop() { return } + t.cancel(errors.New("stopped")) + if t.broadcaster != nil { t.broadcaster.Shutdown() } _ = t.resourceSlices.RemoveEventHandler(t.resourceSlicesHandle) _ = t.deviceTaints.RemoveEventHandler(t.deviceTaintsHandle) _ = t.deviceClasses.RemoveEventHandler(t.deviceClassesHandle) + + t.wg.Wait() } // ListPatchedResourceSlices returns all ResourceSlices in the cluster with @@ -320,7 +357,6 @@ func (t *Tracker) pushEvent(oldObj, newObj any) { t.rwMutex.Lock() defer t.rwMutex.Unlock() for _, handler := range t.eventHandlers { - handler := handler if oldObj == nil { t.eventQueue.WriteOne(func() { handler.OnAdd(newObj, false) diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/allocator.go b/vendor/k8s.io/dynamic-resource-allocation/structured/allocator.go index 82b9d153d5..e4f2d72b5e 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/allocator.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/allocator.go @@ -227,7 +227,7 @@ var availableAllocators = []struct { slices []*resourceapi.ResourceSlice, celCache *cel.Cache, ) (Allocator, error) { - return incubating.NewAllocator(ctx, features, allocatedState.AllocatedDevices, classLister, slices, celCache) + return incubating.NewAllocator(ctx, features, allocatedState, classLister, slices, celCache) }, nodeMatches: incubating.NodeMatches, }, @@ -260,32 +260,7 @@ func NodeMatches(features Features, node *v1.Node, nodeNameToMatch string, allNo return false, fmt.Errorf("internal error: no NodeMatches implementation available for feature set %v", features) } -// IsDeviceAllocated checks if a device is allocated, considering both fully allocated devices -// and partially consumed devices when consumable capacity is enabled. +// IsDeviceAllocated checks if a device has committed allocation state. func IsDeviceAllocated(deviceID DeviceID, allocatedState *AllocatedState) bool { - // Check if device is fully allocated (traditional case) - if allocatedState.AllocatedDevices.Has(deviceID) { - return true - } - - // Check if device is partially consumed via shared allocations (consumable capacity case). - // We need to check if any shared device ID corresponds to our device. - for sharedDeviceID := range allocatedState.AllocatedSharedDeviceIDs { - // Extract the base device ID from the shared device ID by recreating it - baseDeviceID := MakeDeviceID( - sharedDeviceID.Driver.String(), - sharedDeviceID.Pool.String(), - sharedDeviceID.Device.String(), - ) - if baseDeviceID == deviceID { - return true - } - } - - // Check if device has consumed capacity tracked (consumable capacity case) - if _, hasConsumedCapacity := allocatedState.AggregatedCapacity[deviceID]; hasConsumedCapacity { - return true - } - - return false + return internal.IsDeviceAllocated(deviceID, allocatedState) } diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/allocatedstate.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/allocatedstate.go index ad7ec44585..d02b916ec7 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/allocatedstate.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/allocatedstate.go @@ -58,6 +58,32 @@ func NewDeviceConsumedCapacity(deviceID DeviceID, consumedCapacity map[resourcea return schedulerapi.NewDeviceConsumedCapacity(deviceID, consumedCapacity) } +// IsDeviceAllocated checks if a device is allocated, considering both fully allocated devices +// and partially consumed devices when consumable capacity is enabled. +func IsDeviceAllocated(deviceID DeviceID, allocatedState *AllocatedState) bool { + // Check if device is fully allocated (traditional case). + if allocatedState.AllocatedDevices.Has(deviceID) { + return true + } + + // Check if device is partially consumed via shared allocations (consumable capacity case). + // We need to check if any shared device ID corresponds to our device. + for sharedDeviceID := range allocatedState.AllocatedSharedDeviceIDs { + if sharedDeviceID.GetDeviceID() == deviceID { + return true + } + } + + // For scheduler-generated state, consumed capacity is recorded together with + // a shared device ID. Keep this check to preserve IsDeviceAllocated semantics + // and handle manually constructed or future AllocatedState producers. + if _, hasConsumedCapacity := allocatedState.AggregatedCapacity[deviceID]; hasConsumedCapacity { + return true + } + + return false +} + // GenerateShareID is a helper function that generates a new share ID. // This remains in the internal package as it's a utility function. func GenerateShareID() *types.UID { diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/allocator_experimental.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/allocator_experimental.go index fd63fff1e8..d2a2ecb92a 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/allocator_experimental.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/allocator_experimental.go @@ -48,7 +48,6 @@ func MakeDeviceID(driver, pool, device string) DeviceID { return internal.MakeDeviceID(driver, pool, device) } -// types_experimental type SharedDeviceID = internal.SharedDeviceID type DeviceConsumedCapacity = internal.DeviceConsumedCapacity type ConsumedCapacityCollection = internal.ConsumedCapacityCollection @@ -82,13 +81,16 @@ var SupportedFeatures = internal.Features{ DeviceTaints: true, DeviceBindingAndStatus: true, ConsumableCapacity: true, + ListTypeAttributes: true, } type Allocator struct { features Features allocatedState AllocatedState classLister DeviceClassLister - slices []*resourceapi.ResourceSlice + slicesOnNode map[string][]*resourceapi.ResourceSlice + slicesShared []*resourceapi.ResourceSlice + allSlices []*resourceapi.ResourceSlice celCache *cel.Cache // availableCounters contains the available counters for each // resource pool. It acts as a cache that is updated the first time @@ -121,16 +123,32 @@ func NewAllocator(ctx context.Context, slices []*resourceapi.ResourceSlice, celCache *cel.Cache, ) (*Allocator, error) { + slicesOnNode := make(map[string][]*resourceapi.ResourceSlice) + slicesShared := make([]*resourceapi.ResourceSlice, 0) + for _, slice := range slices { + nodeName := ptr.Deref(slice.Spec.NodeName, "") + if nodeName == "" || len(slice.Spec.SharedCounters) > 0 { + slicesShared = append(slicesShared, slice) + } else { + slicesOnNode[nodeName] = append(slicesOnNode[nodeName], slice) + } + } return &Allocator{ features: features, allocatedState: allocatedState, classLister: classLister, - slices: slices, + slicesOnNode: slicesOnNode, + slicesShared: slicesShared, + allSlices: slices, celCache: celCache, availableCounters: make(map[draapi.UniqueString]counterSets), }, nil } +func (a *Allocator) Channel() internal.AllocatorChannel { + return internal.Experimental +} + func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resourceapi.ResourceClaim) (finalResult []resourceapi.AllocationResult, finalErr error) { alloc := &allocator{ Allocator: a, @@ -145,23 +163,19 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou result: make([]internalAllocationResult, len(claims)), allocatingCapacity: NewConsumedCapacityCollection(), } - alloc.logger.V(5).Info("Starting allocation", "numClaims", len(alloc.claimsToAllocate), "numSlices", len(alloc.slices)) + slicesForNode := slices.Concat(alloc.slicesOnNode[node.Name], alloc.slicesShared) + alloc.logger.V(5).Info("Starting allocation", "numClaims", len(alloc.claimsToAllocate), "numSlicesForNode", len(slicesForNode)) defer func() { alloc.logger.V(5).Info("Done with allocation", "success", len(finalResult) == len(alloc.claimsToAllocate), "err", finalErr) }() - alloc.logger.V(5).Info("Gathering pools", "slices", alloc.slices) // First determine all eligible pools. - pools, err := GatherPools(ctx, alloc.slices, node, a.features) + pools, err := GatherPools(ctx, slicesForNode, node, a.features, alloc.allSlices) if err != nil { return nil, fmt.Errorf("gather pool information: %w", err) } alloc.pools = pools - if loggerV := alloc.logger.V(7); loggerV.Enabled() { - loggerV.Info("Gathered pool information", "numPools", len(pools), "pools", pools) - } else { - alloc.logger.V(5).Info("Gathered pool information", "numPools", len(pools)) - } + alloc.logger.V(5).Info("Gathered pool information", "pools", logPools(alloc.logger, pools)) // We allocate one claim after the other and for each claim, all of // its requests. For each individual device we pick one possible @@ -229,12 +243,12 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // We can only predict a lower number of devices because it depends on which // subrequest gets chosen. for i, subReq := range request.FirstAvailable { + requestKey.subRequestIndex = i reqData, err := alloc.validateDeviceRequest(&deviceSubRequestAccessor{subRequest: &subReq}, &exactDeviceRequestAccessor{request: request}, requestKey, pools) if err != nil { return nil, err } - requestKey.subRequestIndex = i alloc.requestData[requestKey] = reqData if reqData.numDevices < minDevicesPerRequest { minDevicesPerRequest = reqData.numDevices @@ -279,6 +293,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou logger: logger, requestNames: sets.New(constraint.Requests...), attributeName: matchAttribute, + features: a.features, } constraints[i] = m case constraint.DistinctAttribute != nil: @@ -292,6 +307,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou logger: logger, requestNames: sets.New(constraint.Requests...), attributeName: distinctAttribute, + features: a.features, attributes: make(map[string]resourceapi.DeviceAttribute), } constraints[i] = m @@ -314,7 +330,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // We can estimate the size based on what we need to allocate. alloc.allocatingDevices = make(map[DeviceID]sets.Set[int], minDevicesTotal) - alloc.logger.V(6).Info("Gathered information about devices", "numAllocated", len(alloc.allocatedState.AllocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) + alloc.logger.V(6).Info("Gathered information about devices", "numAllocatedDevices", len(alloc.allocatedState.AllocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) // In practice, there aren't going to be many different CEL // expressions. Most likely, there is going to be handful of different @@ -329,7 +345,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // All errors get created such that they can be returned by Allocate // without further wrapping. - done, err := alloc.allocateOne(deviceIndices{}, false) + done, err := alloc.allocateOne(deviceIndices{}, false, deviceLocation{}) if errors.Is(err, errStop) { return nil, nil } @@ -552,6 +568,7 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq id: DeviceID{Driver: slice.Spec.Driver, Pool: slice.Spec.Pool.Name, Device: slice.Spec.Devices[deviceIndex].Name}, Device: &slice.Spec.Devices[deviceIndex], slice: slice, + pool: pool, } if alloc.features.ConsumableCapacity { // Next validate whether resource request over capacity @@ -651,6 +668,13 @@ type deviceIndices struct { deviceIndex int // The index of a device within a request or subrequest. } +// deviceLocation identifies a device by its position in the allocator's pools. +type deviceLocation struct { + poolIndex int + sliceIndex int + deviceIndex int +} + type requestData struct { // The request or subrequest which needs to be allocated. // Never nil. @@ -740,6 +764,97 @@ type constraint interface { remove(requestName, subRequestName string, device *draapi.Device, deviceID DeviceID) } +// deviceAttributeListAsSet is set-based representation of DeviceAttributeListType. +// This has the same structure as DeviceAttributeListType, but uses sets.Set instead of slices. +type deviceAttributeListAsSet struct { + intValue sets.Set[int64] + boolValue sets.Set[bool] + stringValue sets.Set[string] + versionValue sets.Set[string] +} + +// hasIntersection checks if two attribute sets have common elements. +// Returns true if there is at least one common element. +func (s *deviceAttributeListAsSet) hasIntersection(other *deviceAttributeListAsSet) bool { + if s == nil || other == nil { + return false + } + + switch { + case s.intValue != nil && other.intValue != nil: + return s.intValue.Intersection(other.intValue).Len() > 0 + case s.boolValue != nil && other.boolValue != nil: + return s.boolValue.Intersection(other.boolValue).Len() > 0 + case s.stringValue != nil && other.stringValue != nil: + return s.stringValue.Intersection(other.stringValue).Len() > 0 + case s.versionValue != nil && other.versionValue != nil: + return s.versionValue.Intersection(other.versionValue).Len() > 0 + default: + // Type mismatch + return false + } +} + +// updateToIntersection updates current set to intersection with the given set. +func (s *deviceAttributeListAsSet) updateToIntersection(other *deviceAttributeListAsSet) { + if s == nil || other == nil { + return + } + + switch { + case s.intValue != nil && other.intValue != nil: + s.intValue = s.intValue.Intersection(other.intValue) + case s.boolValue != nil && other.boolValue != nil: + s.boolValue = s.boolValue.Intersection(other.boolValue) + case s.stringValue != nil && other.stringValue != nil: + s.stringValue = s.stringValue.Intersection(other.stringValue) + case s.versionValue != nil && other.versionValue != nil: + s.versionValue = s.versionValue.Intersection(other.versionValue) + } +} + +// attributeAsSet creates deviceAttributeListAsSet from DeviceAttribute. +// Both scalar and list attributes are converted to set representation. +// For scalar values, creates a single-element set. +// For list values, creates a set from all elements. +// Returns nil if the attribute type is unknown or empty. +func attributeAsSet(attribute *resourceapi.DeviceAttribute) *deviceAttributeListAsSet { + if attribute == nil { + return nil + } + + result := &deviceAttributeListAsSet{} + + switch { + case len(attribute.IntValues) > 0: + result.intValue = sets.New(attribute.IntValues...) + return result + case len(attribute.BoolValues) > 0: + result.boolValue = sets.New(attribute.BoolValues...) + return result + case len(attribute.StringValues) > 0: + result.stringValue = sets.New(attribute.StringValues...) + return result + case len(attribute.VersionValues) > 0: + result.versionValue = sets.New(attribute.VersionValues...) + return result + case attribute.IntValue != nil: + result.intValue = sets.New(*attribute.IntValue) + return result + case attribute.BoolValue != nil: + result.boolValue = sets.New(*attribute.BoolValue) + return result + case attribute.StringValue != nil: + result.stringValue = sets.New(*attribute.StringValue) + return result + case attribute.VersionValue != nil: + result.versionValue = sets.New(*attribute.VersionValue) + return result + default: + return nil + } +} + // matchAttributeConstraint compares an attribute value across devices. // All devices must share the same value. When the set of devices is // empty, any device that has the attribute can be added. After that, @@ -751,8 +866,14 @@ type matchAttributeConstraint struct { logger klog.Logger // Includes name and attribute name, so no need to repeat in log messages. requestNames sets.Set[string] attributeName resourceapi.FullyQualifiedName + features Features + + // For scalar values (existing behavior) + attribute *resourceapi.DeviceAttribute + + // For list values (when DRAListTypeAttributes feature gate is enabled) + intersection *deviceAttributeListAsSet - attribute *resourceapi.DeviceAttribute numDevices int } @@ -772,40 +893,68 @@ func (m *matchAttributeConstraint) add(requestName, subRequestName string, devic if m.numDevices == 0 { // The first device can always get picked. - m.attribute = attribute + // Initialize either scalar attribute or list set based on the attribute type. + if m.features.ListTypeAttributes { + // Convert attribute to set representation (both scalar and list) + m.intersection = attributeAsSet(attribute) + if m.intersection == nil { + m.logger.V(7).Info("Attribute type unknown") + return false + } + } else { + // Scalar attribute: use existing behavior + m.attribute = attribute + } m.numDevices = 1 m.logger.V(7).Info("First in set") return true } - switch { - case attribute.StringValue != nil: - if m.attribute.StringValue == nil || *attribute.StringValue != *m.attribute.StringValue { - m.logger.V(7).Info("String values different") - return false - } - case attribute.IntValue != nil: - if m.attribute.IntValue == nil || *attribute.IntValue != *m.attribute.IntValue { - m.logger.V(7).Info("Int values different") + // Check if we are matching with set-based logic or scalar-based logic + if m.features.ListTypeAttributes { + // Set-based matching: check if there is non-empty intersection + newSet := attributeAsSet(attribute) + if newSet == nil { + m.logger.V(7).Info("Unknown attribute type") return false } - case attribute.BoolValue != nil: - if m.attribute.BoolValue == nil || *attribute.BoolValue != *m.attribute.BoolValue { - m.logger.V(7).Info("Bool values different") + if !m.intersection.hasIntersection(newSet) { + m.logger.V(7).Info("Attribute values have no common elements") return false } - case attribute.VersionValue != nil: - // semver 2.0.0 requires that version strings are in their - // minimal form (in particular, no leading zeros). Therefore a - // strict "exact equal" check can do a string comparison. - if m.attribute.VersionValue == nil || *attribute.VersionValue != *m.attribute.VersionValue { - m.logger.V(7).Info("Version values different") + // Update to intersection + m.intersection.updateToIntersection(newSet) + } else { + // Scalar matching: use existing behavior + switch { + case attribute.StringValue != nil: + if m.attribute.StringValue == nil || *attribute.StringValue != *m.attribute.StringValue { + m.logger.V(7).Info("String values different") + return false + } + case attribute.IntValue != nil: + if m.attribute.IntValue == nil || *attribute.IntValue != *m.attribute.IntValue { + m.logger.V(7).Info("Int values different") + return false + } + case attribute.BoolValue != nil: + if m.attribute.BoolValue == nil || *attribute.BoolValue != *m.attribute.BoolValue { + m.logger.V(7).Info("Bool values different") + return false + } + case attribute.VersionValue != nil: + // semver 2.0.0 requires that version strings are in their + // minimal form (in particular, no leading zeros). Therefore a + // strict "exact equal" check can do a string comparison. + if m.attribute.VersionValue == nil || *attribute.VersionValue != *m.attribute.VersionValue { + m.logger.V(7).Info("Version values different") + return false + } + default: + // Unknown value type, cannot match. + m.logger.V(7).Info("Unknown attribute type") return false } - default: - // Unknown value type, cannot match. - m.logger.V(7).Info("Match attribute type unknown") - return false } m.numDevices++ @@ -864,7 +1013,24 @@ func lookupAttribute(device *draapi.Device, deviceID DeviceID, attributeName res // allocateSubRequest is true when trying to allocate one particular subrequest. // This allows the logic for subrequests to call allocateOne with the same // device index without causing infinite recursion. -func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (bool, error) { +// +// startLocation provides the starting point when searching for the next device to +// allocate. Since we have a list of pools, each with a list of slices which again +// contains a list of devices, we have defined an order in which the devices will +// be attempted for allocation. Since the order of devices doesn't matter within a +// single request, we want to make sure we only attempt all combinations of devices, +// and not search through all permutations (since many of them will have the same set +// of devices and therefore be identical allocations). Note that the order of devices +// does matter across requests and claims. So by providing the startLocation, we +// make sure that the allocator only attempts allocations that follows the order +// of the available devices, thereby avoiding different permutations. For example, +// this means that for the devices [1, 2, 3], we will only attempt the following +// possible allocations [1], [2], [3], [1, 2], [1, 3], [2, 3], and [1, 2, 3]. +// +// The null startLocation (= all indices zero) means that all devices are considered. +// The only situation where a non-null startLocation is used is when looking for the +// next device within the same request. +func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool, startLocation deviceLocation) (bool, error) { alloc.numAllocateOneInvocations.Add(1) if alloc.ctx.Err() != nil { @@ -882,7 +1048,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b claim := alloc.claimsToAllocate[r.claimIndex] if r.requestIndex >= len(claim.Spec.Devices.Requests) { // Done with the claim, continue with the next one. - success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false, deviceLocation{}) if errors.Is(err, errAllocationResultMaxSizeExceeded) { // We don't need to propagate this further because // this is not a fatal error. Retrying the claim under @@ -929,7 +1095,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b } r.subRequestIndex = subRequestIndex - success, err := alloc.allocateOne(r, true /* prevent infinite recusion */) + success, err := alloc.allocateOne(r, true /* prevent infinite recusion */, deviceLocation{}) // If we reached the allocation result limit, we can try // with the next subrequest if there is one. It might request // fewer devices, so it might succeed. @@ -970,7 +1136,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // Done with request, continue with next one. We have completed the work for // the request or subrequest, so we can no longer be allocating devices for // a subrequest. - success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false, deviceLocation{}) // We want to propagate any errAllocationResultMaxSizeExceeded to the caller. If // that error is returned here, it means none of the requests/subrequests after this one // could be allocated while staying within the limit on the number of devices, so there @@ -1009,7 +1175,8 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // get all of them, then there is no solution and we have to stop. return false, nil } - done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest) + // No need to propagate the startLocation here since we only try one combination of devices. + done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, subRequestIndex: r.subRequestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest, deviceLocation{}) if err != nil || !done { // If we get an error or didn't complete, we need to backtrack. Depending // on the situation we might be able to retry, so we make sure we @@ -1021,15 +1188,33 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b } // We need to find suitable devices. - for _, pool := range alloc.pools { + for poolIndex := startLocation.poolIndex; poolIndex < len(alloc.pools); poolIndex++ { + pool := alloc.pools[poolIndex] // We don't allocate devices from invalid or incomplete pools, but // don't error out here since there might be available devices in other // pools. if pool.IsIncomplete || pool.IsInvalid { continue } - for _, slice := range pool.DeviceSlicesTargetingNode { - for deviceIndex := range slice.Spec.Devices { + // We should start at the slice provided by startLocation unless we searched through + // all devices in the previous pool and have started at the next pool. When this happens, + // we should start at the first slice in the pool. + sliceStart := 0 + if poolIndex == startLocation.poolIndex { + sliceStart = startLocation.sliceIndex + } + for sliceIndex := sliceStart; sliceIndex < len(pool.DeviceSlicesTargetingNode); sliceIndex++ { + slice := pool.DeviceSlicesTargetingNode[sliceIndex] + + // We should start at the device provided by startLocation unless we searched through + // all devices in the previous slice and have started at the next slice. When this happens, + // we should start at the first device in the pool. + deviceStart := 0 + if poolIndex == startLocation.poolIndex && + sliceIndex == startLocation.sliceIndex { + deviceStart = startLocation.deviceIndex + } + for deviceIndex := deviceStart; deviceIndex < len(slice.Spec.Devices); deviceIndex++ { deviceID := DeviceID{Driver: pool.Driver, Pool: pool.Pool, Device: slice.Spec.Devices[deviceIndex].Name} // Checking for "in use" is cheap and thus gets done first. @@ -1089,7 +1274,16 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b subRequestIndex: r.subRequestIndex, deviceIndex: r.deviceIndex + 1, } - done, err := alloc.allocateOne(deviceKey, allocateSubRequest) + nextLocation := deviceLocation{ + poolIndex: poolIndex, + sliceIndex: sliceIndex, + deviceIndex: deviceIndex + 1, + } + // This is the allocation attempt for the next device in the same request. + // If allocateOne finds out that it is done with the request, it moves to + // the next without setting a start location, so each request is free to try + // all devices. + done, err := alloc.allocateOne(deviceKey, allocateSubRequest, nextLocation) // If we found a solution, we can stop. if err == nil && done { return done, nil @@ -1456,7 +1650,7 @@ func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error } // Devices that aren't allocated doesn't consume any counters, so we don't // need to consider them. - if !alloc.allocatedState.AllocatedDevices.Has(deviceID) { + if !internal.IsDeviceAllocated(deviceID, &alloc.allocatedState) { continue } for _, deviceCounterConsumption := range device.ConsumesCounters { diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/constraint.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/constraint.go index f528832faa..307584ef86 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/constraint.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/constraint.go @@ -36,6 +36,7 @@ type distinctAttributeConstraint struct { logger klog.Logger // Includes name and attribute name, so no need to repeat in log messages. requestNames sets.Set[string] attributeName resourceapi.FullyQualifiedName + features Features attributes map[string]resourceapi.DeviceAttribute numDevices int @@ -93,6 +94,37 @@ func (m *distinctAttributeConstraint) matches(requestName, subRequestName string } func (m *distinctAttributeConstraint) matchesAttribute(attribute resourceapi.DeviceAttribute) bool { + if m.features.ListTypeAttributes { + // Set-based comparison for ListAttributes feature: + // Check that the new device's attribute set is disjoint from all existing devices. + // This implements "Pairwise Disjoint" semantics for distinct attributes. + newSet := attributeAsSet(&attribute) + if newSet == nil { + m.logger.V(7).Info("Unknown attribute type") + return false + } + + // Check that the new device is disjoint from each existing device + for _, attr := range m.attributes { + existingSet := attributeAsSet(&attr) + if existingSet == nil { + continue + } + if newSet.hasIntersection(existingSet) { + // New device has common elements with an existing device. + // This violates the distinct constraint. + m.logger.V(7).Info("Constraint not satisfied, devices have common elements") + return false + } + } + + // New device is disjoint from all existing devices. + // The constraint is satisfied. + m.logger.V(7).Info("Constraint satisfied, new device is disjoint from all existing devices") + return true + } + + // Scalar comparison (existing behavior) for _, attr := range m.attributes { switch { case attribute.StringValue != nil: diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/pools_experimental.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/pools_experimental.go index bd265d69c6..b71c29505f 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/pools_experimental.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/experimental/pools_experimental.go @@ -17,14 +17,19 @@ limitations under the License. package experimental import ( + "cmp" "context" "fmt" + "slices" + + "github.com/go-logr/logr" v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" draapi "k8s.io/dynamic-resource-allocation/api" + "k8s.io/klog/v2" "k8s.io/utils/ptr" ) @@ -51,39 +56,27 @@ func NodeMatches(node *v1.Node, nodeNameToMatch string, allNodesMatch bool, node // Out-dated slices are silently ignored. Pools may be incomplete (not all // required slices available) or invalid (for example, device names not unique). // Both is recorded in the result. -func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node *v1.Node, features Features) ([]*Pool, error) { +func GatherPools(ctx context.Context, slicesForNode []*resourceapi.ResourceSlice, node *v1.Node, features Features, allSlices []*resourceapi.ResourceSlice) ([]*Pool, error) { pools := make(map[PoolID][]*draapi.ResourceSlice) - var slicesWithBindingConditions []*resourceapi.ResourceSlice - for _, slice := range slices { + for _, slice := range slicesForNode { if !features.PartitionableDevices && (slice.Spec.PerDeviceNodeSelection != nil || len(slice.Spec.SharedCounters) > 0) { continue } + // Determine if the slice is relevant for the node. + relevant := false + // Always include slices with SharedCounters since they are needed to use a pool // regardless of their node selector. if len(slice.Spec.SharedCounters) > 0 { - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } + relevant = true } else if nodeName, allNodes := ptr.Deref(slice.Spec.NodeName, ""), ptr.Deref(slice.Spec.AllNodes, false); nodeName != "" || allNodes || slice.Spec.NodeSelector != nil { match, err := NodeMatches(node, nodeName, allNodes, slice.Spec.NodeSelector) if err != nil { return nil, fmt.Errorf("failed to perform node selection for slice %s: %w", slice.Name, err) } - if match { - if hasBindingConditions(slice) { - // If there is a Device in the ResourceSlice that contains BindingConditions, - // the ResourceSlice should be sorted to be after the ResourceSlice without BindingConditions - // because then the allocation is going to prefer the simpler devices without - // binding conditions. - slicesWithBindingConditions = append(slicesWithBindingConditions, slice) - continue - } - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } - } + relevant = match } else if ptr.Deref(slice.Spec.PerDeviceNodeSelection, false) { for _, device := range slice.Spec.Devices { match, err := NodeMatches(node, ptr.Deref(device.NodeName, ""), ptr.Deref(device.AllNodes, false), device.NodeSelector) @@ -92,15 +85,7 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node device.String(), slice.Name, err) } if match { - if hasBindingConditions(slice) { - // If there is a Device in the ResourceSlice that contains BindingConditions, - // the ResourceSlice should be sorted to be after the ResourceSlice without BindingConditions. - slicesWithBindingConditions = append(slicesWithBindingConditions, slice) - break - } - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } + relevant = true break } } @@ -115,11 +100,10 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node continue } - } - - for _, slice := range slicesWithBindingConditions { - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) + if relevant { + if err := addSlice(pools, slice); err != nil { + return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) + } } } @@ -151,7 +135,7 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node // which were filtered out above because their node selection made them look irrelevant // for the current node. This is necessary for "allocate all" mode (it rejects incomplete // pools). - isObsolete, allSlicesForPool := checkSlicesInPool(slices, poolID, slicesForPool[0].Spec.Pool.Generation) + isObsolete, allSlicesForPool := checkSlicesInPool(allSlices, poolID, slicesForPool[0].Spec.Pool.Generation) if isObsolete { // A more thorough check determined that the DRA driver is in the process // of replacing the current generation. The newer one didn't have any slice @@ -188,6 +172,13 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node } result = append(result, pool) } + + // Sort pools by ID to ensure a deterministic allocation order. + // Because the allocator uses a first-fit search, this allows driver authors + // to influence prioritization through their naming conventions. + sortPoolsByID(result) + sortPoolsByID(resultWithBindingConditions) + if len(resultWithBindingConditions) != 0 { result = append(result, resultWithBindingConditions...) } @@ -195,6 +186,21 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node return result, nil } +func sortSlicesByName(slicesToSort []*draapi.ResourceSlice) { + slices.SortFunc(slicesToSort, func(a, b *draapi.ResourceSlice) int { + return cmp.Compare(a.Name, b.Name) + }) +} + +func sortPoolsByID(pools []*Pool) { + slices.SortFunc(pools, func(a, b *Pool) int { + if cmp := cmp.Compare(a.PoolID.Driver.String(), b.PoolID.Driver.String()); cmp != 0 { + return cmp + } + return cmp.Compare(a.PoolID.Pool.String(), b.PoolID.Pool.String()) + }) +} + func addSlice(pools map[PoolID][]*draapi.ResourceSlice, s *resourceapi.ResourceSlice) error { var slice draapi.ResourceSlice if err := draapi.Convert_v1_ResourceSlice_To_api_ResourceSlice(s, &slice, nil); err != nil { @@ -227,6 +233,11 @@ func addSlice(pools map[PoolID][]*draapi.ResourceSlice, s *resourceapi.ResourceS } func buildPool(id PoolID, slices []*draapi.ResourceSlice, features Features, allSlicesForPool []*resourceapi.ResourceSlice) (*Pool, error) { + // Sort slices by name to ensure a deterministic allocation order. + // Because the allocator uses a first-fit search, this allows driver authors + // to influence prioritization through their naming conventions. + sortSlicesByName(slices) + var deviceSlices []*draapi.ResourceSlice var counterSetSlices []*draapi.ResourceSlice if features.PartitionableDevices { @@ -374,15 +385,6 @@ func validateDeviceCounterConsumption(counterSets map[draapi.UniqueString]*draap return nil } -func hasBindingConditions(slice *resourceapi.ResourceSlice) bool { - for _, device := range slice.Spec.Devices { - if device.BindingConditions != nil { - return true - } - } - return false -} - func poolHasBindingConditions(pool Pool) bool { for _, slice := range pool.DeviceSlicesTargetingNode { for _, device := range slice.Spec.Devices { @@ -444,3 +446,80 @@ type PoolID struct { func (p PoolID) String() string { return p.Driver.String() + "/" + p.Pool.String() } + +// At V(6), log only a limited number of devices to avoid blowing up logs. For +// many E2E tests, 10 devices is enough for all devices without having to +// truncate, at least when running the tests sequentially. +const maxDevicesLevel6 = 10 + +// logPools returns a handle for the value in a structured log call which +// includes varying amounts of information about the pools, depending on +// the verbosity of the logger. +func logPools(logger klog.Logger, pools []*Pool) any { + // We need to check verbosity here because our caller's source code + // location may be relevant (-vmodule !). + helper, logger := logger.WithCallStackHelper() + helper() + + // We always produce the same output at V <= 5. 6 adds a summary and + // 7 is a complete dump. + verbosity := 5 + for i := 7; i > verbosity; i-- { + if loggerV := logger.V(i); loggerV.Enabled() { + verbosity = i + break + } + } + return &poolsLogger{verbosity, pools} +} + +type poolsLogger struct { + verbosity int + pools []*Pool +} + +var _ logr.Marshaler = &poolsLogger{} + +func (p *poolsLogger) MarshalLog() any { + info := map[string]any{"count": len(p.pools)} + if p.verbosity == 6 { + meta := make([]map[string]any, len(p.pools)) + for i, pool := range p.pools { + meta[i] = map[string]any{ + "id": pool.PoolID.String(), + "isIncomplete": pool.IsIncomplete, + "isInvalid": pool.IsInvalid, + "InvalidReason": pool.InvalidReason, + } + } + info["meta"] = meta + info["devices"] = p.listDevices(maxDevicesLevel6) + } + if p.verbosity >= 7 { + info["devices"] = p.listDevices(-1) + info["content"] = p.pools + } + return info +} + +func (p *poolsLogger) listDevices(maxDevices int) []string { + var devices []string + for _, pool := range p.pools { + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesTargetingNode, maxDevices) + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesNotTargetingNode, maxDevices) + } + return devices +} + +func (p *poolsLogger) addDevicesInSlices(devices []string, poolID PoolID, slices []*draapi.ResourceSlice, maxDevices int) []string { + for _, slice := range slices { + for _, device := range slice.Spec.Devices { + if maxDevices != -1 && len(devices) >= maxDevices { + devices = append(devices, "...") + return devices + } + devices = append(devices, DeviceID{Driver: poolID.Driver, Pool: poolID.Pool, Device: device.Name}.String()) + } + } + return devices +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/allocator_incubating.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/allocator_incubating.go index a051dd9640..a77feed54c 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/allocator_incubating.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/allocator_incubating.go @@ -28,6 +28,8 @@ import ( v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" draapi "k8s.io/dynamic-resource-allocation/api" "k8s.io/dynamic-resource-allocation/cel" @@ -46,22 +48,49 @@ func MakeDeviceID(driver, pool, device string) DeviceID { return internal.MakeDeviceID(driver, pool, device) } +type SharedDeviceID = internal.SharedDeviceID +type DeviceConsumedCapacity = internal.DeviceConsumedCapacity +type ConsumedCapacityCollection = internal.ConsumedCapacityCollection +type ConsumedCapacity = internal.ConsumedCapacity +type AllocatedState = internal.AllocatedState + +func GenerateNewShareID() *types.UID { + return internal.GenerateShareID() +} + +func NewConsumedCapacity() ConsumedCapacity { + return internal.NewConsumedCapacity() +} + +func NewDeviceConsumedCapacity(deviceID DeviceID, + consumedCapacity map[resourceapi.QualifiedName]resource.Quantity) DeviceConsumedCapacity { + return internal.NewDeviceConsumedCapacity(deviceID, consumedCapacity) +} + +func NewConsumedCapacityCollection() ConsumedCapacityCollection { + return internal.NewConsumedCapacityCollection() +} + // SupportedFeatures includes all additional features, // making this the variant that is used when any of those // are enabled. var SupportedFeatures = internal.Features{ - AdminAccess: true, - PrioritizedList: true, - PartitionableDevices: true, - DeviceTaints: true, + AdminAccess: true, + PrioritizedList: true, + PartitionableDevices: true, + DeviceTaints: true, + DeviceBindingAndStatus: true, + ConsumableCapacity: true, } type Allocator struct { - features Features - allocatedDevices sets.Set[DeviceID] - classLister DeviceClassLister - slices []*resourceapi.ResourceSlice - celCache *cel.Cache + features Features + allocatedState AllocatedState + classLister DeviceClassLister + slicesOnNode map[string][]*resourceapi.ResourceSlice + slicesShared []*resourceapi.ResourceSlice + allSlices []*resourceapi.ResourceSlice + celCache *cel.Cache // availableCounters contains the available counters for each // resource pool. It acts as a cache that is updated the first time // the available counters are needed for each pool. The information @@ -88,21 +117,37 @@ var _ internal.AllocatorExtended = &Allocator{} // The returned Allocator can be used multiple times and is thread-safe. func NewAllocator(ctx context.Context, features Features, - allocatedDevices sets.Set[DeviceID], + allocatedState AllocatedState, classLister DeviceClassLister, slices []*resourceapi.ResourceSlice, celCache *cel.Cache, ) (*Allocator, error) { + slicesOnNode := make(map[string][]*resourceapi.ResourceSlice) + slicesShared := make([]*resourceapi.ResourceSlice, 0) + for _, slice := range slices { + nodeName := ptr.Deref(slice.Spec.NodeName, "") + if nodeName == "" || len(slice.Spec.SharedCounters) > 0 { + slicesShared = append(slicesShared, slice) + } else { + slicesOnNode[nodeName] = append(slicesOnNode[nodeName], slice) + } + } return &Allocator{ features: features, - allocatedDevices: allocatedDevices, + allocatedState: allocatedState, classLister: classLister, - slices: slices, + slicesOnNode: slicesOnNode, + slicesShared: slicesShared, + allSlices: slices, celCache: celCache, availableCounters: make(map[draapi.UniqueString]counterSets), }, nil } +func (a *Allocator) Channel() internal.AllocatorChannel { + return internal.Incubating +} + func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resourceapi.ResourceClaim) (finalResult []resourceapi.AllocationResult, finalErr error) { alloc := &allocator{ Allocator: a, @@ -115,23 +160,21 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou consumedCounters: make(map[draapi.UniqueString]counterSets), requestData: make(map[requestIndices]requestData), result: make([]internalAllocationResult, len(claims)), + allocatingCapacity: NewConsumedCapacityCollection(), } - alloc.logger.V(5).Info("Starting allocation", "numClaims", len(alloc.claimsToAllocate), "numSlices", len(alloc.slices)) + slicesForNode := slices.Concat(alloc.slicesOnNode[node.Name], alloc.slicesShared) + alloc.logger.V(5).Info("Starting allocation", "numClaims", len(alloc.claimsToAllocate), "numSlicesForNode", len(slicesForNode)) defer func() { alloc.logger.V(5).Info("Done with allocation", "success", len(finalResult) == len(alloc.claimsToAllocate), "err", finalErr) }() // First determine all eligible pools. - pools, err := GatherPools(ctx, alloc.slices, node, a.features) + pools, err := GatherPools(ctx, slicesForNode, node, a.features, alloc.allSlices) if err != nil { return nil, fmt.Errorf("gather pool information: %w", err) } alloc.pools = pools - if loggerV := alloc.logger.V(7); loggerV.Enabled() { - loggerV.Info("Gathered pool information", "numPools", len(pools), "pools", pools) - } else { - alloc.logger.V(5).Info("Gathered pool information", "numPools", len(pools)) - } + alloc.logger.V(5).Info("Gathered pool information", "pools", logPools(alloc.logger, pools)) // We allocate one claim after the other and for each claim, all of // its requests. For each individual device we pick one possible @@ -174,22 +217,37 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou return nil, fmt.Errorf("claim %s, request %s: has subrequests, but the DRAPrioritizedList feature is disabled", klog.KObj(claim), request.Name) } + // Error out if the consumableCapacity feature is not enabled + // and the request contains capacity requests. + if !a.features.ConsumableCapacity { + if request.Exactly != nil && request.Exactly.Capacity != nil { + return nil, fmt.Errorf("claim %s, request %s: has capacity requests, but the DRAConsumableCapacity feature is disabled", + klog.KObj(claim), request.Name) + } + for _, subReq := range request.FirstAvailable { + // Error out if any subrequest contains capacity requests. + if subReq.Capacity != nil { + return nil, fmt.Errorf("claim %s, subrequest %s: has capacity requests, but the DRAConsumableCapacity feature is disabled", + klog.KObj(claim), subReq.Name) + } + } + } + if hasSubRequests { // We need to find the minimum number of devices that can be allocated // for the request, so setting this to a high number so we can do the // easy comparison in the loop. minDevicesPerRequest := math.MaxInt - // A request with subrequests gets one entry per subrequest in alloc.requestData. // We can only predict a lower number of devices because it depends on which // subrequest gets chosen. for i, subReq := range request.FirstAvailable { + requestKey.subRequestIndex = i reqData, err := alloc.validateDeviceRequest(&deviceSubRequestAccessor{subRequest: &subReq}, &exactDeviceRequestAccessor{request: request}, requestKey, pools) if err != nil { return nil, err } - requestKey.subRequestIndex = i alloc.requestData[requestKey] = reqData if reqData.numDevices < minDevicesPerRequest { minDevicesPerRequest = reqData.numDevices @@ -236,6 +294,20 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou attributeName: matchAttribute, } constraints[i] = m + case constraint.DistinctAttribute != nil: + distinctAttribute := resourceapi.FullyQualifiedName(*constraint.DistinctAttribute) + logger := alloc.logger + if loggerV := alloc.logger.V(6); loggerV.Enabled() { + logger = klog.LoggerWithName(logger, "distinctAttributeConstraint") + logger = klog.LoggerWithValues(logger, "distinctAttribute", distinctAttribute) + } + m := &distinctAttributeConstraint{ + logger: logger, + requestNames: sets.New(constraint.Requests...), + attributeName: distinctAttribute, + attributes: make(map[string]resourceapi.DeviceAttribute), + } + constraints[i] = m default: // Unknown constraint type! return nil, fmt.Errorf("claim %s, constraint #%d: empty constraint (unsupported constraint type?)", klog.KObj(claim), i) @@ -255,7 +327,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // We can estimate the size based on what we need to allocate. alloc.allocatingDevices = make(map[DeviceID]sets.Set[int], minDevicesTotal) - alloc.logger.V(6).Info("Gathered information about devices", "numAllocated", len(alloc.allocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) + alloc.logger.V(6).Info("Gathered information about devices", "numAllocatedDevices", len(alloc.allocatedState.AllocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) // In practice, there aren't going to be many different CEL // expressions. Most likely, there is going to be handful of different @@ -270,7 +342,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // All errors get created such that they can be returned by Allocate // without further wrapping. - done, err := alloc.allocateOne(deviceIndices{}, false) + done, err := alloc.allocateOne(deviceIndices{}, false, deviceLocation{}) if errors.Is(err, errStop) { return nil, nil } @@ -298,13 +370,36 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou allocationResult := &result[claimIndex] allocationResult.Devices.Results = make([]resourceapi.DeviceRequestAllocationResult, len(internalResult.devices)) for i, internal := range internalResult.devices { + var consumedCapacity map[resourceapi.QualifiedName]resource.Quantity + if internal.consumedCapacity != nil { + consumedCapacity = make(map[resourceapi.QualifiedName]resource.Quantity, len(internal.consumedCapacity)) + for key, val := range internal.consumedCapacity { + consumedCapacity[key] = val.DeepCopy() + } + } allocationResult.Devices.Results[i] = resourceapi.DeviceRequestAllocationResult{ - Request: internal.requestName(), - Driver: internal.id.Driver.String(), - Pool: internal.id.Pool.String(), - Device: internal.id.Device.String(), - AdminAccess: internal.adminAccess, - Tolerations: internal.lookupRequest(claim).tolerations(), + Request: internal.requestName(), + Driver: internal.id.Driver.String(), + Pool: internal.id.Pool.String(), + Device: internal.id.Device.String(), + AdminAccess: internal.adminAccess, + Tolerations: internal.lookupRequest(claim).tolerations(), + ShareID: internal.shareID, + ConsumedCapacity: consumedCapacity, + } + // Performance optimization: skip the for loop if the feature is off. + // Not needed for correctness because if the feature is off, the selected + // device should not have binding conditions. + if a.features.DeviceBindingAndStatus { + allocationResult.Devices.Results[i].BindingConditions = internal.BindingConditions + allocationResult.Devices.Results[i].BindingFailureConditions = internal.BindingFailureConditions + } + // Performance optimization: skip the for loop if the feature is off. + // Not needed for correctness because if the feature is off, the selected + // device should not have binding conditions. + if a.features.DeviceBindingAndStatus { + allocationResult.Devices.Results[i].BindingConditions = internal.BindingConditions + allocationResult.Devices.Results[i].BindingFailureConditions = internal.BindingFailureConditions } } @@ -388,7 +483,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou } // Determine node selector. - nodeSelector, err := alloc.createNodeSelector(internalResult.devices) + nodeSelector, err := alloc.createNodeSelector(internalResult.devices, node.Name) if err != nil { return nil, fmt.Errorf("create NodeSelector for claim %s: %w", claim.Name, err) } @@ -459,7 +554,6 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq if pool.IsInvalid { return requestData, fmt.Errorf("claim %s, request %s: asks for all devices, but resource pool %s is currently invalid", klog.KObj(claim), request.name(), pool.PoolID) } - for _, slice := range pool.DeviceSlicesTargetingNode { for deviceIndex := range slice.Spec.Devices { selectable, err := alloc.isSelectable(requestKey, requestData, slice, deviceIndex) @@ -471,6 +565,21 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq id: DeviceID{Driver: slice.Spec.Driver, Pool: slice.Spec.Pool.Name, Device: slice.Spec.Devices[deviceIndex].Name}, Device: &slice.Spec.Devices[deviceIndex], slice: slice, + pool: pool, + } + if alloc.features.ConsumableCapacity { + // Next validate whether resource request over capacity + device := slice.Spec.Devices[deviceIndex] + success, err := alloc.CmpRequestOverCapacity(requestData.request, slice, device) + if err != nil { + alloc.logger.V(7).Info("Skip comparing device capacity request", + "device", device, "request", requestData.request.name(), "err", err) + continue + } + if !success { + alloc.logger.V(7).Info("Device capacity not enough", "device", device) + continue + } } requestData.allDevices = append(requestData.allDevices, device) } @@ -518,7 +627,12 @@ type allocator struct { // be allocated. // Claims are identified by their index in claimsToAllocate. allocatingDevices map[DeviceID]sets.Set[int] - result []internalAllocationResult + // allocatingCapacity tracks the amount of device capacity that will be newly allocated + // for a particular attempt to find a solution. + // The map is indexed by device ID, and each value represents the accumulated capacity + // requested by all allocations targeting that device. + allocatingCapacity ConsumedCapacityCollection + result []internalAllocationResult } // counterSets is a map with the name of counter sets to the counters in @@ -551,6 +665,13 @@ type deviceIndices struct { deviceIndex int // The index of a device within a request or subrequest. } +// deviceLocation identifies a device by its position in the allocator's pools. +type deviceLocation struct { + poolIndex int + sliceIndex int + deviceIndex int +} + type requestData struct { // The request or subrequest which needs to be allocated. // Never nil. @@ -588,11 +709,13 @@ type internalAllocationResult struct { type internalDeviceResult struct { *draapi.Device - request string // name of the request (if no subrequests) or the subrequest - parentRequest string // name of the request which contains the subrequest, empty otherwise - id DeviceID - slice *draapi.ResourceSlice - adminAccess *bool + request string // name of the request (if no subrequests) or the subrequest + parentRequest string // name of the request which contains the subrequest, empty otherwise + id DeviceID + shareID *types.UID + slice *draapi.ResourceSlice + consumedCapacity map[resourceapi.QualifiedName]resource.Quantity + adminAccess *bool } func (idr internalDeviceResult) requestName() string { @@ -762,7 +885,24 @@ func lookupAttribute(device *draapi.Device, deviceID DeviceID, attributeName res // allocateSubRequest is true when trying to allocate one particular subrequest. // This allows the logic for subrequests to call allocateOne with the same // device index without causing infinite recursion. -func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (bool, error) { +// +// startLocation provides the starting point when searching for the next device to +// allocate. Since we have a list of pools, each with a list of slices which again +// contains a list of devices, we have defined an order in which the devices will +// be attempted for allocation. Since the order of devices doesn't matter within a +// single request, we want to make sure we only attempt all combinations of devices, +// and not search through all permutations (since many of them will have the same set +// of devices and therefore be identical allocations). Note that the order of devices +// does matter across requests and claims. So by providing the startLocation, we +// make sure that the allocator only attempts allocations that follows the order +// of the available devices, thereby avoiding different permutations. For example, +// this means that for the devices [1, 2, 3], we will only attempt the following +// possible allocations [1], [2], [3], [1, 2], [1, 3], [2, 3], and [1, 2, 3]. +// +// The null startLocation (= all indices zero) means that all devices are considered. +// The only situation where a non-null startLocation is used is when looking for the +// next device within the same request. +func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool, startLocation deviceLocation) (bool, error) { alloc.numAllocateOneInvocations.Add(1) if alloc.ctx.Err() != nil { @@ -780,7 +920,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b claim := alloc.claimsToAllocate[r.claimIndex] if r.requestIndex >= len(claim.Spec.Devices.Requests) { // Done with the claim, continue with the next one. - success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false, deviceLocation{}) if errors.Is(err, errAllocationResultMaxSizeExceeded) { // We don't need to propagate this further because // this is not a fatal error. Retrying the claim under @@ -827,7 +967,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b } r.subRequestIndex = subRequestIndex - success, err := alloc.allocateOne(r, true /* prevent infinite recusion */) + success, err := alloc.allocateOne(r, true /* prevent infinite recusion */, deviceLocation{}) // If we reached the allocation result limit, we can try // with the next subrequest if there is one. It might request // fewer devices, so it might succeed. @@ -868,7 +1008,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // Done with request, continue with next one. We have completed the work for // the request or subrequest, so we can no longer be allocating devices for // a subrequest. - success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false, deviceLocation{}) // We want to propagate any errAllocationResultMaxSizeExceeded to the caller. If // that error is returned here, it means none of the requests/subrequests after this one // could be allocated while staying within the limit on the number of devices, so there @@ -888,7 +1028,11 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b return false, errAllocationResultMaxSizeExceeded } - alloc.logger.V(6).Info("Allocating one device", "currentClaim", r.claimIndex, "totalClaims", len(alloc.claimsToAllocate), "currentRequest", r.requestIndex, "currentSubRequest", r.subRequestIndex, "totalRequestsPerClaim", len(claim.Spec.Devices.Requests), "currentDevice", r.deviceIndex, "devicesPerRequest", requestData.numDevices, "allDevices", doAllDevices, "adminAccess", request.adminAccess()) + alloc.logger.V(6).Info("Allocating one device", "currentClaim", r.claimIndex, + "totalClaims", len(alloc.claimsToAllocate), "currentRequest", r.requestIndex, + "currentSubRequest", r.subRequestIndex, "totalRequestsPerClaim", len(claim.Spec.Devices.Requests), + "currentDevice", r.deviceIndex, "devicesPerRequest", requestData.numDevices, "allDevices", doAllDevices, "adminAccess", request.adminAccess(), "capacities", request.capacities()) + if doAllDevices { // For "all" devices we already know which ones we need. We // just need to check whether we can use them. @@ -903,7 +1047,8 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // get all of them, then there is no solution and we have to stop. return false, nil } - done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest) + // No need to propagate the startLocation here since we only try one combination of devices. + done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, subRequestIndex: r.subRequestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest, deviceLocation{}) if err != nil || !done { // If we get an error or didn't complete, we need to backtrack. Depending // on the situation we might be able to retry, so we make sure we @@ -915,15 +1060,33 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b } // We need to find suitable devices. - for _, pool := range alloc.pools { + for poolIndex := startLocation.poolIndex; poolIndex < len(alloc.pools); poolIndex++ { + pool := alloc.pools[poolIndex] // We don't allocate devices from invalid or incomplete pools, but // don't error out here since there might be available devices in other // pools. if pool.IsIncomplete || pool.IsInvalid { continue } - for _, slice := range pool.DeviceSlicesTargetingNode { - for deviceIndex := range slice.Spec.Devices { + // We should start at the slice provided by startLocation unless we searched through + // all devices in the previous pool and have started at the next pool. When this happens, + // we should start at the first slice in the pool. + sliceStart := 0 + if poolIndex == startLocation.poolIndex { + sliceStart = startLocation.sliceIndex + } + for sliceIndex := sliceStart; sliceIndex < len(pool.DeviceSlicesTargetingNode); sliceIndex++ { + slice := pool.DeviceSlicesTargetingNode[sliceIndex] + + // We should start at the device provided by startLocation unless we searched through + // all devices in the previous slice and have started at the next slice. When this happens, + // we should start at the first device in the pool. + deviceStart := 0 + if poolIndex == startLocation.poolIndex && + sliceIndex == startLocation.sliceIndex { + deviceStart = startLocation.deviceIndex + } + for deviceIndex := deviceStart; deviceIndex < len(slice.Spec.Devices); deviceIndex++ { deviceID := DeviceID{Driver: pool.Driver, Pool: pool.Pool, Device: slice.Spec.Devices[deviceIndex].Name} // Checking for "in use" is cheap and thus gets done first. @@ -946,6 +1109,20 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b alloc.logger.V(7).Info("Device not selectable", "device", deviceID) continue } + if alloc.features.ConsumableCapacity { + // Next validate whether resource request over capacity + device := slice.Spec.Devices[deviceIndex] + success, err := alloc.CmpRequestOverCapacity(requestData.request, slice, device) + if err != nil { + alloc.logger.V(7).Info("Skip comparing device capacity request", + "device", deviceID, "request", requestData.request.name(), "err", err) + continue + } + if !success { + alloc.logger.V(7).Info("Device capacity not enough", "device", deviceID) + continue + } + } // Finally treat as allocated and move on to the next device. device := deviceWithID{ @@ -969,7 +1146,16 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b subRequestIndex: r.subRequestIndex, deviceIndex: r.deviceIndex + 1, } - done, err := alloc.allocateOne(deviceKey, allocateSubRequest) + nextLocation := deviceLocation{ + poolIndex: poolIndex, + sliceIndex: sliceIndex, + deviceIndex: deviceIndex + 1, + } + // This is the allocation attempt for the next device in the same request. + // If allocateOne finds out that it is done with the request, it moves to + // the next without setting a start location, so each request is free to try + // all devices. + done, err := alloc.allocateOne(deviceKey, allocateSubRequest, nextLocation) // If we found a solution, we can stop. if err == nil && done { return done, nil @@ -1047,6 +1233,20 @@ func (alloc *allocator) isSelectable(r requestIndices, requestData requestData, } +// CmpRequestOverCapacity checks if the given device has sufficient remaining capacity +// to satisfy the resource request. +// Return true if success. +func (alloc *allocator) CmpRequestOverCapacity(request requestAccessor, slice *draapi.ResourceSlice, device draapi.Device) (bool, error) { + deviceID := DeviceID{Driver: slice.Spec.Driver, Pool: slice.Spec.Pool.Name, Device: device.Name} + allocatingCapacity := alloc.allocatingCapacity[deviceID] + allowMultipleAllocations := device.AllowMultipleAllocations + capacities := device.Capacity + if allocatedCapacity, found := alloc.allocatedState.AggregatedCapacity[deviceID]; found { + return CmpRequestOverCapacity(allocatedCapacity, request.capacities(), allowMultipleAllocations, capacities, allocatingCapacity) + } + return CmpRequestOverCapacity(NewConsumedCapacity(), request.capacities(), allowMultipleAllocations, capacities, allocatingCapacity) +} + func (alloc *allocator) selectorsMatch(r requestIndices, device *draapi.Device, deviceID DeviceID, class *resourceapi.DeviceClass, selectors []resourceapi.DeviceSelector) (bool, error) { for i, selector := range selectors { expr := alloc.celCache.GetOrCompile(selector.CEL.Expression) @@ -1068,7 +1268,7 @@ func (alloc *allocator) selectorsMatch(r requestIndices, device *draapi.Device, if err := draapi.Convert_api_Device_To_v1_Device(device, &d, nil); err != nil { return false, fmt.Errorf("convert Device: %w", err) } - matches, details, err := expr.DeviceMatches(alloc.ctx, cel.Device{Driver: deviceID.Driver.String(), Attributes: d.Attributes, Capacity: d.Capacity}) + matches, details, err := expr.DeviceMatches(alloc.ctx, cel.Device{Driver: deviceID.Driver.String(), AllowMultipleAllocations: d.AllowMultipleAllocations, Attributes: d.Attributes, Capacity: d.Capacity}) if class != nil { alloc.logger.V(7).Info("CEL result", "device", deviceID, "class", klog.KObj(class), "selector", i, "expression", selector.CEL.Expression, "matches", matches, "actualCost", ptr.Deref(details.ActualCost(), 0), "err", err) } else { @@ -1094,6 +1294,11 @@ func (alloc *allocator) selectorsMatch(r requestIndices, device *draapi.Device, // allocateDevice checks device availability and constraints for one // candidate. The device must be selectable. // +// r identifies the request for which allocation is attempted. +// The device is the candidate under consideration. +// If "must" is true, then it is okay (but not required) to return an error which describes in more detail why allocation wasn't possible. +// This is used when the caller wants exactly this device and will give up if it cannot allocate it. +// // If that candidate works out okay, the shared state gets updated // as if that candidate had been allocated. If allocation cannot continue later // and must try something else, then the rollback function can be invoked to @@ -1106,7 +1311,11 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus requestKey := requestIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, subRequestIndex: r.subRequestIndex} requestData := alloc.requestData[requestKey] request := requestData.request - if request.adminAccess() && alloc.allocatingDeviceForClaim(device.id, r.claimIndex) { + allowMultipleAllocations := false + if alloc.features.ConsumableCapacity { + allowMultipleAllocations = device.AllowMultipleAllocations != nil && *device.AllowMultipleAllocations + } + if !allowMultipleAllocations && request.adminAccess() && alloc.allocatingDeviceForClaim(device.id, r.claimIndex) { alloc.logger.V(7).Info("Device in use in same claim", "device", device.id) return false, nil, nil } @@ -1122,8 +1331,11 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus return false, nil, nil } + // Skip counter availability check for devices that allow multiple allocation and some capacity has already in-use. + skipCounterCheck := allowMultipleAllocations && alloc.deviceCapacityInUse(device.id) + // The API validation logic has checked the ConsumesCounters referred should exist inside SharedCounters. - if len(device.ConsumesCounters) > 0 { + if !skipCounterCheck && len(device.ConsumesCounters) > 0 { // If a device consumes counters from a counter set, verify that // there is sufficient counters available. ok, err := alloc.checkAvailableCounters(device) @@ -1171,14 +1383,41 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus } } - // All constraints satisfied. Mark as in use (unless we do admin access) + // All constraints satisfied. Mark as in use (unless we do admin access or allow multiple allocations) // and record the result. alloc.logger.V(7).Info("Device allocated", "device", device.id) if alloc.allocatingDevices[device.id] == nil { alloc.allocatingDevices[device.id] = make(sets.Set[int]) } - alloc.allocatingDevices[device.id].Insert(r.claimIndex) + if !allowMultipleAllocations { + alloc.allocatingDevices[device.id].Insert(r.claimIndex) + } + + consumedCapacity := make(map[resourceapi.QualifiedName]resource.Quantity, 0) + var shareID *types.UID + if alloc.features.ConsumableCapacity { + // Validate whether resource request over capacity + success, err := alloc.CmpRequestOverCapacity(requestData.request, device.slice, *device.Device) + // The error should not occur at this point as it should be detected in the previous step. + if err != nil { + alloc.logger.V(7).Info("Failed to compare device capacity request on allocateDevice", + "device", device, "request", requestData.request.name(), "err", err) + return false, nil, nil + } + if !success { + alloc.logger.V(7).Info("Device capacity not enough", "device", device) + return false, nil, nil + } + + if allowMultipleAllocations { + consumedCapacity = GetConsumedCapacityFromRequest(request.capacities(), device.Capacity) + shareID = GenerateNewShareID() + alloc.logger.V(7).Info("Device capacity allocated", "device", device.id, + "consumed capacity", klog.Format(consumedCapacity)) + alloc.allocatingCapacity.Insert(NewDeviceConsumedCapacity(device.id, consumedCapacity)) + } + } result := internalDeviceResult{ request: request.name(), @@ -1186,10 +1425,14 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus id: device.id, Device: device.Device, slice: device.slice, + shareID: shareID, } if request.adminAccess() { result.adminAccess = ptr.To(request.adminAccess()) } + if len(consumedCapacity) > 0 { + result.consumedCapacity = consumedCapacity + } previousNumResults := len(alloc.result[r.claimIndex].devices) alloc.result[r.claimIndex].devices = append(alloc.result[r.claimIndex].devices, result) @@ -1198,8 +1441,16 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus constraint.remove(baseRequestName, subRequestName, device.Device, device.id) } alloc.allocatingDevices[device.id].Delete(r.claimIndex) - if alloc.features.PartitionableDevices && len(device.ConsumesCounters) > 0 { - alloc.deallocateCountersForDevice(device) + if allowMultipleAllocations { + requestedResource := alloc.result[r.claimIndex].devices[previousNumResults].consumedCapacity + if requestedResource != nil { + alloc.allocatingCapacity.Remove(NewDeviceConsumedCapacity(device.id, requestedResource)) + } + } else { + alloc.allocatingDevices[device.id].Delete(r.claimIndex) + if alloc.features.PartitionableDevices && len(device.ConsumesCounters) > 0 { + alloc.deallocateCountersForDevice(device) + } } // Truncate, but keep the underlying slice. alloc.result[r.claimIndex].devices = alloc.result[r.claimIndex].devices[:previousNumResults] @@ -1271,7 +1522,7 @@ func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error } // Devices that aren't allocated doesn't consume any counters, so we don't // need to consider them. - if !alloc.allocatedDevices.Has(deviceID) { + if !internal.IsDeviceAllocated(deviceID, &alloc.allocatedState) { continue } for _, deviceCounterConsumption := range device.ConsumesCounters { @@ -1346,7 +1597,12 @@ func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error } func (alloc *allocator) deviceInUse(deviceID DeviceID) bool { - return alloc.allocatedDevices.Has(deviceID) || alloc.allocatingDeviceForAnyClaim(deviceID) + return alloc.allocatedState.AllocatedDevices.Has(deviceID) || alloc.allocatingDeviceForAnyClaim(deviceID) +} + +func (alloc *allocator) deviceCapacityInUse(deviceID DeviceID) bool { + _, found := alloc.allocatedState.AggregatedCapacity[deviceID] + return found || alloc.allocatingCapacityForAnyClaim(deviceID) } func (alloc *allocator) allocatingDeviceForAnyClaim(deviceID DeviceID) bool { @@ -1357,6 +1613,11 @@ func (alloc *allocator) allocatingDeviceForClaim(deviceID DeviceID, claimIndex i return alloc.allocatingDevices[deviceID].Has(claimIndex) } +func (alloc *allocator) allocatingCapacityForAnyClaim(deviceID DeviceID) bool { + _, found := alloc.allocatingCapacity[deviceID] + return found +} + // deallocateCountersForDevice subtracts the consumed counters of the provided // device from the consumedCounters data structure. func (alloc *allocator) deallocateCountersForDevice(device deviceWithID) { @@ -1376,7 +1637,7 @@ func (alloc *allocator) deallocateCountersForDevice(device deviceWithID) { // createNodeSelector constructs a node selector for the allocation, if needed, // otherwise it returns nil. -func (alloc *allocator) createNodeSelector(result []internalDeviceResult) (*v1.NodeSelector, error) { +func (alloc *allocator) createNodeSelector(result []internalDeviceResult, targetNodeName string) (*v1.NodeSelector, error) { // Selector with one term. That term gets extended with additional // requirements from the different devices. ns := &v1.NodeSelector{ @@ -1394,15 +1655,15 @@ func (alloc *allocator) createNodeSelector(result []internalDeviceResult) (*v1.N nodeName = slice.Spec.NodeName nodeSelector = slice.Spec.NodeSelector } - if nodeName != nil { - // At least one device is local to one node. This - // restricts the allocation to that node. + if nodeName != nil || result[i].BindsToNode { + // At least one device is local to one node or binds to a node, + // so we need to restrict the allocation to that node. return &v1.NodeSelector{ NodeSelectorTerms: []v1.NodeSelectorTerm{{ MatchFields: []v1.NodeSelectorRequirement{{ Key: "metadata.name", Operator: v1.NodeSelectorOpIn, - Values: []string{*nodeName}, + Values: []string{targetNodeName}, }}, }}, }, nil @@ -1444,6 +1705,7 @@ type requestAccessor interface { hasAdminAccess() bool selectors() []resourceapi.DeviceSelector tolerations() []resourceapi.DeviceToleration + capacities() *resourceapi.CapacityRequirements } // exactDeviceRequestAccessor is an implementation of the @@ -1484,6 +1746,10 @@ func (d *exactDeviceRequestAccessor) tolerations() []resourceapi.DeviceToleratio return d.request.Exactly.Tolerations } +func (d *exactDeviceRequestAccessor) capacities() *resourceapi.CapacityRequirements { + return d.request.Exactly.Capacity +} + // deviceSubRequestAccessor is an implementation of the // requestAccessor interface for DeviceSubRequests. type deviceSubRequestAccessor struct { @@ -1522,6 +1788,10 @@ func (d *deviceSubRequestAccessor) tolerations() []resourceapi.DeviceToleration return d.subRequest.Tolerations } +func (d *deviceSubRequestAccessor) capacities() *resourceapi.CapacityRequirements { + return d.subRequest.Capacity +} + func addNewNodeSelectorRequirements(from []v1.NodeSelectorRequirement, to *[]v1.NodeSelectorRequirement) { for _, requirement := range from { if !containsNodeSelectorRequirement(*to, requirement) { diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/constraint.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/constraint.go new file mode 100644 index 0000000000..7324d6a50a --- /dev/null +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/constraint.go @@ -0,0 +1,131 @@ +/* +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 incubating + +import ( + "fmt" + + resourceapi "k8s.io/api/resource/v1" + "k8s.io/apimachinery/pkg/util/sets" + draapi "k8s.io/dynamic-resource-allocation/api" + "k8s.io/klog/v2" +) + +// distinctAttributeConstraint compares an attribute value across devices. +// All devices must share the same value. When the set of devices is +// empty, any device that has the attribute can be added. After that, +// only matching devices can be added. +// +// We don't need to track *which* devices are part of the set, only +// how many. +type distinctAttributeConstraint struct { + logger klog.Logger // Includes name and attribute name, so no need to repeat in log messages. + requestNames sets.Set[string] + attributeName resourceapi.FullyQualifiedName + + attributes map[string]resourceapi.DeviceAttribute + numDevices int +} + +func (m *distinctAttributeConstraint) add(requestName, subRequestName string, device *draapi.Device, deviceID DeviceID) bool { + if m.requestNames.Len() > 0 && !m.matches(requestName, subRequestName) { + // Device not affected by constraint. + return true + } + + attribute := lookupAttribute(device, deviceID, m.attributeName) + if attribute == nil { + // Doesn't have the attribute. + m.logger.V(7).Info("Constraint not satisfied, attribute not set") + return false + } + + if m.numDevices == 0 { + // The first device can always get picked. + m.attributes[requestName] = *attribute + m.numDevices = 1 + m.logger.V(7).Info("First attribute added") + return true + } + + if !m.matchesAttribute(*attribute) { + m.logger.V(7).Info("Constraint not satisfied, has some duplicated attributes") + return false + } + m.attributes[requestName] = *attribute + m.numDevices++ + m.logger.V(7).Info("Constraint satisfied by device", "device", deviceID, "numDevices", m.numDevices) + return true + +} + +func (m *distinctAttributeConstraint) remove(requestName, subRequestName string, device *draapi.Device, deviceID DeviceID) { + if m.requestNames.Len() > 0 && !m.matches(requestName, subRequestName) { + // Device not affected by constraint. + return + } + delete(m.attributes, requestName) + m.numDevices-- + m.logger.V(7).Info("Device removed from constraint set", "device", deviceID, "numDevices", m.numDevices) +} + +func (m *distinctAttributeConstraint) matches(requestName, subRequestName string) bool { + if subRequestName == "" { + return m.requestNames.Has(requestName) + } else { + fullSubRequestName := fmt.Sprintf("%s/%s", requestName, subRequestName) + return m.requestNames.Has(requestName) || m.requestNames.Has(fullSubRequestName) + } +} + +func (m *distinctAttributeConstraint) matchesAttribute(attribute resourceapi.DeviceAttribute) bool { + for _, attr := range m.attributes { + switch { + case attribute.StringValue != nil: + if attr.StringValue != nil && *attribute.StringValue == *attr.StringValue { + m.logger.V(7).Info("String values duplicated") + return false + } + case attribute.IntValue != nil: + if attr.IntValue != nil && *attribute.IntValue == *attr.IntValue { + m.logger.V(7).Info("Int values duplicated") + return false + } + case attribute.BoolValue != nil: + if attr.BoolValue != nil && *attribute.BoolValue == *attr.BoolValue { + m.logger.V(7).Info("Bool values duplicated") + return false + } + case attribute.VersionValue != nil: + // semver 2.0.0 requires that version strings are in their + // minimal form (in particular, no leading zeros). Therefore a + // strict "exact equal" check can do a string comparison. + if attr.VersionValue != nil && *attribute.VersionValue == *attr.VersionValue { + m.logger.V(7).Info("Version values duplicated") + return false + } + default: + // Unknown value type, cannot match. + // This condition should not be reached + // as the unknown value type should be failed on CEL compile (getAttributeValue). + m.logger.V(7).Info("Distinct attribute type unknown") + return false + } + } + // All distinct + return true +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/consumable_capacity.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/consumable_capacity.go new file mode 100644 index 0000000000..2bb3239f58 --- /dev/null +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/consumable_capacity.go @@ -0,0 +1,211 @@ +/* +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 incubating + +import ( + "errors" + + resourceapi "k8s.io/api/resource/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/utils/ptr" +) + +// CmpRequestOverCapacity checks whether the new capacity request can be added within the given capacity, +// and checks whether the requested value is against the capacity requestPolicy. +func CmpRequestOverCapacity(currentConsumedCapacity ConsumedCapacity, deviceRequestCapacity *resourceapi.CapacityRequirements, + allowMultipleAllocations *bool, capacity map[resourceapi.QualifiedName]resourceapi.DeviceCapacity, allocatingCapacity ConsumedCapacity) (bool, error) { + if requestsContainNonExistCapacity(deviceRequestCapacity, capacity) { + return false, errors.New("some requested capacity has not been defined") + } + clone := currentConsumedCapacity.Clone() + for name, cap := range capacity { + var requestedValPtr *resource.Quantity + if deviceRequestCapacity != nil && deviceRequestCapacity.Requests != nil { + if requestedVal, requestedFound := deviceRequestCapacity.Requests[name]; requestedFound { + requestedValPtr = &requestedVal + } + } + consumedCapacity := calculateConsumedCapacity(requestedValPtr, cap) + if violatesPolicy(consumedCapacity, cap.RequestPolicy) { + return false, nil + } + // If the current clone already contains an entry for this capacity, add the consumedCapacity to it. + // Otherwise, initialize it with calculated consumedCapacity. + if _, allocatedFound := clone[name]; allocatedFound { + clone[name].Add(consumedCapacity) + } else { + clone[name] = ptr.To(consumedCapacity) + } + // If allocatingCapacity contains an entry for this capacity, add its value to clone as well. + if allocatingVal, allocatingFound := allocatingCapacity[name]; allocatingFound { + clone[name].Add(*allocatingVal) + } + if clone[name].Cmp(cap.Value) > 0 { + return false, nil + } + } + return true, nil +} + +// requestsNonExistCapacity returns true if requests contain non-exist capacity. +func requestsContainNonExistCapacity(deviceRequestCapacity *resourceapi.CapacityRequirements, + capacity map[resourceapi.QualifiedName]resourceapi.DeviceCapacity) bool { + if deviceRequestCapacity == nil || deviceRequestCapacity.Requests == nil { + return false + } + for name := range deviceRequestCapacity.Requests { + if _, found := capacity[name]; !found { + return true + } + } + return false +} + +// calculateConsumedCapacity returns valid capacity to be consumed regarding the requested capacity and device capacity policy. +// +// If no requestPolicy, return capacity.Value. +// If no requestVal, fill the quantity by fillEmptyRequest function +// Otherwise, use requestPolicy to calculate the consumed capacity from request if applicable. +func calculateConsumedCapacity(requestedVal *resource.Quantity, capacity resourceapi.DeviceCapacity) resource.Quantity { + if requestedVal == nil { + return fillEmptyRequest(capacity) + } + if capacity.RequestPolicy == nil { + return requestedVal.DeepCopy() + } + switch { + case capacity.RequestPolicy.ValidRange != nil && capacity.RequestPolicy.ValidRange.Min != nil: + return roundUpRange(requestedVal, capacity.RequestPolicy.ValidRange) + case capacity.RequestPolicy.ValidValues != nil: + return roundUpValidValues(requestedVal, capacity.RequestPolicy.ValidValues) + } + return *requestedVal +} + +// fillEmptyRequest +// return requestPolicy.default if defined. +// Otherwise, return capacity value. +func fillEmptyRequest(capacity resourceapi.DeviceCapacity) resource.Quantity { + if capacity.RequestPolicy != nil && capacity.RequestPolicy.Default != nil { + return capacity.RequestPolicy.Default.DeepCopy() + } + return capacity.Value.DeepCopy() +} + +// roundUpRange rounds the requestedVal up to fit within the specified validRange. +// - If requestedVal is less than Min, it returns Min. +// - If Step is specified, it rounds requestedVal up to the nearest multiple of Step +// starting from Min. +// - If no Step is specified and requestedVal >= Min, it returns requestedVal as is. +func roundUpRange(requestedVal *resource.Quantity, validRange *resourceapi.CapacityRequestPolicyRange) resource.Quantity { + if requestedVal.Cmp(*validRange.Min) < 0 { + return validRange.Min.DeepCopy() + } + if validRange.Step == nil { + return *requestedVal + } + requestedInt64 := requestedVal.Value() + step := validRange.Step.Value() + min := validRange.Min.Value() + added := (requestedInt64 - min) + n := added / step + mod := added % step + if mod != 0 { + n += 1 + } + val := min + step*n + return *resource.NewQuantity(val, resource.BinarySI) +} + +// roundUpValidValues returns the first value in validValues that is greater than or equal to requestedVal. +// If no such value exists, it returns requestedVal itself. +func roundUpValidValues(requestedVal *resource.Quantity, validValues []resource.Quantity) resource.Quantity { + // Simple sequential search is used as the maximum entry of validValues is finite and small (≤10), + // and the list must already be sorted in ascending order, ensured by API validation. + // Note: A binary search could alternatively be used for better efficiency if the list grows larger. + for _, validValue := range validValues { + if requestedVal.Cmp(validValue) <= 0 { + return validValue.DeepCopy() + } + } + return *requestedVal +} + +// GetConsumedCapacityFromRequest returns valid consumed capacity, +// according to claim request and defined capacity. +func GetConsumedCapacityFromRequest(requestedCapacity *resourceapi.CapacityRequirements, + consumableCapacity map[resourceapi.QualifiedName]resourceapi.DeviceCapacity) map[resourceapi.QualifiedName]resource.Quantity { + consumedCapacity := make(map[resourceapi.QualifiedName]resource.Quantity) + for name, cap := range consumableCapacity { + var requestedValPtr *resource.Quantity + if requestedCapacity != nil && requestedCapacity.Requests != nil { + if requestedVal, requestedFound := requestedCapacity.Requests[name]; requestedFound { + requestedValPtr = &requestedVal + } + } + capacity := calculateConsumedCapacity(requestedValPtr, cap) + consumedCapacity[name] = capacity + } + return consumedCapacity +} + +// violatesPolicy checks whether the request violate the requestPolicy. +func violatesPolicy(requestedVal resource.Quantity, policy *resourceapi.CapacityRequestPolicy) bool { + if policy == nil { + // no policy to check + return false + } + if policy.Default != nil && requestedVal == *policy.Default { + return false + } + switch { + case policy.ValidRange != nil: + return violateValidRange(requestedVal, *policy.ValidRange) + case len(policy.ValidValues) > 0: + return violateValidValues(requestedVal, policy.ValidValues) + } + // no policy violated through to completion. + return false +} + +func violateValidRange(requestedVal resource.Quantity, validRange resourceapi.CapacityRequestPolicyRange) bool { + if validRange.Max != nil && + requestedVal.Cmp(*validRange.Max) > 0 { + return true + } + if validRange.Step != nil { + requestedInt64 := requestedVal.Value() + step := validRange.Step.Value() + min := validRange.Min.Value() + added := (requestedInt64 - min) + mod := added % step + // must be a multiply of step + if mod != 0 { + return true + } + } + return false +} + +func violateValidValues(requestedVal resource.Quantity, validValues []resource.Quantity) bool { + for _, validVal := range validValues { + if requestedVal.Cmp(validVal) == 0 { + return false + } + } + return true +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/pools_incubating.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/pools_incubating.go index 5522b1a8fd..73a09d29b6 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/pools_incubating.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/incubating/pools_incubating.go @@ -17,14 +17,19 @@ limitations under the License. package incubating import ( + "cmp" "context" "fmt" + "slices" + + "github.com/go-logr/logr" v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" draapi "k8s.io/dynamic-resource-allocation/api" + "k8s.io/klog/v2" "k8s.io/utils/ptr" ) @@ -51,30 +56,27 @@ func NodeMatches(node *v1.Node, nodeNameToMatch string, allNodesMatch bool, node // Out-dated slices are silently ignored. Pools may be incomplete (not all // required slices available) or invalid (for example, device names not unique). // Both is recorded in the result. -func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node *v1.Node, features Features) ([]*Pool, error) { +func GatherPools(ctx context.Context, slicesForNode []*resourceapi.ResourceSlice, node *v1.Node, features Features, allSlices []*resourceapi.ResourceSlice) ([]*Pool, error) { pools := make(map[PoolID][]*draapi.ResourceSlice) - for _, slice := range slices { + for _, slice := range slicesForNode { if !features.PartitionableDevices && (slice.Spec.PerDeviceNodeSelection != nil || len(slice.Spec.SharedCounters) > 0) { continue } + // Determine if the slice is relevant for the node. + relevant := false + // Always include slices with SharedCounters since they are needed to use a pool // regardless of their node selector. if len(slice.Spec.SharedCounters) > 0 { - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } + relevant = true } else if nodeName, allNodes := ptr.Deref(slice.Spec.NodeName, ""), ptr.Deref(slice.Spec.AllNodes, false); nodeName != "" || allNodes || slice.Spec.NodeSelector != nil { match, err := NodeMatches(node, nodeName, allNodes, slice.Spec.NodeSelector) if err != nil { return nil, fmt.Errorf("failed to perform node selection for slice %s: %w", slice.Name, err) } - if match { - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } - } + relevant = match } else if ptr.Deref(slice.Spec.PerDeviceNodeSelection, false) { for _, device := range slice.Spec.Devices { match, err := NodeMatches(node, ptr.Deref(device.NodeName, ""), ptr.Deref(device.AllNodes, false), device.NodeSelector) @@ -83,9 +85,7 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node device.String(), slice.Name, err) } if match { - if err := addSlice(pools, slice); err != nil { - return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) - } + relevant = true break } } @@ -100,6 +100,11 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node continue } + if relevant { + if err := addSlice(pools, slice); err != nil { + return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) + } + } } // Find incomplete pools and flatten into a single slice. @@ -110,6 +115,7 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node // if they are not relevant for the node, so we have to be // careful with the "is incomplete" check. result := make([]*Pool, 0, len(pools)) + var resultWithBindingConditions []*Pool for poolID, slicesForPool := range pools { // If we have all slices, we are done. isComplete := int64(len(slicesForPool)) == slicesForPool[0].Spec.Pool.ResourceSliceCount @@ -118,6 +124,10 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node if err != nil { return nil, err } + if poolHasBindingConditions(*pool) { + resultWithBindingConditions = append(resultWithBindingConditions, pool) + continue + } result = append(result, pool) continue } @@ -125,7 +135,7 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node // which were filtered out above because their node selection made them look irrelevant // for the current node. This is necessary for "allocate all" mode (it rejects incomplete // pools). - isObsolete, allSlicesForPool := checkSlicesInPool(slices, poolID, slicesForPool[0].Spec.Pool.Generation) + isObsolete, allSlicesForPool := checkSlicesInPool(allSlices, poolID, slicesForPool[0].Spec.Pool.Generation) if isObsolete { // A more thorough check determined that the DRA driver is in the process // of replacing the current generation. The newer one didn't have any slice @@ -155,12 +165,42 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node if err != nil { return nil, err } + // if pool has binding conditions, add the pool to the end of the result + if poolHasBindingConditions(*pool) { + resultWithBindingConditions = append(resultWithBindingConditions, pool) + continue + } result = append(result, pool) } + // Sort pools by ID to ensure a deterministic allocation order. + // Because the allocator uses a first-fit search, this allows driver authors + // to influence prioritization through their naming conventions. + sortPoolsByID(result) + sortPoolsByID(resultWithBindingConditions) + + if len(resultWithBindingConditions) != 0 { + result = append(result, resultWithBindingConditions...) + } + return result, nil } +func sortSlicesByName(slicesToSort []*draapi.ResourceSlice) { + slices.SortFunc(slicesToSort, func(a, b *draapi.ResourceSlice) int { + return cmp.Compare(a.Name, b.Name) + }) +} + +func sortPoolsByID(pools []*Pool) { + slices.SortFunc(pools, func(a, b *Pool) int { + if cmp := cmp.Compare(a.PoolID.Driver.String(), b.PoolID.Driver.String()); cmp != 0 { + return cmp + } + return cmp.Compare(a.PoolID.Pool.String(), b.PoolID.Pool.String()) + }) +} + func addSlice(pools map[PoolID][]*draapi.ResourceSlice, s *resourceapi.ResourceSlice) error { var slice draapi.ResourceSlice if err := draapi.Convert_v1_ResourceSlice_To_api_ResourceSlice(s, &slice, nil); err != nil { @@ -193,6 +233,11 @@ func addSlice(pools map[PoolID][]*draapi.ResourceSlice, s *resourceapi.ResourceS } func buildPool(id PoolID, slices []*draapi.ResourceSlice, features Features, allSlicesForPool []*resourceapi.ResourceSlice) (*Pool, error) { + // Sort slices by name to ensure a deterministic allocation order. + // Because the allocator uses a first-fit search, this allows driver authors + // to influence prioritization through their naming conventions. + sortSlicesByName(slices) + var deviceSlices []*draapi.ResourceSlice var counterSetSlices []*draapi.ResourceSlice if features.PartitionableDevices { @@ -340,6 +385,17 @@ func validateDeviceCounterConsumption(counterSets map[draapi.UniqueString]*draap return nil } +func poolHasBindingConditions(pool Pool) bool { + for _, slice := range pool.DeviceSlicesTargetingNode { + for _, device := range slice.Spec.Devices { + if device.BindingConditions != nil { + return true + } + } + } + return false +} + // checkSlicesInPool is an expensive check of all slices in the pool. // The generation is what the caller wants to move ahead with. // @@ -390,3 +446,80 @@ type PoolID struct { func (p PoolID) String() string { return p.Driver.String() + "/" + p.Pool.String() } + +// At V(6), log only a limited number of devices to avoid blowing up logs. For +// many E2E tests, 10 devices is enough for all devices without having to +// truncate, at least when running the tests sequentially. +const maxDevicesLevel6 = 10 + +// logPools returns a handle for the value in a structured log call which +// includes varying amounts of information about the pools, depending on +// the verbosity of the logger. +func logPools(logger klog.Logger, pools []*Pool) any { + // We need to check verbosity here because our caller's source code + // location may be relevant (-vmodule !). + helper, logger := logger.WithCallStackHelper() + helper() + + // We always produce the same output at V <= 5. 6 adds a summary and + // 7 is a complete dump. + verbosity := 5 + for i := 7; i > verbosity; i-- { + if loggerV := logger.V(i); loggerV.Enabled() { + verbosity = i + break + } + } + return &poolsLogger{verbosity, pools} +} + +type poolsLogger struct { + verbosity int + pools []*Pool +} + +var _ logr.Marshaler = &poolsLogger{} + +func (p *poolsLogger) MarshalLog() any { + info := map[string]any{"count": len(p.pools)} + if p.verbosity == 6 { + meta := make([]map[string]any, len(p.pools)) + for i, pool := range p.pools { + meta[i] = map[string]any{ + "id": pool.PoolID.String(), + "isIncomplete": pool.IsIncomplete, + "isInvalid": pool.IsInvalid, + "InvalidReason": pool.InvalidReason, + } + } + info["meta"] = meta + info["devices"] = p.listDevices(maxDevicesLevel6) + } + if p.verbosity >= 7 { + info["devices"] = p.listDevices(-1) + info["content"] = p.pools + } + return info +} + +func (p *poolsLogger) listDevices(maxDevices int) []string { + var devices []string + for _, pool := range p.pools { + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesTargetingNode, maxDevices) + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesNotTargetingNode, maxDevices) + } + return devices +} + +func (p *poolsLogger) addDevicesInSlices(devices []string, poolID PoolID, slices []*draapi.ResourceSlice, maxDevices int) []string { + for _, slice := range slices { + for _, device := range slice.Spec.Devices { + if maxDevices != -1 && len(devices) >= maxDevices { + devices = append(devices, "...") + return devices + } + devices = append(devices, DeviceID{Driver: poolID.Driver, Pool: poolID.Pool, Device: device.Name}.String()) + } + } + return devices +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/allocator_stable.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/allocator_stable.go index eb51355247..bb85ff5286 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/allocator_stable.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/allocator_stable.go @@ -24,6 +24,7 @@ import ( "slices" "strings" "sync" + "sync/atomic" v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" @@ -45,14 +46,15 @@ func MakeDeviceID(driver, pool, device string) DeviceID { return internal.MakeDeviceID(driver, pool, device) } -// SupportedFeatures does not include any additional features. -// The "stable" implementation can only be used if all of those -// are off. -// -// At least that's its purpose conceptually: in practice, all -// code supporting the additional features is still there. -// It could get removed. -var SupportedFeatures = internal.Features{} +// SupportedFeatures includes all additional features, +// making this the variant that is used when any of those +// are enabled. +var SupportedFeatures = internal.Features{ + AdminAccess: true, + PrioritizedList: true, + PartitionableDevices: true, + DeviceTaints: true, +} type Allocator struct { features Features @@ -60,19 +62,26 @@ type Allocator struct { classLister DeviceClassLister slices []*resourceapi.ResourceSlice celCache *cel.Cache - // availableCounters contains the available counters for individual - // ResourceSlices. It acts as a cache that is updated the first time - // the available counters are needed for each ResourceSlice. The information - // about each slice is never updated once set the first time. + // availableCounters contains the available counters for each + // resource pool. It acts as a cache that is updated the first time + // the available counters are needed for each pool. The information + // about each pool is never updated once set the first time. // This is computed bsed on information on the Allocator, so it will // be correct even for multiple usages of the Allocator. - // The keys in the map are ResourceSlice names. + // The keys in the map are resource pool names. // The allocator might be accessed by different goroutines, so // access to this map must be synchronized. - availableCounters map[string]counterSets + availableCounters map[draapi.UniqueString]counterSets mutex sync.RWMutex + // numAllocateOneInvocations counts the number of times the allocateOne + // function is called for the allocator. This is a measurement of the + // amount of work the allocator had to do to allocate devices + // for the claims. + numAllocateOneInvocations atomic.Int64 } +var _ internal.AllocatorExtended = &Allocator{} + // NewAllocator returns an allocator for a certain set of claims or an error if // some problem was detected which makes it impossible to allocate claims. // @@ -90,10 +99,14 @@ func NewAllocator(ctx context.Context, classLister: classLister, slices: slices, celCache: celCache, - availableCounters: make(map[string]counterSets), + availableCounters: make(map[draapi.UniqueString]counterSets), }, nil } +func (a *Allocator) Channel() internal.AllocatorChannel { + return internal.Stable +} + func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resourceapi.ResourceClaim) (finalResult []resourceapi.AllocationResult, finalErr error) { alloc := &allocator{ Allocator: a, @@ -103,7 +116,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou claimsToAllocate: claims, deviceMatchesRequest: make(map[matchKey]bool), constraints: make([][]constraint, len(claims)), - consumedCounters: make(map[string]counterSets), + consumedCounters: make(map[draapi.UniqueString]counterSets), requestData: make(map[requestIndices]requestData), result: make([]internalAllocationResult, len(claims)), } @@ -118,11 +131,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou return nil, fmt.Errorf("gather pool information: %w", err) } alloc.pools = pools - if loggerV := alloc.logger.V(7); loggerV.Enabled() { - loggerV.Info("Gathered pool information", "numPools", len(pools), "pools", pools) - } else { - alloc.logger.V(5).Info("Gathered pool information", "numPools", len(pools)) - } + alloc.logger.V(5).Info("Gathered pool information", "pools", logPools(alloc.logger, pools)) // We allocate one claim after the other and for each claim, all of // its requests. For each individual device we pick one possible @@ -175,12 +184,12 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // We can only predict a lower number of devices because it depends on which // subrequest gets chosen. for i, subReq := range request.FirstAvailable { + requestKey.subRequestIndex = i reqData, err := alloc.validateDeviceRequest(&deviceSubRequestAccessor{subRequest: &subReq}, &exactDeviceRequestAccessor{request: request}, requestKey, pools) if err != nil { return nil, err } - requestKey.subRequestIndex = i alloc.requestData[requestKey] = reqData if reqData.numDevices < minDevicesPerRequest { minDevicesPerRequest = reqData.numDevices @@ -246,7 +255,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou // We can estimate the size based on what we need to allocate. alloc.allocatingDevices = make(map[DeviceID]sets.Set[int], minDevicesTotal) - alloc.logger.V(6).Info("Gathered information about devices", "numAllocated", len(alloc.allocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) + alloc.logger.V(5).Info("Gathered information about devices", "allocatedDevices", logAllocatedDevices(alloc.logger, alloc.allocatedDevices), "minDevicesToBeAllocated", minDevicesTotal) // In practice, there aren't going to be many different CEL // expressions. Most likely, there is going to be handful of different @@ -295,6 +304,7 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou Pool: internal.id.Pool.String(), Device: internal.id.Device.String(), AdminAccess: internal.adminAccess, + Tolerations: internal.lookupRequest(claim).tolerations(), } } @@ -388,9 +398,11 @@ func (a *Allocator) Allocate(ctx context.Context, node *v1.Node, claims []*resou return result, nil } -func (a *Allocator) GetStats() *Stats { - // Not implemented. - return nil +func (a *Allocator) GetStats() Stats { + s := Stats{ + NumAllocateOneInvocations: a.numAllocateOneInvocations.Load(), + } + return s } func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentRequest requestAccessor, requestKey requestIndices, pools []*Pool) (requestData, error) { @@ -448,7 +460,7 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq return requestData, fmt.Errorf("claim %s, request %s: asks for all devices, but resource pool %s is currently invalid", klog.KObj(claim), request.name(), pool.PoolID) } - for _, slice := range pool.Slices { + for _, slice := range pool.DeviceSlicesTargetingNode { for deviceIndex := range slice.Spec.Devices { selectable, err := alloc.isSelectable(requestKey, requestData, slice, deviceIndex) if err != nil { @@ -459,6 +471,7 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq id: DeviceID{Driver: slice.Spec.Driver, Pool: slice.Spec.Pool.Name, Device: slice.Spec.Devices[deviceIndex].Name}, Device: &slice.Spec.Devices[deviceIndex], slice: slice, + pool: pool, } requestData.allDevices = append(requestData.allDevices, device) } @@ -477,6 +490,13 @@ func (alloc *allocator) validateDeviceRequest(request requestAccessor, parentReq // that allocation cannot succeed. var errStop = errors.New("stop allocation") +// errAllocationResultMaxSizeExceeded is a special error that gets return by +// allocatedOne when the number of allocated devices exceeds the max number +// allowed. This is checked by earlier invocations in the recursion and used +// to do more aggressive backtracking and avoid attempting allocations that +// we know can not succeed. +var errAllocationResultMaxSizeExceeded = errors.New("allocation max size exceeded") + // allocator is used while an [Allocator.Allocate] is running. Only a single // goroutine works with it, so there is no need for locking. type allocator struct { @@ -490,8 +510,8 @@ type allocator struct { constraints [][]constraint // one list of constraints per claim // consumedCounters keeps track of the counters consumed by all devices // that are in the process of being allocated. - // The keys in the map are ResourceSlice names. - consumedCounters map[string]counterSets + // The keys in the map are resource pool names. + consumedCounters map[draapi.UniqueString]counterSets requestData map[requestIndices]requestData // one entry per request with no subrequests and one entry per subrequest // allocatingDevices tracks which devices will be newly allocated for a // particular attempt to find a solution. The map is indexed by device @@ -560,6 +580,7 @@ type deviceWithID struct { *draapi.Device id DeviceID slice *draapi.ResourceSlice + pool *Pool } type internalAllocationResult struct { @@ -575,11 +596,36 @@ type internalDeviceResult struct { adminAccess *bool } -func (i internalDeviceResult) requestName() string { - if i.parentRequest == "" { - return i.request +func (idr internalDeviceResult) requestName() string { + if idr.parentRequest == "" { + return idr.request } - return fmt.Sprintf("%s/%s", i.parentRequest, i.request) + return fmt.Sprintf("%s/%s", idr.parentRequest, idr.request) +} + +func (idr internalDeviceResult) lookupRequest(claim *resourceapi.ResourceClaim) requestAccessor { + requestName := idr.request + if idr.parentRequest != "" { + requestName = idr.parentRequest + } + for i := range claim.Spec.Devices.Requests { + request := &claim.Spec.Devices.Requests[i] + if request.Name != requestName { + continue + } + if idr.parentRequest == "" { + // No need to check sub-requests. + return &exactDeviceRequestAccessor{request} + } + for j := range request.FirstAvailable { + subRequest := &request.FirstAvailable[j] + if subRequest.Name != idr.request { + continue + } + return &deviceSubRequestAccessor{subRequest} + } + } + return nil } type constraint interface { @@ -718,6 +764,8 @@ func lookupAttribute(device *draapi.Device, deviceID DeviceID, attributeName res // This allows the logic for subrequests to call allocateOne with the same // device index without causing infinite recursion. func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (bool, error) { + alloc.numAllocateOneInvocations.Add(1) + if alloc.ctx.Err() != nil { return false, fmt.Errorf("filter operation aborted: %w", context.Cause(alloc.ctx)) } @@ -733,7 +781,17 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b claim := alloc.claimsToAllocate[r.claimIndex] if r.requestIndex >= len(claim.Spec.Devices.Requests) { // Done with the claim, continue with the next one. - return alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex + 1}, false) + if errors.Is(err, errAllocationResultMaxSizeExceeded) { + // We don't need to propagate this further because + // this is not a fatal error. Retrying the claim under + // different circumstances may succeed if it uses + // subrequests and changing the allocation of some + // prior claim enables allocating a subrequest here + // which needs fewer devices. + return false, nil + } + return success, err } // r.subRequestIndex is zero unless the for loop below is in the @@ -746,16 +804,40 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // hitting the first subrequest, but not if we are already working on a // specific subrequest. if !allocateSubRequest && requestData.parentRequest != nil { + // Keep track of whether all attempts to do allocation with the + // subrequests results in the allocation result limit exceeded. + // If so, there is no need to make attempts with other devices + // in the previous request (if any), except when + // it is a firstAvailable request where some sub-requests + // need less devices than others. + allAllocationExceeded := true for subRequestIndex := 0; ; subRequestIndex++ { nextSubRequestKey := requestKey nextSubRequestKey.subRequestIndex = subRequestIndex if _, ok := alloc.requestData[nextSubRequestKey]; !ok { // Past the end of the subrequests without finding a solution -> give up. + // + // Return errAllocationResultMaxSizeExceeded if all + // attempts for the subrequests failed to due to reaching + // the max size limit. This would mean that there are no + // solution that involves the previous request (if any). + if allAllocationExceeded { + return false, errAllocationResultMaxSizeExceeded + } return false, nil } r.subRequestIndex = subRequestIndex success, err := alloc.allocateOne(r, true /* prevent infinite recusion */) + // If we reached the allocation result limit, we can try + // with the next subrequest if there is one. It might request + // fewer devices, so it might succeed. + if errors.Is(err, errAllocationResultMaxSizeExceeded) { + continue + } + // If we get here, at least one of the subrequests failed for a + // different reason than errAllocationResultMaxSizeExceeded. + allAllocationExceeded = false if err != nil { return false, err } @@ -787,17 +869,24 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // Done with request, continue with next one. We have completed the work for // the request or subrequest, so we can no longer be allocating devices for // a subrequest. - return alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false) + success, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex + 1}, false) + // We want to propagate any errAllocationResultMaxSizeExceeded to the caller. If + // that error is returned here, it means none of the requests/subrequests after this one + // could be allocated while staying within the limit on the number of devices, so there + // are no solution in the current request/subrequest that would work. + return success, err } + // Before trying to allocate devices, check if allocating the devices + // in the current request will put us over the threshold. // We can calculate this by adding the number of already allocated devices with the number // of devices in the current request, and then finally subtract the deviceIndex since we // don't want to double count any devices already allocated for the current request. numDevicesAfterAlloc := len(alloc.result[r.claimIndex].devices) + requestData.numDevices - r.deviceIndex if numDevicesAfterAlloc > resourceapi.AllocationResultsMaxSize { - // Don't return an error here since we want to keep searching for - // a solution that works. - return false, nil + // Return a special error so we can identify this situation in the + // callers and do more aggressive backtracking. + return false, errAllocationResultMaxSizeExceeded } alloc.logger.V(6).Info("Allocating one device", "currentClaim", r.claimIndex, "totalClaims", len(alloc.claimsToAllocate), "currentRequest", r.requestIndex, "currentSubRequest", r.subRequestIndex, "totalRequestsPerClaim", len(claim.Spec.Devices.Requests), "currentDevice", r.deviceIndex, "devicesPerRequest", requestData.numDevices, "allDevices", doAllDevices, "adminAccess", request.adminAccess()) @@ -815,14 +904,13 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b // get all of them, then there is no solution and we have to stop. return false, nil } - done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest) - if err != nil { - return false, err - } - if !done { - // Backtrack. + done, err := alloc.allocateOne(deviceIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, subRequestIndex: r.subRequestIndex, deviceIndex: r.deviceIndex + 1}, allocateSubRequest) + if err != nil || !done { + // If we get an error or didn't complete, we need to backtrack. Depending + // on the situation we might be able to retry, so we make sure we + // deallocate. deallocate() - return false, nil + return false, err } return done, nil } @@ -835,7 +923,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b if pool.IsIncomplete || pool.IsInvalid { continue } - for _, slice := range pool.Slices { + for _, slice := range pool.DeviceSlicesTargetingNode { for deviceIndex := range slice.Spec.Devices { deviceID := DeviceID{Driver: pool.Driver, Pool: pool.Pool, Device: slice.Spec.Devices[deviceIndex].Name} @@ -865,6 +953,7 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b id: deviceID, Device: &slice.Spec.Devices[deviceIndex], slice: slice, + pool: pool, } allocated, deallocate, err := alloc.allocateDevice(r, device, false) if err != nil { @@ -882,17 +971,22 @@ func (alloc *allocator) allocateOne(r deviceIndices, allocateSubRequest bool) (b deviceIndex: r.deviceIndex + 1, } done, err := alloc.allocateOne(deviceKey, allocateSubRequest) - if err != nil { - return false, err - } - - // If we found a solution, then we can stop. - if done { + // If we found a solution, we can stop. + if err == nil && done { return done, nil } - // Otherwise try some other device after rolling back. + // Otherwise we didn't find a solution, and we need to deallocate + // so the temporary allocation is correct for trying other devices. deallocate() + + if err != nil { + // If we hit an error, we return. This might be that we reached + // the allocation size limit, and if so, it will be caught further + // up the stack and other subrequests will be attempted if there + // are any. + return false, err + } } } } @@ -1005,6 +1099,9 @@ func (alloc *allocator) selectorsMatch(r requestIndices, device *draapi.Device, // as if that candidate had been allocated. If allocation cannot continue later // and must try something else, then the rollback function can be invoked to // restore the previous state. +// +// The rollback function is only provided in case of a successful allocation +// (true and no error). func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, must bool) (bool, func(), error) { claim := alloc.claimsToAllocate[r.claimIndex] requestKey := requestIndices{claimIndex: r.claimIndex, requestIndex: r.requestIndex, subRequestIndex: r.subRequestIndex} @@ -1053,7 +1150,7 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus // Might be tainted, in which case the taint has to be tolerated. // The check is skipped if the feature is disabled. - if alloc.features.DeviceTaints && !allTaintsTolerated(device.Device, request) { + if alloc.features.DeviceTaints && taintPreventsAllocation(device.Device, request) { return false, nil, nil } @@ -1111,13 +1208,17 @@ func (alloc *allocator) allocateDevice(r deviceIndices, device deviceWithID, mus }, nil } -func allTaintsTolerated(device *draapi.Device, request requestAccessor) bool { +func taintPreventsAllocation(device *draapi.Device, request requestAccessor) bool { for _, taint := range device.Taints { - if !taintTolerated(taint, request) { - return false + switch taint.Effect { + // Only known effects prevent allocation, others (including None) are ignored. + case resourceapi.DeviceTaintEffectNoExecute, resourceapi.DeviceTaintEffectNoSchedule: + if !taintTolerated(taint, request) { + return true + } } } - return true + return false } func taintTolerated(taint resourceapi.DeviceTaint, request requestAccessor) bool { @@ -1135,13 +1236,13 @@ func taintTolerated(taint resourceapi.DeviceTaint, request requestAccessor) bool // Gets called only if the partitionable devices feature is enabled and the device // consumes counters. func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error) { - slice := device.slice - sliceName := slice.Name + pool := device.pool + poolName := pool.PoolID.Pool - // Check first if the available counters for this slice have already been + // Check first if the available counters for this pool have already been // calculated. alloc.mutex.RLock() - availableCountersForSlice, found := alloc.availableCounters[sliceName] + availableCountersForPool, found := alloc.availableCounters[poolName] alloc.mutex.RUnlock() // If not, we need to do it now. But we store the result so it doesn't need // to be calculated again. @@ -1149,69 +1250,73 @@ func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error // might also do this work. But the input will be the same to all of them, so // the result will also always be the same. if !found { - availableCountersForSlice = make(counterSets, len(slice.Spec.SharedCounters)) - for _, counterSet := range slice.Spec.SharedCounters { + availableCountersForPool = make(counterSets, len(pool.CounterSets)) + for _, counterSet := range pool.CounterSets { availableCountersForCounterSet := make(map[string]resourceapi.Counter, len(counterSet.Counters)) for name, c := range counterSet.Counters { availableCountersForCounterSet[name] = c } - availableCountersForSlice[counterSet.Name] = availableCountersForCounterSet + availableCountersForPool[counterSet.Name] = availableCountersForCounterSet } // Update the data structure to reflect counters already consumed by allocated devices. This // only includes devices where the allocation process has completed, so this will never // change during the allocation process. - for _, device := range slice.Spec.Devices { - deviceID := DeviceID{ - Driver: slice.Spec.Driver, - Pool: slice.Spec.Pool.Name, - Device: device.Name, - } - // Devices that aren't allocated doesn't consume any counters, so we don't - // need to consider them. - if !alloc.allocatedDevices.Has(deviceID) { - continue - } - for _, deviceCounterConsumption := range device.ConsumesCounters { - availableCountersForCounterSet := availableCountersForSlice[deviceCounterConsumption.CounterSet] - for name, c := range deviceCounterConsumption.Counters { - existingCounter, ok := availableCountersForCounterSet[name] - if !ok { - // the API validation logic has been added to make sure the counters referred should exist in counter sets. + for _, resourceSlices := range [][]*draapi.ResourceSlice{pool.DeviceSlicesTargetingNode, pool.DeviceSlicesNotTargetingNode} { + for _, slice := range resourceSlices { + for _, device := range slice.Spec.Devices { + deviceID := DeviceID{ + Driver: slice.Spec.Driver, + Pool: slice.Spec.Pool.Name, + Device: device.Name, + } + // Devices that aren't allocated doesn't consume any counters, so we don't + // need to consider them. + if !alloc.allocatedDevices.Has(deviceID) { continue } - // This can potentially result in negative available counters. That is fine, - // we just treat it as no counters available. - existingCounter.Value.Sub(c.Value) - availableCountersForCounterSet[name] = existingCounter + for _, deviceCounterConsumption := range device.ConsumesCounters { + availableCountersForCounterSet := availableCountersForPool[deviceCounterConsumption.CounterSet] + for name, c := range deviceCounterConsumption.Counters { + existingCounter, ok := availableCountersForCounterSet[name] + if !ok { + // the API validation logic has been added to make sure the counters referred should exist in counter sets. + continue + } + // This can potentially result in negative available counters. That is fine, + // we just treat it as no counters available. + existingCounter.Value.Sub(c.Value) + availableCountersForCounterSet[name] = existingCounter + } + } + // Note that we don't include devices in the alloc.allocatingDevices here since + // counters consumed by devices for the current claims are tracked in + // alloc.consumedCounters } } - // Note that we don't include devices in the alloc.allocatingDevices here since - // counters consumed by devices for the current claims are tracked in - // alloc.consumedCounters } // Set the available counters on the allocator so we don't have to // compute this again. alloc.mutex.Lock() - alloc.availableCounters[sliceName] = availableCountersForSlice + alloc.availableCounters[poolName] = availableCountersForPool alloc.mutex.Unlock() } // Update the consumedCounters data structure with the counters consumed // by the current device. - consumedCountersForSlice, found := alloc.consumedCounters[sliceName] + consumedCountersForPool, found := alloc.consumedCounters[poolName] // If no devices in the allocating state have consumed any counters from the current - // slice, initialize the data structure. + // pool, initialize the data structure. if !found { - consumedCountersForSlice = make(counterSets) - alloc.consumedCounters[sliceName] = consumedCountersForSlice + consumedCountersForPool = make(counterSets) + alloc.consumedCounters[poolName] = consumedCountersForPool } for _, deviceCounterConsumption := range device.ConsumesCounters { - consumedCountersForCounterSet, found := consumedCountersForSlice[deviceCounterConsumption.CounterSet] + consumedCountersForCounterSet, found := consumedCountersForPool[deviceCounterConsumption.CounterSet] if !found { consumedCountersForCounterSet = make(map[string]resourceapi.Counter) - consumedCountersForSlice[deviceCounterConsumption.CounterSet] = consumedCountersForCounterSet + consumedCountersForPool[deviceCounterConsumption.CounterSet] = consumedCountersForCounterSet } for name, c := range deviceCounterConsumption.Counters { consumedCounters, found := consumedCountersForCounterSet[name] @@ -1227,8 +1332,8 @@ func (alloc *allocator) checkAvailableCounters(device deviceWithID) (bool, error // Check that we didn't exceed the availability of any counters by allocating // the current device. If we did, the current set of devices doesn't work, so we // update the consumed counters to no longer reflect the current device. - for availableCounterSetName, availableCounters := range availableCountersForSlice { - consumedCounters := consumedCountersForSlice[availableCounterSetName] + for availableCounterSetName, availableCounters := range availableCountersForPool { + consumedCounters := consumedCountersForPool[availableCounterSetName] for availableCounterName, availableCounter := range availableCounters { consumedCounter := consumedCounters[availableCounterName] if availableCounter.Value.Cmp(consumedCounter.Value) < 0 { @@ -1256,13 +1361,12 @@ func (alloc *allocator) allocatingDeviceForClaim(deviceID DeviceID, claimIndex i // deallocateCountersForDevice subtracts the consumed counters of the provided // device from the consumedCounters data structure. func (alloc *allocator) deallocateCountersForDevice(device deviceWithID) { - slice := device.slice - sliceName := slice.Name + poolName := device.pool.PoolID.Pool - consumedCountersForSlice := alloc.consumedCounters[sliceName] + consumedCountersForPool := alloc.consumedCounters[poolName] for _, deviceCounterConsumption := range device.ConsumesCounters { counterSetName := deviceCounterConsumption.CounterSet - consumedCounterSet := consumedCountersForSlice[counterSetName] + consumedCounterSet := consumedCountersForPool[counterSetName] for name, c := range deviceCounterConsumption.Counters { consumedCounter := consumedCounterSet[name] consumedCounter.Value.Sub(c.Value) diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/pools_stable.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/pools_stable.go index 951c723421..df79f92b6c 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/pools_stable.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/stable/pools_stable.go @@ -19,12 +19,16 @@ package stable import ( "context" "fmt" + "slices" + + "github.com/go-logr/logr" v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" draapi "k8s.io/dynamic-resource-allocation/api" + "k8s.io/klog/v2" "k8s.io/utils/ptr" ) @@ -52,14 +56,20 @@ func NodeMatches(node *v1.Node, nodeNameToMatch string, allNodesMatch bool, node // required slices available) or invalid (for example, device names not unique). // Both is recorded in the result. func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node *v1.Node, features Features) ([]*Pool, error) { - pools := make(map[PoolID]*Pool) + pools := make(map[PoolID][]*draapi.ResourceSlice) for _, slice := range slices { - if !features.PartitionableDevices && slice.Spec.PerDeviceNodeSelection != nil { + if !features.PartitionableDevices && (slice.Spec.PerDeviceNodeSelection != nil || len(slice.Spec.SharedCounters) > 0) { continue } - if nodeName, allNodes := ptr.Deref(slice.Spec.NodeName, ""), ptr.Deref(slice.Spec.AllNodes, false); nodeName != "" || allNodes || slice.Spec.NodeSelector != nil { + // Always include slices with SharedCounters since they are needed to use a pool + // regardless of their node selector. + if len(slice.Spec.SharedCounters) > 0 { + if err := addSlice(pools, slice); err != nil { + return nil, fmt.Errorf("failed to add node slice %s: %w", slice.Name, err) + } + } else if nodeName, allNodes := ptr.Deref(slice.Spec.NodeName, ""), ptr.Deref(slice.Spec.AllNodes, false); nodeName != "" || allNodes || slice.Spec.NodeSelector != nil { match, err := NodeMatches(node, nodeName, allNodes, slice.Spec.NodeSelector) if err != nil { return nil, fmt.Errorf("failed to perform node selection for slice %s: %w", slice.Name, err) @@ -104,81 +114,234 @@ func GatherPools(ctx context.Context, slices []*resourceapi.ResourceSlice, node // if they are not relevant for the node, so we have to be // careful with the "is incomplete" check. result := make([]*Pool, 0, len(pools)) - for poolID, pool := range pools { - // If we have all slices, we are done. If not, then we need to start looking for slices + for poolID, slicesForPool := range pools { + // If we have all slices, we are done. + isComplete := int64(len(slicesForPool)) == slicesForPool[0].Spec.Pool.ResourceSliceCount + if isComplete { + pool, err := buildPool(poolID, slicesForPool, features, nil) + if err != nil { + return nil, err + } + result = append(result, pool) + continue + } + // If not, then we need to start looking for slices // which were filtered out above because their node selection made them look irrelevant // for the current node. This is necessary for "allocate all" mode (it rejects incomplete // pools). - isComplete := int64(len(pool.Slices)) == pool.Slices[0].Spec.Pool.ResourceSliceCount - if !isComplete { - isObsolete, numSlices := checkSlicesInPool(slices, poolID, pool.Slices[0].Spec.Pool.Generation) - if isObsolete { - // A more thorough check determined that the DRA driver is in the process - // of replacing the current generation. The newer one didn't have any slice - // which devices for the node, or we would have noticed sooner. - // - // Let's ignore the old device information by ignoring the pool. - continue - } - // Use the more complete number of slices to check for "incomplete pool". + isObsolete, allSlicesForPool := checkSlicesInPool(slices, poolID, slicesForPool[0].Spec.Pool.Generation) + if isObsolete { + // A more thorough check determined that the DRA driver is in the process + // of replacing the current generation. The newer one didn't have any slice + // which devices for the node, or we would have noticed sooner. // - // The slices that we return to the caller still don't represent the whole - // pool, but that's okay: we *want* to limit the result to relevant devices - // so the caller doesn't need to check node selectors unnecessarily. - isComplete = numSlices == pool.Slices[0].Spec.Pool.ResourceSliceCount + // Let's ignore the old device information by ignoring the pool. + continue + } + // Use the more complete number of slices to check for "incomplete pool". + // + // The slices that we return to the caller still don't represent the whole + // pool, but that's okay: we *want* to limit the result to relevant devices + // so the caller doesn't need to check node selectors unnecessarily. + isComplete = int64(len(allSlicesForPool)) == slicesForPool[0].Spec.Pool.ResourceSliceCount + // If a pool is incomplete, we don't allow allocation so we don't need + // to do any validation. We need to keep track of the incomplete pools here + // to make sure allocationMode: All doesn't succeed without considering all + // devices. + if !isComplete { + result = append(result, &Pool{ + PoolID: poolID, + IsIncomplete: true, + }) + continue + } + pool, err := buildPool(poolID, slicesForPool, features, allSlicesForPool) + if err != nil { + return nil, err } - pool.IsIncomplete = !isComplete - pool.IsInvalid, pool.InvalidReason = poolIsInvalid(pool) result = append(result, pool) } return result, nil } -func addSlice(pools map[PoolID]*Pool, s *resourceapi.ResourceSlice) error { +func addSlice(pools map[PoolID][]*draapi.ResourceSlice, s *resourceapi.ResourceSlice) error { var slice draapi.ResourceSlice if err := draapi.Convert_v1_ResourceSlice_To_api_ResourceSlice(s, &slice, nil); err != nil { return fmt.Errorf("convert ResourceSlice: %w", err) } id := PoolID{Driver: slice.Spec.Driver, Pool: slice.Spec.Pool.Name} - pool := pools[id] - if pool == nil { + slicesForPool := pools[id] + if slicesForPool == nil { // New pool. - pool = &Pool{ - PoolID: id, - Slices: []*draapi.ResourceSlice{&slice}, - } - pools[id] = pool + pools[id] = []*draapi.ResourceSlice{&slice} return nil } - if slice.Spec.Pool.Generation < pool.Slices[0].Spec.Pool.Generation { + if slice.Spec.Pool.Generation < slicesForPool[0].Spec.Pool.Generation { // Out-dated. return nil } - if slice.Spec.Pool.Generation > pool.Slices[0].Spec.Pool.Generation { + if slice.Spec.Pool.Generation > slicesForPool[0].Spec.Pool.Generation { // Newer, replaces all old slices. - pool.Slices = nil + pools[id] = []*draapi.ResourceSlice{&slice} + return nil } // Add to pool. - pool.Slices = append(pool.Slices, &slice) + slicesForPool = append(slicesForPool, &slice) + pools[id] = slicesForPool + return nil +} + +func buildPool(id PoolID, slices []*draapi.ResourceSlice, features Features, allSlicesForPool []*resourceapi.ResourceSlice) (*Pool, error) { + var deviceSlices []*draapi.ResourceSlice + var counterSetSlices []*draapi.ResourceSlice + if features.PartitionableDevices { + for _, slice := range slices { + if len(slice.Spec.SharedCounters) > 0 { + counterSetSlices = append(counterSetSlices, slice) + } else { + deviceSlices = append(deviceSlices, slice) + } + } + } else { + deviceSlices = slices + } + if err := validateDeviceNames(deviceSlices); err != nil { + return &Pool{ + PoolID: id, + IsInvalid: true, + InvalidReason: err.Error(), + }, nil + } + // If the partitionable devices feature is not enabled, we don't need to + // validate counter sets and consumed counters, so we are done. + if !features.PartitionableDevices { + return &Pool{ + PoolID: id, + DeviceSlicesTargetingNode: deviceSlices, + }, nil + } + + counterSets, err := getAndValidateCounterSets(counterSetSlices) + if err != nil { + return &Pool{ + PoolID: id, + IsInvalid: true, + InvalidReason: err.Error(), + }, nil + } + + if err := validateDeviceCounterConsumption(counterSets, slices); err != nil { + return &Pool{ + PoolID: id, + IsInvalid: true, + InvalidReason: err.Error(), + }, nil + } + // If we have already seen all slices (both with counter sets and devices), + // we don't need to do any more validation. + if allSlicesForPool == nil || len(slices) == len(allSlicesForPool) { + return &Pool{ + PoolID: id, + DeviceSlicesTargetingNode: deviceSlices, + CounterSets: counterSets, + }, nil + } + + // If we have slices that were discarded earlier because they didn't target the current node + // we need to check them now. They might include devices that consume counters in the pool and + // the allocator needs to know about them to correctly determine available counters. + // + // We only want to convert the slices we haven't already converted, so make it easy to + // look up the names of converted slices. + slicesTargetingNodeNames := sets.New[string]() + for _, slice := range slices { + slicesTargetingNodeNames.Insert(slice.Name) + } + var slicesNotTargetingNode []*draapi.ResourceSlice + for _, slice := range allSlicesForPool { + if slicesTargetingNodeNames.Has(slice.Name) { + continue + } + var convertedSlice draapi.ResourceSlice + if err := draapi.Convert_v1_ResourceSlice_To_api_ResourceSlice(slice, &convertedSlice, nil); err != nil { + return nil, fmt.Errorf("convert ResourceSlice: %w", err) + } + slicesNotTargetingNode = append(slicesNotTargetingNode, &convertedSlice) + } + // We need to make sure the devices here are correctly consuming counters and counter + // sets. Otherwise the allocator might make incorrect decisions. + // We don't validate the device names here. It might be that we should do that, but + // this is consistent with existing behavior where we don't validate slices that + // we don't allocate from. + if err := validateDeviceCounterConsumption(counterSets, slicesNotTargetingNode); err != nil { + return &Pool{ + PoolID: id, + IsInvalid: true, + InvalidReason: err.Error(), + }, nil + } + return &Pool{ + PoolID: id, + DeviceSlicesTargetingNode: deviceSlices, + DeviceSlicesNotTargetingNode: slicesNotTargetingNode, + CounterSets: counterSets, + }, nil +} + +func getAndValidateCounterSets(slices []*draapi.ResourceSlice) (map[draapi.UniqueString]*draapi.CounterSet, error) { + counterSets := make(map[draapi.UniqueString]*draapi.CounterSet) + // We only capture the first error we encounter. + for _, slice := range slices { + for i := range slice.Spec.SharedCounters { + counterSet := slice.Spec.SharedCounters[i] + if _, found := counterSets[counterSet.Name]; found { + return nil, fmt.Errorf("duplicate counter set name %s", counterSet.Name) + } + counterSets[counterSet.Name] = &counterSet + } + } + return counterSets, nil +} + +func validateDeviceNames(resourceSlices []*draapi.ResourceSlice) error { + deviceNames := sets.New[draapi.UniqueString]() + for _, slice := range resourceSlices { + for _, device := range slice.Spec.Devices { + // Make sure we don't have duplicate device names + if deviceNames.Has(device.Name) { + return fmt.Errorf("duplicate device name %s", device.Name) + } + deviceNames.Insert(device.Name) + } + } return nil } -func poolIsInvalid(pool *Pool) (bool, string) { - devices := sets.New[draapi.UniqueString]() - for _, slice := range pool.Slices { +func validateDeviceCounterConsumption(counterSets map[draapi.UniqueString]*draapi.CounterSet, resourceSlices []*draapi.ResourceSlice) error { + for _, slice := range resourceSlices { for _, device := range slice.Spec.Devices { - if devices.Has(device.Name) { - return true, fmt.Sprintf("duplicate device name %s", device.Name) + // Make sure all consumed counters for the device references counter sets that exists and + // that they consume counters that exists within those counter sets. + for _, deviceCounterConsumption := range device.ConsumesCounters { + counterSet, found := counterSets[deviceCounterConsumption.CounterSet] + if !found { + return fmt.Errorf("counter set %s not found", deviceCounterConsumption.CounterSet) + } + + for counterName := range deviceCounterConsumption.Counters { + if _, found := counterSet.Counters[counterName]; !found { + return fmt.Errorf("counter %s not found in counter set %s", counterName, counterSet.Name) + } + } } - devices.Insert(device.Name) } } - return false, "" + return nil } // checkSlicesInPool is an expensive check of all slices in the pool. @@ -186,13 +349,15 @@ func poolIsInvalid(pool *Pool) (bool, string) { // // It returns: // - current generation is obsolete -> no further checking -// - total number of slices with the generation +// - all slices with the generation in the pool // // Future TODO: detect inconsistent ResourceSliceCount, also in poolIsInvalid. -func checkSlicesInPool(slices []*resourceapi.ResourceSlice, poolID PoolID, generation int64) (isObsolete bool, numSlices int64) { +func checkSlicesInPool(slices []*resourceapi.ResourceSlice, poolID PoolID, generation int64) (bool, []*resourceapi.ResourceSlice) { // A cached index by pool ID would make this more efficient. // It may be needed long-term to support features which always have to consider all slices. - for _, slice := range slices { + var allSlicesForPool []*resourceapi.ResourceSlice + for i := range slices { + slice := slices[i] if slice.Spec.Driver != poolID.Driver.String() || slice.Spec.Pool.Name != poolID.Pool.String() { // Different pool. @@ -200,24 +365,26 @@ func checkSlicesInPool(slices []*resourceapi.ResourceSlice, poolID PoolID, gener } switch { case slice.Spec.Pool.Generation == generation: - numSlices++ + allSlicesForPool = append(allSlicesForPool, slice) case slice.Spec.Pool.Generation > generation: // The caller must have missed some other slice in the pool. // Abort! - return true, 0 + return true, nil default: // Older generation, ignore. } } - return false, numSlices + return false, allSlicesForPool } type Pool struct { PoolID - IsIncomplete bool - IsInvalid bool - InvalidReason string - Slices []*draapi.ResourceSlice + IsIncomplete bool + IsInvalid bool + InvalidReason string + DeviceSlicesTargetingNode []*draapi.ResourceSlice + DeviceSlicesNotTargetingNode []*draapi.ResourceSlice + CounterSets map[draapi.UniqueString]*draapi.CounterSet } type PoolID struct { @@ -227,3 +394,126 @@ type PoolID struct { func (p PoolID) String() string { return p.Driver.String() + "/" + p.Pool.String() } + +// At V(6), log only a limited number of devices to avoid blowing up logs. For +// many E2E tests, 10 devices is enough for all devices without having to +// truncate, at least when running the tests sequentially. +const maxDevicesLevel6 = 10 + +// logPools returns a handle for the value in a structured log call which +// includes varying amounts of information about the pools, depending on +// the verbosity of the logger. +func logPools(logger klog.Logger, pools []*Pool) any { + // We need to check verbosity here because our caller's source code + // location may be relevant (-vmodule !). + helper, logger := logger.WithCallStackHelper() + helper() + + // We always produce the same output at V <= 5. 6 adds a summary and + // 7 is a complete dump. + verbosity := 5 + for i := 7; i > verbosity; i-- { + if loggerV := logger.V(i); loggerV.Enabled() { + verbosity = i + break + } + } + return &poolsLogger{verbosity, pools} +} + +type poolsLogger struct { + verbosity int + pools []*Pool +} + +var _ logr.Marshaler = &poolsLogger{} + +func (p *poolsLogger) MarshalLog() any { + info := map[string]any{"count": len(p.pools)} + if p.verbosity == 6 { + meta := make([]map[string]any, len(p.pools)) + for i, pool := range p.pools { + meta[i] = map[string]any{ + "id": pool.PoolID.String(), + "isIncomplete": pool.IsIncomplete, + "isInvalid": pool.IsInvalid, + "InvalidReason": pool.InvalidReason, + } + } + info["meta"] = meta + info["devices"] = p.listDevices(maxDevicesLevel6) + } + if p.verbosity >= 7 { + info["devices"] = p.listDevices(-1) + info["content"] = p.pools + } + return info +} + +func (p *poolsLogger) listDevices(maxDevices int) []string { + var devices []string + for _, pool := range p.pools { + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesTargetingNode, maxDevices) + devices = p.addDevicesInSlices(devices, pool.PoolID, pool.DeviceSlicesNotTargetingNode, maxDevices) + } + return devices +} + +func (p *poolsLogger) addDevicesInSlices(devices []string, poolID PoolID, slices []*draapi.ResourceSlice, maxDevices int) []string { + for _, slice := range slices { + for _, device := range slice.Spec.Devices { + if maxDevices != -1 && len(devices) >= maxDevices { + devices = append(devices, "...") + return devices + } + devices = append(devices, DeviceID{Driver: poolID.Driver, Pool: poolID.Pool, Device: device.Name}.String()) + } + } + return devices +} + +// logPools returns a handle for the value in a structured log call which +// includes varying amounts of information about the allocated devices, depending on +// the verbosity of the logger. +func logAllocatedDevices(logger klog.Logger, allocatedDevices sets.Set[DeviceID]) any { + // We need to check verbosity here because our caller's source code + // location may be relevant (-vmodule !). + helper, logger := logger.WithCallStackHelper() + helper() + + // We always produce the same output at V <= 5. 6 adds all IDs. + verbosity := 5 + for i := 7; i > verbosity; i-- { + if loggerV := logger.V(i); loggerV.Enabled() { + verbosity = i + break + } + } + + return &allocatedDevicesLogger{verbosity, allocatedDevices} +} + +type allocatedDevicesLogger struct { + verbosity int + devices sets.Set[DeviceID] +} + +var _ logr.Marshaler = &allocatedDevicesLogger{} + +func (a *allocatedDevicesLogger) MarshalLog() any { + info := map[string]any{"count": len(a.devices)} + if a.verbosity >= 6 { + ids := make([]string, 0, len(a.devices)) + for id := range a.devices { + if a.verbosity == 6 && len(ids) >= maxDevicesLevel6 { + ids = append(ids, "...") + break + } + ids = append(ids, id.String()) + } + slices.Sort(ids) + info["devices"] = ids + + } + return info +} diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/types.go b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/types.go index a1f2ad9878..4c06905732 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/internal/types.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/internal/types.go @@ -41,6 +41,7 @@ type DeviceClassLister interface { // This interface is also broader than the public one. type Allocator interface { Allocate(ctx context.Context, node *v1.Node, claims []*resourceapi.ResourceClaim) (finalResult []resourceapi.AllocationResult, finalErr error) + Channel() AllocatorChannel } // AllocatorExtended is an optional interface. Not all variants implement it. @@ -57,6 +58,14 @@ type Stats struct { NumAllocateOneInvocations int64 } +type AllocatorChannel string + +const ( + Experimental = "experimental" + Stable = "stable" + Incubating = "incubating" +) + // Features control optional functionality during ResourceClaim allocation. // Each entry must correspond to at least one control flow change. Entries can // be removed when the control flow change is no longer necessary (= feature is @@ -72,6 +81,7 @@ type Features struct { ConsumableCapacity bool DeviceBindingAndStatus bool DeviceTaints bool + ListTypeAttributes bool PartitionableDevices bool PrioritizedList bool } @@ -93,6 +103,9 @@ func (f Features) Set() sets.Set[string] { if f.DeviceTaints { enabled.Insert("DRADeviceTaints") } + if f.ListTypeAttributes { + enabled.Insert("DRAListTypeAttributes") + } if f.PartitionableDevices { enabled.Insert("DRAPartitionableDevices") } @@ -110,6 +123,7 @@ var FeaturesAll = Features{ ConsumableCapacity: true, DeviceBindingAndStatus: true, DeviceTaints: true, + ListTypeAttributes: true, PartitionableDevices: true, PrioritizedList: true, } diff --git a/vendor/k8s.io/dynamic-resource-allocation/structured/schedulerapi/types.go b/vendor/k8s.io/dynamic-resource-allocation/structured/schedulerapi/types.go index a401a8e1aa..8e06e886ec 100644 --- a/vendor/k8s.io/dynamic-resource-allocation/structured/schedulerapi/types.go +++ b/vendor/k8s.io/dynamic-resource-allocation/structured/schedulerapi/types.go @@ -58,6 +58,10 @@ func (d SharedDeviceID) String() string { return deviceIDStr } +func (d SharedDeviceID) GetDeviceID() DeviceID { + return DeviceID{d.Driver, d.Pool, d.Device} +} + // MakeSharedDeviceID creates a new SharedDeviceID from a DeviceID and share ID. // This function is used in consumable capacity features and the scheduler. func MakeSharedDeviceID(deviceID DeviceID, shareID *types.UID) SharedDeviceID { diff --git a/vendor/k8s.io/klog/v2/ktesting/options.go b/vendor/k8s.io/klog/v2/ktesting/options.go new file mode 100644 index 0000000000..2119a22266 --- /dev/null +++ b/vendor/k8s.io/klog/v2/ktesting/options.go @@ -0,0 +1,132 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "flag" + "strconv" + + "k8s.io/klog/v2/internal/serialize" + "k8s.io/klog/v2/internal/verbosity" +) + +// Config influences logging in a test logger. To make this configurable via +// command line flags, instantiate this once per program and use AddFlags to +// bind command line flags to the instance before passing it to NewTestContext. +// +// Must be constructed with NewConfig. +type Config struct { + vstate *verbosity.VState + co configOptions +} + +// Verbosity returns a value instance that can be used to query (via String) or +// modify (via Set) the verbosity threshold. This is thread-safe and can be +// done at runtime. +func (c *Config) Verbosity() flag.Value { + return c.vstate.V() +} + +// VModule returns a value instance that can be used to query (via String) or +// modify (via Set) the vmodule settings. This is thread-safe and can be done +// at runtime. +func (c *Config) VModule() flag.Value { + return c.vstate.VModule() +} + +// ConfigOption implements functional parameters for NewConfig. +type ConfigOption func(co *configOptions) + +type configOptions struct { + anyToString serialize.AnyToStringFunc + verbosityFlagName string + vmoduleFlagName string + verbosityDefault int + bufferLogs bool +} + +// AnyToString overrides the default formatter for values that are not +// supported directly by klog. The default is `fmt.Sprintf("%+v")`. +// The formatter must not panic. +func AnyToString(anyToString func(value interface{}) string) ConfigOption { + return func(co *configOptions) { + co.anyToString = anyToString + } +} + +// VerbosityFlagName overrides the default -testing.v for the verbosity level. +func VerbosityFlagName(name string) ConfigOption { + return func(co *configOptions) { + co.verbosityFlagName = name + } +} + +// VModulFlagName overrides the default -testing.vmodule for the per-module +// verbosity levels. +func VModuleFlagName(name string) ConfigOption { + return func(co *configOptions) { + co.vmoduleFlagName = name + } +} + +// Verbosity overrides the default verbosity level of 5. That default is higher +// than in klog itself because it enables logging entries for "the steps +// leading up to errors and warnings" and "troubleshooting" (see +// https://github.com/kubernetes/community/blob/9406b4352fe2d5810cb21cc3cb059ce5886de157/contributors/devel/sig-instrumentation/logging.md#logging-conventions), +// which is useful when debugging a failed test. `go test` only shows the log +// output for failed tests. To see all output, use `go test -v`. +func Verbosity(level int) ConfigOption { + return func(co *configOptions) { + co.verbosityDefault = level + } +} + +// BufferLogs controls whether log entries are captured in memory in addition +// to being printed. Off by default. Unit tests that want to verify that +// log entries are emitted as expected can turn this on and then retrieve +// the captured log through the Underlier LogSink interface. +func BufferLogs(enabled bool) ConfigOption { + return func(co *configOptions) { + co.bufferLogs = enabled + } +} + +// NewConfig returns a configuration with recommended defaults and optional +// modifications. Command line flags are not bound to any FlagSet yet. +func NewConfig(opts ...ConfigOption) *Config { + c := &Config{ + co: configOptions{ + verbosityFlagName: "testing.v", + vmoduleFlagName: "testing.vmodule", + verbosityDefault: 5, + }, + } + for _, opt := range opts { + opt(&c.co) + } + + c.vstate = verbosity.New() + // Cannot fail for this input. + _ = c.vstate.V().Set(strconv.FormatInt(int64(c.co.verbosityDefault), 10)) + return c +} + +// AddFlags registers the command line flags that control the configuration. +func (c *Config) AddFlags(fs *flag.FlagSet) { + fs.Var(c.vstate.V(), c.co.verbosityFlagName, "number for the log level verbosity of the testing logger") + fs.Var(c.vstate.VModule(), c.co.vmoduleFlagName, "comma-separated list of pattern=N log level settings for files matching the patterns") +} diff --git a/vendor/k8s.io/klog/v2/ktesting/setup.go b/vendor/k8s.io/klog/v2/ktesting/setup.go new file mode 100644 index 0000000000..bf1d03447f --- /dev/null +++ b/vendor/k8s.io/klog/v2/ktesting/setup.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + + "github.com/go-logr/logr" +) + +// DefaultConfig is the global default logging configuration for a unit +// test. It is used by NewTestContext and k8s.io/klogr/testing/init. +var DefaultConfig = NewConfig() + +// NewTestContext returns a logger and context for use in a unit test case or +// benchmark. The tl parameter can be a testing.T or testing.B pointer that +// will receive all log output. Importing k8s.io/klogr/testing/init will add +// command line flags that modify the configuration of that log output. +func NewTestContext(tl TL) (logr.Logger, context.Context) { + logger := NewLogger(tl, DefaultConfig) + ctx := logr.NewContext(context.Background(), logger) + return logger, ctx + +} diff --git a/vendor/k8s.io/klog/v2/ktesting/testinglogger.go b/vendor/k8s.io/klog/v2/ktesting/testinglogger.go new file mode 100644 index 0000000000..e8ffd4115d --- /dev/null +++ b/vendor/k8s.io/klog/v2/ktesting/testinglogger.go @@ -0,0 +1,407 @@ +/* +Copyright 2019 The Kubernetes Authors. +Copyright 2020 Intel Corporation. + +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 testinglogger contains an implementation of the logr interface +// which is logging through a function like testing.TB.Log function. +// Therefore it can be used in standard Go tests and Gingko test suites +// to ensure that output is associated with the currently running test. +// +// In addition, the log data is captured in a buffer and can be used by the +// test to verify that the code under test is logging as expected. To get +// access to that data, cast the LogSink into the Underlier type and retrieve +// it: +// +// logger := ktesting.NewLogger(...) +// if testingLogger, ok := logger.GetSink().(ktesting.Underlier); ok { +// t := testingLogger.GetUnderlying() +// buffer := testingLogger.GetBuffer() +// text := buffer.String() +// log := buffer.Data() +// +// Serialization of the structured log parameters is done in the same way +// as for klog.InfoS. +package ktesting + +import ( + "fmt" + "strings" + "sync" + "time" + + "github.com/go-logr/logr" + + "k8s.io/klog/v2" + "k8s.io/klog/v2/internal/buffer" + "k8s.io/klog/v2/internal/dbg" + "k8s.io/klog/v2/internal/serialize" + "k8s.io/klog/v2/internal/severity" + "k8s.io/klog/v2/internal/verbosity" +) + +// TL is the relevant subset of testing.TB. +type TL interface { + Helper() + Log(args ...interface{}) +} + +// NopTL implements TL with empty stubs. It can be used when only capturing +// output in memory is relevant. +type NopTL struct{} + +func (n NopTL) Helper() {} +func (n NopTL) Log(...interface{}) {} + +var _ TL = NopTL{} + +// BufferTL implements TL with an in-memory buffer. +type BufferTL struct { + strings.Builder +} + +func (n *BufferTL) Helper() {} +func (n *BufferTL) Log(args ...interface{}) { + n.Builder.WriteString(fmt.Sprintln(args...)) +} + +var _ TL = &BufferTL{} + +// NewLogger constructs a new logger for the given test interface. +// +// Beware that testing.T does not support logging after the test that +// it was created for has completed. If a test leaks goroutines +// and those goroutines log something after test completion, +// that output will be printed via the global klog logger with +// ` leaked goroutine` as prefix. +// +// Verbosity can be modified at any time through the Config.V and +// Config.VModule API. +func NewLogger(t TL, c *Config) logr.Logger { + l := tlogger{ + shared: &tloggerShared{ + t: t, + config: c, + }, + } + if c.co.anyToString != nil { + l.shared.formatter.AnyToStringHook = c.co.anyToString + } + + type testCleanup interface { + Cleanup(func()) + Name() string + } + + // Stopping the logging is optional and only done (and required) + // for testing.T/B/F. + if tb, ok := t.(testCleanup); ok { + tb.Cleanup(l.shared.stop) + l.shared.testName = tb.Name() + } + return logr.New(l) +} + +// Buffer stores log entries as formatted text and structured data. +// It is safe to use this concurrently. +type Buffer interface { + // String returns the log entries in a format that is similar to the + // klog text output. + String() string + + // Data returns the log entries as structs. + Data() Log +} + +// Log contains log entries in the order in which they were generated. +type Log []LogEntry + +// DeepCopy returns a copy of the log. The error instance and key/value +// pairs remain shared. +func (l Log) DeepCopy() Log { + log := make(Log, 0, len(l)) + log = append(log, l...) + return log +} + +// LogEntry represents all information captured for a log entry. +type LogEntry struct { + // Timestamp stores the time when the log entry was created. + Timestamp time.Time + + // Type is either LogInfo or LogError. + Type LogType + + // Prefix contains the WithName strings concatenated with a slash. + Prefix string + + // Message is the fixed log message string. + Message string + + // Verbosity is always 0 for LogError. + Verbosity int + + // Err is always nil for LogInfo. It may or may not be + // nil for LogError. + Err error + + // WithKVList are the concatenated key/value pairs from WithValues + // calls. It's guaranteed to have an even number of entries because + // the logger ensures that when WithValues is called. + WithKVList []interface{} + + // ParameterKVList are the key/value pairs passed into the call, + // without any validation. + ParameterKVList []interface{} +} + +// LogType determines whether a log entry was created with an Error or Info +// call. +type LogType string + +const ( + // LogError is the special value used for Error log entries. + LogError = LogType("ERROR") + + // LogInfo is the special value used for Info log entries. + LogInfo = LogType("INFO") +) + +// Underlier is implemented by the LogSink of this logger. It provides access +// to additional APIs that are normally hidden behind the Logger API. +type Underlier interface { + // GetUnderlying returns the testing instance that logging goes to. + // It returns nil when the test has completed already. + GetUnderlying() TL + + // GetBuffer grants access to the in-memory copy of the log entries. + GetBuffer() Buffer +} + +type logBuffer struct { + mutex sync.Mutex + text strings.Builder + log Log +} + +func (b *logBuffer) String() string { + b.mutex.Lock() + defer b.mutex.Unlock() + return b.text.String() +} + +func (b *logBuffer) Data() Log { + b.mutex.Lock() + defer b.mutex.Unlock() + return b.log.DeepCopy() +} + +// tloggerShared holds values that are the same for all LogSink instances. It +// gets referenced by pointer in the tlogger struct. +type tloggerShared struct { + // mutex protects access to t. + mutex sync.Mutex + + // t gets cleared when the test is completed. + t TL + + // The time when the test completed. + stopTime time.Time + + // We warn once when a leaked goroutine logs after test completion. + // + // Not terminating immediately is fairly normal: many controllers + // log "terminating" messages while they shut down, which often is + // right after test completion, if that is when the test cancels the + // context and then doesn't wait for goroutines (which is often + // not possible). + // + // Therefore there is the [stopGracePeriod] during which messages get + // logged to the global logger without the warning. + goroutineWarningDone bool + + formatter serialize.Formatter + testName string + config *Config + buffer logBuffer + callDepth int +} + +// Log output of a leaked goroutine during this period after test completion +// does not trigger the warning. +const stopGracePeriod = 10 * time.Second + +func (ls *tloggerShared) stop() { + ls.mutex.Lock() + defer ls.mutex.Unlock() + ls.t = nil + ls.stopTime = time.Now() +} + +// tlogger is the actual LogSink implementation. +type tlogger struct { + shared *tloggerShared + prefix string + values []interface{} +} + +// fallbackLogger is called while l.shared.mutex is locked and after it has +// been determined that the original testing.TB is no longer usable. +func (l tlogger) fallbackLogger() logr.Logger { + logger := klog.Background().WithValues(l.values...).WithName(l.shared.testName + " leaked goroutine") + if l.prefix != "" { + logger = logger.WithName(l.prefix) + } + // Skip direct caller (= Error or Info) plus the logr wrapper. + logger = logger.WithCallDepth(l.shared.callDepth + 1) + + if !l.shared.goroutineWarningDone { + duration := time.Since(l.shared.stopTime) + if duration > stopGracePeriod { + + logger.WithCallDepth(1).Info("WARNING: test kept at least one goroutine running after test completion", "timeSinceCompletion", duration.Round(time.Second), "callstack", string(dbg.Stacks(false))) + l.shared.goroutineWarningDone = true + } + } + return logger +} + +func (l tlogger) Init(info logr.RuntimeInfo) { + l.shared.callDepth = info.CallDepth +} + +func (l tlogger) GetCallStackHelper() func() { + l.shared.mutex.Lock() + defer l.shared.mutex.Unlock() + if l.shared.t == nil { + return func() {} + } + + return l.shared.t.Helper +} + +func (l tlogger) Info(level int, msg string, kvList ...interface{}) { + l.shared.mutex.Lock() + defer l.shared.mutex.Unlock() + if l.shared.t == nil { + l.fallbackLogger().V(level).Info(msg, kvList...) + return + } + + l.shared.t.Helper() + buf := buffer.GetBuffer() + l.shared.formatter.FormatKVs(&buf.Buffer, l.values, kvList) + l.log(LogInfo, msg, level, buf, nil, kvList) +} + +func (l tlogger) Enabled(level int) bool { + return l.shared.config.vstate.Enabled(verbosity.Level(level), l.shared.callDepth+1) +} + +func (l tlogger) Error(err error, msg string, kvList ...interface{}) { + l.shared.mutex.Lock() + defer l.shared.mutex.Unlock() + if l.shared.t == nil { + l.fallbackLogger().Error(err, msg, kvList...) + return + } + + l.shared.t.Helper() + buf := buffer.GetBuffer() + var errKV []interface{} + if err != nil { + errKV = []interface{}{"err", err} + } + l.shared.formatter.FormatKVs(&buf.Buffer, errKV, l.values, kvList) + l.log(LogError, msg, 0, buf, err, kvList) +} + +func (l tlogger) log(what LogType, msg string, level int, buf *buffer.Buffer, err error, kvList []interface{}) { + l.shared.t.Helper() + s := severity.InfoLog + if what == LogError { + s = severity.ErrorLog + } + args := []interface{}{buf.SprintHeader(s, time.Now())} + if l.prefix != "" { + args = append(args, l.prefix+":") + } + args = append(args, msg) + if buf.Len() > 0 { + // Skip leading space inserted by serialize.KVListFormat. + args = append(args, string(buf.Bytes()[1:])) + } + l.shared.t.Log(args...) + + if !l.shared.config.co.bufferLogs { + return + } + + l.shared.buffer.mutex.Lock() + defer l.shared.buffer.mutex.Unlock() + + // Store as text. + l.shared.buffer.text.WriteString(string(what)) + for i := 1; i < len(args); i++ { + l.shared.buffer.text.WriteByte(' ') + l.shared.buffer.text.WriteString(args[i].(string)) + } + lastArg := args[len(args)-1].(string) + if lastArg[len(lastArg)-1] != '\n' { + l.shared.buffer.text.WriteByte('\n') + } + + // Store as raw data. + l.shared.buffer.log = append(l.shared.buffer.log, + LogEntry{ + Timestamp: time.Now(), + Type: what, + Prefix: l.prefix, + Message: msg, + Verbosity: level, + Err: err, + WithKVList: l.values, + ParameterKVList: kvList, + }, + ) +} + +// WithName returns a new logr.Logger with the specified name appended. klogr +// uses '/' characters to separate name elements. Callers should not pass '/' +// in the provided name string, but this library does not actually enforce that. +func (l tlogger) WithName(name string) logr.LogSink { + if len(l.prefix) > 0 { + l.prefix = l.prefix + "/" + } + l.prefix += name + return l +} + +func (l tlogger) WithValues(kvList ...interface{}) logr.LogSink { + l.values = serialize.WithValues(l.values, kvList) + return l +} + +func (l tlogger) GetUnderlying() TL { + return l.shared.t +} + +func (l tlogger) GetBuffer() Buffer { + return &l.shared.buffer +} + +var _ logr.LogSink = &tlogger{} +var _ logr.CallStackHelperLogSink = &tlogger{} +var _ Underlier = &tlogger{} diff --git a/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/generated.protomessage.pb.go b/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/generated.protomessage.pb.go deleted file mode 100644 index f72b7ec30b..0000000000 --- a/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/generated.protomessage.pb.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1 - -func (*APIService) ProtoMessage() {} - -func (*APIServiceCondition) ProtoMessage() {} - -func (*APIServiceList) ProtoMessage() {} - -func (*APIServiceSpec) ProtoMessage() {} - -func (*APIServiceStatus) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} diff --git a/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1/generated.protomessage.pb.go deleted file mode 100644 index 23dd6b3aa1..0000000000 --- a/vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1/generated.protomessage.pb.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - -/* -Copyright 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. -*/ - -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*APIService) ProtoMessage() {} - -func (*APIServiceCondition) ProtoMessage() {} - -func (*APIServiceList) ProtoMessage() {} - -func (*APIServiceSpec) ProtoMessage() {} - -func (*APIServiceStatus) ProtoMessage() {} - -func (*ServiceReference) ProtoMessage() {} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservice.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservice.go new file mode 100644 index 0000000000..7ed5fa1133 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservice.go @@ -0,0 +1,292 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + internal "k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal" +) + +// APIServiceApplyConfiguration represents a declarative configuration of the APIService type for use +// with apply. +// +// APIService represents a server for a particular GroupVersion. +// Name must be "version.group". +type APIServiceApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // Spec contains information for locating and communicating with a server + Spec *APIServiceSpecApplyConfiguration `json:"spec,omitempty"` + // Status contains derived information about an API server + Status *APIServiceStatusApplyConfiguration `json:"status,omitempty"` +} + +// APIService constructs a declarative configuration of the APIService type for use with +// apply. +func APIService(name string) *APIServiceApplyConfiguration { + b := &APIServiceApplyConfiguration{} + b.WithName(name) + b.WithKind("APIService") + b.WithAPIVersion("apiregistration.k8s.io/v1") + return b +} + +// ExtractAPIServiceFrom extracts the applied configuration owned by fieldManager from +// aPIService for the specified subresource. Pass an empty string for subresource to extract +// the main resource. Common subresources include "status", "scale", etc. +// aPIService must be a unmodified APIService API object that was retrieved from the Kubernetes API. +// ExtractAPIServiceFrom provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractAPIServiceFrom(aPIService *apiregistrationv1.APIService, fieldManager string, subresource string) (*APIServiceApplyConfiguration, error) { + b := &APIServiceApplyConfiguration{} + err := managedfields.ExtractInto(aPIService, internal.Parser().Type("io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(aPIService.Name) + + b.WithKind("APIService") + b.WithAPIVersion("apiregistration.k8s.io/v1") + return b, nil +} + +// ExtractAPIService extracts the applied configuration owned by fieldManager from +// aPIService. If no managedFields are found in aPIService for fieldManager, a +// APIServiceApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// aPIService must be a unmodified APIService API object that was retrieved from the Kubernetes API. +// ExtractAPIService provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +func ExtractAPIService(aPIService *apiregistrationv1.APIService, fieldManager string) (*APIServiceApplyConfiguration, error) { + return ExtractAPIServiceFrom(aPIService, fieldManager, "") +} + +// ExtractAPIServiceStatus extracts the applied configuration owned by fieldManager from +// aPIService for the status subresource. +func ExtractAPIServiceStatus(aPIService *apiregistrationv1.APIService, fieldManager string) (*APIServiceApplyConfiguration, error) { + return ExtractAPIServiceFrom(aPIService, fieldManager, "status") +} + +func (b APIServiceApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithKind(value string) *APIServiceApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithAPIVersion(value string) *APIServiceApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithName(value string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithGenerateName(value string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithNamespace(value string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithUID(value types.UID) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithResourceVersion(value string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithGeneration(value int64) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *APIServiceApplyConfiguration) WithLabels(entries map[string]string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *APIServiceApplyConfiguration) WithAnnotations(entries map[string]string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *APIServiceApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *APIServiceApplyConfiguration) WithFinalizers(values ...string) *APIServiceApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *APIServiceApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithSpec(value *APIServiceSpecApplyConfiguration) *APIServiceApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *APIServiceApplyConfiguration) WithStatus(value *APIServiceStatusApplyConfiguration) *APIServiceApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *APIServiceApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *APIServiceApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *APIServiceApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *APIServiceApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalercondition.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicecondition.go similarity index 55% rename from vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalercondition.go rename to vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicecondition.go index a23e18b158..e7255009b8 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2beta2/horizontalpodautoscalercondition.go +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicecondition.go @@ -16,44 +16,41 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v2beta2 +package v1 import ( - autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" ) -// HorizontalPodAutoscalerConditionApplyConfiguration represents a declarative configuration of the HorizontalPodAutoscalerCondition type for use +// APIServiceConditionApplyConfiguration represents a declarative configuration of the APIServiceCondition type for use // with apply. // -// HorizontalPodAutoscalerCondition describes the state of -// a HorizontalPodAutoscaler at a certain point. -type HorizontalPodAutoscalerConditionApplyConfiguration struct { - // type describes the current condition - Type *autoscalingv2beta2.HorizontalPodAutoscalerConditionType `json:"type,omitempty"` - // status is the status of the condition (True, False, Unknown) - Status *v1.ConditionStatus `json:"status,omitempty"` - // lastTransitionTime is the last time the condition transitioned from - // one status to another +// APIServiceCondition describes the state of an APIService at a particular point +type APIServiceConditionApplyConfiguration struct { + // Type is the type of the condition. + Type *apiregistrationv1.APIServiceConditionType `json:"type,omitempty"` + // Status is the status of the condition. + // Can be True, False, Unknown. + Status *apiregistrationv1.ConditionStatus `json:"status,omitempty"` + // Last time the condition transitioned from one status to another. LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"` - // reason is the reason for the condition's last transition. + // Unique, one-word, CamelCase reason for the condition's last transition. Reason *string `json:"reason,omitempty"` - // message is a human-readable explanation containing details about - // the transition + // Human-readable message indicating details about last transition. Message *string `json:"message,omitempty"` } -// HorizontalPodAutoscalerConditionApplyConfiguration constructs a declarative configuration of the HorizontalPodAutoscalerCondition type for use with +// APIServiceConditionApplyConfiguration constructs a declarative configuration of the APIServiceCondition type for use with // apply. -func HorizontalPodAutoscalerCondition() *HorizontalPodAutoscalerConditionApplyConfiguration { - return &HorizontalPodAutoscalerConditionApplyConfiguration{} +func APIServiceCondition() *APIServiceConditionApplyConfiguration { + return &APIServiceConditionApplyConfiguration{} } // WithType sets the Type field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Type field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithType(value autoscalingv2beta2.HorizontalPodAutoscalerConditionType) *HorizontalPodAutoscalerConditionApplyConfiguration { +func (b *APIServiceConditionApplyConfiguration) WithType(value apiregistrationv1.APIServiceConditionType) *APIServiceConditionApplyConfiguration { b.Type = &value return b } @@ -61,7 +58,7 @@ func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithType(value auto // WithStatus sets the Status field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Status field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithStatus(value v1.ConditionStatus) *HorizontalPodAutoscalerConditionApplyConfiguration { +func (b *APIServiceConditionApplyConfiguration) WithStatus(value apiregistrationv1.ConditionStatus) *APIServiceConditionApplyConfiguration { b.Status = &value return b } @@ -69,7 +66,7 @@ func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithStatus(value v1 // WithLastTransitionTime sets the LastTransitionTime field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the LastTransitionTime field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithLastTransitionTime(value metav1.Time) *HorizontalPodAutoscalerConditionApplyConfiguration { +func (b *APIServiceConditionApplyConfiguration) WithLastTransitionTime(value metav1.Time) *APIServiceConditionApplyConfiguration { b.LastTransitionTime = &value return b } @@ -77,7 +74,7 @@ func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithLastTransitionT // WithReason sets the Reason field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Reason field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithReason(value string) *HorizontalPodAutoscalerConditionApplyConfiguration { +func (b *APIServiceConditionApplyConfiguration) WithReason(value string) *APIServiceConditionApplyConfiguration { b.Reason = &value return b } @@ -85,7 +82,7 @@ func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithReason(value st // WithMessage sets the Message field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Message field is set to the value of the last call. -func (b *HorizontalPodAutoscalerConditionApplyConfiguration) WithMessage(value string) *HorizontalPodAutoscalerConditionApplyConfiguration { +func (b *APIServiceConditionApplyConfiguration) WithMessage(value string) *APIServiceConditionApplyConfiguration { b.Message = &value return b } diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicespec.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicespec.go new file mode 100644 index 0000000000..074ff08f85 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicespec.go @@ -0,0 +1,124 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// APIServiceSpecApplyConfiguration represents a declarative configuration of the APIServiceSpec type for use +// with apply. +// +// APIServiceSpec contains information for locating and communicating with a server. +// Only https is supported, though you are able to disable certificate verification. +type APIServiceSpecApplyConfiguration struct { + // Service is a reference to the service for this API server. It must communicate + // on port 443. + // If the Service is nil, that means the handling for the API groupversion is handled locally on this server. + // The call will simply delegate to the normal handler chain to be fulfilled. + Service *ServiceReferenceApplyConfiguration `json:"service,omitempty"` + // Group is the API group name this server hosts + Group *string `json:"group,omitempty"` + // Version is the API version this server hosts. For example, "v1" + Version *string `json:"version,omitempty"` + // InsecureSkipTLSVerify disables TLS certificate verification when communicating with this server. + // This is strongly discouraged. You should use the CABundle instead. + InsecureSkipTLSVerify *bool `json:"insecureSkipTLSVerify,omitempty"` + // CABundle is a PEM encoded CA bundle which will be used to validate an API server's serving certificate. + // If unspecified, system trust roots on the apiserver are used. + CABundle []byte `json:"caBundle,omitempty"` + // GroupPriorityMinimum is the priority this group should have at least. Higher priority means that the group is preferred by clients over lower priority ones. + // Note that other versions of this group might specify even higher GroupPriorityMinimum values such that the whole group gets a higher priority. + // The primary sort is based on GroupPriorityMinimum, ordered highest number to lowest (20 before 10). + // The secondary sort is based on the alphabetical comparison of the name of the object. (v1.bar before v1.foo) + // We'd recommend something like: *.k8s.io (except extensions) at 18000 and + // PaaSes (OpenShift, Deis) are recommended to be in the 2000s + GroupPriorityMinimum *int32 `json:"groupPriorityMinimum,omitempty"` + // VersionPriority controls the ordering of this API version inside of its group. Must be greater than zero. + // The primary sort is based on VersionPriority, ordered highest to lowest (20 before 10). + // Since it's inside of a group, the number can be small, probably in the 10s. + // In case of equal version priorities, the version string will be used to compute the order inside a group. + // If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered + // lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version), + // then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first + // by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing major + // version, then minor version. An example sorted list of versions: + // v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10. + VersionPriority *int32 `json:"versionPriority,omitempty"` +} + +// APIServiceSpecApplyConfiguration constructs a declarative configuration of the APIServiceSpec type for use with +// apply. +func APIServiceSpec() *APIServiceSpecApplyConfiguration { + return &APIServiceSpecApplyConfiguration{} +} + +// WithService sets the Service field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Service field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithService(value *ServiceReferenceApplyConfiguration) *APIServiceSpecApplyConfiguration { + b.Service = value + return b +} + +// WithGroup sets the Group field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Group field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithGroup(value string) *APIServiceSpecApplyConfiguration { + b.Group = &value + return b +} + +// WithVersion sets the Version field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Version field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithVersion(value string) *APIServiceSpecApplyConfiguration { + b.Version = &value + return b +} + +// WithInsecureSkipTLSVerify sets the InsecureSkipTLSVerify field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the InsecureSkipTLSVerify field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithInsecureSkipTLSVerify(value bool) *APIServiceSpecApplyConfiguration { + b.InsecureSkipTLSVerify = &value + return b +} + +// WithCABundle adds the given value to the CABundle field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the CABundle field. +func (b *APIServiceSpecApplyConfiguration) WithCABundle(values ...byte) *APIServiceSpecApplyConfiguration { + for i := range values { + b.CABundle = append(b.CABundle, values[i]) + } + return b +} + +// WithGroupPriorityMinimum sets the GroupPriorityMinimum field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GroupPriorityMinimum field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithGroupPriorityMinimum(value int32) *APIServiceSpecApplyConfiguration { + b.GroupPriorityMinimum = &value + return b +} + +// WithVersionPriority sets the VersionPriority field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the VersionPriority field is set to the value of the last call. +func (b *APIServiceSpecApplyConfiguration) WithVersionPriority(value int32) *APIServiceSpecApplyConfiguration { + b.VersionPriority = &value + return b +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicestatus.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicestatus.go new file mode 100644 index 0000000000..900e2834c2 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/apiservicestatus.go @@ -0,0 +1,47 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// APIServiceStatusApplyConfiguration represents a declarative configuration of the APIServiceStatus type for use +// with apply. +// +// APIServiceStatus contains derived information about an API server +type APIServiceStatusApplyConfiguration struct { + // Current service state of apiService. + Conditions []APIServiceConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// APIServiceStatusApplyConfiguration constructs a declarative configuration of the APIServiceStatus type for use with +// apply. +func APIServiceStatus() *APIServiceStatusApplyConfiguration { + return &APIServiceStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *APIServiceStatusApplyConfiguration) WithConditions(values ...*APIServiceConditionApplyConfiguration) *APIServiceStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/servicereference.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/servicereference.go new file mode 100644 index 0000000000..0b333f0cf2 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1/servicereference.go @@ -0,0 +1,64 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ServiceReferenceApplyConfiguration represents a declarative configuration of the ServiceReference type for use +// with apply. +// +// ServiceReference holds a reference to Service.legacy.k8s.io +type ServiceReferenceApplyConfiguration struct { + // Namespace is the namespace of the service + Namespace *string `json:"namespace,omitempty"` + // Name is the name of the service + Name *string `json:"name,omitempty"` + // If specified, the port on the service that hosting webhook. + // Default to 443 for backward compatibility. + // `port` should be a valid port number (1-65535, inclusive). + Port *int32 `json:"port,omitempty"` +} + +// ServiceReferenceApplyConfiguration constructs a declarative configuration of the ServiceReference type for use with +// apply. +func ServiceReference() *ServiceReferenceApplyConfiguration { + return &ServiceReferenceApplyConfiguration{} +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ServiceReferenceApplyConfiguration) WithNamespace(value string) *ServiceReferenceApplyConfiguration { + b.Namespace = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ServiceReferenceApplyConfiguration) WithName(value string) *ServiceReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithPort sets the Port field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Port field is set to the value of the last call. +func (b *ServiceReferenceApplyConfiguration) WithPort(value int32) *ServiceReferenceApplyConfiguration { + b.Port = &value + return b +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal/internal.go b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal/internal.go new file mode 100644 index 0000000000..5cde85e8d7 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal/internal.go @@ -0,0 +1,369 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package internal + +import ( + fmt "fmt" + sync "sync" + + typed "sigs.k8s.io/structured-merge-diff/v6/typed" +) + +func Parser() *typed.Parser { + parserOnce.Do(func() { + var err error + parser, err = typed.NewParser(schemaYAML) + if err != nil { + panic(fmt.Sprintf("Failed to parse schema: %v", err)) + } + }) + return parser +} + +var parserOnce sync.Once +var parser *typed.Parser +var schemaYAML = typed.YAMLObject(`types: +- name: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1 + map: + elementType: + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_deduced_ + elementRelationship: separable +- name: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry + map: + fields: + - name: apiVersion + type: + scalar: string + - name: fieldsType + type: + scalar: string + - name: fieldsV1 + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1 + - name: manager + type: + scalar: string + - name: operation + type: + scalar: string + - name: subresource + type: + scalar: string + - name: time + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time +- name: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + map: + fields: + - name: annotations + type: + map: + elementType: + scalar: string + - name: creationTimestamp + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: deletionGracePeriodSeconds + type: + scalar: numeric + - name: deletionTimestamp + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: finalizers + type: + list: + elementType: + scalar: string + elementRelationship: associative + - name: generateName + type: + scalar: string + - name: generation + type: + scalar: numeric + - name: labels + type: + map: + elementType: + scalar: string + - name: managedFields + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry + elementRelationship: atomic + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + - name: ownerReferences + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference + elementRelationship: associative + keys: + - uid + - name: resourceVersion + type: + scalar: string + - name: selfLink + type: + scalar: string + - name: uid + type: + scalar: string +- name: io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference + map: + fields: + - name: apiVersion + type: + scalar: string + default: "" + - name: blockOwnerDeletion + type: + scalar: boolean + - name: controller + type: + scalar: boolean + - name: kind + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" + - name: uid + type: + scalar: string + default: "" + elementRelationship: atomic +- name: io.k8s.apimachinery.pkg.apis.meta.v1.Time + scalar: untyped +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec + default: {} + - name: status + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceStatus + default: {} +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceCondition + map: + fields: + - name: lastTransitionTime + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: message + type: + scalar: string + - name: reason + type: + scalar: string + - name: status + type: + scalar: string + default: "" + - name: type + type: + scalar: string + default: "" +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec + map: + fields: + - name: caBundle + type: + scalar: string + - name: group + type: + scalar: string + - name: groupPriorityMinimum + type: + scalar: numeric + default: 0 + - name: insecureSkipTLSVerify + type: + scalar: boolean + - name: service + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ServiceReference + - name: version + type: + scalar: string + - name: versionPriority + type: + scalar: numeric + default: 0 +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceCondition + elementRelationship: associative + keys: + - type +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ServiceReference + map: + fields: + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + - name: port + type: + scalar: numeric +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIService + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceSpec + default: {} + - name: status + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceStatus + default: {} +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceCondition + map: + fields: + - name: lastTransitionTime + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time + - name: message + type: + scalar: string + - name: reason + type: + scalar: string + - name: status + type: + scalar: string + default: "" + - name: type + type: + scalar: string + default: "" +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceSpec + map: + fields: + - name: caBundle + type: + scalar: string + - name: group + type: + scalar: string + - name: groupPriorityMinimum + type: + scalar: numeric + default: 0 + - name: insecureSkipTLSVerify + type: + scalar: boolean + - name: service + type: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ServiceReference + - name: version + type: + scalar: string + - name: versionPriority + type: + scalar: numeric + default: 0 +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceCondition + elementRelationship: associative + keys: + - type +- name: io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ServiceReference + map: + fields: + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + - name: port + type: + scalar: numeric +- name: __untyped_atomic_ + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic +- name: __untyped_deduced_ + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_deduced_ + elementRelationship: separable +`) diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiservice.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiservice.go index a27b9848d8..dc48ba62a5 100644 --- a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiservice.go +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiservice.go @@ -26,6 +26,7 @@ import ( watch "k8s.io/apimachinery/pkg/watch" gentype "k8s.io/client-go/gentype" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + applyconfigurationapiregistrationv1 "k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1" scheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" ) @@ -47,18 +48,21 @@ type APIServiceInterface interface { List(ctx context.Context, opts metav1.ListOptions) (*apiregistrationv1.APIServiceList, error) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *apiregistrationv1.APIService, err error) + Apply(ctx context.Context, aPIService *applyconfigurationapiregistrationv1.APIServiceApplyConfiguration, opts metav1.ApplyOptions) (result *apiregistrationv1.APIService, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, aPIService *applyconfigurationapiregistrationv1.APIServiceApplyConfiguration, opts metav1.ApplyOptions) (result *apiregistrationv1.APIService, err error) APIServiceExpansion } // aPIServices implements APIServiceInterface type aPIServices struct { - *gentype.ClientWithList[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList] + *gentype.ClientWithListAndApply[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList, *applyconfigurationapiregistrationv1.APIServiceApplyConfiguration] } // newAPIServices returns a APIServices func newAPIServices(c *ApiregistrationV1Client) *aPIServices { return &aPIServices{ - gentype.NewClientWithList[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList]( + gentype.NewClientWithListAndApply[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList, *applyconfigurationapiregistrationv1.APIServiceApplyConfiguration]( "apiservices", c.RESTClient(), scheme.ParameterCodec, diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/alias.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/alias.go deleted file mode 100644 index fbf256d528..0000000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/alias.go +++ /dev/null @@ -1,967 +0,0 @@ -// 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. - -// Code generated by alias_gen.go; DO NOT EDIT. - -//go:build goexperiment.jsonv2 && go1.25 - -// Package json implements semantic processing of JSON as specified in RFC 8259. -// JSON is a simple data interchange format that can represent -// primitive data types such as booleans, strings, and numbers, -// in addition to structured data types such as objects and arrays. -// -// [Marshal] and [Unmarshal] encode and decode Go values -// to/from JSON text contained within a []byte. -// [MarshalWrite] and [UnmarshalRead] operate on JSON text -// by writing to or reading from an [io.Writer] or [io.Reader]. -// [MarshalEncode] and [UnmarshalDecode] operate on JSON text -// by encoding to or decoding from a [jsontext.Encoder] or [jsontext.Decoder]. -// [Options] may be passed to each of the marshal or unmarshal functions -// to configure the semantic behavior of marshaling and unmarshaling -// (i.e., alter how JSON data is understood as Go data and vice versa). -// [jsontext.Options] may also be passed to the marshal or unmarshal functions -// to configure the syntactic behavior of encoding or decoding. -// -// The data types of JSON are mapped to/from the data types of Go based on -// the closest logical equivalent between the two type systems. For example, -// a JSON boolean corresponds with a Go bool, -// a JSON string corresponds with a Go string, -// a JSON number corresponds with a Go int, uint or float, -// a JSON array corresponds with a Go slice or array, and -// a JSON object corresponds with a Go struct or map. -// See the documentation on [Marshal] and [Unmarshal] for a comprehensive list -// of how the JSON and Go type systems correspond. -// -// Arbitrary Go types can customize their JSON representation by implementing -// [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom]. -// This provides authors of Go types with control over how their types are -// serialized as JSON. Alternatively, users can implement functions that match -// [MarshalFunc], [MarshalToFunc], [UnmarshalFunc], or [UnmarshalFromFunc] -// to specify the JSON representation for arbitrary types. -// This provides callers of JSON functionality with control over -// how any arbitrary type is serialized as JSON. -// -// # JSON Representation of Go structs -// -// A Go struct is naturally represented as a JSON object, -// where each Go struct field corresponds with a JSON object member. -// When marshaling, all Go struct fields are recursively encoded in depth-first -// order as JSON object members except those that are ignored or omitted. -// When unmarshaling, JSON object members are recursively decoded -// into the corresponding Go struct fields. -// Object members that do not match any struct fields, -// also known as “unknown members”, are ignored by default or rejected -// if [RejectUnknownMembers] is specified. -// -// The representation of each struct field can be customized in the -// "json" struct field tag, where the tag is a comma separated list of options. -// As a special case, if the entire tag is `json:"-"`, -// then the field is ignored with regard to its JSON representation. -// Some options also have equivalent behavior controlled by a caller-specified [Options]. -// Field-specified options take precedence over caller-specified options. -// -// The first option is the JSON object name override for the Go struct field. -// If the name is not specified, then the Go struct field name -// is used as the JSON object name. JSON names containing commas or quotes, -// or names identical to "" or "-", can be specified using -// a single-quoted string literal, where the syntax is identical to -// the Go grammar for a double-quoted string literal, -// but instead uses single quotes as the delimiters. -// By default, unmarshaling uses case-sensitive matching to identify -// the Go struct field associated with a JSON object name. -// -// After the name, the following tag options are supported: -// -// - omitzero: When marshaling, the "omitzero" option specifies that -// the struct field should be omitted if the field value is zero -// as determined by the "IsZero() bool" method if present, -// otherwise based on whether the field is the zero Go value. -// This option has no effect when unmarshaling. -// -// - omitempty: When marshaling, the "omitempty" option specifies that -// the struct field should be omitted if the field value would have been -// encoded as a JSON null, empty string, empty object, or empty array. -// This option has no effect when unmarshaling. -// -// - string: The "string" option specifies that [StringifyNumbers] -// be set when marshaling or unmarshaling a struct field value. -// This causes numeric types to be encoded as a JSON number -// within a JSON string, and to be decoded from a JSON string -// containing the JSON number without any surrounding whitespace. -// This extra level of encoding is often necessary since -// many JSON parsers cannot precisely represent 64-bit integers. -// -// - case: When unmarshaling, the "case" option specifies how -// JSON object names are matched with the JSON name for Go struct fields. -// The option is a key-value pair specified as "case:value" where -// the value must either be 'ignore' or 'strict'. -// The 'ignore' value specifies that matching is case-insensitive -// where dashes and underscores are also ignored. If multiple fields match, -// the first declared field in breadth-first order takes precedence. -// The 'strict' value specifies that matching is case-sensitive. -// This takes precedence over the [MatchCaseInsensitiveNames] option. -// -// - inline: The "inline" option specifies that -// the JSON representable content of this field type is to be promoted -// as if they were specified in the parent struct. -// It is the JSON equivalent of Go struct embedding. -// A Go embedded field is implicitly inlined unless an explicit JSON name -// is specified. The inlined field must be a Go struct -// (that does not implement any JSON methods), [jsontext.Value], -// map[~string]T, or an unnamed pointer to such types. When marshaling, -// inlined fields from a pointer type are omitted if it is nil. -// Inlined fields of type [jsontext.Value] and map[~string]T are called -// “inlined fallbacks” as they can represent all possible -// JSON object members not directly handled by the parent struct. -// Only one inlined fallback field may be specified in a struct, -// while many non-fallback fields may be specified. This option -// must not be specified with any other option (including the JSON name). -// -// - unknown: The "unknown" option is a specialized variant -// of the inlined fallback to indicate that this Go struct field -// contains any number of unknown JSON object members. The field type must -// be a [jsontext.Value], map[~string]T, or an unnamed pointer to such types. -// If [DiscardUnknownMembers] is specified when marshaling, -// the contents of this field are ignored. -// If [RejectUnknownMembers] is specified when unmarshaling, -// any unknown object members are rejected regardless of whether -// an inlined fallback with the "unknown" option exists. This option -// must not be specified with any other option (including the JSON name). -// -// - format: The "format" option specifies a format flag -// used to specialize the formatting of the field value. -// The option is a key-value pair specified as "format:value" where -// the value must be either a literal consisting of letters and numbers -// (e.g., "format:RFC3339") or a single-quoted string literal -// (e.g., "format:'2006-01-02'"). The interpretation of the format flag -// is determined by the struct field type. -// -// The "omitzero" and "omitempty" options are mostly semantically identical. -// The former is defined in terms of the Go type system, -// while the latter in terms of the JSON type system. -// Consequently they behave differently in some circumstances. -// For example, only a nil slice or map is omitted under "omitzero", while -// an empty slice or map is omitted under "omitempty" regardless of nilness. -// The "omitzero" option is useful for types with a well-defined zero value -// (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]). -// -// Every Go struct corresponds to a list of JSON representable fields -// which is constructed by performing a breadth-first search over -// all struct fields (excluding unexported or ignored fields), -// where the search recursively descends into inlined structs. -// The set of non-inlined fields in a struct must have unique JSON names. -// If multiple fields all have the same JSON name, then the one -// at shallowest depth takes precedence and the other fields at deeper depths -// are excluded from the list of JSON representable fields. -// If multiple fields at the shallowest depth have the same JSON name, -// but exactly one is explicitly tagged with a JSON name, -// then that field takes precedence and all others are excluded from the list. -// This is analogous to Go visibility rules for struct field selection -// with embedded struct types. -// -// Marshaling or unmarshaling a non-empty struct -// without any JSON representable fields results in a [SemanticError]. -// Unexported fields must not have any `json` tags except for `json:"-"`. -// -// # Security Considerations -// -// JSON is frequently used as a data interchange format to communicate -// between different systems, possibly implemented in different languages. -// For interoperability and security reasons, it is important that -// all implementations agree upon the semantic meaning of the data. -// -// [For example, suppose we have two micro-services.] -// The first service is responsible for authenticating a JSON request, -// while the second service is responsible for executing the request -// (having assumed that the prior service authenticated the request). -// If an attacker were able to maliciously craft a JSON request such that -// both services believe that the same request is from different users, -// it could bypass the authenticator with valid credentials for one user, -// but maliciously perform an action on behalf of a different user. -// -// According to RFC 8259, there unfortunately exist many JSON texts -// that are syntactically valid but semantically ambiguous. -// For example, the standard does not define how to interpret duplicate -// names within an object. -// -// The v1 [encoding/json] and [encoding/json/v2] packages -// interpret some inputs in different ways. In particular: -// -// - The standard specifies that JSON must be encoded using UTF-8. -// By default, v1 replaces invalid bytes of UTF-8 in JSON strings -// with the Unicode replacement character, -// while v2 rejects inputs with invalid UTF-8. -// To change the default, specify the [jsontext.AllowInvalidUTF8] option. -// The replacement of invalid UTF-8 is a form of data corruption -// that alters the precise meaning of strings. -// -// - The standard does not specify a particular behavior when -// duplicate names are encountered within a JSON object, -// which means that different implementations may behave differently. -// By default, v1 allows for the presence of duplicate names, -// while v2 rejects duplicate names. -// To change the default, specify the [jsontext.AllowDuplicateNames] option. -// If allowed, object members are processed in the order they are observed, -// meaning that later values will replace or be merged into prior values, -// depending on the Go value type. -// -// - The standard defines a JSON object as an unordered collection of name/value pairs. -// While ordering can be observed through the underlying [jsontext] API, -// both v1 and v2 generally avoid exposing the ordering. -// No application should semantically depend on the order of object members. -// Allowing duplicate names is a vector through which ordering of members -// can accidentally be observed and depended upon. -// -// - The standard suggests that JSON object names are typically compared -// based on equality of the sequence of Unicode code points, -// which implies that comparing names is often case-sensitive. -// When unmarshaling a JSON object into a Go struct, -// by default, v1 uses a (loose) case-insensitive match on the name, -// while v2 uses a (strict) case-sensitive match on the name. -// To change the default, specify the [MatchCaseInsensitiveNames] option. -// The use of case-insensitive matching provides another vector through -// which duplicate names can occur. Allowing case-insensitive matching -// means that v1 or v2 might interpret JSON objects differently from most -// other JSON implementations (which typically use a case-sensitive match). -// -// - The standard does not specify a particular behavior when -// an unknown name in a JSON object is encountered. -// When unmarshaling a JSON object into a Go struct, by default -// both v1 and v2 ignore unknown names and their corresponding values. -// To change the default, specify the [RejectUnknownMembers] option. -// -// - The standard suggests that implementations may use a float64 -// to represent a JSON number. Consequently, large JSON integers -// may lose precision when stored as a floating-point type. -// Both v1 and v2 correctly preserve precision when marshaling and -// unmarshaling a concrete integer type. However, even if v1 and v2 -// preserve precision for concrete types, other JSON implementations -// may not be able to preserve precision for outputs produced by v1 or v2. -// The `string` tag option can be used to specify that an integer type -// is to be quoted within a JSON string to avoid loss of precision. -// Furthermore, v1 and v2 may still lose precision when unmarshaling -// into an any interface value, where unmarshal uses a float64 -// by default to represent a JSON number. -// To change the default, specify the [WithUnmarshalers] option -// with a custom unmarshaler that pre-populates the interface value -// with a concrete Go type that can preserve precision. -// -// RFC 8785 specifies a canonical form for any JSON text, -// which explicitly defines specific behaviors that RFC 8259 leaves undefined. -// In theory, if a text can successfully [jsontext.Value.Canonicalize] -// without changing the semantic meaning of the data, then it provides a -// greater degree of confidence that the data is more secure and interoperable. -// -// The v2 API generally chooses more secure defaults than v1, -// but care should still be taken with large integers or unknown members. -// -// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s -package json - -import ( - "encoding/json/jsontext" - "encoding/json/v2" - "io" -) - -// Marshal serializes a Go value as a []byte according to the provided -// marshal and encode options (while ignoring unmarshal or decode options). -// It does not terminate the output with a newline. -// -// Type-specific marshal functions and methods take precedence -// over the default representation of a value. -// Functions or methods that operate on *T are only called when encoding -// a value of type T (by taking its address) or a non-nil value of *T. -// Marshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that -// these functions and methods can be consistently called. For performance, -// it is recommended that Marshal be passed a non-nil pointer to the value. -// -// The input value is encoded as JSON according the following rules: -// -// - If any type-specific functions in a [WithMarshalers] option match -// the value type, then those functions are called to encode the value. -// If all applicable functions return [SkipFunc], -// then the value is encoded according to subsequent rules. -// -// - If the value type implements [MarshalerTo], -// then the MarshalJSONTo method is called to encode the value. -// -// - If the value type implements [Marshaler], -// then the MarshalJSON method is called to encode the value. -// -// - If the value type implements [encoding.TextAppender], -// then the AppendText method is called to encode the value and -// subsequently encode its result as a JSON string. -// -// - If the value type implements [encoding.TextMarshaler], -// then the MarshalText method is called to encode the value and -// subsequently encode its result as a JSON string. -// -// - Otherwise, the value is encoded according to the value's type -// as described in detail below. -// -// Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). -// -// The representation of each type is as follows: -// -// - A Go boolean is encoded as a JSON boolean (e.g., true or false). -// It does not support any custom format flags. -// -// - A Go string is encoded as a JSON string. -// It does not support any custom format flags. -// -// - A Go []byte or [N]byte is encoded as a JSON string containing -// the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the bytes value is encoded as a JSON array -// where each byte is recursively JSON-encoded as each JSON array element. -// -// - A Go integer is encoded as a JSON number without fractions or exponents. -// If [StringifyNumbers] is specified or encoding a JSON object name, -// then the JSON number is encoded within a JSON string. -// It does not support any custom format flags. -// -// - A Go float is encoded as a JSON number. -// If [StringifyNumbers] is specified or encoding a JSON object name, -// then the JSON number is encoded within a JSON string. -// If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as -// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. -// Otherwise, the presence of non-finite numbers results in a [SemanticError]. -// -// - A Go map is encoded as a JSON object, where each Go map key and value -// is recursively encoded as a name and value pair in the JSON object. -// The Go map key must encode as a JSON string, otherwise this results -// in a [SemanticError]. The Go map is traversed in a non-deterministic order. -// For deterministic encoding, consider using the [Deterministic] option. -// If the format is "emitnull", then a nil map is encoded as a JSON null. -// If the format is "emitempty", then a nil map is encoded as an empty JSON object, -// regardless of whether [FormatNilMapAsNull] is specified. -// Otherwise by default, a nil map is encoded as an empty JSON object. -// -// - A Go struct is encoded as a JSON object. -// See the “JSON Representation of Go structs” section -// in the package-level documentation for more details. -// -// - A Go slice is encoded as a JSON array, where each Go slice element -// is recursively JSON-encoded as the elements of the JSON array. -// If the format is "emitnull", then a nil slice is encoded as a JSON null. -// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, -// regardless of whether [FormatNilSliceAsNull] is specified. -// Otherwise by default, a nil slice is encoded as an empty JSON array. -// -// - A Go array is encoded as a JSON array, where each Go array element -// is recursively JSON-encoded as the elements of the JSON array. -// The JSON array length is always identical to the Go array length. -// It does not support any custom format flags. -// -// - A Go pointer is encoded as a JSON null if nil, otherwise it is -// the recursively JSON-encoded representation of the underlying value. -// Format flags are forwarded to the encoding of the underlying value. -// -// - A Go interface is encoded as a JSON null if nil, otherwise it is -// the recursively JSON-encoded representation of the underlying value. -// It does not support any custom format flags. -// -// - A Go [time.Time] is encoded as a JSON string containing the timestamp -// formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared -// in the time package (e.g., RFC1123), then that format is used. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// To avoid a fractional component, round the timestamp to the relevant unit. -// Otherwise, the format is used as-is with [time.Time.Format] if non-empty. -// -// - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// To avoid a fractional component, round the duration to the relevant unit. -// If the format is "units", it is encoded as a JSON string formatted using -// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is encoded as a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// using only accurate units of hours, minutes, and seconds. -// -// - All other Go types (e.g., complex numbers, channels, and functions) -// have no default representation and result in a [SemanticError]. -// -// JSON cannot represent cyclic data structures and Marshal does not handle them. -// Passing cyclic structures will result in an error. -func Marshal(in any, opts ...Options) (out []byte, err error) { - return json.Marshal(in, opts...) -} - -// MarshalWrite serializes a Go value into an [io.Writer] according to the provided -// marshal and encode options (while ignoring unmarshal or decode options). -// It does not terminate the output with a newline. -// See [Marshal] for details about the conversion of a Go value into JSON. -func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) { - return json.MarshalWrite(out, in, opts...) -} - -// MarshalEncode serializes a Go value into an [jsontext.Encoder] according to -// the provided marshal options (while ignoring unmarshal, encode, or decode options). -// Any marshal-relevant options already specified on the [jsontext.Encoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Marshal] and [MarshalWrite], encode options are ignored because -// they must have already been specified on the provided [jsontext.Encoder]. -// -// See [Marshal] for details about the conversion of a Go value into JSON. -func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { - return json.MarshalEncode(out, in, opts...) -} - -// Unmarshal decodes a []byte input into a Go value according to the provided -// unmarshal and decode options (while ignoring marshal or encode options). -// The input must be a single JSON value with optional whitespace interspersed. -// The output must be a non-nil pointer. -// -// Type-specific unmarshal functions and methods take precedence -// over the default representation of a value. -// Functions or methods that operate on *T are only called when decoding -// a value of type T (by taking its address) or a non-nil value of *T. -// Unmarshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that -// these functions and methods can be consistently called. -// -// The input is decoded into the output according the following rules: -// -// - If any type-specific functions in a [WithUnmarshalers] option match -// the value type, then those functions are called to decode the JSON -// value. If all applicable functions return [SkipFunc], -// then the input is decoded according to subsequent rules. -// -// - If the value type implements [UnmarshalerFrom], -// then the UnmarshalJSONFrom method is called to decode the JSON value. -// -// - If the value type implements [Unmarshaler], -// then the UnmarshalJSON method is called to decode the JSON value. -// -// - If the value type implements [encoding.TextUnmarshaler], -// then the input is decoded as a JSON string and -// the UnmarshalText method is called with the decoded string value. -// This fails with a [SemanticError] if the input is not a JSON string. -// -// - Otherwise, the JSON value is decoded according to the value's type -// as described in detail below. -// -// Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). -// A JSON null may be decoded into every supported Go value where -// it is equivalent to storing the zero value of the Go value. -// If the input JSON kind is not handled by the current Go value type, -// then this fails with a [SemanticError]. Unless otherwise specified, -// the decoded value replaces any pre-existing value. -// -// The representation of each type is as follows: -// -// - A Go boolean is decoded from a JSON boolean (e.g., true or false). -// It does not support any custom format flags. -// -// - A Go string is decoded from a JSON string. -// It does not support any custom format flags. -// -// - A Go []byte or [N]byte is decoded from a JSON string -// containing the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the Go slice or array is decoded from a -// JSON array where each JSON element is recursively decoded for each byte. -// When decoding into a non-nil []byte, the slice length is reset to zero -// and the decoded input is appended to it. -// When decoding into a [N]byte, the input must decode to exactly N bytes, -// otherwise it fails with a [SemanticError]. -// -// - A Go integer is decoded from a JSON number. -// It must be decoded from a JSON string containing a JSON number -// if [StringifyNumbers] is specified or decoding a JSON object name. -// It fails with a [SemanticError] if the JSON number -// has a fractional or exponent component. -// It also fails if it overflows the representation of the Go integer type. -// It does not support any custom format flags. -// -// - A Go float is decoded from a JSON number. -// It must be decoded from a JSON string containing a JSON number -// if [StringifyNumbers] is specified or decoding a JSON object name. -// It fails if it overflows the representation of the Go float type. -// If the format is "nonfinite", then the JSON strings -// "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. -// Otherwise, the presence of such strings results in a [SemanticError]. -// -// - A Go map is decoded from a JSON object, -// where each JSON object name and value pair is recursively decoded -// as the Go map key and value. Maps are not cleared. -// If the Go map is nil, then a new map is allocated to decode into. -// If the decoded key matches an existing Go map entry, the entry value -// is reused by decoding the JSON object value into it. -// The formats "emitnull" and "emitempty" have no effect when decoding. -// -// - A Go struct is decoded from a JSON object. -// See the “JSON Representation of Go structs” section -// in the package-level documentation for more details. -// -// - A Go slice is decoded from a JSON array, where each JSON element -// is recursively decoded and appended to the Go slice. -// Before appending into a Go slice, a new slice is allocated if it is nil, -// otherwise the slice length is reset to zero. -// The formats "emitnull" and "emitempty" have no effect when decoding. -// -// - A Go array is decoded from a JSON array, where each JSON array element -// is recursively decoded as each corresponding Go array element. -// Each Go array element is zeroed before decoding into it. -// It fails with a [SemanticError] if the JSON array does not contain -// the exact same number of elements as the Go array. -// It does not support any custom format flags. -// -// - A Go pointer is decoded based on the JSON kind and underlying Go type. -// If the input is a JSON null, then this stores a nil pointer. -// Otherwise, it allocates a new underlying value if the pointer is nil, -// and recursively JSON decodes into the underlying value. -// Format flags are forwarded to the decoding of the underlying type. -// -// - A Go interface is decoded based on the JSON kind and underlying Go type. -// If the input is a JSON null, then this stores a nil interface value. -// Otherwise, a nil interface value of an empty interface type is initialized -// with a zero Go bool, string, float64, map[string]any, or []any if the -// input is a JSON boolean, string, number, object, or array, respectively. -// If the interface value is still nil, then this fails with a [SemanticError] -// since decoding could not determine an appropriate Go type to decode into. -// For example, unmarshaling into a nil io.Reader fails since -// there is no concrete type to populate the interface value with. -// Otherwise an underlying value exists and it recursively decodes -// the JSON input into it. It does not support any custom format flags. -// -// - A Go [time.Time] is decoded from a JSON string containing the time -// formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared in -// the time package (e.g., RFC1123), then that format is used for parsing. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty. -// -// - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// If the format is "units", it is decoded from a JSON string parsed using -// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is decoded from a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// accepting only accurate units of hours, minutes, or seconds. -// -// - All other Go types (e.g., complex numbers, channels, and functions) -// have no default representation and result in a [SemanticError]. -// -// In general, unmarshaling follows merge semantics (similar to RFC 7396) -// where the decoded Go value replaces the destination value -// for any JSON kind other than an object. -// For JSON objects, the input object is merged into the destination value -// where matching object members recursively apply merge semantics. -func Unmarshal(in []byte, out any, opts ...Options) (err error) { - return json.Unmarshal(in, out, opts...) -} - -// UnmarshalRead deserializes a Go value from an [io.Reader] according to the -// provided unmarshal and decode options (while ignoring marshal or encode options). -// The input must be a single JSON value with optional whitespace interspersed. -// It consumes the entirety of [io.Reader] until [io.EOF] is encountered, -// without reporting an error for EOF. The output must be a non-nil pointer. -// See [Unmarshal] for details about the conversion of JSON into a Go value. -func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) { - return json.UnmarshalRead(in, out, opts...) -} - -// UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to -// the provided unmarshal options (while ignoring marshal, encode, or decode options). -// Any unmarshal options already specified on the [jsontext.Decoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because -// they must have already been specified on the provided [jsontext.Decoder]. -// -// The input may be a stream of one or more JSON values, -// where this only unmarshals the next JSON value in the stream. -// The output must be a non-nil pointer. -// See [Unmarshal] for details about the conversion of JSON into a Go value. -func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) { - return json.UnmarshalDecode(in, out, opts...) -} - -// Marshalers is a list of functions that may override the marshal behavior -// of specific types. Populate [WithMarshalers] to use it with -// [Marshal], [MarshalWrite], or [MarshalEncode]. -// A nil *Marshalers is equivalent to an empty list. -// There are no exported fields or methods on Marshalers. -type Marshalers = json.Marshalers - -// JoinMarshalers constructs a flattened list of marshal functions. -// If multiple functions in the list are applicable for a value of a given type, -// then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, -// otherwise the default marshaling behavior is used. -// -// For example: -// -// m1 := JoinMarshalers(f1, f2) -// m2 := JoinMarshalers(f0, m1, f3) // equivalent to m3 -// m3 := JoinMarshalers(f0, f1, f2, f3) // equivalent to m2 -func JoinMarshalers(ms ...*Marshalers) *Marshalers { - return json.JoinMarshalers(ms...) -} - -// Unmarshalers is a list of functions that may override the unmarshal behavior -// of specific types. Populate [WithUnmarshalers] to use it with -// [Unmarshal], [UnmarshalRead], or [UnmarshalDecode]. -// A nil *Unmarshalers is equivalent to an empty list. -// There are no exported fields or methods on Unmarshalers. -type Unmarshalers = json.Unmarshalers - -// JoinUnmarshalers constructs a flattened list of unmarshal functions. -// If multiple functions in the list are applicable for a value of a given type, -// then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, -// otherwise the default unmarshaling behavior is used. -// -// For example: -// -// u1 := JoinUnmarshalers(f1, f2) -// u2 := JoinUnmarshalers(f0, u1, f3) // equivalent to u3 -// u3 := JoinUnmarshalers(f0, f1, f2, f3) // equivalent to u2 -func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers { - return json.JoinUnmarshalers(us...) -} - -// MarshalFunc constructs a type-specific marshaler that -// specifies how to marshal values of type T. -// T can be any type except a named pointer. -// The function is always provided with a non-nil pointer value -// if T is an interface or pointer type. -// -// The function must marshal exactly one JSON value. -// The value of T must not be retained outside the function call. -// It may not return [SkipFunc]. -func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { - return json.MarshalFunc[T](fn) -} - -// MarshalToFunc constructs a type-specific marshaler that -// specifies how to marshal values of type T. -// T can be any type except a named pointer. -// The function is always provided with a non-nil pointer value -// if T is an interface or pointer type. -// -// The function must marshal exactly one JSON value by calling write methods -// on the provided encoder. It may return [SkipFunc] such that marshaling can -// move on to the next marshal function. However, no mutable method calls may -// be called on the encoder if [SkipFunc] is returned. -// The pointer to [jsontext.Encoder] and the value of T -// must not be retained outside the function call. -func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { - return json.MarshalToFunc[T](fn) -} - -// UnmarshalFunc constructs a type-specific unmarshaler that -// specifies how to unmarshal values of type T. -// T must be an unnamed pointer or an interface type. -// The function is always provided with a non-nil pointer value. -// -// The function must unmarshal exactly one JSON value. -// The input []byte must not be mutated. -// The input []byte and value T must not be retained outside the function call. -// It may not return [SkipFunc]. -func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { - return json.UnmarshalFunc[T](fn) -} - -// UnmarshalFromFunc constructs a type-specific unmarshaler that -// specifies how to unmarshal values of type T. -// T must be an unnamed pointer or an interface type. -// The function is always provided with a non-nil pointer value. -// -// The function must unmarshal exactly one JSON value by calling read methods -// on the provided decoder. It may return [SkipFunc] such that unmarshaling can -// move on to the next unmarshal function. However, no mutable method calls may -// be called on the decoder if [SkipFunc] is returned. -// The pointer to [jsontext.Decoder] and the value of T -// must not be retained outside the function call. -func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers { - return json.UnmarshalFromFunc[T](fn) -} - -// Marshaler is implemented by types that can marshal themselves. -// It is recommended that types implement [MarshalerTo] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. -// -// It is recommended that implementations return a buffer that is safe -// for the caller to retain and potentially mutate. -type Marshaler = json.Marshaler - -// MarshalerTo is implemented by types that can marshal themselves. -// It is recommended that types implement MarshalerTo instead of [Marshaler] -// since this is both more performant and flexible. -// If a type implements both Marshaler and MarshalerTo, -// then MarshalerTo takes precedence. In such a case, both implementations -// should aim to have equivalent behavior for the default marshal options. -// -// The implementation must write only one JSON value to the Encoder and -// must not retain the pointer to [jsontext.Encoder]. -type MarshalerTo = json.MarshalerTo - -// Unmarshaler is implemented by types that can unmarshal themselves. -// It is recommended that types implement [UnmarshalerFrom] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. -// -// The input can be assumed to be a valid encoding of a JSON value -// if called from unmarshal functionality in this package. -// UnmarshalJSON must copy the JSON data if it is retained after returning. -// It is recommended that UnmarshalJSON implement merge semantics when -// unmarshaling into a pre-populated value. -// -// Implementations must not retain or mutate the input []byte. -type Unmarshaler = json.Unmarshaler - -// UnmarshalerFrom is implemented by types that can unmarshal themselves. -// It is recommended that types implement UnmarshalerFrom instead of [Unmarshaler] -// since this is both more performant and flexible. -// If a type implements both Unmarshaler and UnmarshalerFrom, -// then UnmarshalerFrom takes precedence. In such a case, both implementations -// should aim to have equivalent behavior for the default unmarshal options. -// -// The implementation must read only one JSON value from the Decoder. -// It is recommended that UnmarshalJSONFrom implement merge semantics when -// unmarshaling into a pre-populated value. -// -// Implementations must not retain the pointer to [jsontext.Decoder]. -type UnmarshalerFrom = json.UnmarshalerFrom - -// ErrUnknownName indicates that a JSON object member could not be -// unmarshaled because the name is not known to the target Go struct. -// This error is directly wrapped within a [SemanticError] when produced. -// -// The name of an unknown JSON object member can be extracted as: -// -// err := ... -// var serr json.SemanticError -// if errors.As(err, &serr) && serr.Err == json.ErrUnknownName { -// ptr := serr.JSONPointer // JSON pointer to unknown name -// name := ptr.LastToken() // unknown name itself -// ... -// } -// -// This error is only returned if [RejectUnknownMembers] is true. -var ErrUnknownName = json.ErrUnknownName - -// SemanticError describes an error determining the meaning -// of JSON data as Go data or vice-versa. -// -// The contents of this error as produced by this package may change over time. -type SemanticError = json.SemanticError - -// Options configure [Marshal], [MarshalWrite], [MarshalEncode], -// [Unmarshal], [UnmarshalRead], and [UnmarshalDecode] with specific features. -// Each function takes in a variadic list of options, where properties -// set in later options override the value of previously set properties. -// -// The Options type is identical to [encoding/json.Options] and -// [encoding/json/jsontext.Options]. Options from the other packages can -// be used interchangeably with functionality in this package. -// -// Options represent either a singular option or a set of options. -// It can be functionally thought of as a Go map of option properties -// (even though the underlying implementation avoids Go maps for performance). -// -// The constructors (e.g., [Deterministic]) return a singular option value: -// -// opt := Deterministic(true) -// -// which is analogous to creating a single entry map: -// -// opt := Options{"Deterministic": true} -// -// [JoinOptions] composes multiple options values to together: -// -// out := JoinOptions(opts...) -// -// which is analogous to making a new map and copying the options over: -// -// out := make(Options) -// for _, m := range opts { -// for k, v := range m { -// out[k] = v -// } -// } -// -// [GetOption] looks up the value of options parameter: -// -// v, ok := GetOption(opts, Deterministic) -// -// which is analogous to a Go map lookup: -// -// v, ok := Options["Deterministic"] -// -// There is a single Options type, which is used with both marshal and unmarshal. -// Some options affect both operations, while others only affect one operation: -// -// - [StringifyNumbers] affects marshaling and unmarshaling -// - [Deterministic] affects marshaling only -// - [FormatNilSliceAsNull] affects marshaling only -// - [FormatNilMapAsNull] affects marshaling only -// - [OmitZeroStructFields] affects marshaling only -// - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling -// - [DiscardUnknownMembers] affects marshaling only -// - [RejectUnknownMembers] affects unmarshaling only -// - [WithMarshalers] affects marshaling only -// - [WithUnmarshalers] affects unmarshaling only -// -// Options that do not affect a particular operation are ignored. -type Options = json.Options - -// JoinOptions coalesces the provided list of options into a single Options. -// Properties set in later options override the value of previously set properties. -func JoinOptions(srcs ...Options) Options { - return json.JoinOptions(srcs...) -} - -// GetOption returns the value stored in opts with the provided setter, -// reporting whether the value is present. -// -// Example usage: -// -// v, ok := json.GetOption(opts, json.Deterministic) -// -// Options are most commonly introspected to alter the JSON representation of -// [MarshalerTo.MarshalJSONTo] and [UnmarshalerFrom.UnmarshalJSONFrom] methods, and -// [MarshalToFunc] and [UnmarshalFromFunc] functions. -// In such cases, the presence bit should generally be ignored. -func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { - return json.GetOption[T](opts, setter) -} - -// DefaultOptionsV2 is the full set of all options that define v2 semantics. -// It is equivalent to all options under [Options], [encoding/json.Options], -// and [encoding/json/jsontext.Options] being set to false or the zero value, -// except for the options related to whitespace formatting. -func DefaultOptionsV2() Options { - return json.DefaultOptionsV2() -} - -// StringifyNumbers specifies that numeric Go types should be marshaled -// as a JSON string containing the equivalent JSON number value. -// When unmarshaling, numeric Go types are parsed from a JSON string -// containing the JSON number without any surrounding whitespace. -// -// According to RFC 8259, section 6, a JSON implementation may choose to -// limit the representation of a JSON number to an IEEE 754 binary64 value. -// This may cause decoders to lose precision for int64 and uint64 types. -// Quoting JSON numbers as a JSON string preserves the exact precision. -// -// This affects either marshaling or unmarshaling. -func StringifyNumbers(v bool) Options { - return json.StringifyNumbers(v) -} - -// Deterministic specifies that the same input value will be serialized -// as the exact same output bytes. Different processes of -// the same program will serialize equal values to the same bytes, -// but different versions of the same program are not guaranteed -// to produce the exact same sequence of bytes. -// -// This only affects marshaling and is ignored when unmarshaling. -func Deterministic(v bool) Options { - return json.Deterministic(v) -} - -// FormatNilSliceAsNull specifies that a nil Go slice should marshal as a -// JSON null instead of the default representation as an empty JSON array -// (or an empty JSON string in the case of ~[]byte). -// Slice fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON array. -// -// This only affects marshaling and is ignored when unmarshaling. -func FormatNilSliceAsNull(v bool) Options { - return json.FormatNilSliceAsNull(v) -} - -// FormatNilMapAsNull specifies that a nil Go map should marshal as a -// JSON null instead of the default representation as an empty JSON object. -// Map fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON object. -// -// This only affects marshaling and is ignored when unmarshaling. -func FormatNilMapAsNull(v bool) Options { - return json.FormatNilMapAsNull(v) -} - -// OmitZeroStructFields specifies that a Go struct should marshal in such a way -// that all struct fields that are zero are omitted from the marshaled output -// if the value is zero as determined by the "IsZero() bool" method if present, -// otherwise based on whether the field is the zero Go value. -// This is semantically equivalent to specifying the `omitzero` tag option -// on every field in a Go struct. -// -// This only affects marshaling and is ignored when unmarshaling. -func OmitZeroStructFields(v bool) Options { - return json.OmitZeroStructFields(v) -} - -// MatchCaseInsensitiveNames specifies that JSON object members are matched -// against Go struct fields using a case-insensitive match of the name. -// Go struct fields explicitly marked with `case:strict` or `case:ignore` -// always use case-sensitive (or case-insensitive) name matching, -// regardless of the value of this option. -// -// This affects either marshaling or unmarshaling. -// For marshaling, this option may alter the detection of duplicate names -// (assuming [jsontext.AllowDuplicateNames] is false) from inlined fields -// if it matches one of the declared fields in the Go struct. -func MatchCaseInsensitiveNames(v bool) Options { - return json.MatchCaseInsensitiveNames(v) -} - -// RejectUnknownMembers specifies that unknown members should be rejected -// when unmarshaling a JSON object, regardless of whether there is a field -// to store unknown members. -// -// This only affects unmarshaling and is ignored when marshaling. -func RejectUnknownMembers(v bool) Options { - return json.RejectUnknownMembers(v) -} - -// WithMarshalers specifies a list of type-specific marshalers to use, -// which can be used to override the default marshal behavior for values -// of particular types. -// -// This only affects marshaling and is ignored when unmarshaling. -func WithMarshalers(v *Marshalers) Options { - return json.WithMarshalers(v) -} - -// WithUnmarshalers specifies a list of type-specific unmarshalers to use, -// which can be used to override the default unmarshal behavior for values -// of particular types. -// -// This only affects unmarshaling and is ignored when marshaling. -func WithUnmarshalers(v *Unmarshalers) Options { - return json.WithUnmarshalers(v) -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go index 85d5303891..dbf92432dd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go index 22ed430fb5..fd034c1a1b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go index 64d2b7a9b6..3f21c8d350 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go index 1f5d018689..50dca26b88 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go index f73ed32405..4509b87e41 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go index d6736342ba..42d6ee8762 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go index 4d328ebee3..30dd584d12 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go index a463168589..ff70951ab5 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - // Package json implements semantic processing of JSON as specified in RFC 8259. // JSON is a simple data interchange format that can represent // primitive data types such as booleans, strings, and numbers, diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go index 5b5d5f93aa..1df765384d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go index 045c6988a6..d539feedd1 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go index 973f52e73a..9ab735814c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fold.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go index 1bfb8ca633..42fc3d4719 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go index 00b43fa307..05801c6b25 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package internal import "errors" diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go index 36300011e7..810128b516 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - // jsonflags implements all the optional boolean flags. // These flags are shared across both "json", "jsontext", and "jsonopts". package jsonflags diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go index c4fc8dba8c..142653518d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsonopts import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go index 6a5acb8ec0..02787719ca 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsonwire import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go index e74ed713ea..35b238a2e2 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsonwire import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go index a0622c65b8..1831a66bde 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - // Package jsonwire implements stateless functionality for handling JSON text. package jsonwire diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/alias.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/alias.go deleted file mode 100644 index dc18d5d55d..0000000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/alias.go +++ /dev/null @@ -1,536 +0,0 @@ -// 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. - -// Code generated by alias_gen.go; DO NOT EDIT. - -//go:build goexperiment.jsonv2 && go1.25 - -// Package jsontext implements syntactic processing of JSON -// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785. -// JSON is a simple data interchange format that can represent -// primitive data types such as booleans, strings, and numbers, -// in addition to structured data types such as objects and arrays. -// -// The [Encoder] and [Decoder] types are used to encode or decode -// a stream of JSON tokens or values. -// -// # Tokens and Values -// -// A JSON token refers to the basic structural elements of JSON: -// -// - a JSON literal (i.e., null, true, or false) -// - a JSON string (e.g., "hello, world!") -// - a JSON number (e.g., 123.456) -// - a begin or end delimiter for a JSON object (i.e., '{' or '}') -// - a begin or end delimiter for a JSON array (i.e., '[' or ']') -// -// A JSON token is represented by the [Token] type in Go. Technically, -// there are two additional structural characters (i.e., ':' and ','), -// but there is no [Token] representation for them since their presence -// can be inferred by the structure of the JSON grammar itself. -// For example, there must always be an implicit colon between -// the name and value of a JSON object member. -// -// A JSON value refers to a complete unit of JSON data: -// -// - a JSON literal, string, or number -// - a JSON object (e.g., `{"name":"value"}`) -// - a JSON array (e.g., `[1,2,3,]`) -// -// A JSON value is represented by the [Value] type in Go and is a []byte -// containing the raw textual representation of the value. There is some overlap -// between tokens and values as both contain literals, strings, and numbers. -// However, only a value can represent the entirety of a JSON object or array. -// -// The [Encoder] and [Decoder] types contain methods to read or write the next -// [Token] or [Value] in a sequence. They maintain a state machine to validate -// whether the sequence of JSON tokens and/or values produces a valid JSON. -// [Options] may be passed to the [NewEncoder] or [NewDecoder] constructors -// to configure the syntactic behavior of encoding and decoding. -// -// # Terminology -// -// The terms "encode" and "decode" are used for syntactic functionality -// that is concerned with processing JSON based on its grammar, and -// the terms "marshal" and "unmarshal" are used for semantic functionality -// that determines the meaning of JSON values as Go values and vice-versa. -// This package (i.e., [jsontext]) deals with JSON at a syntactic layer, -// while [encoding/json/v2] deals with JSON at a semantic layer. -// The goal is to provide a clear distinction between functionality that -// is purely concerned with encoding versus that of marshaling. -// For example, one can directly encode a stream of JSON tokens without -// needing to marshal a concrete Go value representing them. -// Similarly, one can decode a stream of JSON tokens without -// needing to unmarshal them into a concrete Go value. -// -// This package uses JSON terminology when discussing JSON, which may differ -// from related concepts in Go or elsewhere in computing literature. -// -// - a JSON "object" refers to an unordered collection of name/value members. -// - a JSON "array" refers to an ordered sequence of elements. -// - a JSON "value" refers to either a literal (i.e., null, false, or true), -// string, number, object, or array. -// -// See RFC 8259 for more information. -// -// # Specifications -// -// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, -// and RFC 8785. Each RFC is generally a stricter subset of another RFC. -// In increasing order of strictness: -// -// - RFC 4627 and RFC 7159 do not require (but recommend) the use of UTF-8 -// and also do not require (but recommend) that object names be unique. -// - RFC 8259 requires the use of UTF-8, -// but does not require (but recommends) that object names be unique. -// - RFC 7493 requires the use of UTF-8 -// and also requires that object names be unique. -// - RFC 8785 defines a canonical representation. It requires the use of UTF-8 -// and also requires that object names be unique and in a specific ordering. -// It specifies exactly how strings and numbers must be formatted. -// -// The primary difference between RFC 4627 and RFC 7159 is that the former -// restricted top-level values to only JSON objects and arrays, while -// RFC 7159 and subsequent RFCs permit top-level values to additionally be -// JSON nulls, booleans, strings, or numbers. -// -// By default, this package operates on RFC 7493, but can be configured -// to operate according to the other RFC specifications. -// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it. -// In particular, it makes specific choices about behavior that RFC 8259 -// leaves as undefined in order to ensure greater interoperability. -// -// # Security Considerations -// -// See the "Security Considerations" section in [encoding/json/v2]. -package jsontext - -import ( - "encoding/json/jsontext" - "io" -) - -// Decoder is a streaming decoder for raw JSON tokens and values. -// It is used to read a stream of top-level JSON values, -// each separated by optional whitespace characters. -// -// [Decoder.ReadToken] and [Decoder.ReadValue] calls may be interleaved. -// For example, the following JSON value: -// -// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} -// -// can be parsed with the following calls (ignoring errors for brevity): -// -// d.ReadToken() // { -// d.ReadToken() // "name" -// d.ReadToken() // "value" -// d.ReadValue() // "array" -// d.ReadToken() // [ -// d.ReadToken() // null -// d.ReadToken() // false -// d.ReadValue() // true -// d.ReadToken() // 3.14159 -// d.ReadToken() // ] -// d.ReadValue() // "object" -// d.ReadValue() // {"k":"v"} -// d.ReadToken() // } -// -// The above is one of many possible sequence of calls and -// may not represent the most sensible method to call for any given token/value. -// For example, it is probably more common to call [Decoder.ReadToken] to obtain a -// string token for object names. -type Decoder = jsontext.Decoder - -// NewDecoder constructs a new streaming decoder reading from r. -// -// If r is a [bytes.Buffer], then the decoder parses directly from the buffer -// without first copying the contents to an intermediate buffer. -// Additional writes to the buffer must not occur while the decoder is in use. -func NewDecoder(r io.Reader, opts ...Options) *Decoder { - return jsontext.NewDecoder(r, opts...) -} - -// Encoder is a streaming encoder from raw JSON tokens and values. -// It is used to write a stream of top-level JSON values, -// each terminated with a newline character. -// -// [Encoder.WriteToken] and [Encoder.WriteValue] calls may be interleaved. -// For example, the following JSON value: -// -// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} -// -// can be composed with the following calls (ignoring errors for brevity): -// -// e.WriteToken(BeginObject) // { -// e.WriteToken(String("name")) // "name" -// e.WriteToken(String("value")) // "value" -// e.WriteValue(Value(`"array"`)) // "array" -// e.WriteToken(BeginArray) // [ -// e.WriteToken(Null) // null -// e.WriteToken(False) // false -// e.WriteValue(Value("true")) // true -// e.WriteToken(Float(3.14159)) // 3.14159 -// e.WriteToken(EndArray) // ] -// e.WriteValue(Value(`"object"`)) // "object" -// e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"} -// e.WriteToken(EndObject) // } -// -// The above is one of many possible sequence of calls and -// may not represent the most sensible method to call for any given token/value. -// For example, it is probably more common to call [Encoder.WriteToken] with a string -// for object names. -type Encoder = jsontext.Encoder - -// NewEncoder constructs a new streaming encoder writing to w -// configured with the provided options. -// It flushes the internal buffer when the buffer is sufficiently full or -// when a top-level value has been written. -// -// If w is a [bytes.Buffer], then the encoder appends directly into the buffer -// without copying the contents from an intermediate buffer. -func NewEncoder(w io.Writer, opts ...Options) *Encoder { - return jsontext.NewEncoder(w, opts...) -} - -// SyntacticError is a description of a syntactic error that occurred when -// encoding or decoding JSON according to the grammar. -// -// The contents of this error as produced by this package may change over time. -type SyntacticError = jsontext.SyntacticError - -// Options configures [NewEncoder], [Encoder.Reset], [NewDecoder], -// and [Decoder.Reset] with specific features. -// Each function takes in a variadic list of options, where properties -// set in latter options override the value of previously set properties. -// -// There is a single Options type, which is used with both encoding and decoding. -// Some options affect both operations, while others only affect one operation: -// -// - [AllowDuplicateNames] affects encoding and decoding -// - [AllowInvalidUTF8] affects encoding and decoding -// - [EscapeForHTML] affects encoding only -// - [EscapeForJS] affects encoding only -// - [PreserveRawStrings] affects encoding only -// - [CanonicalizeRawInts] affects encoding only -// - [CanonicalizeRawFloats] affects encoding only -// - [ReorderRawObjects] affects encoding only -// - [SpaceAfterColon] affects encoding only -// - [SpaceAfterComma] affects encoding only -// - [Multiline] affects encoding only -// - [WithIndent] affects encoding only -// - [WithIndentPrefix] affects encoding only -// -// Options that do not affect a particular operation are ignored. -// -// The Options type is identical to [encoding/json.Options] and -// [encoding/json/v2.Options]. Options from the other packages may -// be passed to functionality in this package, but are ignored. -// Options from this package may be used with the other packages. -type Options = jsontext.Options - -// AllowDuplicateNames specifies that JSON objects may contain -// duplicate member names. Disabling the duplicate name check may provide -// performance benefits, but breaks compliance with RFC 7493, section 2.3. -// The input or output will still be compliant with RFC 8259, -// which leaves the handling of duplicate names as unspecified behavior. -// -// This affects either encoding or decoding. -func AllowDuplicateNames(v bool) Options { - return jsontext.AllowDuplicateNames(v) -} - -// AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, -// which will be mangled as the Unicode replacement character, U+FFFD. -// This causes the encoder or decoder to break compliance with -// RFC 7493, section 2.1, and RFC 8259, section 8.1. -// -// This affects either encoding or decoding. -func AllowInvalidUTF8(v bool) Options { - return jsontext.AllowInvalidUTF8(v) -} - -// EscapeForHTML specifies that '<', '>', and '&' characters within JSON strings -// should be escaped as a hexadecimal Unicode codepoint (e.g., \u003c) so that -// the output is safe to embed within HTML. -// -// This only affects encoding and is ignored when decoding. -func EscapeForHTML(v bool) Options { - return jsontext.EscapeForHTML(v) -} - -// EscapeForJS specifies that U+2028 and U+2029 characters within JSON strings -// should be escaped as a hexadecimal Unicode codepoint (e.g., \u2028) so that -// the output is valid to embed within JavaScript. See RFC 8259, section 12. -// -// This only affects encoding and is ignored when decoding. -func EscapeForJS(v bool) Options { - return jsontext.EscapeForJS(v) -} - -// PreserveRawStrings specifies that when encoding a raw JSON string in a -// [Token] or [Value], pre-escaped sequences -// in a JSON string are preserved to the output. -// However, raw strings still respect [EscapeForHTML] and [EscapeForJS] -// such that the relevant characters are escaped. -// If [AllowInvalidUTF8] is enabled, bytes of invalid UTF-8 -// are preserved to the output. -// -// This only affects encoding and is ignored when decoding. -func PreserveRawStrings(v bool) Options { - return jsontext.PreserveRawStrings(v) -} - -// CanonicalizeRawInts specifies that when encoding a raw JSON -// integer number (i.e., a number without a fraction and exponent) in a -// [Token] or [Value], the number is canonicalized -// according to RFC 8785, section 3.2.2.3. As a special case, -// the number -0 is canonicalized as 0. -// -// JSON numbers are treated as IEEE 754 double precision numbers. -// Any numbers with precision beyond what is representable by that form -// will lose their precision when canonicalized. For example, -// integer values beyond ±2⁵³ will lose their precision. -// For example, 1234567890123456789 is formatted as 1234567890123456800. -// -// This only affects encoding and is ignored when decoding. -func CanonicalizeRawInts(v bool) Options { - return jsontext.CanonicalizeRawInts(v) -} - -// CanonicalizeRawFloats specifies that when encoding a raw JSON -// floating-point number (i.e., a number with a fraction or exponent) in a -// [Token] or [Value], the number is canonicalized -// according to RFC 8785, section 3.2.2.3. As a special case, -// the number -0 is canonicalized as 0. -// -// JSON numbers are treated as IEEE 754 double precision numbers. -// It is safe to canonicalize a serialized single precision number and -// parse it back as a single precision number and expect the same value. -// If a number exceeds ±1.7976931348623157e+308, which is the maximum -// finite number, then it saturated at that value and formatted as such. -// -// This only affects encoding and is ignored when decoding. -func CanonicalizeRawFloats(v bool) Options { - return jsontext.CanonicalizeRawFloats(v) -} - -// ReorderRawObjects specifies that when encoding a raw JSON object in a -// [Value], the object members are reordered according to -// RFC 8785, section 3.2.3. -// -// This only affects encoding and is ignored when decoding. -func ReorderRawObjects(v bool) Options { - return jsontext.ReorderRawObjects(v) -} - -// SpaceAfterColon specifies that the JSON output should emit a space character -// after each colon separator following a JSON object name. -// If false, then no space character appears after the colon separator. -// -// This only affects encoding and is ignored when decoding. -func SpaceAfterColon(v bool) Options { - return jsontext.SpaceAfterColon(v) -} - -// SpaceAfterComma specifies that the JSON output should emit a space character -// after each comma separator following a JSON object value or array element. -// If false, then no space character appears after the comma separator. -// -// This only affects encoding and is ignored when decoding. -func SpaceAfterComma(v bool) Options { - return jsontext.SpaceAfterComma(v) -} - -// Multiline specifies that the JSON output should expand to multiple lines, -// where every JSON object member or JSON array element appears on -// a new, indented line according to the nesting depth. -// -// If [SpaceAfterColon] is not specified, then the default is true. -// If [SpaceAfterComma] is not specified, then the default is false. -// If [WithIndent] is not specified, then the default is "\t". -// -// If set to false, then the output is a single-line, -// where the only whitespace emitted is determined by the current -// values of [SpaceAfterColon] and [SpaceAfterComma]. -// -// This only affects encoding and is ignored when decoding. -func Multiline(v bool) Options { - return jsontext.Multiline(v) -} - -// WithIndent specifies that the encoder should emit multiline output -// where each element in a JSON object or array begins on a new, indented line -// beginning with the indent prefix (see [WithIndentPrefix]) -// followed by one or more copies of indent according to the nesting depth. -// The indent must only be composed of space or tab characters. -// -// If the intent to emit indented output without a preference for -// the particular indent string, then use [Multiline] instead. -// -// This only affects encoding and is ignored when decoding. -// Use of this option implies [Multiline] being set to true. -func WithIndent(indent string) Options { - return jsontext.WithIndent(indent) -} - -// WithIndentPrefix specifies that the encoder should emit multiline output -// where each element in a JSON object or array begins on a new, indented line -// beginning with the indent prefix followed by one or more copies of indent -// (see [WithIndent]) according to the nesting depth. -// The prefix must only be composed of space or tab characters. -// -// This only affects encoding and is ignored when decoding. -// Use of this option implies [Multiline] being set to true. -func WithIndentPrefix(prefix string) Options { - return jsontext.WithIndentPrefix(prefix) -} - -// AppendQuote appends a double-quoted JSON string literal representing src -// to dst and returns the extended buffer. -// It uses the minimal string representation per RFC 8785, section 3.2.2.2. -// Invalid UTF-8 bytes are replaced with the Unicode replacement character -// and an error is returned at the end indicating the presence of invalid UTF-8. -// The dst must not overlap with the src. -func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { - return jsontext.AppendQuote[Bytes](dst, src) -} - -// AppendUnquote appends the decoded interpretation of src as a -// double-quoted JSON string literal to dst and returns the extended buffer. -// The input src must be a JSON string without any surrounding whitespace. -// Invalid UTF-8 bytes are replaced with the Unicode replacement character -// and an error is returned at the end indicating the presence of invalid UTF-8. -// Any trailing bytes after the JSON string literal results in an error. -// The dst must not overlap with the src. -func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { - return jsontext.AppendUnquote[Bytes](dst, src) -} - -// ErrDuplicateName indicates that a JSON token could not be -// encoded or decoded because it results in a duplicate JSON object name. -// This error is directly wrapped within a [SyntacticError] when produced. -// -// The name of a duplicate JSON object member can be extracted as: -// -// err := ... -// var serr jsontext.SyntacticError -// if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName { -// ptr := serr.JSONPointer // JSON pointer to duplicate name -// name := ptr.LastToken() // duplicate name itself -// ... -// } -// -// This error is only returned if [AllowDuplicateNames] is false. -var ErrDuplicateName = jsontext.ErrDuplicateName - -// ErrNonStringName indicates that a JSON token could not be -// encoded or decoded because it is not a string, -// as required for JSON object names according to RFC 8259, section 4. -// This error is directly wrapped within a [SyntacticError] when produced. -var ErrNonStringName = jsontext.ErrNonStringName - -// Pointer is a JSON Pointer (RFC 6901) that references a particular JSON value -// relative to the root of the top-level JSON value. -// -// A Pointer is a slash-separated list of tokens, where each token is -// either a JSON object name or an index to a JSON array element -// encoded as a base-10 integer value. -// It is impossible to distinguish between an array index and an object name -// (that happens to be an base-10 encoded integer) without also knowing -// the structure of the top-level JSON value that the pointer refers to. -// -// There is exactly one representation of a pointer to a particular value, -// so comparability of Pointer values is equivalent to checking whether -// they both point to the exact same value. -type Pointer = jsontext.Pointer - -// Token represents a lexical JSON token, which may be one of the following: -// - a JSON literal (i.e., null, true, or false) -// - a JSON string (e.g., "hello, world!") -// - a JSON number (e.g., 123.456) -// - a begin or end delimiter for a JSON object (i.e., { or } ) -// - a begin or end delimiter for a JSON array (i.e., [ or ] ) -// -// A Token cannot represent entire array or object values, while a [Value] can. -// There is no Token to represent commas and colons since -// these structural tokens can be inferred from the surrounding context. -type Token = jsontext.Token - -var ( - Null = jsontext.Null - False = jsontext.False - True = jsontext.True - BeginObject = jsontext.BeginObject - EndObject = jsontext.EndObject - BeginArray = jsontext.BeginArray - EndArray = jsontext.EndArray -) - -// Bool constructs a Token representing a JSON boolean. -func Bool(b bool) Token { - return jsontext.Bool(b) -} - -// String constructs a Token representing a JSON string. -// The provided string should contain valid UTF-8, otherwise invalid characters -// may be mangled as the Unicode replacement character. -func String(s string) Token { - return jsontext.String(s) -} - -// Float constructs a Token representing a JSON number. -// The values NaN, +Inf, and -Inf will be represented -// as a JSON string with the values "NaN", "Infinity", and "-Infinity". -func Float(n float64) Token { - return jsontext.Float(n) -} - -// Int constructs a Token representing a JSON number from an int64. -func Int(n int64) Token { - return jsontext.Int(n) -} - -// Uint constructs a Token representing a JSON number from a uint64. -func Uint(n uint64) Token { - return jsontext.Uint(n) -} - -// Kind represents each possible JSON token kind with a single byte, -// which is conveniently the first byte of that kind's grammar -// with the restriction that numbers always be represented with '0': -// -// - 'n': null -// - 'f': false -// - 't': true -// - '"': string -// - '0': number -// - '{': object begin -// - '}': object end -// - '[': array begin -// - ']': array end -// -// An invalid kind is usually represented using 0, -// but may be non-zero due to invalid JSON data. -type Kind = jsontext.Kind - -// AppendFormat formats the JSON value in src and appends it to dst -// according to the specified options. -// See [Value.Format] for more details about the formatting behavior. -// -// The dst and src may overlap. -// If an error is reported, then the entirety of src is appended to dst. -func AppendFormat(dst, src []byte, opts ...Options) ([]byte, error) { - return jsontext.AppendFormat(dst, src, opts...) -} - -// Value represents a single raw JSON value, which may be one of the following: -// - a JSON literal (i.e., null, true, or false) -// - a JSON string (e.g., "hello, world!") -// - a JSON number (e.g., 123.456) -// - an entire JSON object (e.g., {"fizz":"buzz"} ) -// - an entire JSON array (e.g., [1,2,3] ) -// -// Value can represent entire array or object values, while [Token] cannot. -// Value may contain leading and/or trailing whitespace. -type Value = jsontext.Value diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go index 7e847de373..96fd5c27cf 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go index 22081df053..bea3ccd348 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - // Package jsontext implements syntactic processing of JSON // as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785. // JSON is a simple data interchange format that can represent diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go index c2e88045ad..36bf7efdf1 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go index 3c53151b3f..1af86d5b67 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go index 0d6dc58c06..b30bb99edf 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go index d22d0635d8..e973b58d6a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go index cf59d99b92..63941baacb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go index a4353be3af..77897b43f5 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go index 6f1aa8e217..fdbfd5d3d0 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go index 3e87c91402..ea8c30eb5b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go index f29f323561..3ea05d3a0f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package jsontext import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go index de401b0de8..2f4744980f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !goexperiment.jsonv2 || !go1.25 - package json import ( diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go index 6067ee03d2..06bcf0c37c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go @@ -147,11 +147,13 @@ func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { return schema.TypeRef{ NamedType: &n, ElementRelationship: &mapRelationship, + Nullable: specSchema.Nullable, } } return schema.TypeRef{ NamedType: &n, + Nullable: specSchema.Nullable, } } @@ -164,7 +166,8 @@ func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { c.pop(c2) return schema.TypeRef{ - Inlined: inlined, + Inlined: inlined, + Nullable: specSchema.Nullable, } } diff --git a/vendor/k8s.io/kube-scheduler/config/v1/types.go b/vendor/k8s.io/kube-scheduler/config/v1/types.go index 8ff68a6ef0..8116b21ce7 100644 --- a/vendor/k8s.io/kube-scheduler/config/v1/types.go +++ b/vendor/k8s.io/kube-scheduler/config/v1/types.go @@ -232,6 +232,12 @@ type Plugins struct { // including `multiPoint.Disabled = '*'` and `multiPoint.Enabled = pluginA` will still register that specific // plugin through MultiPoint. This follows the same behavior as all other extension point configurations. MultiPoint PluginSet `json:"multiPoint,omitempty"` + + // PlacementGenerate is a list of plugins that should be invoked during pod group scheduling cycle when determining placements for a pod group. + PlacementGenerate PluginSet `json:"placementGenerate,omitempty"` + + // PlacementScore is a list of plugins that should be invoked during workload scheduling cycle when ranking pod group assignments. + PlacementScore PluginSet `json:"placementScore,omitempty"` } // PluginSet specifies enabled and disabled plugins for an extension point. @@ -250,11 +256,11 @@ type PluginSet struct { Disabled []Plugin `json:"disabled,omitempty"` } -// Plugin specifies a plugin name and its weight when applicable. Weight is used only for Score plugins. +// Plugin specifies a plugin name and its weight when applicable. Weight is used only for Score and PlacementScore plugins. type Plugin struct { // Name defines the name of plugin Name string `json:"name"` - // Weight defines the weight of plugin, only used for Score plugins. + // Weight defines the weight of plugin, only used for Score and PlacementScore plugins. Weight *int32 `json:"weight,omitempty"` } diff --git a/vendor/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go b/vendor/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go index 788a602790..2d8e3b166c 100644 --- a/vendor/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go @@ -485,6 +485,8 @@ func (in *Plugins) DeepCopyInto(out *Plugins) { in.Bind.DeepCopyInto(&out.Bind) in.PostBind.DeepCopyInto(&out.PostBind) in.MultiPoint.DeepCopyInto(&out.MultiPoint) + in.PlacementGenerate.DeepCopyInto(&out.PlacementGenerate) + in.PlacementScore.DeepCopyInto(&out.PlacementScore) return } diff --git a/vendor/k8s.io/kube-scheduler/framework/cycle_state.go b/vendor/k8s.io/kube-scheduler/framework/cycle_state.go index 49c8ea58bb..4d103b2e39 100644 --- a/vendor/k8s.io/kube-scheduler/framework/cycle_state.go +++ b/vendor/k8s.io/kube-scheduler/framework/cycle_state.go @@ -65,6 +65,18 @@ type CycleState interface { // SetSkipPreBindPlugins sets plugins that should be skipped in the PerBind extension point. // This function is mostly for the scheduling framework runtime, plugins usually don't have to use it. SetSkipPreBindPlugins(plugins sets.Set[string]) + // GetParallelPreBindPlugins returns plugins that can be run in parallel with other plugins + // in the PreBind extension point. + // This function is mostly for the scheduling framework runtime, plugins usually don't have to use it. + GetParallelPreBindPlugins() sets.Set[string] + // GetParallelPreBindPlugins returns plugins that can be run in parallel with other plugins + // in the PreBind extension point. + // This function is mostly for the scheduling framework runtime, plugins usually don't have to use it. + SetParallelPreBindPlugins(plugins sets.Set[string]) + // ShouldSkipAllPostFilterPlugins returns whether all plugins should be skipped in the PostFilter extension point. + // This function is mostly for the scheduling framework runtime, plugins usually don't have to use it. + ShouldSkipAllPostFilterPlugins() bool + // Read retrieves data with the given "key" from CycleState. If the key is not // present, ErrNotFound is returned. // @@ -81,4 +93,39 @@ type CycleState interface { // Clone creates a copy of CycleState and returns its pointer. Clone returns // nil if the context being cloned is nil. Clone() CycleState + // IsPodGroupSchedulingCycle returns true if this cycle is a pod group scheduling cycle. + // If set to false, it means that the pod referencing this CycleState either passed the pod group cycle + // or doesn't belong to any pod group. + // This field can only be set to true when GenericWorkload feature flag is enabled. + IsPodGroupSchedulingCycle() bool + // GetPodGroupSchedulingCycle gets the cycle state of the PodGroup for a Pod. + // This should be only used when GenericWorkload feature flag is enabled. + GetPodGroupSchedulingCycle() PodGroupCycleState + // SetPodGroupSchedulingCycle sets the cycle state of the PodGroup for a Pod. + // This should be only used when GenericWorkload feature flag is enabled. + SetPodGroupSchedulingCycle(PodGroupCycleState) +} + +// PodGroupCycleState provides a mechanism for plugins that operate on pod groups to store and retrieve arbitrary data. +// StateData stored by one plugin can be read, altered, or deleted by another plugin that operates on a pod group. +// PodGroupCycleState does not provide any data protection, as all plugins are assumed to be +// trusted. +type PodGroupCycleState interface { + // ShouldRecordPluginMetrics returns whether metrics.PluginExecutionDuration metrics + // should be recorded. + // This function is mostly for the scheduling framework runtime, plugins usually don't have to use it. + ShouldRecordPluginMetrics() bool + // Read retrieves data with the given "key" from PodGroupCycleState. If the key is not + // present, ErrNotFound is returned. + // + // See PodGroupCycleState for notes on concurrency. + Read(key StateKey) (StateData, error) + // Write stores the given "val" in PodGroupCycleState with the given "key". + // + // See PodGroupCycleState for notes on concurrency. + Write(key StateKey, val StateData) + // Delete deletes data with the given key from PodGroupCycleState. + // + // See PodGroupCycleState for notes on concurrency. + Delete(key StateKey) } diff --git a/vendor/k8s.io/kube-scheduler/framework/interface.go b/vendor/k8s.io/kube-scheduler/framework/interface.go index dff535cb4c..5575c2dd82 100644 --- a/vendor/k8s.io/kube-scheduler/framework/interface.go +++ b/vendor/k8s.io/kube-scheduler/framework/interface.go @@ -22,6 +22,7 @@ import ( "context" "errors" "math" + "slices" "strings" "time" @@ -192,6 +193,11 @@ func (s *Status) IsRejected() bool { return code == Unschedulable || code == UnschedulableAndUnresolvable || code == Pending } +// IsError returns true if and only if "Status" is non-nil and its Code is "Error". +func (s *Status) IsError() bool { + return s.Code() == Error +} + // AsError returns nil if the status is a success, a wait or a skip; otherwise returns an "error" object // with a concatenated message on reasons of the Status. func (s *Status) AsError() error { @@ -226,6 +232,16 @@ func (s *Status) String() string { return s.Message() } +// Clone clones the entire Status and returns a copy. +func (s *Status) Clone() *Status { + return &Status{ + code: s.code, + reasons: slices.Clone(s.reasons), + err: s.err, + plugin: s.plugin, + } +} + // NewStatus makes a Status out of the given arguments and returns its pointer. func NewStatus(code Code, reasons ...string) *Status { s := &Status{ @@ -285,12 +301,35 @@ type PluginScore struct { Score int64 } +// PlacementPluginScores stores scores for a given placement. +type PlacementPluginScores struct { + // Placement is the placement info that can be used to identify a specific placement. + Placement *Placement + // Scores is scores from plugins and extenders. + Scores []PluginScore + // TotalScore is the total score in Scores. + TotalScore int64 + // Randomizer is used to provide randomness + // when randomizing placements within a common score. + Randomizer int +} + const ( // MaxNodeScore is the maximum score a Score plugin is expected to return. - MaxNodeScore int64 = 100 + // + // Deprecated: use MaxScore instead. + MaxNodeScore int64 = MaxScore // MinNodeScore is the minimum score a Score plugin is expected to return. - MinNodeScore int64 = 0 + // + // Deprecated: use MinScore instead. + MinNodeScore int64 = MinScore + + // MaxScore is the maximum score a Score or PlacementScore plugin is expected to return. + MaxScore int64 = 100 + + // MinScore is the minimum score a Score or PlacementScore plugin is expected to return. + MinScore int64 = 0 // MaxTotalScore is the maximum total score. MaxTotalScore int64 = math.MaxInt64 @@ -326,7 +365,23 @@ type WaitingPod interface { // to unblock the pod. Allow(pluginName string) // Reject declares the waiting pod unschedulable. - Reject(pluginName, msg string) + Reject(pluginName, msg string) bool + // Preempt preempts the waiting pod. Compared to reject it does not mark the pod as unschedulable, + // allowing it to be rescheduled. + Preempt(pluginName, msg string) bool +} + +// PodInPreBind represents a pod currently in preBind phase. +type PodInPreBind interface { + // CancelPod cancels the context attached to a goroutine running binding cycle of this pod + // if the pod is not marked as prebound. + // Returns true if the cancel was successfully run. + CancelPod(reason string) bool + + // MarkPrebound marks the pod as prebound, making it impossible to cancel the context of binding cycle + // via PodInPreBind + // Returns false if the context was already canceled. + MarkPrebound() bool } // PreFilterResult wraps needed info for scheduler framework to act upon PreFilter phase. @@ -364,6 +419,19 @@ type PostFilterResult struct { *NominatingInfo } +// PreBindPreFlightResult wraps needed info for scheduler framework to act upon PreBindPreFlight phase. +type PreBindPreFlightResult struct { + // AllowParallel indicates whether this plugin's PreBind method can be run + // in parallel with other plugins during PreBind phase. + // The scheduler groups consecutive plugins that return AllowParallel: true + // and runs them in parallel. + // A plugin that returns AllowParallel: false breaks the parallel group + // and runs sequentially. + // Note: skipped plugins are effectively ignored, but if a skipped plugin returns + // AllowParallel: false, it still breaks the parallel group of adjacent plugins. + AllowParallel bool +} + // Plugin is the parent type for all the scheduling framework plugins. type Plugin interface { Name() string @@ -581,11 +649,13 @@ type ReservePlugin interface { // These plugins are called before a pod being scheduled. type PreBindPlugin interface { Plugin - // PreBindPreFlight is called before PreBind, and the plugin is supposed to return Success, Skip, or Error status. + // PreBindPreFlight is called before PreBind, and the plugin is supposed to return two values: + // - PreBindPreFlightResult (nil is valid, and means results with the zero values on all fields). + // - Success, Skip, or Error status. // If it returns Success, it means this PreBind plugin will handle this pod. // If it returns Skip, it means this PreBind plugin has nothing to do with the pod, and PreBind will be skipped. // This function should be lightweight, and shouldn't do any actual operation, e.g., creating a volume etc. - PreBindPreFlight(ctx context.Context, state CycleState, p *v1.Pod, nodeName string) *Status + PreBindPreFlight(ctx context.Context, state CycleState, p *v1.Pod, nodeName string) (*PreBindPreFlightResult, *Status) // PreBind is called before binding a pod. All prebind plugins must return // success or the pod will be rejected and won't be sent for binding. @@ -682,6 +752,55 @@ type SignPlugin interface { SignPod(ctx context.Context, pod *v1.Pod) ([]SignFragment, *Status) } +// GeneratePlacementsResult represents the result of the PlacementGeneratePlugin. +type GeneratePlacementsResult struct { + // Placements is the set of placements that the plugin wants to partition the resources into. + // The partitions can overlap. + // + // To represent no valid partitions, set the array to nil or empty. + Placements []*Placement +} + +// PlacementGeneratePlugin is an interface for plugins that generate candidate Placements. +type PlacementGeneratePlugin interface { + Plugin + + // GeneratePlacements generates a list of potential Placements for the given PodGroup within the parent placement. + // Each Placement represents a candidate set of resources, e.g., nodes matching a selector. + GeneratePlacements(ctx context.Context, state PodGroupCycleState, podGroup PodGroupInfo, parentPlacement *Placement) (*GeneratePlacementsResult, *Status) +} + +// PlacementScore stores result of a placement score plugin to be later used for normalization. +type PlacementScore struct { + // Placement is the placement for which the score was computed + Placement *Placement + // Score is the score for a given placement, which is used to rank the placements and pick the best one. + Score int64 +} + +// PlacementScoreExtensions is an interface for PlacementScore extended functionality. +type PlacementScoreExtensions interface { + // NormalizePlacementScore is called for all placement scores produced by the same plugin's "ScorePlacement" + // method. A successful run of NormalizePlacementScore will update the scores list and return + // a success status. + NormalizePlacementScore(ctx context.Context, state PodGroupCycleState, podGroup PodGroupInfo, placementScores []PlacementScore) *Status +} + +// PlacementScorePlugin is an interface for plugins that score feasible Placements. +type PlacementScorePlugin interface { + Plugin + + // ScorePlacement calculates a score for a given Placement. + // This function is called only for Placements that have been deemed feasible for the sufficient number of pods in the PodGroup scheduling cycle. + // The PodGroupAssignments indicates the node assigned to each pod within this Placement. + // The returned score is a int64 with higher scores generally indicating more preferable Placements. + // Plugins can implement various scoring strategies, such as bin packing to minimize resource fragmentation. + ScorePlacement(ctx context.Context, state PodGroupCycleState, podGroup PodGroupInfo, placement *PodGroupAssignments) (int64, *Status) + + // PlacementScoreExtensions returns a PlacementScoreExtensions interface if it implements one, or nil if does not. + PlacementScoreExtensions() PlacementScoreExtensions +} + // Handle provides data and some tools that plugins can use. It is // passed to the plugin factories at the time of plugin initialization. Plugins // must store and use this handle to call framework functions. @@ -717,6 +836,15 @@ type Handle interface { // The return value indicates if the pod is waiting or not. RejectWaitingPod(uid types.UID) bool + // AddPodInPreBind adds a pod to the pods in preBind list. + AddPodInPreBind(uid types.UID, cancel context.CancelCauseFunc) + + // GetPodInPreBind returns a pod that is in the binding cycle but before it is bound given its UID. + GetPodInPreBind(uid types.UID) PodInPreBind + + // RemovePodInPreBind removes a pod from the pods in preBind list. + RemovePodInPreBind(uid types.UID) + // ClientSet returns a kubernetes clientSet. ClientSet() clientset.Interface @@ -724,7 +852,7 @@ type Handle interface { KubeConfig() *restclient.Config // EventRecorder returns an event recorder. - EventRecorder() events.EventRecorder + EventRecorder() events.EventRecorderLogger SharedInformerFactory() informers.SharedInformerFactory @@ -757,11 +885,11 @@ type Handle interface { // ProfileName returns the profile name associated to a profile. ProfileName() string - // WorkloadManager can be used to provide workload-aware scheduling. - WorkloadManager() WorkloadManager + // PodGroupManager provides an interface for runtime information about pod groups from scheduler's cache. + PodGroupManager() PodGroupManager - // Sign a pod. - SignPod(ctx context.Context, pod *v1.Pod, recordPluginStats bool) PodSignature + // SignPod creates a PodSignature for a pod. + SignPod(ctx context.Context, pod *v1.Pod) PodSignature } // Parallelizer helps run scheduling operations in parallel chunks where possible, to improve performance and CPU utilization. diff --git a/vendor/k8s.io/kube-scheduler/framework/listers.go b/vendor/k8s.io/kube-scheduler/framework/listers.go index 98796329e7..701e81408f 100644 --- a/vendor/k8s.io/kube-scheduler/framework/listers.go +++ b/vendor/k8s.io/kube-scheduler/framework/listers.go @@ -17,10 +17,9 @@ limitations under the License. package framework import ( - "time" - v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" @@ -50,6 +49,13 @@ type StorageInfoLister interface { type SharedLister interface { NodeInfos() NodeInfoLister StorageInfos() StorageInfoLister + PodGroupStates() PodGroupStateLister +} + +// PodGroupStateLister provides read access to pod group states. +type PodGroupStateLister interface { + // Get returns the PodGroupState of the given pod group. + Get(namespace string, podGroupName string) (PodGroupState, error) } type CSINodeLister interface { @@ -99,15 +105,20 @@ type ResourceClaimTracker interface { GatherAllocatedState() (*structured.AllocatedState, error) // SignalClaimPendingAllocation signals to the tracker that the given ResourceClaim will be allocated via an API call in the - // binding phase. This change is immediately reflected in the result of List() and the other accessors. + // binding phase, therefore the given ResourceClaim must be non-nil and have a non-nil Status.Allocation. + // If the claim already has a pending allocation, then the allocation becomes shared. The same number of SignalClaimPendingAllocation() callers + // for a given claimUID is expected to eventually call MaybeRemoveClaimPendingAllocation() for that claimUID. + // This change is immediately reflected in the result of List() and the other accessors. SignalClaimPendingAllocation(claimUID types.UID, allocatedClaim *resourceapi.ResourceClaim) error // ClaimHasPendingAllocation answers whether a given claim has a pending allocation during the binding phase. It can be used to avoid // race conditions in subsequent scheduling phases. - ClaimHasPendingAllocation(claimUID types.UID) bool - // RemoveClaimPendingAllocation removes the pending allocation for the given ResourceClaim from the tracker if any was signaled via - // SignalClaimPendingAllocation(). Returns whether there was a pending allocation to remove. List() and the other accessors immediately - // stop reflecting the pending allocation in the results. - RemoveClaimPendingAllocation(claimUID types.UID) (deleted bool) + GetPendingAllocation(claimUID types.UID) *resourceapi.AllocationResult + // MaybeRemoveClaimPendingAllocation might remove the pending allocation for the given ResourceClaim from the tracker if any was signaled via + // SignalClaimPendingAllocation(). When `forceRemove` is true, it always removes the pending allocation. Otherwise, it removes the pending + // allocation only when no other pods are still using that pending allocation (from SignalClaimPendingAllocation and AcquirePendingAllocation). + // Returns whether there was a pending allocation and it was removed. + // List() and the other accessors immediately stop reflecting the pending allocation in the results when the pending allocation is removed. + MaybeRemoveClaimPendingAllocation(claimUID types.UID, forceRemove bool) (deleted bool) // AssumeClaimAfterAPICall signals to the tracker that an API call modifying the given ResourceClaim was made in the binding phase, and the // changes should be reflected in informers very soon. This change is immediately reflected in the result of List() and the other accessors. @@ -127,6 +138,12 @@ type DeviceClassResolver interface { GetDeviceClass(resourceName v1.ResourceName) *resourceapi.DeviceClass } +// PodGroupLister can be used to obtain PodGroups. +type PodGroupLister interface { + // Get returns the PodGroup with the given podGroupName. + Get(namespace, podGroupName string) (*schedulingapi.PodGroup, error) +} + // SharedDRAManager can be used to obtain DRA objects, and track modifications to them in-memory - mainly by the DRA plugin. // The plugin's default implementation obtains the objects from the API. A different implementation can be // plugged into the framework in order to simulate the state of DRA objects. For example, Cluster Autoscaler @@ -136,6 +153,7 @@ type SharedDRAManager interface { ResourceSlices() ResourceSliceLister DeviceClasses() DeviceClassLister DeviceClassResolver() DeviceClassResolver + PodGroups() PodGroupLister } // CSIManager can be used to obtain CSINode objects, and track changes to CSINode objects in-memory. @@ -146,17 +164,18 @@ type CSIManager interface { CSINodes() CSINodeLister } -// WorkloadManager provides an interface for scheduling plugins to provide workload-aware scheduling. -// It acts as the central source of truth for runtime information about workloads. -type WorkloadManager interface { - // PodGroupInfo retrieves the runtime state for a specific pod group, identified by workload's namespace and reference. - PodGroupInfo(namespace string, workloadRef *v1.WorkloadReference) (PodGroupInfo, error) +// PodGroupManager provides an interface for runtime information about pod groups in the scheduler cache. +type PodGroupManager interface { + // PodGroupStates returns the PodGroupStateLister. + PodGroupStates() PodGroupStateLister } -// PodGroupInfo provides an interface to view and modify the state of a single pod group. -type PodGroupInfo interface { +// PodGroupState provides an interface to view the state of a single pod group. +type PodGroupState interface { // AllPods returns the UIDs of all pods known to the scheduler for this group. AllPods() sets.Set[types.UID] + // AllPodsCount returns the number of all pods known to the scheduler for this group. + AllPodsCount() int // UnscheduledPods returns all pods that are unscheduled for this group, // i.e., are neither assumed nor assigned. // The returned map type corresponds to the argument of the PodActivator.Activate method. @@ -166,11 +185,8 @@ type PodGroupInfo interface { AssumedPods() sets.Set[types.UID] // AssignedPods returns the UIDs of all pods already assigned (bound) for this group. AssignedPods() sets.Set[types.UID] - // AssumePod marks a pod as having reached the Reserve stage. - AssumePod(podUID types.UID) - // ForgetPod removes a pod from the assumed state. - ForgetPod(podUID types.UID) - // SchedulingTimeout returns the remaining time until the pod group scheduling times out. - // A new deadline is created if one doesn't exist, or if the previous one has expired. - SchedulingTimeout() time.Duration + // ScheduledPods returns the pods that are either assumed or assigned for this pod group. + ScheduledPods() []*v1.Pod + // ScheduledPodsCount returns the number of pods for this group that are either assumed or assigned. + ScheduledPodsCount() int } diff --git a/vendor/k8s.io/kube-scheduler/framework/signers.go b/vendor/k8s.io/kube-scheduler/framework/signers.go index 934864aa75..3812e7ef41 100644 --- a/vendor/k8s.io/kube-scheduler/framework/signers.go +++ b/vendor/k8s.io/kube-scheduler/framework/signers.go @@ -18,6 +18,7 @@ package framework import ( "encoding/json" + "slices" "sort" v1 "k8s.io/api/core/v1" @@ -59,9 +60,7 @@ func HostPortsSigner(pod *v1.Pod) any { } } ports := portSet.UnsortedList() - sort.Slice(ports, func(i, j int) bool { - return ports[i] < ports[j] - }) + slices.Sort(ports) return ports } @@ -69,18 +68,14 @@ func NodeSelectorRequirementsSigner(reqs []v1.NodeSelectorRequirement) ([]string ret := make([]string, len(reqs)) for i, req := range reqs { t := req.DeepCopy() - sort.Slice(t.Values, func(i, j int) bool { - return t.Values[i] < t.Values[j] - }) + slices.Sort(t.Values) v, err := json.Marshal(t) if err != nil { return nil, err } ret[i] = string(v) } - sort.Slice(ret, func(i, j int) bool { - return ret[i] < ret[j] - }) + slices.Sort(ret) return ret, nil } @@ -125,9 +120,7 @@ func PreferredSchedulingTermSigner(terms []v1.PreferredSchedulingTerm) ([]string } newTerms[i] = string(termStr) } - sort.Slice(newTerms, func(i, j int) bool { - return newTerms[i] < newTerms[j] - }) + slices.Sort(newTerms) return newTerms, nil } @@ -144,10 +137,7 @@ func NodeSelectorTermsSigner(terms []v1.NodeSelectorTerm) ([]string, error) { } req[i] = string(tStr) } - - sort.Slice(req, func(i, j int) bool { - return req[i] < req[j] - }) + slices.Sort(req) return req, nil } @@ -210,8 +200,6 @@ func VolumesSigner(pod *v1.Pod) any { ret = append(ret, string(volStr)) } } - sort.Slice(ret, func(i, j int) bool { - return ret[i] < ret[j] - }) + slices.Sort(ret) return ret } diff --git a/vendor/k8s.io/kube-scheduler/framework/types.go b/vendor/k8s.io/kube-scheduler/framework/types.go index eb463c8ee4..7d929c9b59 100644 --- a/vendor/k8s.io/kube-scheduler/framework/types.go +++ b/vendor/k8s.io/kube-scheduler/framework/types.go @@ -23,6 +23,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" ndf "k8s.io/component-helpers/nodedeclaredfeatures" "k8s.io/klog/v2" @@ -170,7 +171,7 @@ const ( ResourceClaim EventResource = "resource.k8s.io/ResourceClaim" ResourceSlice EventResource = "resource.k8s.io/ResourceSlice" DeviceClass EventResource = "resource.k8s.io/DeviceClass" - Workload EventResource = "scheduling.k8s.io/Workload" + PodGroup EventResource = "scheduling.k8s.io/PodGroup" // WildCard is a special EventResource to match all resources. // e.g., If you register `{Resource: "*", ActionType: All}` in EventsToRegister, @@ -287,6 +288,8 @@ type NodeInfo interface { Snapshot() NodeInfo // String returns representation of human readable format of this NodeInfo. String() string + // GetNodeAllocatableDRAClaimState returns the node allocatable DRA claim allocation states on this node. + GetNodeAllocatableDRAClaimState() map[types.NamespacedName]*NodeAllocatableDRAClaimState // AddPodInfo adds pod information to this NodeInfo. // Consider using this instead of AddPod if a PodInfo is already computed. @@ -636,3 +639,64 @@ func (h HostPortInfo) sanitize(ip, protocol *string) { *protocol = string(v1.ProtocolTCP) } } + +// PodGroupInfo is a wrapper around the PodGroup API object together with a list of unscheduled pods that belong to the pod group. +// Typically used as an input to pod group scheduling cycle plugins. +type PodGroupInfo interface { + // GetUnscheduledPods returns pods that are currently being considered for scheduling. + // The order of the pods is deterministic and based on signature, priority and timestamp. + // This structure only contains the pods considered for scheduling in the pod group scheduling cycle. + GetUnscheduledPods() []*v1.Pod + + // GetName returns the PodGroup name that is used to identify the pod group. + GetName() string + // GetNamespace returns the namespace the pod group belongs to. + GetNamespace() string +} + +// Placement determines the resources to be considered when scheduling a pod group. +// Pod group scheduling cycle can check multiple placements and select the one that results +// in the best pod assignments. +type Placement struct { + // Name uniquely identifies the placement. + // This is used for diagnostics and debugability. + // The choice of the name is up to the PlacementGeneratePlugin. + Name string + // Nodes specifies the nodes that are valid for this placement. + // Scheduler will try to schedule the pod group using only those nodes. + Nodes []NodeInfo +} + +// ProposedAssignment associates pod of a pod group with a proposed node assignment, determined in pod group scheduling cycle. +type ProposedAssignment interface { + // GetPod returns the pod that has the proposed node assignment. + GetPod() *v1.Pod + // GetNodeName returns the name of the proposed node for the pod. + GetNodeName() string +} + +// PodGroupAssignments holds the temporary assignments of pods in a pod group to nodes for a placement. +// Can be used in the pod group scheduling cycle to determine the best placement for a pod group. +type PodGroupAssignments struct { + *Placement + // ProposedAssignments associates pods with proposed nodes that were determined for a given placement + // during the pod group scheduling cycle. + // The pods are guaranteed to also be present in the PodGroupInfo. + ProposedAssignments []ProposedAssignment +} + +// NodeAllocatableDRAClaimState holds information about a node allocatable resource DRA claim's allocation on a node. +type NodeAllocatableDRAClaimState struct { + // ConsumerPods is a set of UIDs of pods that are consuming the DRA claim on this node. + ConsumerPods sets.Set[types.UID] +} + +// Snapshot returns a copy of NodeAllocatableDRAClaimAllocationState with ConsumerPods cloned. +func (s *NodeAllocatableDRAClaimState) Snapshot() *NodeAllocatableDRAClaimState { + if s == nil { + return nil + } + return &NodeAllocatableDRAClaimState{ + ConsumerPods: s.ConsumerPods.Clone(), + } +} diff --git a/vendor/k8s.io/kubectl/pkg/drain/filters.go b/vendor/k8s.io/kubectl/pkg/drain/filters.go index 1edec35ffa..9a2137bda6 100644 --- a/vendor/k8s.io/kubectl/pkg/drain/filters.go +++ b/vendor/k8s.io/kubectl/pkg/drain/filters.go @@ -17,7 +17,6 @@ limitations under the License. package drain import ( - "context" "fmt" "strings" "time" @@ -33,7 +32,7 @@ const ( daemonSetWarning = "ignoring DaemonSet-managed Pods" localStorageFatal = "Pods with local storage (use --delete-emptydir-data to override)" localStorageWarning = "deleting Pods with local storage" - unmanagedFatal = "cannot delete Pods that declare no controller (use --force to override)" + unmanagedFatal = "Pods that declare no controller (use --force to override)" unmanagedWarning = "deleting Pods that declare no controller" ) @@ -193,7 +192,7 @@ func (d *Helper) daemonSetFilter(pod corev1.Pod) PodDeleteStatus { return MakePodDeleteStatusOkay() } - if _, err := d.Client.AppsV1().DaemonSets(pod.Namespace).Get(context.TODO(), controllerRef.Name, metav1.GetOptions{}); err != nil { + if _, err := d.Client.AppsV1().DaemonSets(pod.Namespace).Get(d.getContext(), controllerRef.Name, metav1.GetOptions{}); err != nil { // remove orphaned pods with a warning if --force is used if apierrors.IsNotFound(err) && d.Force { return MakePodDeleteStatusWithWarning(true, err.Error()) diff --git a/vendor/k8s.io/kubectl/pkg/scale/scale.go b/vendor/k8s.io/kubectl/pkg/scale/scale.go index d2dc51fc69..fd55935362 100644 --- a/vendor/k8s.io/kubectl/pkg/scale/scale.go +++ b/vendor/k8s.io/kubectl/pkg/scale/scale.go @@ -39,10 +39,10 @@ type Scaler interface { // retries in the event of resource version mismatch (if retry is not nil), // and optionally waits until the status of the resource matches newSize (if wait is not nil) // TODO: Make the implementation of this watch-based (#56075) once #31345 is fixed. - Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams, gvr schema.GroupVersionResource, dryRun bool) error + Scale(namespace, name string, newSize uint, actualSize *int32, preconditions *ScalePrecondition, retry, wait *RetryParams, gvr schema.GroupVersionResource, dryRun bool) error // ScaleSimple does a simple one-shot attempt at scaling - not useful on its own, but // a necessary building block for Scale - ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource, dryRun bool) (updatedResourceVersion string, err error) + ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource, dryRun bool) (updatedResourceVersion string, actualSize int32, err error) } // NewScaler get a scaler for a given resource @@ -81,12 +81,15 @@ func NewRetryParams(interval, timeout time.Duration) *RetryParams { } // ScaleCondition is a closure around Scale that facilitates retries via util.wait -func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, gvr schema.GroupVersionResource, dryRun bool) wait.ConditionWithContextFunc { +func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, actualSize *int32, gvr schema.GroupVersionResource, dryRun bool) wait.ConditionWithContextFunc { return func(context.Context) (bool, error) { - rv, err := r.ScaleSimple(namespace, name, precondition, count, gvr, dryRun) + rv, size, err := r.ScaleSimple(namespace, name, precondition, count, gvr, dryRun) if updatedResourceVersion != nil { *updatedResourceVersion = rv } + if actualSize != nil { + *actualSize = size + } // Retry only on update conflicts. if apierrors.IsConflict(err) { return false, nil @@ -117,14 +120,14 @@ type genericScaler struct { var _ Scaler = &genericScaler{} // ScaleSimple updates a scale of a given resource. It returns the resourceVersion of the scale if the update was successful. -func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource, dryRun bool) (updatedResourceVersion string, err error) { +func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource, dryRun bool) (updatedResourceVersion string, actualSize int32, err error) { if preconditions != nil { scale, err := s.scaleNamespacer.Scales(namespace).Get(context.TODO(), gvr.GroupResource(), name, metav1.GetOptions{}) if err != nil { - return "", err + return "", 0, err } if err = preconditions.validate(scale); err != nil { - return "", err + return "", 0, err } scale.Spec.Replicas = int32(newSize) updateOptions := metav1.UpdateOptions{} @@ -133,9 +136,9 @@ func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *Scale } updatedScale, err := s.scaleNamespacer.Scales(namespace).Update(context.TODO(), gvr.GroupResource(), scale, updateOptions) if err != nil { - return "", err + return "", 0, err } - return updatedScale.ResourceVersion, nil + return updatedScale.ResourceVersion, updatedScale.Spec.Replicas, nil } // objectForReplicas is used for encoding scale patch @@ -151,7 +154,7 @@ func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *Scale } patch, err := json.Marshal(&spec) if err != nil { - return "", err + return "", 0, err } patchOptions := metav1.PatchOptions{} if dryRun { @@ -159,19 +162,19 @@ func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *Scale } updatedScale, err := s.scaleNamespacer.Scales(namespace).Patch(context.TODO(), gvr, name, types.MergePatchType, patch, patchOptions) if err != nil { - return "", err + return "", 0, err } - return updatedScale.ResourceVersion, nil + return updatedScale.ResourceVersion, updatedScale.Spec.Replicas, nil } // Scale updates a scale of a given resource to a new size, with optional precondition check (if preconditions is not nil), // optional retries (if retry is not nil), and then optionally waits for the status to reach desired count. -func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams, gvr schema.GroupVersionResource, dryRun bool) error { +func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, actualSize *int32, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams, gvr schema.GroupVersionResource, dryRun bool) error { if retry == nil { // make it try only once, immediately retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond} } - cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, gvr, dryRun) + cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, actualSize, gvr, dryRun) if err := wait.PollUntilContextTimeout(context.Background(), retry.Interval, retry.Timeout, true, cond); err != nil { return err } diff --git a/vendor/k8s.io/kubectl/pkg/scheme/install.go b/vendor/k8s.io/kubectl/pkg/scheme/install.go index 34c9878220..4a6567c704 100644 --- a/vendor/k8s.io/kubectl/pkg/scheme/install.go +++ b/vendor/k8s.io/kubectl/pkg/scheme/install.go @@ -43,7 +43,6 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" storagev1 "k8s.io/api/storage/v1" storagev1alpha1 "k8s.io/api/storage/v1alpha1" storagev1beta1 "k8s.io/api/storage/v1beta1" @@ -78,6 +77,5 @@ func init() { utilruntime.Must(Scheme.SetVersionPriority(networkingv1.SchemeGroupVersion)) utilruntime.Must(Scheme.SetVersionPriority(policyv1beta1.SchemeGroupVersion, policyv1.SchemeGroupVersion)) utilruntime.Must(Scheme.SetVersionPriority(rbacv1.SchemeGroupVersion, rbacv1beta1.SchemeGroupVersion, rbacv1alpha1.SchemeGroupVersion)) - utilruntime.Must(Scheme.SetVersionPriority(schedulingv1alpha1.SchemeGroupVersion)) utilruntime.Must(Scheme.SetVersionPriority(storagev1.SchemeGroupVersion, storagev1beta1.SchemeGroupVersion, storagev1alpha1.SchemeGroupVersion)) } diff --git a/vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go b/vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go index 8b8481c7bd..327230dda0 100644 --- a/vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go +++ b/vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go @@ -121,7 +121,9 @@ func loadSystemLanguage() string { } pieces := strings.Split(langStr, ".") if len(pieces) != 2 { - klog.V(3).Infof("Unexpected system language (%s), defaulting to en_US", langStr) + if langStr != "C" { + klog.V(3).Infof("Unexpected system language (%s), defaulting to en_US", langStr) + } return "default" } return pieces[0] diff --git a/vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go b/vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go index 04b8cdab24..2c99cc9a65 100644 --- a/vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go +++ b/vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubectl/pkg/util/term/term.go b/vendor/k8s.io/kubectl/pkg/util/term/term.go index 93a992fe31..895a8aa2af 100644 --- a/vendor/k8s.io/kubectl/pkg/util/term/term.go +++ b/vendor/k8s.io/kubectl/pkg/util/term/term.go @@ -17,6 +17,7 @@ limitations under the License. package term import ( + "errors" "io" "os" @@ -113,3 +114,27 @@ func (t TTY) Safe(fn SafeFunc) error { term.RestoreTerminal(inFd, state) }).Run(fn) } + +type detachableReader struct { + escapeProxy io.Reader +} + +func NewDetachableReader(r io.Reader, detachKeys string) (io.Reader, error) { + detachKeyBytes, err := term.ToBytes(detachKeys) + if err != nil { + return nil, err + } + return &detachableReader{ + escapeProxy: term.NewEscapeProxy(r, detachKeyBytes), + }, nil +} + +func (r *detachableReader) Read(p []byte) (n int, err error) { + n, err = r.escapeProxy.Read(p) + if errors.Is(err, term.EscapeError{}) { + // EscapeError is expected when the user types the detach key sequence, so we should not treat it as an error. + // Instead, we return io.EOF so that the attach session will end gracefully. + err = io.EOF + } + return n, err +} diff --git a/vendor/k8s.io/kubelet/config/v1beta1/types.go b/vendor/k8s.io/kubelet/config/v1beta1/types.go index a7c4e21829..40e6567c5a 100644 --- a/vendor/k8s.io/kubelet/config/v1beta1/types.go +++ b/vendor/k8s.io/kubelet/config/v1beta1/types.go @@ -102,6 +102,18 @@ const ( AlwaysVerify ImagePullCredentialsVerificationPolicy = "AlwaysVerify" ) +// MemoryReservationPolicy defines how the kubelet applies cgroup v2 memory protection. +type MemoryReservationPolicy string + +const ( + // NoneMemoryReservationPolicy disables memory.min protection for containers and pods. + // This is the default to maintain node stability by preventing "locked" memory. + NoneMemoryReservationPolicy MemoryReservationPolicy = "None" + // TieredReservationMemoryReservationPolicy enables tiered memory protection: + // memory.min for Guaranteed pods, memory.low for Burstable pods. + TieredReservationMemoryReservationPolicy MemoryReservationPolicy = "TieredReservation" +) + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KubeletConfiguration contains the configuration for the Kubelet @@ -180,6 +192,16 @@ type KubeletConfiguration struct { // Default: nil // +optional TLSCipherSuites []string `json:"tlsCipherSuites,omitempty"` + // tlsCurvePreferences is the set of allowed key exchange mechanisms for the server, + // specified as numeric Go crypto/tls CurveID values. + // The supported values depend on the Go version used. + // See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. + // The order of the list is ignored, and key exchange mechanisms are + // chosen by Go from this list using an internal preference order. + // If empty, the default Go curves will be used. + // Default: nil + // +optional + TLSCurvePreferences []int32 `json:"tlsCurvePreferences,omitempty"` // tlsMinVersion is the minimum TLS version supported. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). // Default: "" @@ -335,6 +357,8 @@ type KubeletConfiguration struct { NodeLeaseDurationSeconds int32 `json:"nodeLeaseDurationSeconds,omitempty"` // imageMinimumGCAge is the minimum age for an unused image before it is // garbage collected. + // The field value must be greater than 0. + // If unset or 0, defaults to 2m. // Default: "2m" // +optional ImageMinimumGCAge metav1.Duration `json:"imageMinimumGCAge,omitempty"` @@ -731,10 +755,11 @@ type KubeletConfiguration struct { KubeReservedCgroup string `json:"kubeReservedCgroup,omitempty"` // This flag specifies the various Node Allocatable enforcements that Kubelet needs to perform. // This flag accepts a list of options. Acceptable options are `none`, `pods`, - // `system-reserved` and `kube-reserved`. + // `system-reserved`, `system-reserved-compressible`, `kube-reserved`, and `kube-reserved-compressible`. // If `none` is specified, no other options may be specified. - // When `system-reserved` is in the list, systemReservedCgroup must be specified. - // When `kube-reserved` is in the list, kubeReservedCgroup must be specified. + // When a `system-reserved` option is in the list, systemReservedCgroup must be specified. + // When a `kube-reserved` option is in the list, kubeReservedCgroup must be specified. + // If a `compressible` option is specified, the corresponding non-compressible option may not be specified. // This field is supported only when `cgroupsPerQOS` is set to true. // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) // for more information. @@ -779,7 +804,6 @@ type KubeletConfiguration struct { // Enabling this feature has security implications. The recommendation is to enable it on a need basis for debugging // purposes and disabling otherwise. // Default: false - // +featureGate=NodeLogQuery // +optional EnableSystemLogQuery *bool `json:"enableSystemLogQuery,omitempty"` // shutdownGracePeriod specifies the total duration that the node should delay the @@ -875,6 +899,16 @@ type KubeletConfiguration struct { // +featureGate=MemoryQoS // +optional MemoryThrottlingFactor *float64 `json:"memoryThrottlingFactor,omitempty"` + // MemoryReservationPolicy controls how the kubelet applies cgroup v2 memory protection. + // "None" (default): The kubelet does not set memory.min for containers and pods, + // ensuring no hard memory is locked by the kernel. + // "TieredReservation": The kubelet sets cgroup v2 memory.min for Guaranteed pods and memory.low for Burstable pods based on memory requests. + // Guaranteed memory is never reclaimed by the kernel; Burstable memory is preferentially retained but may be reclaimed under extreme pressure. + // See https://kep.k8s.io/2570 for more details. + // Default: None + // +featureGate=MemoryQoS + // +optional + MemoryReservationPolicy MemoryReservationPolicy `json:"memoryReservationPolicy,omitempty"` // registerWithTaints are an array of taints to add to a node object when // the kubelet registers itself. This only takes effect when registerNode // is true and upon the initial registration of the node. @@ -923,7 +957,6 @@ type KubeletConfiguration struct { FailCgroupV1 *bool `json:"failCgroupV1,omitempty"` // UserNamespaces contains User Namespace configurations. - // +featureGate=UserNamespacesSupport // +optional UserNamespaces *UserNamespaces `json:"userNamespaces,omitempty"` } @@ -1131,7 +1164,6 @@ type UserNamespaces struct { // Changing the value may require recreating all containers on the node. // // Default: 65536 - // +featureGate=UserNamespacesSupport // +optional IDsPerPod *int64 `json:"idsPerPod,omitempty"` } diff --git a/vendor/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go index 6a90801818..a60d9b28a3 100644 --- a/vendor/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go @@ -338,6 +338,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.TLSCurvePreferences != nil { + in, out := &in.TLSCurvePreferences, &out.TLSCurvePreferences + *out = make([]int32, len(*in)) + copy(*out, *in) + } in.Authentication.DeepCopyInto(&out.Authentication) out.Authorization = in.Authorization if in.RegistryPullQPS != nil { diff --git a/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.pb.go b/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.pb.go index e2221a4c59..3d232fbbe9 100644 --- a/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.pb.go +++ b/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.pb.go @@ -208,8 +208,12 @@ type DeviceHealth struct { // If not specified, zero, or negative, Kubelet will use a default timeout. // Negative values will be logged and treated as if not specified. HealthCheckTimeoutSeconds int64 `protobuf:"varint,4,opt,name=health_check_timeout_seconds,json=healthCheckTimeoutSeconds,proto3" json:"health_check_timeout_seconds,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // An optional message providing additional details about the device's health. + // Maximum length is 1024 characters. Messages longer than 1024 characters + // will be truncated to 1021 characters with "..." appended. + Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DeviceHealth) Reset() { @@ -270,6 +274,13 @@ func (x *DeviceHealth) GetHealthCheckTimeoutSeconds() int64 { return 0 } +func (x *DeviceHealth) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + // NodeWatchResourcesResponse contains a list of devices and their current health. // This should be a complete list for the driver; Kubelet will reconcile this // state with its internal cache. Any devices managed by the driver that are @@ -332,7 +343,7 @@ var file_staging_src_k8s_io_kubelet_pkg_apis_dra_health_v1alpha1_api_proto_rawDe 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xdf, 0x01, 0x0a, + 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xf9, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x32, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, @@ -346,27 +357,29 @@ var file_staging_src_k8s_io_kubelet_pkg_apis_dra_health_v1alpha1_api_proto_rawDe 0x1c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x4e, - 0x0a, 0x1a, 0x4e, 0x6f, 0x64, 0x65, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2a, 0x37, - 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, - 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x48, - 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, - 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, 0x32, 0x78, 0x0a, 0x11, 0x44, 0x52, 0x41, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x63, 0x0a, 0x12, - 0x4e, 0x6f, 0x64, 0x65, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x12, 0x23, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x6f, - 0x64, 0x65, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, - 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6b, 0x75, 0x62, 0x65, - 0x6c, 0x65, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x64, 0x72, 0x61, - 0x2d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x4e, 0x0a, 0x1a, 0x4e, 0x6f, 0x64, 0x65, + 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, + 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2a, 0x37, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, + 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, + 0x02, 0x32, 0x78, 0x0a, 0x11, 0x44, 0x52, 0x41, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x63, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65, 0x57, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x24, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x6f, 0x64, + 0x65, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x6b, + 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x74, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x64, 0x72, 0x61, 0x2d, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, }) var ( diff --git a/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.proto b/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.proto index 1a25781704..247166b045 100644 --- a/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.proto +++ b/vendor/k8s.io/kubelet/pkg/apis/dra-health/v1alpha1/api.proto @@ -61,6 +61,11 @@ message DeviceHealth { // If not specified, zero, or negative, Kubelet will use a default timeout. // Negative values will be logged and treated as if not specified. int64 health_check_timeout_seconds = 4; + + // An optional message providing additional details about the device's health. + // Maximum length is 1024 characters. Messages longer than 1024 characters + // will be truncated to 1021 characters with "..." appended. + string message = 5; } // NodeWatchResourcesResponse contains a list of devices and their current health. diff --git a/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.pb.go b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.pb.go new file mode 100644 index 0000000000..066bdc372d --- /dev/null +++ b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.pb.go @@ -0,0 +1,471 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.4 +// protoc v4.23.4 +// source: staging/src/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto + +package v1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type EventType int32 + +const ( + EventType_UNSPECIFIED EventType = 0 + EventType_ADDED EventType = 1 + EventType_MODIFIED EventType = 2 + EventType_DELETED EventType = 3 + EventType_INITIAL_SYNC_COMPLETE EventType = 4 +) + +// Enum value maps for EventType. +var ( + EventType_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "ADDED", + 2: "MODIFIED", + 3: "DELETED", + 4: "INITIAL_SYNC_COMPLETE", + } + EventType_value = map[string]int32{ + "UNSPECIFIED": 0, + "ADDED": 1, + "MODIFIED": 2, + "DELETED": 3, + "INITIAL_SYNC_COMPLETE": 4, + } +) + +func (x EventType) Enum() *EventType { + p := new(EventType) + *p = x + return p +} + +func (x EventType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (EventType) Descriptor() protoreflect.EnumDescriptor { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_enumTypes[0].Descriptor() +} + +func (EventType) Type() protoreflect.EnumType { + return &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_enumTypes[0] +} + +func (x EventType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use EventType.Descriptor instead. +func (EventType) EnumDescriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{0} +} + +// This is sent for each update in the Watch stream +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +type WatchPodsEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + // ADDED, MODIFIED, DELETED, INITIAL_SYNC_COMPLETE + Type EventType `protobuf:"varint,1,opt,name=type,proto3,enum=v1alpha1.EventType" json:"type,omitempty"` + // pod is nil for INITIAL_SYNC_COMPLETE. + // For DELETED events, only the pod name, namespace, and UID are guaranteed to be set. + Pod []byte `protobuf:"bytes,2,opt,name=pod,proto3" json:"pod,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchPodsEvent) Reset() { + *x = WatchPodsEvent{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchPodsEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchPodsEvent) ProtoMessage() {} + +func (x *WatchPodsEvent) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchPodsEvent.ProtoReflect.Descriptor instead. +func (*WatchPodsEvent) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{0} +} + +func (x *WatchPodsEvent) GetType() EventType { + if x != nil { + return x.Type + } + return EventType_UNSPECIFIED +} + +func (x *WatchPodsEvent) GetPod() []byte { + if x != nil { + return x.Pod + } + return nil +} + +// ListPodsResponse returns a list of Pods. +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +type ListPodsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Pods [][]byte `protobuf:"bytes,1,rep,name=pods,proto3" json:"pods,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPodsResponse) Reset() { + *x = ListPodsResponse{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPodsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPodsResponse) ProtoMessage() {} + +func (x *ListPodsResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPodsResponse.ProtoReflect.Descriptor instead. +func (*ListPodsResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{1} +} + +func (x *ListPodsResponse) GetPods() [][]byte { + if x != nil { + return x.Pods + } + return nil +} + +// GetPodResponse returns a Pod. +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +type GetPodResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Pod []byte `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetPodResponse) Reset() { + *x = GetPodResponse{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPodResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPodResponse) ProtoMessage() {} + +func (x *GetPodResponse) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPodResponse.ProtoReflect.Descriptor instead. +func (*GetPodResponse) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{2} +} + +func (x *GetPodResponse) GetPod() []byte { + if x != nil { + return x.Pod + } + return nil +} + +type WatchPodsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchPodsRequest) Reset() { + *x = WatchPodsRequest{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchPodsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchPodsRequest) ProtoMessage() {} + +func (x *WatchPodsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchPodsRequest.ProtoReflect.Descriptor instead. +func (*WatchPodsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{3} +} + +type ListPodsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPodsRequest) Reset() { + *x = ListPodsRequest{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPodsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPodsRequest) ProtoMessage() {} + +func (x *ListPodsRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPodsRequest.ProtoReflect.Descriptor instead. +func (*ListPodsRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{4} +} + +type GetPodRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PodUID string `protobuf:"bytes,1,opt,name=podUID,proto3" json:"podUID,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetPodRequest) Reset() { + *x = GetPodRequest{} + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPodRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPodRequest) ProtoMessage() {} + +func (x *GetPodRequest) ProtoReflect() protoreflect.Message { + mi := &file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPodRequest.ProtoReflect.Descriptor instead. +func (*GetPodRequest) Descriptor() ([]byte, []int) { + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP(), []int{5} +} + +func (x *GetPodRequest) GetPodUID() string { + if x != nil { + return x.PodUID + } + return "" +} + +var File_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto protoreflect.FileDescriptor + +var file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDesc = string([]byte{ + 0x0a, 0x3b, 0x73, 0x74, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x6b, 0x38, + 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x74, 0x2f, 0x70, 0x6b, 0x67, + 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x4b, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x50, 0x6f, 0x64, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x03, 0x70, 0x6f, 0x64, 0x22, 0x26, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x22, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x70, 0x6f, 0x64, + 0x22, 0x12, 0x0a, 0x10, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x27, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x50, 0x6f, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x64, 0x55, + 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, + 0x2a, 0x5d, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, + 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, + 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, + 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x32, + 0xd1, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x64, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x50, 0x6f, 0x64, 0x73, 0x12, 0x1a, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x50, 0x6f, 0x64, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x43, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x73, 0x12, 0x19, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, 0x12, 0x17, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x27, 0x5a, 0x25, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6b, 0x75, + 0x62, 0x65, 0x6c, 0x65, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x70, + 0x6f, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +}) + +var ( + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescOnce sync.Once + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescData []byte +) + +func file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescGZIP() []byte { + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescOnce.Do(func() { + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDesc), len(file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDesc))) + }) + return file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDescData +} + +var file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_goTypes = []any{ + (EventType)(0), // 0: v1alpha1.EventType + (*WatchPodsEvent)(nil), // 1: v1alpha1.WatchPodsEvent + (*ListPodsResponse)(nil), // 2: v1alpha1.ListPodsResponse + (*GetPodResponse)(nil), // 3: v1alpha1.GetPodResponse + (*WatchPodsRequest)(nil), // 4: v1alpha1.WatchPodsRequest + (*ListPodsRequest)(nil), // 5: v1alpha1.ListPodsRequest + (*GetPodRequest)(nil), // 6: v1alpha1.GetPodRequest +} +var file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_depIdxs = []int32{ + 0, // 0: v1alpha1.WatchPodsEvent.type:type_name -> v1alpha1.EventType + 4, // 1: v1alpha1.Pods.WatchPods:input_type -> v1alpha1.WatchPodsRequest + 5, // 2: v1alpha1.Pods.ListPods:input_type -> v1alpha1.ListPodsRequest + 6, // 3: v1alpha1.Pods.GetPod:input_type -> v1alpha1.GetPodRequest + 1, // 4: v1alpha1.Pods.WatchPods:output_type -> v1alpha1.WatchPodsEvent + 2, // 5: v1alpha1.Pods.ListPods:output_type -> v1alpha1.ListPodsResponse + 3, // 6: v1alpha1.Pods.GetPod:output_type -> v1alpha1.GetPodResponse + 4, // [4:7] is the sub-list for method output_type + 1, // [1:4] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_init() } +func file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_init() { + if File_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDesc), len(file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_rawDesc)), + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_goTypes, + DependencyIndexes: file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_depIdxs, + EnumInfos: file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_enumTypes, + MessageInfos: file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_msgTypes, + }.Build() + File_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto = out.File + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_goTypes = nil + file_staging_src_k8s_io_kubelet_pkg_apis_pods_v1alpha1_api_proto_depIdxs = nil +} diff --git a/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto new file mode 100644 index 0000000000..480d12d27d --- /dev/null +++ b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; +package v1alpha1; + +option go_package = "k8s.io/kubelet/pkg/apis/pods/v1alpha1"; + +service Pods { + // WatchPods will initially return an ADDED WatchPodsEvent for each + // existing Pod, followed by an INITIAL_SYNC_COMPLETE WatchPodsEvent. + // It then returns a WatchPodsEvent whenever a Pod is created, deleted, or updated. + rpc WatchPods(WatchPodsRequest) returns (stream WatchPodsEvent) {} + + // ListPods returns a of List of Pods + rpc ListPods(ListPodsRequest) returns (ListPodsResponse) {} + + // GetPod returns a Pod for given pod's UID + rpc GetPod(GetPodRequest) returns (GetPodResponse) {} +} + +enum EventType { + UNSPECIFIED = 0; + ADDED = 1; + MODIFIED = 2; + DELETED = 3; + INITIAL_SYNC_COMPLETE = 4; +} + + +// This is sent for each update in the Watch stream +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +message WatchPodsEvent { + // ADDED, MODIFIED, DELETED, INITIAL_SYNC_COMPLETE + EventType type = 1; + // pod is nil for INITIAL_SYNC_COMPLETE. + // For DELETED events, only the pod name, namespace, and UID are guaranteed to be set. + bytes pod = 2; +} + +// ListPodsResponse returns a list of Pods. +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +message ListPodsResponse { + repeated bytes pods = 1; +} + +// GetPodResponse returns a Pod. +// Pod bytes are generated by calling v1.Pod#Marshal(). +// They are convertable to a pod by calling v1.Pod#Unmarshal(). +message GetPodResponse { + bytes pod = 1; +} + + + +message WatchPodsRequest {} + +message ListPodsRequest {} + +message GetPodRequest { + string podUID = 1; +} diff --git a/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api_grpc.pb.go b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api_grpc.pb.go new file mode 100644 index 0000000000..e2d44c684e --- /dev/null +++ b/vendor/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api_grpc.pb.go @@ -0,0 +1,227 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v4.23.4 +// source: staging/src/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto + +package v1alpha1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Pods_WatchPods_FullMethodName = "/v1alpha1.Pods/WatchPods" + Pods_ListPods_FullMethodName = "/v1alpha1.Pods/ListPods" + Pods_GetPod_FullMethodName = "/v1alpha1.Pods/GetPod" +) + +// PodsClient is the client API for Pods service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PodsClient interface { + // WatchPods will initially return an ADDED WatchPodsEvent for each + // existing Pod, followed by an INITIAL_SYNC_COMPLETE WatchPodsEvent. + // It then returns a WatchPodsEvent whenever a Pod is created, deleted, or updated. + WatchPods(ctx context.Context, in *WatchPodsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[WatchPodsEvent], error) + // ListPods returns a of List of Pods + ListPods(ctx context.Context, in *ListPodsRequest, opts ...grpc.CallOption) (*ListPodsResponse, error) + // GetPod returns a Pod for given pod's UID + GetPod(ctx context.Context, in *GetPodRequest, opts ...grpc.CallOption) (*GetPodResponse, error) +} + +type podsClient struct { + cc grpc.ClientConnInterface +} + +func NewPodsClient(cc grpc.ClientConnInterface) PodsClient { + return &podsClient{cc} +} + +func (c *podsClient) WatchPods(ctx context.Context, in *WatchPodsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[WatchPodsEvent], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Pods_ServiceDesc.Streams[0], Pods_WatchPods_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[WatchPodsRequest, WatchPodsEvent]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Pods_WatchPodsClient = grpc.ServerStreamingClient[WatchPodsEvent] + +func (c *podsClient) ListPods(ctx context.Context, in *ListPodsRequest, opts ...grpc.CallOption) (*ListPodsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListPodsResponse) + err := c.cc.Invoke(ctx, Pods_ListPods_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *podsClient) GetPod(ctx context.Context, in *GetPodRequest, opts ...grpc.CallOption) (*GetPodResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetPodResponse) + err := c.cc.Invoke(ctx, Pods_GetPod_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PodsServer is the server API for Pods service. +// All implementations must embed UnimplementedPodsServer +// for forward compatibility. +type PodsServer interface { + // WatchPods will initially return an ADDED WatchPodsEvent for each + // existing Pod, followed by an INITIAL_SYNC_COMPLETE WatchPodsEvent. + // It then returns a WatchPodsEvent whenever a Pod is created, deleted, or updated. + WatchPods(*WatchPodsRequest, grpc.ServerStreamingServer[WatchPodsEvent]) error + // ListPods returns a of List of Pods + ListPods(context.Context, *ListPodsRequest) (*ListPodsResponse, error) + // GetPod returns a Pod for given pod's UID + GetPod(context.Context, *GetPodRequest) (*GetPodResponse, error) + mustEmbedUnimplementedPodsServer() +} + +// UnimplementedPodsServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedPodsServer struct{} + +func (UnimplementedPodsServer) WatchPods(*WatchPodsRequest, grpc.ServerStreamingServer[WatchPodsEvent]) error { + return status.Errorf(codes.Unimplemented, "method WatchPods not implemented") +} +func (UnimplementedPodsServer) ListPods(context.Context, *ListPodsRequest) (*ListPodsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPods not implemented") +} +func (UnimplementedPodsServer) GetPod(context.Context, *GetPodRequest) (*GetPodResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPod not implemented") +} +func (UnimplementedPodsServer) mustEmbedUnimplementedPodsServer() {} +func (UnimplementedPodsServer) testEmbeddedByValue() {} + +// UnsafePodsServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PodsServer will +// result in compilation errors. +type UnsafePodsServer interface { + mustEmbedUnimplementedPodsServer() +} + +func RegisterPodsServer(s grpc.ServiceRegistrar, srv PodsServer) { + // If the following call pancis, it indicates UnimplementedPodsServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Pods_ServiceDesc, srv) +} + +func _Pods_WatchPods_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(WatchPodsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(PodsServer).WatchPods(m, &grpc.GenericServerStream[WatchPodsRequest, WatchPodsEvent]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Pods_WatchPodsServer = grpc.ServerStreamingServer[WatchPodsEvent] + +func _Pods_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPodsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PodsServer).ListPods(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Pods_ListPods_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PodsServer).ListPods(ctx, req.(*ListPodsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Pods_GetPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetPodRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PodsServer).GetPod(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Pods_GetPod_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PodsServer).GetPod(ctx, req.(*GetPodRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Pods_ServiceDesc is the grpc.ServiceDesc for Pods service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Pods_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "v1alpha1.Pods", + HandlerType: (*PodsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListPods", + Handler: _Pods_ListPods_Handler, + }, + { + MethodName: "GetPod", + Handler: _Pods_GetPod_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "WatchPods", + Handler: _Pods_WatchPods_Handler, + ServerStreams: true, + }, + }, + Metadata: "staging/src/k8s.io/kubelet/pkg/apis/pods/v1alpha1/api.proto", +} diff --git a/vendor/k8s.io/kubelet/pkg/cri/streaming/.import-restrictions b/vendor/k8s.io/kubelet/pkg/cri/streaming/.import-restrictions deleted file mode 100644 index 10215ff925..0000000000 --- a/vendor/k8s.io/kubelet/pkg/cri/streaming/.import-restrictions +++ /dev/null @@ -1,5 +0,0 @@ -rules: - # prevent exposing internal api in streaming packages - - selectorRegexp: k8s[.]io/kubernetes - allowedPrefixes: - - k8s.io/kubernetes/pkg/kubelet/cri diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/auth.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/auth.go index 1000f319ae..aefcd45e38 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/auth.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/auth.go @@ -51,7 +51,7 @@ func BuildAuth(nodeName types.NodeName, client clientset.Interface, config kubel sarClient = client.AuthorizationV1() } - authenticator, runAuthenticatorCAReload, err := BuildAuthn(tokenClient, config.Authentication) + authenticator, runAuthenticatorCAReload, clientCAProvider, err := BuildAuthn(tokenClient, config.Authentication) if err != nil { return nil, nil, err } @@ -64,18 +64,23 @@ func BuildAuth(nodeName types.NodeName, client clientset.Interface, config kubel } authorizer = wrapAuthorizerWithMetricsScraper(authorizer) - return server.NewKubeletAuth(authenticator, attributes, authorizer), runAuthenticatorCAReload, nil + return server.NewKubeletAuth(authenticator, attributes, authorizer, clientCAProvider), runAuthenticatorCAReload, nil } // BuildAuthn creates an authenticator compatible with the kubelet's needs -func BuildAuthn(client authenticationclient.AuthenticationV1Interface, authn kubeletconfig.KubeletAuthentication) (authenticator.Request, func(<-chan struct{}), error) { +func BuildAuthn(client authenticationclient.AuthenticationV1Interface, authn kubeletconfig.KubeletAuthentication) (authenticator.Request, func(<-chan struct{}), dynamiccertificates.CAContentProvider, error) { + var caContentProvider dynamiccertificates.CAContentProvider var dynamicCAContentFromFile *dynamiccertificates.DynamicFileCAContent var err error if len(authn.X509.ClientCAFile) > 0 { dynamicCAContentFromFile, err = dynamiccertificates.NewDynamicCAContentFromFile("client-ca-bundle", authn.X509.ClientCAFile) if err != nil { - return nil, nil, err + return nil, nil, nil, err } + caContentProvider = dynamicCAContentFromFile + } else { + // no client CA configured, make a non-nil no-op CA provider + caContentProvider = dynamiccertificates.NewUnionCAContentProvider() } authenticatorConfig := authenticatorfactory.DelegatingAuthenticatorConfig{ @@ -86,7 +91,7 @@ func BuildAuthn(client authenticationclient.AuthenticationV1Interface, authn kub if authn.Webhook.Enabled { if client == nil { - return nil, nil, errors.New("no client provided, cannot use webhook authentication") + return nil, nil, nil, errors.New("no client provided, cannot use webhook authentication") } authenticatorConfig.WebhookRetryBackoff = genericoptions.DefaultAuthWebhookRetryBackoff() authenticatorConfig.TokenAccessReviewClient = client @@ -94,7 +99,7 @@ func BuildAuthn(client authenticationclient.AuthenticationV1Interface, authn kub authenticator, _, err := authenticatorConfig.New() if err != nil { - return nil, nil, err + return nil, nil, nil, err } return authenticator, func(stopCh <-chan struct{}) { @@ -111,7 +116,7 @@ func BuildAuthn(client authenticationclient.AuthenticationV1Interface, authn kub if dynamicCAContentFromFile != nil { go dynamicCAContentFromFile.Run(ctx, 1) } - }, err + }, caContentProvider, err } // BuildAuthz creates an authorizer compatible with the kubelet's needs diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_others.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_others.go index 1d81b9e4af..7993a7fb72 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_others.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_windows.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_windows.go index 651bb484f4..5488969237 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_windows.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/init_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_linux.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_linux.go index c2ba0d1bce..295cc10d0a 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_linux.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_other.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_other.go index f630d1024b..77aa2c8244 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_other.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/globalflags_other.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go index 7b6d6f7d2c..582186e348 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go @@ -86,8 +86,10 @@ type KubeletFlags struct { // Omit this flag to use the combination of built-in default configuration values and flags. KubeletConfigFile string - // kubeletDropinConfigDirectory is a path to a directory to specify dropins allows the user to optionally specify - // additional configs to overwrite what is provided by default and in the KubeletConfigFile flag + // KubeletDropinConfigDirectory is the path to a directory containing drop-in configuration files that override settings from defaults and the --config file. + // The path may be absolute or relative; relative paths are under the Kubelet's current working directory. + // Drop-in files must have a '.conf' suffix and are processed in lexical order. Only '.conf' files are loaded; all other files are ignored. + // All .conf files in the directory and its subdirectories are processed in lexical order. KubeletDropinConfigDirectory string // WindowsService should be set to true if kubelet is running as a service on Windows. @@ -280,7 +282,7 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { f.addOSFlags(fs) fs.StringVar(&f.KubeletConfigFile, "config", f.KubeletConfigFile, "The Kubelet will load its initial configuration from this file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this flag to use the built-in default configuration values. Command-line flags override configuration from this file.") - fs.StringVar(&f.KubeletDropinConfigDirectory, "config-dir", "", "Path to a directory to specify drop-ins, allows the user to optionally specify additional configs to overwrite what is provided by default and in the KubeletConfigFile flag. [default='']") + fs.StringVar(&f.KubeletDropinConfigDirectory, "config-dir", "", "Path to a directory containing drop-in configuration files that override settings from defaults and the --config file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Drop-in files must have a '.conf' suffix (e.g., '99-kubelet-address.conf') and are processed in lexical order. Only '.conf' files are loaded; all other files are ignored. All .conf files in the directory and its subdirectories are processed in lexical order. [default='']") fs.StringVar(&f.KubeConfig, "kubeconfig", f.KubeConfig, "Path to a kubeconfig file, specifying how to connect to the API server. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode.") fs.StringVar(&f.BootstrapKubeconfig, "bootstrap-kubeconfig", f.BootstrapKubeconfig, "Path to a kubeconfig file that will be used to get client certificate for kubelet. "+ @@ -469,7 +471,8 @@ func AddKubeletConfigFlags(mainfs *pflag.FlagSet, c *kubeletconfigapi.KubeletCon fs.BoolVar(&c.RunOnce, "runonce", c.RunOnce, "If true, exit after spawning pods from static pod files or remote urls. Exclusive with --enable-server") fs.BoolVar(&c.CPUCFSQuota, "cpu-cfs-quota", c.CPUCFSQuota, "Enable CPU CFS quota enforcement for containers that specify CPU limits") - fs.DurationVar(&c.CPUCFSQuotaPeriod.Duration, "cpu-cfs-quota-period", c.CPUCFSQuotaPeriod.Duration, "Sets CPU CFS quota period value, cpu.cfs_period_us, defaults to Linux Kernel default") + fs.DurationVar(&c.CPUCFSQuotaPeriod.Duration, "cpu-cfs-quota-period", c.CPUCFSQuotaPeriod.Duration, "Sets CPU CFS quota period value (cpu.cfs_period_us). Defaults to Linux Kernel default. "+"Requires the CustomCPUCFSQuotaPeriod feature gate to set non-default values.") + fs.BoolVar(&c.EnableControllerAttachDetach, "enable-controller-attach-detach", c.EnableControllerAttachDetach, "Enables the Attach/Detach controller to manage attachment/detachment of volumes scheduled to this node, and disables kubelet from executing any attach/detach operations") fs.BoolVar(&c.MakeIPTablesUtilChains, "make-iptables-util-chains", c.MakeIPTablesUtilChains, "If true, kubelet will ensure iptables utility rules are present on host.") fs.StringVar(&c.ContainerLogMaxSize, "container-log-max-size", c.ContainerLogMaxSize, " Set the maximum size (e.g. 10Mi) of container log file before it is rotated.") diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_others.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_others.go index 083231a8d6..3f03bb788e 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_others.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_windows.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_windows.go index 1805b33d82..e6cd2b430e 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_windows.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/osflags_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go index ba40088dfe..95ce1ff5a9 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go @@ -52,11 +52,6 @@ func ProbeVolumePlugins(ctx context.Context, featureGate featuregate.FeatureGate // // Kubelet does not currently need to configure volume plugins. // If/when it does, see kube-controller-manager/app/plugins.go for example of using volume.VolumeConfig - var err error - allPlugins, err = appendLegacyProviderVolumes(ctx, allPlugins, featureGate) - if err != nil { - return allPlugins, err - } allPlugins = append(allPlugins, emptydir.ProbeVolumePlugins()...) allPlugins = append(allPlugins, git_repo.ProbeVolumePlugins()...) allPlugins = append(allPlugins, hostpath.ProbeVolumePlugins(volume.VolumeConfig{})...) @@ -78,6 +73,6 @@ func ProbeVolumePlugins(ctx context.Context, featureGate featuregate.FeatureGate // GetDynamicPluginProber gets the probers of dynamically discoverable plugins // for kubelet. // Currently only Flexvolume plugins are dynamically discoverable. -func GetDynamicPluginProber(pluginDir string, runner exec.Interface) volume.DynamicPluginProber { - return flexvolume.GetDynamicPluginProber(pluginDir, runner) +func GetDynamicPluginProber(ctx context.Context, pluginDir string, runner exec.Interface) volume.DynamicPluginProber { + return flexvolume.GetDynamicPluginProber(ctx, pluginDir, runner) } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins_providers.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins_providers.go deleted file mode 100644 index 8fdde49a84..0000000000 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins_providers.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2019 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 app - -import ( - "context" - - "k8s.io/component-base/featuregate" - "k8s.io/csi-translation-lib/plugins" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/volume/csimigration" - "k8s.io/kubernetes/pkg/volume/portworx" -) - -type probeFn func() []volume.VolumePlugin - -func appendPluginBasedOnFeatureFlags(ctx context.Context, plugins []volume.VolumePlugin, inTreePluginName string, - featureGate featuregate.FeatureGate, pluginInfo pluginInfo) ([]volume.VolumePlugin, error) { - logger := klog.FromContext(ctx) - _, err := csimigration.CheckMigrationFeatureFlags(featureGate, pluginInfo.pluginMigrationFeature, pluginInfo.pluginUnregisterFeature) - if err != nil { - logger.Info("Unexpected CSI Migration Feature Flags combination detected, CSI Migration may not take effect", "err", err) - // TODO: fail and return here once alpha only tests can set the feature flags for a plugin correctly - } - - // Skip appending the in-tree plugin to the list of plugins to be probed/initialized - // if the plugin unregister feature flag is set - if featureGate.Enabled(pluginInfo.pluginUnregisterFeature) { - logger.Info("Skipped registration of plugin since feature flag is enabled", "pluginName", inTreePluginName, "featureFlag", pluginInfo.pluginUnregisterFeature) - return plugins, nil - } - - plugins = append(plugins, pluginInfo.pluginProbeFunction()...) - return plugins, nil -} - -type pluginInfo struct { - pluginMigrationFeature featuregate.Feature - pluginUnregisterFeature featuregate.Feature - pluginProbeFunction probeFn -} - -func appendLegacyProviderVolumes(ctx context.Context, allPlugins []volume.VolumePlugin, featureGate featuregate.FeatureGate) ([]volume.VolumePlugin, error) { - pluginMigrationStatus := make(map[string]pluginInfo) - pluginMigrationStatus[plugins.PortworxVolumePluginName] = pluginInfo{pluginMigrationFeature: features.CSIMigrationPortworx, pluginUnregisterFeature: features.InTreePluginPortworxUnregister, pluginProbeFunction: portworx.ProbeVolumePlugins} - var err error - for pluginName, pluginInfo := range pluginMigrationStatus { - allPlugins, err = appendPluginBasedOnFeatureFlags(ctx, allPlugins, pluginName, featureGate, pluginInfo) - if err != nil { - return allPlugins, err - } - } - return allPlugins, nil -} diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go index 65174afad7..17f8fd3da5 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go @@ -63,6 +63,7 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" + utilversion "k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/wait" genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server/flagz" @@ -83,6 +84,7 @@ import ( "k8s.io/component-base/logs" logsapi "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/metrics" + metricsfeatures "k8s.io/component-base/metrics/features" "k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/tracing" "k8s.io/component-base/version" @@ -119,6 +121,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/watchdog" utilfs "k8s.io/kubernetes/pkg/util/filesystem" "k8s.io/kubernetes/pkg/util/flock" + utilkernel "k8s.io/kubernetes/pkg/util/kernel" "k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/rlimit" "k8s.io/kubernetes/pkg/volume/util/hostutil" @@ -218,8 +221,10 @@ is checked every 20 seconds (also configurable with a flag).`, } } // Merge the kubelet configurations if --config-dir is set + var skippedDropinFiles []string if len(kubeletFlags.KubeletDropinConfigDirectory) > 0 { - if err := mergeKubeletConfigurations(kubeletConfig, kubeletFlags.KubeletDropinConfigDirectory); err != nil { + skippedDropinFiles, err = mergeKubeletConfigurations(kubeletConfig, kubeletFlags.KubeletDropinConfigDirectory) + if err != nil { return fmt.Errorf("failed to merge kubelet configs: %w", err) } } @@ -284,6 +289,14 @@ is checked every 20 seconds (also configurable with a flag).`, for k := range config.StaticPodURLHeader { config.StaticPodURLHeader[k] = []string{""} } + + // Log skipped drop-in files if any were encountered during configuration merge + if len(skippedDropinFiles) > 0 { + for _, skippedFile := range skippedDropinFiles { + logger.V(4).Info("Skipped file in drop-in directory (does not have .conf extension)", "file", skippedFile) + } + } + // log the kubelet's config for inspection logger.V(5).Info("KubeletConfiguration", "configuration", klog.Format(config)) @@ -320,63 +333,70 @@ is checked every 20 seconds (also configurable with a flag).`, // configurations in files with lower numeric prefixes are applied first, followed by higher numeric prefixes. // For example, if the drop-in directory contains files named "10-config.conf" and "20-config.conf", // the configurations in "10-config.conf" will be applied first, and then the configurations in "20-config.conf" will be applied, -// potentially overriding the previous values. -func mergeKubeletConfigurations(kubeletConfig *kubeletconfiginternal.KubeletConfiguration, kubeletDropInConfigDir string) error { +// potentially overriding the previous values. Files in subdirectories are also processed in lexical order. +// Returns a list of skipped files and an error. +func mergeKubeletConfigurations(kubeletConfig *kubeletconfiginternal.KubeletConfiguration, kubeletDropInConfigDir string) ([]string, error) { const dropinFileExtension = ".conf" + var skippedFiles []string // TODO: move the "internal --> versioned --> merge --> default --> internal" operation inside the loop, // and use the version of each drop-in file as the versioned target once config files can be in versions other than just v1beta1 versionedConfig := &kubeletconfigv1beta1.KubeletConfiguration{} if err := kubeletconfigv1beta1conversion.Convert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(kubeletConfig, versionedConfig, nil); err != nil { - return err + return nil, err } baseKubeletConfigJSON, err := json.Marshal(versionedConfig) if err != nil { - return fmt.Errorf("failed to marshal base config: %w", err) + return nil, fmt.Errorf("failed to marshal base config: %w", err) } // Walk through the drop-in directory and update the configuration for each file if err := filepath.WalkDir(kubeletDropInConfigDir, func(path string, info fs.DirEntry, err error) error { if err != nil { return err } - if !info.IsDir() && filepath.Ext(info.Name()) == dropinFileExtension { - dropinConfigJSON, gvk, err := loadDropinConfigFileIntoJSON(path) - if err != nil { - return fmt.Errorf("failed to load kubelet dropin file, path: %s, error: %w", path, err) - } - if gvk == nil || gvk.Empty() { - return fmt.Errorf("failed to load kubelet dropin file, path: %s, no apiVersion/kind", path) - } - // TODO: expand this once more than a single kubelet config version exists - if *gvk != kubeletconfigv1beta1.SchemeGroupVersion.WithKind("KubeletConfiguration") { - return fmt.Errorf("failed to load kubelet dropin file, path: %s, unknown apiVersion/kind: %v", path, gvk.String()) - } - mergedConfigJSON, err := jsonpatch.MergePatch(baseKubeletConfigJSON, dropinConfigJSON) - if err != nil { - return fmt.Errorf("failed to merge drop-in and current config: %w", err) - } - baseKubeletConfigJSON = mergedConfigJSON + if info.IsDir() { + return nil + } + if filepath.Ext(info.Name()) != dropinFileExtension { + skippedFiles = append(skippedFiles, path) + return nil + } + dropinConfigJSON, gvk, err := loadDropinConfigFileIntoJSON(path) + if err != nil { + return fmt.Errorf("failed to load kubelet dropin file, path: %s, error: %w", path, err) } + if gvk == nil || gvk.Empty() { + return fmt.Errorf("failed to load kubelet dropin file, path: %s, no apiVersion/kind", path) + } + // TODO: expand this once more than a single kubelet config version exists + if *gvk != kubeletconfigv1beta1.SchemeGroupVersion.WithKind("KubeletConfiguration") { + return fmt.Errorf("failed to load kubelet dropin file, path: %s, unknown apiVersion/kind: %v", path, gvk.String()) + } + mergedConfigJSON, err := jsonpatch.MergePatch(baseKubeletConfigJSON, dropinConfigJSON) + if err != nil { + return fmt.Errorf("failed to merge drop-in and current config: %w", err) + } + baseKubeletConfigJSON = mergedConfigJSON return nil }); err != nil { - return fmt.Errorf("failed to walk through kubelet dropin directory %q: %w", kubeletDropInConfigDir, err) + return nil, fmt.Errorf("failed to walk through kubelet dropin directory %q: %w", kubeletDropInConfigDir, err) } // reset versioned config and decode versionedConfig = &kubeletconfigv1beta1.KubeletConfiguration{} if err := json.Unmarshal(baseKubeletConfigJSON, versionedConfig); err != nil { - return fmt.Errorf("failed to unmarshal merged JSON into kubelet configuration: %w", err) + return nil, fmt.Errorf("failed to unmarshal merged JSON into kubelet configuration: %w", err) } // apply defaulting after decoding kubeletconfigv1beta1conversion.SetDefaults_KubeletConfiguration(versionedConfig) // convert back to internal config if err := kubeletconfigv1beta1conversion.Convert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(versionedConfig, kubeletConfig, nil); err != nil { - return fmt.Errorf("failed to convert merged config to internal kubelet configuration: %w", err) + return nil, fmt.Errorf("failed to convert merged config to internal kubelet configuration: %w", err) } - return nil + return skippedFiles, nil } // newFlagSetWithGlobals constructs a new pflag.FlagSet with global flags registered @@ -511,7 +531,7 @@ func UnsecuredDependencies(ctx context.Context, s *options.KubeletServer, featur OOMAdjuster: oom.NewOOMAdjuster(), OSInterface: kubecontainer.RealOS{}, VolumePlugins: plugins, - DynamicPluginProber: GetDynamicPluginProber(s.VolumePluginDir, pluginRunner), + DynamicPluginProber: GetDynamicPluginProber(ctx, s.VolumePluginDir, pluginRunner), TLSOptions: tlsOptions}, nil } @@ -540,12 +560,12 @@ func setConfigz(cz *configz.Config, kc *kubeletconfiginternal.KubeletConfigurati if err != nil { return err } - versioned := kubeletconfigv1beta1.KubeletConfiguration{} - if err := scheme.Convert(kc, &versioned, nil); err != nil { + versioned := &kubeletconfigv1beta1.KubeletConfiguration{} + if err := scheme.Convert(kc, versioned, nil); err != nil { return err } - cz.Set(versioned) - return nil + versioned.GetObjectKind().SetGroupVersionKind(kubeletconfigv1beta1.SchemeGroupVersion.WithKind("KubeletConfiguration")) + return cz.Set(versioned) } func initConfigz(ctx context.Context, kc *kubeletconfiginternal.KubeletConfiguration) error { @@ -616,15 +636,28 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend if err != nil { return err } + // Propagate feature gate state to the metrics subsystem. This must be called + // after feature gates are set and before any histogram metrics are registered. + metricsfeatures.ApplyFeatureGates(featureGate) // validate the initial KubeletServer (we set feature gates first, because this validation depends on feature gates) if err := options.ValidateKubeletServer(s); err != nil { return err } - // Warn if MemoryQoS enabled with cgroups v1 - if utilfeature.DefaultFeatureGate.Enabled(features.MemoryQoS) && - !kubeletutil.IsCgroup2UnifiedMode() { - logger.Info("Warning: MemoryQoS feature only works with cgroups v2 on Linux, but enabled with cgroups v1") + // Warn about MemoryQoS compatibility issues + if utilfeature.DefaultFeatureGate.Enabled(features.MemoryQoS) { + if !kubeletutil.IsCgroup2UnifiedMode() { + logger.Info("Warning: MemoryQoS feature only works with cgroups v2 on Linux, but enabled with cgroups v1") + } else { + kernelVersion, err := utilkernel.GetVersion() + if err != nil { + logger.Error(err, "Failed to detect kernel version for MemoryQoS compatibility check") + } else if kernelVersion.LessThan(utilversion.MustParseGeneric(utilkernel.MemoryQoSMinKernelVersion)) { + logger.Info("Warning: MemoryQoS memory.high throttling may cause process livelock on older kernels", + "currentKernel", kernelVersion, + "minimumKernel", utilkernel.MemoryQoSMinKernelVersion) + } + } } // Obtain Kubelet Lock File if s.ExitOnLockContention && s.LockFilePath == "" { @@ -724,7 +757,7 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend runAuthenticatorCAReload(ctx.Done()) } - if err := kubelet.PreInitRuntimeService(&s.KubeletConfiguration, kubeDeps); err != nil { + if err := kubelet.PreInitRuntimeService(ctx, &s.KubeletConfiguration, kubeDeps); err != nil { return err } @@ -767,7 +800,7 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend if kubeDeps.CAdvisorInterface == nil { imageFsInfoProvider := cadvisor.NewImageFsInfoProvider(s.ContainerRuntimeEndpoint) - kubeDeps.CAdvisorInterface, err = cadvisor.New(imageFsInfoProvider, s.RootDirectory, cgroupRoots, cadvisor.UsingLegacyCadvisorStats(s.ContainerRuntimeEndpoint), s.LocalStorageCapacityIsolation) + kubeDeps.CAdvisorInterface, err = cadvisor.New(klog.FromContext(ctx), imageFsInfoProvider, s.RootDirectory, cgroupRoots, cadvisor.UsingLegacyCadvisorStats(s.ContainerRuntimeEndpoint), s.LocalStorageCapacityIsolation) if err != nil { return err } @@ -873,6 +906,7 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend CPUManagerReconcilePeriod: s.CPUManagerReconcilePeriod.Duration, MemoryManagerPolicy: s.MemoryManagerPolicy, MemoryManagerReservedMemory: s.ReservedMemory, + MemoryReservationPolicy: s.MemoryReservationPolicy, PodPidsLimit: s.PodPidsLimit, EnforceCPULimits: s.CPUCFSQuota, CPUCFSQuotaPeriod: s.CPUCFSQuotaPeriod.Duration, @@ -911,12 +945,12 @@ func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Depend if s.HealthzPort > 0 { mux := http.NewServeMux() healthz.InstallHandler(mux) - go wait.Until(func() { + go wait.UntilWithContext(ctx, func(ctx context.Context) { err := http.ListenAndServe(net.JoinHostPort(s.HealthzBindAddress, strconv.Itoa(int(s.HealthzPort))), mux) if err != nil { logger.Error(err, "Failed to start healthz server") } - }, 5*time.Second, wait.NeverStop) + }, 5*time.Second) } // If systemd is used, notify it that we have started @@ -1144,7 +1178,7 @@ func InitializeTLS(ctx context.Context, kf *options.KubeletFlags, kc *kubeletcon if len(tlsCipherSuites) > 0 { insecureCiphers := cliflag.InsecureTLSCiphers() - for i := 0; i < len(tlsCipherSuites); i++ { + for i := range tlsCipherSuites { for cipherName, cipherID := range insecureCiphers { if tlsCipherSuites[i] == cipherID { logger.Info("Use of insecure cipher detected.", "cipher", cipherName) @@ -1164,24 +1198,18 @@ func InitializeTLS(ctx context.Context, kf *options.KubeletFlags, kc *kubeletcon } } - tlsOptions := &server.TLSOptions{ - Config: &tls.Config{ - MinVersion: minTLSVersion, - CipherSuites: tlsCipherSuites, - }, - CertFile: kc.TLSCertFile, - KeyFile: kc.TLSPrivateKeyFile, + curvePreferences, err := cliflag.TLSCurvePreferences(kc.TLSCurvePreferences) + if err != nil { + return nil, err } - if len(kc.Authentication.X509.ClientCAFile) > 0 { - clientCAs, err := certutil.NewPool(kc.Authentication.X509.ClientCAFile) - if err != nil { - return nil, fmt.Errorf("unable to load client CA file %s: %w", kc.Authentication.X509.ClientCAFile, err) - } - // Specify allowed CAs for client certificates - tlsOptions.Config.ClientCAs = clientCAs - // Populate PeerCertificates in requests, but don't reject connections without verified certificates - tlsOptions.Config.ClientAuth = tls.RequestClientCert + tlsOptions := &server.TLSOptions{ + MinVersion: minTLSVersion, + CipherSuites: tlsCipherSuites, + CurvePreferences: curvePreferences, + CertFile: kc.TLSCertFile, + KeyFile: kc.TLSPrivateKeyFile, + ClientCAFile: kc.Authentication.X509.ClientCAFile, } return tlsOptions, nil @@ -1267,16 +1295,18 @@ func RunKubelet(ctx context.Context, kubeServer *options.KubeletServer, kubeDeps func startKubelet(ctx context.Context, k kubelet.Bootstrap, podCfg *config.PodConfig, kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *kubelet.Dependencies, enableServer bool) { // start the kubelet - go k.Run(podCfg.Updates()) + go k.Run(ctx, podCfg.Updates()) // start the kubelet server if enableServer { - go k.ListenAndServe(ctx, kubeCfg, kubeDeps.TLSOptions, kubeDeps.Auth, kubeDeps.TracerProvider) + go k.ListenAndServe(ctx, kubeCfg, kubeDeps.TLSConfig, kubeDeps.Auth, kubeDeps.TracerProvider) } if kubeCfg.ReadOnlyPort > 0 { go k.ListenAndServeReadOnly(ctx, netutils.ParseIPSloppy(kubeCfg.Address), uint(kubeCfg.ReadOnlyPort), kubeDeps.TracerProvider) } + go k.ListenAndServePodResources(ctx) + go k.ListenAndServePods(ctx) } func createAndInitKubelet( @@ -1322,7 +1352,7 @@ func createAndInitKubelet( k.BirthCry() - k.StartGarbageCollection() + k.StartGarbageCollection(ctx) return k, nil } @@ -1384,7 +1414,7 @@ func getCgroupDriverFromCRI(ctx context.Context, s *options.KubeletServer, kubeD ) // Retry a couple of times, hoping that any errors are transient. // Fail quickly on known, non transient errors. - for i := 0; i < 3; i++ { + for range 3 { runtimeConfig, err = kubeDeps.RemoteRuntimeService.RuntimeConfig(ctx) if err != nil { s, ok := status.FromError(err) @@ -1397,7 +1427,7 @@ func getCgroupDriverFromCRI(ctx context.Context, s *options.KubeletServer, kubeD } // CRI implementation doesn't support RuntimeConfig, fallback legacyregistry.MustRegister(kubeletmetrics.CRILosingSupport) - kubeletmetrics.CRILosingSupport.WithLabelValues("1.36.0").Inc() + kubeletmetrics.CRILosingSupport.WithLabelValues("1.37.0").Inc() logger.Info("CRI implementation should be updated to support RuntimeConfig. Falling back to using cgroupDriver from kubelet config.") return nil } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_others.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_others.go index 1f96ad7e52..4faf436d3e 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_others.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go index c4e74c8cb9..b3f6722859 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2015 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_windows.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_windows.go index 781cd95cca..79261a9aa3 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_windows.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/api/pod/util.go b/vendor/k8s.io/kubernetes/pkg/api/pod/util.go index 1d0ae2209b..dbda812aad 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/pod/util.go +++ b/vendor/k8s.io/kubernetes/pkg/api/pod/util.go @@ -430,7 +430,9 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po AllowContainerRestartPolicyRules: utilfeature.DefaultFeatureGate.Enabled(features.ContainerRestartRules), AllowUserNamespacesWithVolumeDevices: false, // This also allows restart rules on sidecar containers. - AllowRestartAllContainers: utilfeature.DefaultFeatureGate.Enabled(features.RestartAllContainersOnContainerExits), + AllowRestartAllContainers: utilfeature.DefaultFeatureGate.Enabled(features.RestartAllContainersOnContainerExits), + AllowImageVolumeWithDigest: utilfeature.DefaultFeatureGate.Enabled(features.ImageVolumeWithDigest), + AllowExistingRestartContainerForNonSidecarInitContainer: hasRestartContainerForNonSidecarInitContainer(oldPodSpec), } // If old spec uses relaxed validation or enabled the RelaxedEnvironmentVariableValidation feature gate, @@ -754,7 +756,7 @@ func dropDisabledFields( dropDisabledDynamicResourceAllocationFields(podSpec, oldPodSpec) dropDisabledClusterTrustBundleProjection(podSpec, oldPodSpec) dropDisabledPodCertificateProjection(podSpec, oldPodSpec) - dropDisabledWorkloadRef(podSpec, oldPodSpec) + dropDisabledSchedulingGroup(podSpec, oldPodSpec) if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) && !inPlacePodVerticalScalingInUse(oldPodSpec) { // Drop ResizePolicy fields. Don't drop updates to Resources field as template.spec.resources @@ -1055,7 +1057,7 @@ func dropDisabledPodStatusFields(podStatus, oldPodStatus *api.PodStatus, podSpec } } - if !utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) { + if !utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) && !resourceHealthStatusInUse(oldPodStatus) { setAllocatedResourcesStatusToNil := func(csl []api.ContainerStatus) { for i := range csl { csl[i].AllocatedResourcesStatus = nil @@ -1066,6 +1068,21 @@ func dropDisabledPodStatusFields(podStatus, oldPodStatus *api.PodStatus, podSpec setAllocatedResourcesStatusToNil(podStatus.EphemeralContainerStatuses) } + if !utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatusMessage) && !resourceHealthStatusMessageInUse(oldPodStatus) { + dropMessageField := func(csl []api.ContainerStatus) { + for i := range csl { + for j := range csl[i].AllocatedResourcesStatus { + for k := range csl[i].AllocatedResourcesStatus[j].Resources { + csl[i].AllocatedResourcesStatus[j].Resources[k].Message = nil + } + } + } + } + dropMessageField(podStatus.ContainerStatuses) + dropMessageField(podStatus.InitContainerStatuses) + dropMessageField(podStatus.EphemeralContainerStatuses) + } + // drop ContainerStatus.User field to empty (disable SupplementalGroupsPolicy) if !utilfeature.DefaultFeatureGate.Enabled(features.SupplementalGroupsPolicy) && !supplementalGroupsPolicyInUse(oldPodSpec) { dropUserField := func(csl []api.ContainerStatus) { @@ -1084,6 +1101,13 @@ func dropDisabledPodStatusFields(podStatus, oldPodStatus *api.PodStatus, podSpec podStatus.Conditions[i].ObservedGeneration = 0 } } + + if !utilfeature.DefaultFeatureGate.Enabled(features.ImageVolumeWithDigest) && !imageVolumeWithDigestInUse(oldPodStatus) { + dropImageVolumeWithDigest(podStatus) + } + + dropPodNodeAllocatableResourceStatus(podStatus, oldPodStatus) + } // dropDisabledDynamicResourceAllocationFields removes pod claim references from @@ -1105,6 +1129,78 @@ func draExendedResourceInUse(podStatus *api.PodStatus) bool { return false } +func dropPodNodeAllocatableResourceStatus(podStatus, oldPodStatus *api.PodStatus) { + if utilfeature.DefaultFeatureGate.Enabled(features.DRANodeAllocatableResources) || draNodeAllocatableResourceStatusInUse(oldPodStatus) { + return + } + podStatus.NodeAllocatableResourceClaimStatuses = nil +} + +func draNodeAllocatableResourceStatusInUse(podStatus *api.PodStatus) bool { + if podStatus == nil { + return false + } + return len(podStatus.NodeAllocatableResourceClaimStatuses) > 0 +} + +func resourceHealthStatusInUse(podStatus *api.PodStatus) bool { + if podStatus == nil { + return false + } + + checkContainerStatuses := func(csl []api.ContainerStatus) bool { + for _, cs := range csl { + if len(cs.AllocatedResourcesStatus) > 0 { + return true + } + } + return false + } + + if checkContainerStatuses(podStatus.ContainerStatuses) { + return true + } + if checkContainerStatuses(podStatus.InitContainerStatuses) { + return true + } + if checkContainerStatuses(podStatus.EphemeralContainerStatuses) { + return true + } + + return false +} + +func resourceHealthStatusMessageInUse(podStatus *api.PodStatus) bool { + if podStatus == nil { + return false + } + + checkContainerStatuses := func(csl []api.ContainerStatus) bool { + for _, cs := range csl { + for _, rs := range cs.AllocatedResourcesStatus { + for _, rh := range rs.Resources { + if rh.Message != nil { + return true + } + } + } + } + return false + } + + if checkContainerStatuses(podStatus.ContainerStatuses) { + return true + } + if checkContainerStatuses(podStatus.InitContainerStatuses) { + return true + } + if checkContainerStatuses(podStatus.EphemeralContainerStatuses) { + return true + } + + return false +} + func dynamicResourceAllocationInUse(podSpec *api.PodSpec) bool { // We only need to check this field because the containers cannot have // resource requirements entries for claims without a corresponding @@ -1831,20 +1927,20 @@ func containerRestartRulesInUse(oldPodSpec *api.PodSpec) bool { return false } -// dropDisabledWorkloadRef removes pod workload reference from its spec +// dropDisabledSchedulingGroup removes pod scheduling group from its spec // unless it is already used by the old pod spec. -func dropDisabledWorkloadRef(podSpec, oldPodSpec *api.PodSpec) { - if !utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) && !workloadRefInUse(oldPodSpec) { - podSpec.WorkloadRef = nil +func dropDisabledSchedulingGroup(podSpec, oldPodSpec *api.PodSpec) { + if !utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) && !schedulingGroupInUse(oldPodSpec) { + podSpec.SchedulingGroup = nil } } -func workloadRefInUse(podSpec *api.PodSpec) bool { +func schedulingGroupInUse(podSpec *api.PodSpec) bool { if podSpec == nil { return false } - return podSpec.WorkloadRef != nil + return podSpec.SchedulingGroup != nil } func restartAllContainersActionInUse(oldPodSpec *api.PodSpec) bool { @@ -1871,3 +1967,77 @@ func restartAllContainersActionInUse(oldPodSpec *api.PodSpec) bool { } return false } + +func imageVolumeWithDigestInUse(oldPodStatus *api.PodStatus) bool { + if oldPodStatus == nil { + return false + } + + for _, containerStatus := range oldPodStatus.ContainerStatuses { + for _, volumeMount := range containerStatus.VolumeMounts { + if volumeMount.VolumeStatus != nil { + return true + } + } + } + + for _, containerStatus := range oldPodStatus.InitContainerStatuses { + for _, volumeMount := range containerStatus.VolumeMounts { + if volumeMount.VolumeStatus != nil { + return true + } + } + } + + for _, containerStatus := range oldPodStatus.EphemeralContainerStatuses { + for _, volumeMount := range containerStatus.VolumeMounts { + if volumeMount.VolumeStatus != nil { + return true + } + } + } + + return false +} + +func dropImageVolumeWithDigest(podStatus *api.PodStatus) { + if podStatus == nil { + return + } + + for i := range podStatus.ContainerStatuses { + for j := range podStatus.ContainerStatuses[i].VolumeMounts { + podStatus.ContainerStatuses[i].VolumeMounts[j].VolumeStatus = nil + } + } + + for i := range podStatus.InitContainerStatuses { + for j := range podStatus.InitContainerStatuses[i].VolumeMounts { + podStatus.InitContainerStatuses[i].VolumeMounts[j].VolumeStatus = nil + } + } + + for i := range podStatus.EphemeralContainerStatuses { + for j := range podStatus.EphemeralContainerStatuses[i].VolumeMounts { + podStatus.EphemeralContainerStatuses[i].VolumeMounts[j].VolumeStatus = nil + } + } +} + +// hasRestartContainerForNonSidecarInitContainer returns true if any non-sidecar init container +// has a RestartContainer resize policy. +func hasRestartContainerForNonSidecarInitContainer(spec *api.PodSpec) bool { + if spec == nil { + return false + } + for _, c := range spec.InitContainers { + if !IsRestartableInitContainer(&c) { + for _, p := range c.ResizePolicy { + if p.RestartPolicy == api.RestartContainer { + return true + } + } + } + } + return false +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go b/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go index a9f0cdad25..58903e2dba 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go +++ b/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go @@ -57,6 +57,11 @@ func GetWarningsForService(service, oldService *api.Service) []string { warnings = append(warnings, utilvalidation.GetWarningsForIP(field.NewPath("spec").Child("externalIPs").Index(i), externalIP)...) } + // Warn about using externalIPs + if len(service.Spec.ExternalIPs) > 0 && !isHeadlessService(service) && service.Spec.Type != api.ServiceTypeExternalName { //nolint:staticcheck // SA1019 testing deprecated field + warnings = append(warnings, "spec.externalIPs is deprecated and may no longer be implemented in some clusters") + } + if len(service.Spec.LoadBalancerIP) > 0 { warnings = append(warnings, utilvalidation.GetWarningsForIP(field.NewPath("spec").Child("loadBalancerIP"), service.Spec.LoadBalancerIP)...) } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/annotations.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/annotations.go index d793cd4aa3..0df01c1438 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/annotations.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/annotations.go @@ -17,19 +17,19 @@ limitations under the License. package autoscaling // MetricSpecsAnnotation is the annotation which holds non-CPU-utilization HPA metric -// specs when converting the `Metrics` field from autoscaling/v2beta1 +// specs when converting the `Metrics` field from autoscaling/v2 const MetricSpecsAnnotation = "autoscaling.alpha.kubernetes.io/metrics" // MetricStatusesAnnotation is the annotation which holds non-CPU-utilization HPA metric -// statuses when converting the `CurrentMetrics` field from autoscaling/v2beta1 +// statuses when converting the `CurrentMetrics` field from autoscaling/v2 const MetricStatusesAnnotation = "autoscaling.alpha.kubernetes.io/current-metrics" // HorizontalPodAutoscalerConditionsAnnotation is the annotation which holds the conditions -// of an HPA when converting the `Conditions` field from autoscaling/v2beta1 +// of an HPA when converting the `Conditions` field from autoscaling/v2 const HorizontalPodAutoscalerConditionsAnnotation = "autoscaling.alpha.kubernetes.io/conditions" // DefaultCPUUtilization is the default value for CPU utilization, provided no other -// metrics are present. This is here because it's used by both the v2beta1 defaulting +// metrics are present. This is here because it's used by both the v2 defaulting // logic, and the pseudo-defaulting done in v1 conversion. const DefaultCPUUtilization = 80 diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go index b8802a992b..dfbc0474d9 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go @@ -433,6 +433,8 @@ const ( // ScalingLimited indicates that the calculated scale based on metrics would be above or // below the range for the HPA, and has thus been capped. ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited" + // ScaledToZero indicates that the HPA controller scaled the workload to zero. + ScaledToZero HorizontalPodAutoscalerConditionType = "ScaledToZero" ) // HorizontalPodAutoscalerCondition describes the state of diff --git a/vendor/k8s.io/kubernetes/pkg/apis/certificates/types.go b/vendor/k8s.io/kubernetes/pkg/apis/certificates/types.go index 1f7e345406..78429bbdf0 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/certificates/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/certificates/types.go @@ -340,8 +340,7 @@ type PodCertificateRequestSpec struct { // seconds (1 hour). This constraint is enforced by kube-apiserver. MaxExpirationSeconds *int32 - // pkixPublicKey is the PKIX-serialized public key the signer will issue the - // certificate to. + // The PKIX-serialized public key the signer will issue the certificate to. // // The key must be one of RSA3072, RSA4096, ECDSAP256, ECDSAP384, ECDSAP521, // or ED25519. Note that this list may be expanded in the future. @@ -352,13 +351,20 @@ type PodCertificateRequestSpec struct { // setting a status.conditions entry with a type of "Denied" and a reason of // "UnsupportedKeyType". It may also suggest a key type that it does support // in the message field. + // + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. Signer + // implementations should extract the public key from the StubPKCS10Request + // field. + // + // +optional PKIXPublicKey []byte - // proofOfPossession proves that the requesting kubelet holds the private - // key corresponding to pkixPublicKey. + // A proof that the requesting kubelet holds the private key corresponding + // to pkixPublicKey. // // It is contructed by signing the ASCII bytes of the pod's UID using - // `PKIXPublicKey`. + // `pkixPublicKey`. // // kube-apiserver validates the proof of possession during creation of the // PodCertificateRequest. @@ -374,8 +380,33 @@ type PodCertificateRequestSpec struct { // If the key is an ED25519 key, the the signature is as described by the // [ED25519 Specification](https://ed25519.cr.yp.to/) (as implemented by the // golang library crypto/ed25519.Sign). + // + // Deprecated: This field is replaced by StubPKCS10Request. If + // StubPKCS10Request is set, this field must be empty. + // + // +optional ProofOfPossession []byte + // A PKCS#10 certificate signing request (DER-serialized) generated by + // Kubelet using the subject private key. + // + // Most signer implementations will ignore the contents of the CSR except to + // extract the subject public key. The API server automatically verifies the + // CSR signature during admission, so the signer does not need to repeat the + // verification. CSRs generated by kubelet are completely empty. + // + // The subject public key must be one of RSA3072, RSA4096, ECDSAP256, + // ECDSAP384, ECDSAP521, or ED25519. Note that this list may be expanded in + // the future. + // + // Signer implementations do not need to support all key types supported by + // kube-apiserver and kubelet. If a signer does not support the key type + // used for a given PodCertificateRequest, it must deny the request by + // setting a status.conditions entry with a type of "Denied" and a reason of + // "UnsupportedKeyType". It may also suggest a key type that it does support + // in the message field. + StubPKCS10Request []byte + // unverifiedUserAnnotations allow pod authors to pass additional information to // the signer implementation. Kubernetes does not restrict or validate this // metadata in any way. @@ -485,6 +516,9 @@ const ( // MaxProofOfPossessionSize is the maximum size permitted for the // ProofOfPossession field. MaxProofOfPossessionSize = 10 * 1024 + // MaxStubPKCS10RequestSize is the maximum size permitted for the + // UnverifiedPKCS10Request field. + MaxStubPKCS10RequestSize = 10 * 1024 // MaxCertificateChainSize is the maximum size permitted for the // CertificateChain field. // diff --git a/vendor/k8s.io/kubernetes/pkg/apis/certificates/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/certificates/zz_generated.deepcopy.go index 9a526c246c..73c5601e4a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/certificates/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/certificates/zz_generated.deepcopy.go @@ -359,6 +359,11 @@ func (in *PodCertificateRequestSpec) DeepCopyInto(out *PodCertificateRequestSpec *out = make([]byte, len(*in)) copy(*out, *in) } + if in.StubPKCS10Request != nil { + in, out := &in.StubPKCS10Request, &out.StubPKCS10Request + *out = make([]byte, len(*in)) + copy(*out, *in) + } if in.UnverifiedUserAnnotations != nil { in, out := &in.UnverifiedUserAnnotations, &out.UnverifiedUserAnnotations *out = make(map[string]string, len(*in)) diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go b/vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go index 43d482f52d..00592c1e4b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go @@ -105,6 +105,9 @@ var Semantic = conversion.EqualitiesOrDie( func(a, b metav1.Time) bool { return a.UTC() == b.UTC() }, + func(a, b metav1.FieldsV1) bool { + return a.Equal(b) + }, func(a, b labels.Selector) bool { return a.String() == b.String() }, diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go index 1de0cf4495..ed0bb0ea87 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go @@ -166,8 +166,7 @@ type VolumeSource struct { Projected *ProjectedVolumeSource // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional PortworxVolume *PortworxVolumeSource // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. @@ -219,10 +218,9 @@ type VolumeSource struct { // A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. - // The volume will be mounted read-only (ro) and non-executable files (noexec). + // The volume will be mounted read-only (ro). // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. - // +featureGate=ImageVolume // +optional Image *ImageVolumeSource } @@ -309,8 +307,7 @@ type PersistentVolumeSource struct { PhotonPersistentDisk *PhotonPersistentDiskVolumeSource // portworxVolume represents a portworx volume attached and mounted on kubelets host machine. // Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type - // are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate - // is on. + // are redirected to the pxd.portworx.com CSI driver. // +optional PortworxVolume *PortworxVolumeSource // scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. @@ -619,6 +616,17 @@ const ( PersistentVolumeClaimVolumeModifyVolumeError PersistentVolumeClaimConditionType = "ModifyVolumeError" // Volume is being modified PersistentVolumeClaimVolumeModifyingVolume PersistentVolumeClaimConditionType = "ModifyingVolume" + + // PersistentVolumeClaimUnused indicates whether the PVC is currently not in use by any Pod. + // When status is True, the PVC is not referenced by any non-terminal Pod. + // The lastTransitionTime indicates when the PVC last transitioned to being unused. + // + // Both in-use time and unused time duration indicated by this condition may be shorter or + // slightly longer than actual in-use time or unused time because of processing delays or + // when this feature was enabled in the cluster. + // + // Requires PersistentVolumeClaimUnusedSinceTime alpha featuregate + PersistentVolumeClaimUnused PersistentVolumeClaimConditionType = "Unused" ) // +enum @@ -2352,7 +2360,8 @@ type SecretKeySelector struct { // EnvFromSource represents the source of a set of ConfigMaps or Secrets type EnvFromSource struct { - // Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. + // Optional text to prepend to the name of each environment variable. + // May consist of any printable ASCII characters except '='. // +optional Prefix string // The ConfigMap to select from. @@ -2642,7 +2651,8 @@ type Container struct { // +optional Ports []ContainerPort // List of sources to populate environment variables in the container. - // The keys defined within a source must be a C_IDENTIFIER. All invalid keys + // The keys defined within a source may consist of any printable ASCII characters except '='. + // All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple // sources, the value associated with the last source will take precedence. // Values defined by an Env with a duplicate key will take precedence. @@ -2996,7 +3006,6 @@ type ContainerStatus struct { // AllocatedResources represents the compute resources allocated for this container by the // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission // and after successfully admitting desired pod resize. - // +featureGate=InPlacePodVerticalScalingAllocatedStatus // +optional AllocatedResources ResourceList // Resources represents the compute resource requests and limits that have been successfully @@ -3078,6 +3087,9 @@ type ResourceHealth struct { // // In future we may want to introduce the PermanentlyUnhealthy Status. Health ResourceHealthStatus + // Message provides human-readable context for Health (e.g. "ECC error count exceeded threshold"). + // This field is populated by the kubelet when ResourceHealthStatusMessage is enabled. + Message *string } // ContainerUser represents user identity information @@ -3161,7 +3173,6 @@ const ( // PodCondition represents pod's condition type PodCondition struct { Type PodConditionType - // +featureGate=PodObservedGenerationTracking // +optional ObservedGeneration int64 Status ConditionStatus @@ -3201,6 +3212,28 @@ type VolumeMountStatus struct { // depending on the mount result. // +optional RecursiveReadOnly *RecursiveReadOnlyMode + // volumeStatus represents volume-type-specific status about the mounted + // volume. + // +optional + VolumeStatus *VolumeStatus +} + +// VolumeStatus represents the status of a mounted volume. +// At most one of its members must be specified. +type VolumeStatus struct { + // image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. + // +featureGate=ImageVolumeWithDigest + // +optional + Image *ImageVolumeStatus +} + +type ImageVolumeStatus struct { + // ImageRef is the digest of the image used for this volume. + // It should have a value that's similar to the pod's status.containerStatuses[i].imageID. + // The ImageRef length should not exceed 256 characters. + // +kubebuilder:validation:MaxLength=256 + // +required + ImageRef string } // RestartPolicy describes how the container should be restarted. @@ -3899,22 +3932,35 @@ type PodSpec struct { // +featureGate=HostnameOverride // +optional HostnameOverride *string - // WorkloadRef provides a reference to the Workload object that this Pod belongs to. - // This field is used by the scheduler to identify the PodGroup and apply the - // correct group scheduling policies. The Workload object referenced - // by this field may not exist at the time the Pod is created. - // This field is immutable, but a Workload object with the same name - // may be recreated with different policies. Doing this during pod scheduling + // SchedulingGroup provides a reference to the immediate scheduling runtime + // grouping object that this Pod belongs to. + // This field is used by the scheduler to identify the group and apply the + // correct group scheduling policies. The association with a group also + // impacts other lifecycle aspects of a Pod that are relevant in a wider context + // of scheduling like preemption, resource attachment, etc. If not specified, + // the Pod is treated as a single unit in all of these aspects. + // The group object referenced by this field may not exist at the time the + // Pod is created. + // This field is immutable, but a group object with the same name may be + // recreated with different policies. Doing this during pod scheduling // may result in the placement not conforming to the expected policies. // // +featureGate=GenericWorkload // +optional - WorkloadRef *WorkloadReference + SchedulingGroup *PodSchedulingGroup } // PodResourceClaim references exactly one ResourceClaim through a ClaimSource. // It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. // Containers that need access to the ResourceClaim reference it with this name. +// +// When the DRAWorkloadResourceClaims feature gate is enabled and this Pod +// belongs to a PodGroup, a PodResourceClaim is matched to a +// PodGroupResourceClaim if all of their fields are equal (Name, +// ResourceClaimName, and ResourceClaimTemplateName). A matched claim references +// a single ResourceClaim shared across all Pods in the PodGroup, reserved for +// the PodGroup in ResourceClaimStatus.ReservedFor rather than for individual +// Pods. type PodResourceClaim struct { // Name uniquely identifies this resource claim inside the pod. // This must be a DNS_LABEL. @@ -3936,6 +3982,16 @@ type PodResourceClaim struct { // generated component, will be used to form a unique name for the // ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. // + // When the DRAWorkloadResourceClaims feature gate is enabled and the pod + // belongs to a PodGroup that defines a PodGroupResourceClaim with the same + // Name and ResourceClaimTemplateName, this PodResourceClaim resolves to the + // ResourceClaim generated for the PodGroup. All pods in the group that + // define an equivalent PodResourceClaim matching the + // PodGroupResourceClaim's Name and ResourceClaimTemplateName share the same + // generated ResourceClaim. ResourceClaims generated for a PodGroup are + // owned by the PodGroup and their lifecycles are tied to the PodGroup + // instead of any individual pod. + // // This field is immutable and no changes will be made to the // corresponding ResourceClaim by the control plane after creating the // ResourceClaim. @@ -3955,9 +4011,16 @@ type PodResourceClaimStatus struct { Name string // ResourceClaimName is the name of the ResourceClaim that was - // generated for the Pod in the namespace of the Pod. If this is - // unset, then generating a ResourceClaim was not necessary. The - // pod.spec.resourceClaims entry can be ignored in this case. + // generated for the Pod in the namespace of the Pod. + // + // When the DRAWorkloadResourceClaims feature is enabled and the + // corresponding PodResourceClaim matches a PodGroupResourceClaim + // made by the Pod's PodGroup, then this is the name of the + // ResourceClaim generated and reserved for the PodGroup. + // + // If this is unset, then generating a ResourceClaim was not + // necessary. The pod.spec.resourceClaims entry can be ignored in + // this case. ResourceClaimName *string } @@ -4008,34 +4071,18 @@ type PodSchedulingGate struct { Name string } -// WorkloadReference identifies the Workload object and PodGroup membership -// that a Pod belongs to. The scheduler uses this information to apply -// workload-aware scheduling semantics. -type WorkloadReference struct { - // Name defines the name of the Workload object this Pod belongs to. - // Workload must be in the same namespace as the Pod. - // If it doesn't match any existing Workload, the Pod will remain unschedulable - // until a Workload object is created and observed by the kube-scheduler. - // It must be a DNS subdomain. - // - // +required - Name string - - // PodGroup is the name of the PodGroup within the Workload that this Pod - // belongs to. If it doesn't match any existing PodGroup within the Workload, - // the Pod will remain unschedulable until the Workload object is recreated - // and observed by the kube-scheduler. It must be a DNS label. - // - // +required - PodGroup string - - // PodGroupReplicaKey specifies the replica key of the PodGroup to which this - // Pod belongs. It is used to distinguish pods belonging to different replicas - // of the same pod group. The pod group policy is applied separately to each replica. - // When set, it must be a DNS label. +// PodSchedulingGroup identifies the runtime scheduling group instance that a Pod belongs to. +// The scheduler uses this information to apply workload-aware scheduling semantics. +// Exactly one field must be specified. +// +union +type PodSchedulingGroup struct { + // PodGroupName specifies the name of the standalone PodGroup object + // that represents the runtime instance of this group. + // Must be a DNS subdomain. // // +optional - PodGroupReplicaKey string + // +oneOf=GroupSelection + PodGroupName *string } // HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the @@ -4409,7 +4456,8 @@ type EphemeralContainerCommon struct { // +optional Ports []ContainerPort // List of sources to populate environment variables in the container. - // The keys defined within a source must be a C_IDENTIFIER. All invalid keys + // The keys defined within a source may consist of any printable ASCII characters except '='. + // All invalid keys // will be reported as an event when the container is starting. When a key exists in multiple // sources, the value associated with the last source will take precedence. // Values defined by an Env with a duplicate key will take precedence. @@ -4517,8 +4565,6 @@ type EphemeralContainer struct { // state of a system. type PodStatus struct { // If set, this represents the .metadata.generation that the pod status was set based upon. - // The PodObservedGenerationTracking feature gate must be enabled to use this field. - // +featureGate=PodObservedGenerationTracking // +optional ObservedGeneration int64 // +optional @@ -4631,6 +4677,16 @@ type PodStatus struct { // +featureGate=InPlacePodLevelResourcesVerticalScaling // +optional Resources *ResourceRequirements + + // NodeAllocatableResourceClaimStatuses contains the status of node-allocatable resources + // that were allocated for this pod through DRA claims. This includes resources currently + // reported in v1.Node `status.allocatable` that are not extended resources + // (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#extended-resources). + // Examples include "cpu", "memory", "ephemeral-storage", and hugepages. + // +featureGate=DRANodeAllocatableResources + // +optional + // +listType=atomic + NodeAllocatableResourceClaimStatuses []NodeAllocatableResourceClaimStatus } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -5110,6 +5166,8 @@ type ServiceSpec struct { // ExternalIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. + // + // Deprecated: ExternalIPs is deprecated and may be removed in a future version. // +optional ExternalIPs []string @@ -5509,7 +5567,6 @@ type NodeRuntimeHandlerFeatures struct { // +optional RecursiveReadOnlyMounts *bool // UserNamespaces is set to true if the runtime handler supports UserNamespaces, including for volumes. - // +featureGate=UserNamespacesSupport // +optional UserNamespaces *bool } @@ -5654,7 +5711,6 @@ type NodeStatus struct { // +optional Config *NodeConfigStatus // The available runtime handlers. - // +featureGate=UserNamespacesSupport // +optional RuntimeHandlers []NodeRuntimeHandler // Features describes the set of features implemented by the CRI implementation. @@ -7169,3 +7225,17 @@ type ImageVolumeSource struct { // +optional PullPolicy PullPolicy } + +// NodeAllocatableResourceClaimStatus describes the status of node allocatable resources allocated via DRA. +type NodeAllocatableResourceClaimStatus struct { + // ResourceClaimName is the resource claim referenced by the pod that resulted in this node allocatable resource allocation. + // +required + ResourceClaimName string + // Containers lists the names of all containers in this pod that reference the claim. + // +optional + // +listType=set + Containers []string + // Resources is a map of the node-allocatable resource name to the aggregate quantity allocated to the claim. + // +required + Resources map[ResourceName]resource.Quantity +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/qos/qos.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/qos/qos.go index b6ba7bf63a..d2cabfcd3a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/qos/qos.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/qos/qos.go @@ -18,7 +18,6 @@ package qos import ( v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/apis/core" @@ -43,10 +42,6 @@ func GetPodQOS(pod *v1.Pod) v1.PodQOSClass { return ComputePodQOS(pod) } -// zeroQuantity represents a resource.Quantity with value "0", used as a baseline -// for resource comparisons. -var zeroQuantity = resource.MustParse("0") - // processResourceList adds non-zero quantities for supported QoS compute resources // quantities from newList to list. func processResourceList(list, newList v1.ResourceList) { @@ -54,7 +49,7 @@ func processResourceList(list, newList v1.ResourceList) { if !isSupportedQoSComputeResource(name) { continue } - if quantity.Cmp(zeroQuantity) == 1 { + if quantity.Sign() == 1 { delta := quantity.DeepCopy() if _, exists := list[name]; !exists { list[name] = delta @@ -75,7 +70,7 @@ func getQOSResources(list v1.ResourceList) sets.Set[string] { if !isSupportedQoSComputeResource(name) { continue } - if quantity.Cmp(zeroQuantity) == 1 { + if quantity.Sign() == 1 { qosResources.Insert(string(name)) } } @@ -120,7 +115,7 @@ func ComputePodQOS(pod *v1.Pod) v1.PodQOSClass { if !isSupportedQoSComputeResource(name) { continue } - if quantity.Cmp(zeroQuantity) == 1 { + if quantity.Sign() == 1 { delta := quantity.DeepCopy() if _, exists := requests[name]; !exists { requests[name] = delta @@ -136,7 +131,7 @@ func ComputePodQOS(pod *v1.Pod) v1.PodQOSClass { if !isSupportedQoSComputeResource(name) { continue } - if quantity.Cmp(zeroQuantity) == 1 { + if quantity.Sign() == 1 { qosLimitsFound.Insert(string(name)) delta := quantity.DeepCopy() if _, exists := limits[name]; !exists { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go index 3770ea1916..459408c526 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go @@ -842,6 +842,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*corev1.ImageVolumeStatus)(nil), (*core.ImageVolumeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ImageVolumeStatus_To_core_ImageVolumeStatus(a.(*corev1.ImageVolumeStatus), b.(*core.ImageVolumeStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*core.ImageVolumeStatus)(nil), (*corev1.ImageVolumeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_core_ImageVolumeStatus_To_v1_ImageVolumeStatus(a.(*core.ImageVolumeStatus), b.(*corev1.ImageVolumeStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*corev1.KeyToPath)(nil), (*core.KeyToPath)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_KeyToPath_To_core_KeyToPath(a.(*corev1.KeyToPath), b.(*core.KeyToPath), scope) }); err != nil { @@ -1072,6 +1082,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*corev1.NodeAllocatableResourceClaimStatus)(nil), (*core.NodeAllocatableResourceClaimStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_NodeAllocatableResourceClaimStatus_To_core_NodeAllocatableResourceClaimStatus(a.(*corev1.NodeAllocatableResourceClaimStatus), b.(*core.NodeAllocatableResourceClaimStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*core.NodeAllocatableResourceClaimStatus)(nil), (*corev1.NodeAllocatableResourceClaimStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_core_NodeAllocatableResourceClaimStatus_To_v1_NodeAllocatableResourceClaimStatus(a.(*core.NodeAllocatableResourceClaimStatus), b.(*corev1.NodeAllocatableResourceClaimStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*corev1.NodeCondition)(nil), (*core.NodeCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_NodeCondition_To_core_NodeCondition(a.(*corev1.NodeCondition), b.(*core.NodeCondition), scope) }); err != nil { @@ -1562,6 +1582,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*corev1.PodSchedulingGroup)(nil), (*core.PodSchedulingGroup)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_PodSchedulingGroup_To_core_PodSchedulingGroup(a.(*corev1.PodSchedulingGroup), b.(*core.PodSchedulingGroup), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*core.PodSchedulingGroup)(nil), (*corev1.PodSchedulingGroup)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_core_PodSchedulingGroup_To_v1_PodSchedulingGroup(a.(*core.PodSchedulingGroup), b.(*corev1.PodSchedulingGroup), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*corev1.PodSecurityContext)(nil), (*core.PodSecurityContext)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_PodSecurityContext_To_core_PodSecurityContext(a.(*corev1.PodSecurityContext), b.(*core.PodSecurityContext), scope) }); err != nil { @@ -2307,6 +2337,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*corev1.VolumeStatus)(nil), (*core.VolumeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_VolumeStatus_To_core_VolumeStatus(a.(*corev1.VolumeStatus), b.(*core.VolumeStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*core.VolumeStatus)(nil), (*corev1.VolumeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_core_VolumeStatus_To_v1_VolumeStatus(a.(*core.VolumeStatus), b.(*corev1.VolumeStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*corev1.VsphereVirtualDiskVolumeSource)(nil), (*core.VsphereVirtualDiskVolumeSource)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_VsphereVirtualDiskVolumeSource_To_core_VsphereVirtualDiskVolumeSource(a.(*corev1.VsphereVirtualDiskVolumeSource), b.(*core.VsphereVirtualDiskVolumeSource), scope) }); err != nil { @@ -2337,16 +2377,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*corev1.WorkloadReference)(nil), (*core.WorkloadReference)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_WorkloadReference_To_core_WorkloadReference(a.(*corev1.WorkloadReference), b.(*core.WorkloadReference), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*core.WorkloadReference)(nil), (*corev1.WorkloadReference)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_core_WorkloadReference_To_v1_WorkloadReference(a.(*core.WorkloadReference), b.(*corev1.WorkloadReference), scope) - }); err != nil { - return err - } if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*corev1.NodeProxyOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_url_Values_To_v1_NodeProxyOptions(a.(*url.Values), b.(*corev1.NodeProxyOptions), scope) }); err != nil { @@ -4648,6 +4678,26 @@ func Convert_core_ImageVolumeSource_To_v1_ImageVolumeSource(in *core.ImageVolume return autoConvert_core_ImageVolumeSource_To_v1_ImageVolumeSource(in, out, s) } +func autoConvert_v1_ImageVolumeStatus_To_core_ImageVolumeStatus(in *corev1.ImageVolumeStatus, out *core.ImageVolumeStatus, s conversion.Scope) error { + out.ImageRef = in.ImageRef + return nil +} + +// Convert_v1_ImageVolumeStatus_To_core_ImageVolumeStatus is an autogenerated conversion function. +func Convert_v1_ImageVolumeStatus_To_core_ImageVolumeStatus(in *corev1.ImageVolumeStatus, out *core.ImageVolumeStatus, s conversion.Scope) error { + return autoConvert_v1_ImageVolumeStatus_To_core_ImageVolumeStatus(in, out, s) +} + +func autoConvert_core_ImageVolumeStatus_To_v1_ImageVolumeStatus(in *core.ImageVolumeStatus, out *corev1.ImageVolumeStatus, s conversion.Scope) error { + out.ImageRef = in.ImageRef + return nil +} + +// Convert_core_ImageVolumeStatus_To_v1_ImageVolumeStatus is an autogenerated conversion function. +func Convert_core_ImageVolumeStatus_To_v1_ImageVolumeStatus(in *core.ImageVolumeStatus, out *corev1.ImageVolumeStatus, s conversion.Scope) error { + return autoConvert_core_ImageVolumeStatus_To_v1_ImageVolumeStatus(in, out, s) +} + func autoConvert_v1_KeyToPath_To_core_KeyToPath(in *corev1.KeyToPath, out *core.KeyToPath, s conversion.Scope) error { out.Key = in.Key out.Path = in.Path @@ -5220,6 +5270,30 @@ func Convert_core_NodeAffinity_To_v1_NodeAffinity(in *core.NodeAffinity, out *co return autoConvert_core_NodeAffinity_To_v1_NodeAffinity(in, out, s) } +func autoConvert_v1_NodeAllocatableResourceClaimStatus_To_core_NodeAllocatableResourceClaimStatus(in *corev1.NodeAllocatableResourceClaimStatus, out *core.NodeAllocatableResourceClaimStatus, s conversion.Scope) error { + out.ResourceClaimName = in.ResourceClaimName + out.Containers = *(*[]string)(unsafe.Pointer(&in.Containers)) + out.Resources = *(*map[core.ResourceName]resource.Quantity)(unsafe.Pointer(&in.Resources)) + return nil +} + +// Convert_v1_NodeAllocatableResourceClaimStatus_To_core_NodeAllocatableResourceClaimStatus is an autogenerated conversion function. +func Convert_v1_NodeAllocatableResourceClaimStatus_To_core_NodeAllocatableResourceClaimStatus(in *corev1.NodeAllocatableResourceClaimStatus, out *core.NodeAllocatableResourceClaimStatus, s conversion.Scope) error { + return autoConvert_v1_NodeAllocatableResourceClaimStatus_To_core_NodeAllocatableResourceClaimStatus(in, out, s) +} + +func autoConvert_core_NodeAllocatableResourceClaimStatus_To_v1_NodeAllocatableResourceClaimStatus(in *core.NodeAllocatableResourceClaimStatus, out *corev1.NodeAllocatableResourceClaimStatus, s conversion.Scope) error { + out.ResourceClaimName = in.ResourceClaimName + out.Containers = *(*[]string)(unsafe.Pointer(&in.Containers)) + out.Resources = *(*map[corev1.ResourceName]resource.Quantity)(unsafe.Pointer(&in.Resources)) + return nil +} + +// Convert_core_NodeAllocatableResourceClaimStatus_To_v1_NodeAllocatableResourceClaimStatus is an autogenerated conversion function. +func Convert_core_NodeAllocatableResourceClaimStatus_To_v1_NodeAllocatableResourceClaimStatus(in *core.NodeAllocatableResourceClaimStatus, out *corev1.NodeAllocatableResourceClaimStatus, s conversion.Scope) error { + return autoConvert_core_NodeAllocatableResourceClaimStatus_To_v1_NodeAllocatableResourceClaimStatus(in, out, s) +} + func autoConvert_v1_NodeCondition_To_core_NodeCondition(in *corev1.NodeCondition, out *core.NodeCondition, s conversion.Scope) error { out.Type = core.NodeConditionType(in.Type) out.Status = core.ConditionStatus(in.Status) @@ -6887,6 +6961,26 @@ func Convert_core_PodSchedulingGate_To_v1_PodSchedulingGate(in *core.PodScheduli return autoConvert_core_PodSchedulingGate_To_v1_PodSchedulingGate(in, out, s) } +func autoConvert_v1_PodSchedulingGroup_To_core_PodSchedulingGroup(in *corev1.PodSchedulingGroup, out *core.PodSchedulingGroup, s conversion.Scope) error { + out.PodGroupName = (*string)(unsafe.Pointer(in.PodGroupName)) + return nil +} + +// Convert_v1_PodSchedulingGroup_To_core_PodSchedulingGroup is an autogenerated conversion function. +func Convert_v1_PodSchedulingGroup_To_core_PodSchedulingGroup(in *corev1.PodSchedulingGroup, out *core.PodSchedulingGroup, s conversion.Scope) error { + return autoConvert_v1_PodSchedulingGroup_To_core_PodSchedulingGroup(in, out, s) +} + +func autoConvert_core_PodSchedulingGroup_To_v1_PodSchedulingGroup(in *core.PodSchedulingGroup, out *corev1.PodSchedulingGroup, s conversion.Scope) error { + out.PodGroupName = (*string)(unsafe.Pointer(in.PodGroupName)) + return nil +} + +// Convert_core_PodSchedulingGroup_To_v1_PodSchedulingGroup is an autogenerated conversion function. +func Convert_core_PodSchedulingGroup_To_v1_PodSchedulingGroup(in *core.PodSchedulingGroup, out *corev1.PodSchedulingGroup, s conversion.Scope) error { + return autoConvert_core_PodSchedulingGroup_To_v1_PodSchedulingGroup(in, out, s) +} + func autoConvert_v1_PodSecurityContext_To_core_PodSecurityContext(in *corev1.PodSecurityContext, out *core.PodSecurityContext, s conversion.Scope) error { out.SELinuxOptions = (*core.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions)) out.WindowsOptions = (*core.WindowsSecurityContextOptions)(unsafe.Pointer(in.WindowsOptions)) @@ -7016,7 +7110,7 @@ func autoConvert_v1_PodSpec_To_core_PodSpec(in *corev1.PodSpec, out *core.PodSpe out.ResourceClaims = *(*[]core.PodResourceClaim)(unsafe.Pointer(&in.ResourceClaims)) out.Resources = (*core.ResourceRequirements)(unsafe.Pointer(in.Resources)) out.HostnameOverride = (*string)(unsafe.Pointer(in.HostnameOverride)) - out.WorkloadRef = (*core.WorkloadReference)(unsafe.Pointer(in.WorkloadRef)) + out.SchedulingGroup = (*core.PodSchedulingGroup)(unsafe.Pointer(in.SchedulingGroup)) return nil } @@ -7074,7 +7168,7 @@ func autoConvert_core_PodSpec_To_v1_PodSpec(in *core.PodSpec, out *corev1.PodSpe out.ResourceClaims = *(*[]corev1.PodResourceClaim)(unsafe.Pointer(&in.ResourceClaims)) out.Resources = (*corev1.ResourceRequirements)(unsafe.Pointer(in.Resources)) out.HostnameOverride = (*string)(unsafe.Pointer(in.HostnameOverride)) - out.WorkloadRef = (*corev1.WorkloadReference)(unsafe.Pointer(in.WorkloadRef)) + out.SchedulingGroup = (*corev1.PodSchedulingGroup)(unsafe.Pointer(in.SchedulingGroup)) return nil } @@ -7099,6 +7193,7 @@ func autoConvert_v1_PodStatus_To_core_PodStatus(in *corev1.PodStatus, out *core. out.ExtendedResourceClaimStatus = (*core.PodExtendedResourceClaimStatus)(unsafe.Pointer(in.ExtendedResourceClaimStatus)) out.AllocatedResources = *(*core.ResourceList)(unsafe.Pointer(&in.AllocatedResources)) out.Resources = (*core.ResourceRequirements)(unsafe.Pointer(in.Resources)) + out.NodeAllocatableResourceClaimStatuses = *(*[]core.NodeAllocatableResourceClaimStatus)(unsafe.Pointer(&in.NodeAllocatableResourceClaimStatuses)) return nil } @@ -7122,6 +7217,7 @@ func autoConvert_core_PodStatus_To_v1_PodStatus(in *core.PodStatus, out *corev1. out.ExtendedResourceClaimStatus = (*corev1.PodExtendedResourceClaimStatus)(unsafe.Pointer(in.ExtendedResourceClaimStatus)) out.AllocatedResources = *(*corev1.ResourceList)(unsafe.Pointer(&in.AllocatedResources)) out.Resources = (*corev1.ResourceRequirements)(unsafe.Pointer(in.Resources)) + out.NodeAllocatableResourceClaimStatuses = *(*[]corev1.NodeAllocatableResourceClaimStatus)(unsafe.Pointer(&in.NodeAllocatableResourceClaimStatuses)) return nil } @@ -7798,6 +7894,7 @@ func Convert_core_ResourceFieldSelector_To_v1_ResourceFieldSelector(in *core.Res func autoConvert_v1_ResourceHealth_To_core_ResourceHealth(in *corev1.ResourceHealth, out *core.ResourceHealth, s conversion.Scope) error { out.ResourceID = core.ResourceID(in.ResourceID) out.Health = core.ResourceHealthStatus(in.Health) + out.Message = (*string)(unsafe.Pointer(in.Message)) return nil } @@ -7809,6 +7906,7 @@ func Convert_v1_ResourceHealth_To_core_ResourceHealth(in *corev1.ResourceHealth, func autoConvert_core_ResourceHealth_To_v1_ResourceHealth(in *core.ResourceHealth, out *corev1.ResourceHealth, s conversion.Scope) error { out.ResourceID = corev1.ResourceID(in.ResourceID) out.Health = corev1.ResourceHealthStatus(in.Health) + out.Message = (*string)(unsafe.Pointer(in.Message)) return nil } @@ -9098,6 +9196,7 @@ func autoConvert_v1_VolumeMountStatus_To_core_VolumeMountStatus(in *corev1.Volum out.MountPath = in.MountPath out.ReadOnly = in.ReadOnly out.RecursiveReadOnly = (*core.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly)) + out.VolumeStatus = (*core.VolumeStatus)(unsafe.Pointer(in.VolumeStatus)) return nil } @@ -9111,6 +9210,7 @@ func autoConvert_core_VolumeMountStatus_To_v1_VolumeMountStatus(in *core.VolumeM out.MountPath = in.MountPath out.ReadOnly = in.ReadOnly out.RecursiveReadOnly = (*corev1.RecursiveReadOnlyMode)(unsafe.Pointer(in.RecursiveReadOnly)) + out.VolumeStatus = (*corev1.VolumeStatus)(unsafe.Pointer(in.VolumeStatus)) return nil } @@ -9301,6 +9401,26 @@ func Convert_core_VolumeSource_To_v1_VolumeSource(in *core.VolumeSource, out *co return autoConvert_core_VolumeSource_To_v1_VolumeSource(in, out, s) } +func autoConvert_v1_VolumeStatus_To_core_VolumeStatus(in *corev1.VolumeStatus, out *core.VolumeStatus, s conversion.Scope) error { + out.Image = (*core.ImageVolumeStatus)(unsafe.Pointer(in.Image)) + return nil +} + +// Convert_v1_VolumeStatus_To_core_VolumeStatus is an autogenerated conversion function. +func Convert_v1_VolumeStatus_To_core_VolumeStatus(in *corev1.VolumeStatus, out *core.VolumeStatus, s conversion.Scope) error { + return autoConvert_v1_VolumeStatus_To_core_VolumeStatus(in, out, s) +} + +func autoConvert_core_VolumeStatus_To_v1_VolumeStatus(in *core.VolumeStatus, out *corev1.VolumeStatus, s conversion.Scope) error { + out.Image = (*corev1.ImageVolumeStatus)(unsafe.Pointer(in.Image)) + return nil +} + +// Convert_core_VolumeStatus_To_v1_VolumeStatus is an autogenerated conversion function. +func Convert_core_VolumeStatus_To_v1_VolumeStatus(in *core.VolumeStatus, out *corev1.VolumeStatus, s conversion.Scope) error { + return autoConvert_core_VolumeStatus_To_v1_VolumeStatus(in, out, s) +} + func autoConvert_v1_VsphereVirtualDiskVolumeSource_To_core_VsphereVirtualDiskVolumeSource(in *corev1.VsphereVirtualDiskVolumeSource, out *core.VsphereVirtualDiskVolumeSource, s conversion.Scope) error { out.VolumePath = in.VolumePath out.FSType = in.FSType @@ -9378,27 +9498,3 @@ func autoConvert_core_WindowsSecurityContextOptions_To_v1_WindowsSecurityContext func Convert_core_WindowsSecurityContextOptions_To_v1_WindowsSecurityContextOptions(in *core.WindowsSecurityContextOptions, out *corev1.WindowsSecurityContextOptions, s conversion.Scope) error { return autoConvert_core_WindowsSecurityContextOptions_To_v1_WindowsSecurityContextOptions(in, out, s) } - -func autoConvert_v1_WorkloadReference_To_core_WorkloadReference(in *corev1.WorkloadReference, out *core.WorkloadReference, s conversion.Scope) error { - out.Name = in.Name - out.PodGroup = in.PodGroup - out.PodGroupReplicaKey = in.PodGroupReplicaKey - return nil -} - -// Convert_v1_WorkloadReference_To_core_WorkloadReference is an autogenerated conversion function. -func Convert_v1_WorkloadReference_To_core_WorkloadReference(in *corev1.WorkloadReference, out *core.WorkloadReference, s conversion.Scope) error { - return autoConvert_v1_WorkloadReference_To_core_WorkloadReference(in, out, s) -} - -func autoConvert_core_WorkloadReference_To_v1_WorkloadReference(in *core.WorkloadReference, out *corev1.WorkloadReference, s conversion.Scope) error { - out.Name = in.Name - out.PodGroup = in.PodGroup - out.PodGroupReplicaKey = in.PodGroupReplicaKey - return nil -} - -// Convert_core_WorkloadReference_To_v1_WorkloadReference is an autogenerated conversion function. -func Convert_core_WorkloadReference_To_v1_WorkloadReference(in *core.WorkloadReference, out *corev1.WorkloadReference, s conversion.Scope) error { - return autoConvert_core_WorkloadReference_To_v1_WorkloadReference(in, out, s) -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.validations.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.validations.go index 7e39374b6b..a8f5fba015 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.validations.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.validations.go @@ -48,14 +48,6 @@ func RegisterValidations(scheme *runtime.Scheme) error { } return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} }) - // type ReplicationControllerList - scheme.AddValidationFunc((*corev1.ReplicationControllerList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ReplicationControllerList(ctx, op, nil /* fldPath */, obj.(*corev1.ReplicationControllerList), safe.Cast[*corev1.ReplicationControllerList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) return nil } @@ -74,13 +66,13 @@ func Validate_ReplicationController(ctx context.Context, op operation.Operation, // call field-attached validations func() { // cohort name earlyReturn := false - if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.DirectEqualPtr, validate.OptionalValue); len(e) != 0 { + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.DirectEqualPtr, validate.OptionalValue).MarkAlpha(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.DirectEqualPtr, validate.LongName)...) + errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.DirectEqualPtr, validate.LongName).MarkAlpha()...) }() return }(fldPath.Child("metadata"), &obj.ObjectMeta, safe.Field(oldObj, func(oldObj *corev1.ReplicationController) *metav1.ObjectMeta { return &oldObj.ObjectMeta }), oldObj != nil)...) @@ -101,27 +93,6 @@ func Validate_ReplicationController(ctx context.Context, op operation.Operation, return errs } -// Validate_ReplicationControllerList validates an instance of ReplicationControllerList according -// to declarative validation rules in the API schema. -func Validate_ReplicationControllerList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *corev1.ReplicationControllerList) (errs field.ErrorList) { - // field corev1.ReplicationControllerList.TypeMeta has no validation - // field corev1.ReplicationControllerList.ListMeta has no validation - - // field corev1.ReplicationControllerList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []corev1.ReplicationController, oldValueCorrelated bool) (errs field.ErrorList) { - // don't revalidate unchanged data - if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { - return nil - } - // iterate the list and call the type's validation function - errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_ReplicationController)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *corev1.ReplicationControllerList) []corev1.ReplicationController { return oldObj.Items }), oldObj != nil)...) - - return errs -} - // Validate_ReplicationControllerSpec validates an instance of ReplicationControllerSpec according // to declarative validation rules in the API schema. func Validate_ReplicationControllerSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *corev1.ReplicationControllerSpec) (errs field.ErrorList) { @@ -135,27 +106,26 @@ func Validate_ReplicationControllerSpec(ctx context.Context, op operation.Operat // call field-attached validations earlyReturn := false // optional fields with default values are effectively required - if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } if earlyReturn { return // do not proceed } - errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha()...) return }(fldPath.Child("replicas"), obj.Replicas, safe.Field(oldObj, func(oldObj *corev1.ReplicationControllerSpec) *int32 { return oldObj.Replicas }), oldObj != nil)...) // field corev1.ReplicationControllerSpec.MinReadySeconds errs = append(errs, func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) { - // optional value-type fields with zero-value defaults are purely documentation // don't revalidate unchanged data if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { return nil } // call field-attached validations - errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha()...) return }(fldPath.Child("minReadySeconds"), &obj.MinReadySeconds, safe.Field(oldObj, func(oldObj *corev1.ReplicationControllerSpec) *int32 { return &oldObj.MinReadySeconds }), oldObj != nil)...) diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go index fbb62132d6..84f855295f 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go @@ -65,6 +65,7 @@ import ( "k8s.io/kubernetes/pkg/apis/core/helper/qos" podshelper "k8s.io/kubernetes/pkg/apis/core/pods" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" + v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" "k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/fieldpath" @@ -176,7 +177,7 @@ func ValidateQualifiedName(value string, fldPath *field.Path) field.ErrorList { func ValidateDNS1123SubdomainWithUnderScore(value string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for _, msg := range validation.IsDNS1123SubdomainWithUnderscore(value) { - allErrs = append(allErrs, field.Invalid(fldPath, value, msg)).WithOrigin("format=k8s-dns-subdomain-with-underscore") + allErrs = append(allErrs, field.Invalid(fldPath, value, msg).WithOrigin("format=k8s-dns-subdomain-with-underscore")) } return allErrs } @@ -185,7 +186,7 @@ func ValidateDNS1123SubdomainWithUnderScore(value string, fldPath *field.Path) f func ValidateDNS1123Subdomain(value string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for _, msg := range validation.IsDNS1123Subdomain(value) { - allErrs = append(allErrs, field.Invalid(fldPath, value, msg)).WithOrigin("format=k8s-long-name") + allErrs = append(allErrs, field.Invalid(fldPath, value, msg).WithOrigin("format=k8s-long-name")) } return allErrs } @@ -342,17 +343,9 @@ var ValidateResourceClaimName = apimachineryvalidation.NameIsDNSSubdomain // name for a ResourceClaimTemplate is valid. var ValidateResourceClaimTemplateName = apimachineryvalidation.NameIsDNSSubdomain -// ValidateWorkloadName can be used to check whether the given -// name for a Workload is valid. -var ValidateWorkloadName = apimachineryvalidation.NameIsDNSSubdomain - // ValidatePodGroupName can be used to check whether the given // name for a PodGroup is valid. -var ValidatePodGroupName = apimachineryvalidation.NameIsDNSLabel - -// ValidatePodGroupReplicaKey can be used to check whether the given -// PodGroupReplicaKey is valid. -var ValidatePodGroupReplicaKey = apimachineryvalidation.NameIsDNSLabel +var ValidatePodGroupName = apimachineryvalidation.NameIsDNSSubdomain // ValidateRuntimeClassName can be used to check whether the given RuntimeClass name is valid. // Prefix indicates this name will be used as part of generation, in which case @@ -1829,7 +1822,7 @@ func ValidateCSIDriverName(driverName string, fldPath *field.Path, opts ...Valid if len(driverName) > 63 { err := field.TooLong(fldPath, "" /*unused*/, 63) if slices.Contains(opts, SizeCovered) { - err = err.MarkCoveredByDeclarative() + err = err.WithOrigin("maxLength").MarkCoveredByDeclarative() } allErrs = append(allErrs, err) } @@ -3653,9 +3646,10 @@ func validateResizePolicy(policyList []core.ContainerResizePolicy, fldPath *fiel } if *podRestartPolicy == core.RestartPolicyNever && p.RestartPolicy != core.NotRequired { - allErrors = append(allErrors, field.Invalid(fldPath, p.RestartPolicy, "must be 'NotRequired' when `restartPolicy` is 'Never'")) + allErrors = append(allErrors, field.Invalid(fldPath, p.RestartPolicy, "must be 'NotRequired' when pod `restartPolicy` is 'Never'")) } } + return allErrors } @@ -3694,7 +3688,7 @@ func validateContainerRestartPolicy(policy *core.ContainerRestartPolicy, rules [ } if len(rules) > 20 { - allErrs = append(allErrs, field.TooLong(fldPath.Child("restartPolicyRules"), rules, 20)) + allErrs = append(allErrs, field.TooMany(fldPath.Child("restartPolicyRules"), len(rules), 20)) } for i, rule := range rules { policyRulesFld := fldPath.Child("restartPolicyRules").Index(i) @@ -3703,7 +3697,7 @@ func validateContainerRestartPolicy(policy *core.ContainerRestartPolicy, rules [ allowedActions = supportedContainerRestartRuleActionsWithRestartAllContainers } if !allowedActions.Has(rule.Action) { - allErrs = append(allErrs, field.NotSupported(policyRulesFld.Child("action"), rule.Action, sets.List(supportedContainerRestartRuleActions))) + allErrs = append(allErrs, field.NotSupported(policyRulesFld.Child("action"), rule.Action, sets.List(allowedActions))) } if rule.ExitCodes != nil { @@ -3713,7 +3707,7 @@ func validateContainerRestartPolicy(policy *core.ContainerRestartPolicy, rules [ } if len(rule.ExitCodes.Values) > 255 { - allErrs = append(allErrs, field.TooLong(exitCodesFld.Child("values"), rule.ExitCodes.Values, 255)) + allErrs = append(allErrs, field.TooMany(exitCodesFld.Child("values"), len(rule.ExitCodes.Values), 255)) } } else { allErrs = append(allErrs, field.Required(policyRulesFld.Child("exitCodes"), "must be specified")) @@ -3866,6 +3860,14 @@ func validateInitContainers(containers []core.Container, os *core.PodOS, regular if !opts.AllowSidecarResizePolicy && len(ctr.ResizePolicy) > 0 { allErrs = append(allErrs, field.Invalid(idxPath.Child("resizePolicy"), ctr.ResizePolicy, "must not be set for init containers")) } + + if !restartAlways && !opts.AllowExistingRestartContainerForNonSidecarInitContainer { + for j, p := range ctr.ResizePolicy { + if p.RestartPolicy == core.RestartContainer { + allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("resizePolicy").Index(j).Child("restartPolicy"), p.RestartPolicy, "must not be set to 'RestartContainer' for non-sidecar initContainers")) + } + } + } } return allErrs @@ -4485,6 +4487,8 @@ type PodValidationOptions struct { AllowEnvFilesValidation bool // Allows containers have restart policy and restart policy rules. AllowContainerRestartPolicyRules bool + // Allow existing RestartContainer resize policy for non-sidecar init containers for backward compatibility + AllowExistingRestartContainerForNonSidecarInitContainer bool // Allow user namespaces with volume devices, even though they will not function properly (should only be tolerated in updates of objects which already have this invalid configuration). AllowUserNamespacesWithVolumeDevices bool // Allow taint toleration comparison operators (Lt, Gt) @@ -4493,6 +4497,8 @@ type PodValidationOptions struct { AllowUserNamespacesHostNetworkSupport bool // Allow containers to have restart policy rule with RestartAllContainers action, applicable for init, sidecar, and regular containers. AllowRestartAllContainers bool + // Allows container statuses to contain image volume digest + AllowImageVolumeWithDigest bool } // validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set, @@ -4725,8 +4731,8 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi } } - if spec.WorkloadRef != nil { - allErrs = append(allErrs, validateWorkloadReference(spec.WorkloadRef, fldPath.Child("workloadRef"))...) + if spec.SchedulingGroup != nil { + allErrs = append(allErrs, validateSchedulingGroup(spec.SchedulingGroup, fldPath.Child("schedulingGroup"))...) } allErrs = append(allErrs, validateFileKeyRefVolumes(spec, fldPath)...) @@ -4977,7 +4983,7 @@ func ValidateNodeSelectorRequirement(rq core.NodeSelectorRequirement, allowInval path := fldPath.Child("values") for valueIndex, value := range rq.Values { for _, msg := range validation.IsValidLabelValue(value) { - allErrs = append(allErrs, field.Invalid(path.Index(valueIndex), value, msg)).WithOrigin("format=k8s-label-value") + allErrs = append(allErrs, field.Invalid(path.Index(valueIndex), value, msg).WithOrigin("format=k8s-label-value")) } } } @@ -6045,6 +6051,7 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions allErrs = append(allErrs, ValidateEphemeralContainerStateTransition(newPod.Status.EphemeralContainerStatuses, oldPod.Status.EphemeralContainerStatuses, fldPath.Child("ephemeralContainerStatuses"))...) allErrs = append(allErrs, validatePodResourceClaimStatuses(newPod.Status.ResourceClaimStatuses, newPod.Spec.ResourceClaims, fldPath.Child("resourceClaimStatuses"))...) allErrs = append(allErrs, validatePodExtendedResourceClaimStatus(newPod.Status.ExtendedResourceClaimStatus, &newPod.Spec, fldPath.Child("extendedResourceClaimStatus"))...) + allErrs = append(allErrs, validateNodeAllocatableResourceClaimStatus(newPod.Status, &newPod.Spec, fldPath.Child("nodeAllocatableResourceClaimStatuses"))...) if newIPErrs := validatePodIPs(newPod, oldPod); len(newIPErrs) > 0 { allErrs = append(allErrs, newIPErrs...) @@ -6063,6 +6070,27 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions // ephemeral containers are not allowed to have resources allocated allErrs = append(allErrs, validateContainerStatusNoAllocatedResourcesStatus(newPod.Status.EphemeralContainerStatuses, fldPath.Child("ephemeralContainerStatuses"))...) + if opts.AllowImageVolumeWithDigest { + for i, containerStatus := range newPod.Status.ContainerStatuses { + for j, volumeMountStatus := range containerStatus.VolumeMounts { + validatedField := fldPath.Child("containerStatuses").Index(i).Child("volumeMounts").Index(j).Child("volumeStatus") + allErrs = append(allErrs, validateVolumeStatus(volumeMountStatus.VolumeStatus, validatedField)...) + } + } + for i, containerStatus := range newPod.Status.InitContainerStatuses { + for j, volumeMountStatus := range containerStatus.VolumeMounts { + validatedField := fldPath.Child("initContainerStatuses").Index(i).Child("volumeMounts").Index(j).Child("volumeStatus") + allErrs = append(allErrs, validateVolumeStatus(volumeMountStatus.VolumeStatus, validatedField)...) + } + } + for i, containerStatus := range newPod.Status.EphemeralContainerStatuses { + for j, volumeMountStatus := range containerStatus.VolumeMounts { + validatedField := fldPath.Child("ephemeralContainerStatuses").Index(i).Child("volumeMounts").Index(j).Child("volumeStatus") + allErrs = append(allErrs, validateVolumeStatus(volumeMountStatus.VolumeStatus, validatedField)...) + } + } + } + return allErrs } @@ -6105,7 +6133,68 @@ func validatePodResourceClaimStatuses(statuses []core.PodResourceClaimStatus, po } if status.ResourceClaimName != nil { for _, detail := range ValidateResourceClaimName(*status.ResourceClaimName, false) { - allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), status.ResourceClaimName, detail)) + allErrs = append(allErrs, field.Invalid(idxPath.Child("resourceClaimName"), status.ResourceClaimName, detail)) + } + } + } + + return allErrs +} + +// validateNodeAllocatableResourceClaimStatus validates NodeAllocatableResourceClaimStatuses in a pod status +func validateNodeAllocatableResourceClaimStatus(podStatus core.PodStatus, podSpec *core.PodSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if len(podStatus.NodeAllocatableResourceClaimStatuses) == 0 { + return allErrs + } + + for i, nodeAllocatableStatus := range podStatus.NodeAllocatableResourceClaimStatuses { + statusFldPath := fldPath.Index(i) + if nodeAllocatableStatus.ResourceClaimName == "" { + allErrs = append(allErrs, field.Required(statusFldPath.Child("resourceClaimName"), "must not be empty")) + } + + // First check the podSpec to see if the ResourceClaim is directly referenced. + // If not, check the podStatus to see if the ResourceClaim was generated from a template. + found := false + for _, claimRef := range podSpec.ResourceClaims { + if (claimRef.ResourceClaimName != nil) && (*claimRef.ResourceClaimName == nodeAllocatableStatus.ResourceClaimName) { + found = true + break + } + } + if !found { + for _, claimRef := range podStatus.ResourceClaimStatuses { + if (claimRef.ResourceClaimName != nil) && (*claimRef.ResourceClaimName == nodeAllocatableStatus.ResourceClaimName) { + found = true + break + } + } + } + + if !found { + allErrs = append(allErrs, field.Invalid(statusFldPath.Child("resourceClaimName"), nodeAllocatableStatus.ResourceClaimName, "no mapping found in pod reference")) + } + + // TODO(KEP-5517): Evaluate if its ok to have no containers referencing a node allocatable resource claim. + // This is pending on defining kubelet cgroup enforcement. + if len(nodeAllocatableStatus.Containers) == 0 { + allErrs = append(allErrs, field.Required(statusFldPath.Child("containers"), "must not be empty")) + } + + resourcesFldPath := statusFldPath.Child("resources") + if len(nodeAllocatableStatus.Resources) == 0 { + allErrs = append(allErrs, field.Required(resourcesFldPath, "must not be empty")) + } + + for resourceName, quantity := range nodeAllocatableStatus.Resources { + keyPath := resourcesFldPath.Key(string(resourceName)) + if !v1helper.IsNativeResource(v1.ResourceName(resourceName)) { + allErrs = append(allErrs, field.Invalid(keyPath, resourceName, "must be a node allocatable resource name")) + } + if quantity.Cmp(resource.Quantity{}) < 0 { + allErrs = append(allErrs, field.Invalid(keyPath, quantity.String(), "must be non-negative")) } } } @@ -6263,7 +6352,15 @@ func ValidatePodResize(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel allErrs = append(allErrs, validatePodLevelResourcesResize(newPod, oldPod, &newPodSpecCopy, specPath, opts)...) } - // Part 3: Validate that the changes between oldPod.Spec.Containers[].Resources and + // Part 3: Disable InPlaceResize if a pod is using DRA resource claims for node-allocatable resources. + // TODO(KEP-5517) - Handle in place resize with node-allocatable resource claims. + // Currently, the presence of any node-allocatable resource claim blocks resizing for all resources, irrespective of whether + // ResourceClaim is used for the same resource. + if len(oldPod.Status.NodeAllocatableResourceClaimStatuses) > 0 { + allErrs = append(allErrs, field.Forbidden(specPath, "pods with node allocatable resource claims cannot be resized")) + } + + // Part 4: Validate that the changes between oldPod.Spec.Containers[].Resources and // newPod.Spec.Containers[].Resources are allowed. Also validate that the changes between oldPod.Spec.InitContainers[].Resources and // newPod.Spec.InitContainers[].Resources are allowed. @@ -6276,17 +6373,15 @@ func ValidatePodResize(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel } // Do not allow removing resource requests/limits on resize. - if utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) { - for ix, ctr := range oldPod.Spec.InitContainers { - if !isRestartableInitContainer(&ctr) { - continue - } - allErrs = append(allErrs, validateContainerResize( - &newPod.Spec.InitContainers[ix].Resources, - &oldPod.Spec.InitContainers[ix].Resources, - newPod.Spec.InitContainers[ix].ResizePolicy, - specPath.Child("initContainers").Index(ix).Child("resources"))...) + for ix, ctr := range oldPod.Spec.InitContainers { + if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingInitContainers) && !isRestartableInitContainer(&ctr) { + continue } + allErrs = append(allErrs, validateContainerResize( + &newPod.Spec.InitContainers[ix].Resources, + &oldPod.Spec.InitContainers[ix].Resources, + newPod.Spec.InitContainers[ix].ResizePolicy, + specPath.Child("initContainers").Index(ix).Child("resources"))...) } for ix := range oldPod.Spec.Containers { allErrs = append(allErrs, validateContainerResize( @@ -6310,18 +6405,32 @@ func ValidatePodResize(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel newPodSpecCopy.Containers = newContainers // Ensure that only CPU and memory resources are mutable for restartable init containers. - // Also ensure that resources are immutable for non-restartable init containers. var newInitContainers []core.Container if utilfeature.DefaultFeatureGate.Enabled(features.SidecarContainers) { for ix, container := range newPodSpecCopy.InitContainers { - if isRestartableInitContainer(&container) { // restartable init container + isRestartable := isRestartableInitContainer(&container) + canResize := isRestartable || utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingInitContainers) + modifiedContainer := !apiequality.Semantic.DeepEqual(container, oldPod.Spec.InitContainers[ix]) + + if canResize { dropCPUMemoryResourcesFromContainer(&container, &oldPod.Spec.InitContainers[ix]) if !apiequality.Semantic.DeepEqual(container, oldPod.Spec.InitContainers[ix]) { // This likely means that the user has made changes to resources other than CPU and memory for sidecar container. - errs := field.Forbidden(specPath, "only cpu and memory resources for sidecar containers are mutable") + errs := field.Forbidden(specPath.Child("initContainers").Index(ix), "only cpu and memory resources for init or sidecar containers are mutable") allErrs = append(allErrs, errs) } - } else if !apiequality.Semantic.DeepEqual(container, oldPod.Spec.InitContainers[ix]) { // non-restartable init container + if modifiedContainer && !isRestartable { + for _, resizePolicy := range container.ResizePolicy { + if resizePolicy.RestartPolicy == core.RestartContainer { + // TODO: This validation check can eventually be removed in 1.40, + // as https://github.com/kubernetes/kubernetes/pull/137458 prohibits + // the ability to set RestartContainer resize policy for non-sidecar init containers. + errs := field.Forbidden(specPath.Child("initContainers").Index(ix), "non-sidecar init containers with a resize policy of RestartContainer cannot be resized") + allErrs = append(allErrs, errs) + } + } + } + } else if modifiedContainer { // modified non-resizable init container // This likely means that the user has modified resources of non-sidecar init container. errs := field.Forbidden(specPath, "resources for non-sidecar init containers are immutable") allErrs = append(allErrs, errs) @@ -9506,6 +9615,14 @@ func validateContainerStatusAllocatedResourcesStatus(containerStatuses []core.Co allErrors = append(allErrors, field.NotSupported(fldPath.Index(i).Child("allocatedResourcesStatus").Index(j).Child("resources").Index(k).Child("health"), r.Health, sets.List(supportedResourceHealthValues))) } + if r.Message != nil { + if len(*r.Message) == 0 { + allErrors = append(allErrors, field.Required(fldPath.Index(i).Child("allocatedResourcesStatus").Index(j).Child("resources").Index(k).Child("message"), "must be non-empty if specified")) + } else if len(*r.Message) > v1.ResourceHealthMessageMaxLength { + allErrors = append(allErrors, field.TooLong(fldPath.Index(i).Child("allocatedResourcesStatus").Index(j).Child("resources").Index(k).Child("message"), *r.Message, v1.ResourceHealthMessageMaxLength)) + } + } + if uniqueResources.Has(r.ResourceID) { allErrors = append(allErrors, field.Duplicate(fldPath.Index(i).Child("allocatedResourcesStatus").Index(j).Child("resources").Index(k).Child("resourceID"), r.ResourceID)) } else { @@ -9588,18 +9705,57 @@ func validateNodeSwapStatus(nodeSwapStatus *core.NodeSwapStatus, fldPath *field. return allErrors } -func validateWorkloadReference(workloadRef *core.WorkloadReference, fldPath *field.Path) field.ErrorList { +func validateSchedulingGroup(schedulingGroup *core.PodSchedulingGroup, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList - for _, detail := range ValidateWorkloadName(workloadRef.Name, false) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), workloadRef.Name, detail)) - } - for _, detail := range ValidatePodGroupName(workloadRef.PodGroup, false) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("podGroup"), workloadRef.PodGroup, detail)) - } - if workloadRef.PodGroupReplicaKey != "" { - for _, detail := range ValidatePodGroupReplicaKey(workloadRef.PodGroupReplicaKey, false) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("podGroupReplicaKey"), workloadRef.PodGroupReplicaKey, detail)) + if schedulingGroup.PodGroupName == nil { + // This is a one-of set, but there's only one possible option present right now. + allErrs = append(allErrs, field.Invalid(fldPath.Child("podGroupName"), schedulingGroup.PodGroupName, "must specify one of: `podGroupName`")) + } else { + name := *schedulingGroup.PodGroupName + for _, detail := range ValidatePodGroupName(name, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("podGroupName"), name, detail)) } } return allErrs } + +func validateImageVolumeStatus(imageVolumeStatus *core.ImageVolumeStatus, fldPath *field.Path) field.ErrorList { + allErrors := field.ErrorList{} + + if imageVolumeStatus == nil { + return allErrors + } + + if imageVolumeStatus.ImageRef == "" { + allErrors = append(allErrors, field.Required(fldPath.Child("imageRef"), "imageRef must not be empty")) + } + + const maxImageRefLen = 256 + if len(imageVolumeStatus.ImageRef) > maxImageRefLen { + allErrors = append(allErrors, field.TooLong(fldPath.Child("imageRef"), imageVolumeStatus.ImageRef, maxImageRefLen)) + } + + return allErrors +} + +// validateVolumeStatus returns an error if the given struct has more than 1 populated field. +func validateVolumeStatus(volumeStatus *core.VolumeStatus, fldPath *field.Path) field.ErrorList { + allErrors := field.ErrorList{} + + if volumeStatus == nil { + return allErrors + } + + numStatuses := 0 + + if volumeStatus.Image != nil { + numStatuses++ + allErrors = append(allErrors, validateImageVolumeStatus(volumeStatus.Image, fldPath.Child("imageVolumeStatus"))...) + } + + if numStatuses > 1 { + allErrors = append(allErrors, field.Forbidden(fldPath, "may not specify more than 1 volume type")) + } + + return allErrors +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go index 017ac70cd4..e2d01dcdd3 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ limitations under the License. package core import ( + resource "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" types "k8s.io/apimachinery/pkg/types" @@ -2170,6 +2171,22 @@ func (in *ImageVolumeSource) DeepCopy() *ImageVolumeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageVolumeStatus) DeepCopyInto(out *ImageVolumeStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageVolumeStatus. +func (in *ImageVolumeStatus) DeepCopy() *ImageVolumeStatus { + if in == nil { + return nil + } + out := new(ImageVolumeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KeyToPath) DeepCopyInto(out *KeyToPath) { *out = *in @@ -2762,6 +2779,34 @@ func (in *NodeAffinity) DeepCopy() *NodeAffinity { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeAllocatableResourceClaimStatus) DeepCopyInto(out *NodeAllocatableResourceClaimStatus) { + *out = *in + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make(map[ResourceName]resource.Quantity, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAllocatableResourceClaimStatus. +func (in *NodeAllocatableResourceClaimStatus) DeepCopy() *NodeAllocatableResourceClaimStatus { + if in == nil { + return nil + } + out := new(NodeAllocatableResourceClaimStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeCondition) DeepCopyInto(out *NodeCondition) { *out = *in @@ -4301,6 +4346,27 @@ func (in *PodSchedulingGate) DeepCopy() *PodSchedulingGate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSchedulingGroup) DeepCopyInto(out *PodSchedulingGroup) { + *out = *in + if in.PodGroupName != nil { + in, out := &in.PodGroupName, &out.PodGroupName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingGroup. +func (in *PodSchedulingGroup) DeepCopy() *PodSchedulingGroup { + if in == nil { + return nil + } + out := new(PodSchedulingGroup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) { *out = *in @@ -4571,10 +4637,10 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { *out = new(string) **out = **in } - if in.WorkloadRef != nil { - in, out := &in.WorkloadRef, &out.WorkloadRef - *out = new(WorkloadReference) - **out = **in + if in.SchedulingGroup != nil { + in, out := &in.SchedulingGroup, &out.SchedulingGroup + *out = new(PodSchedulingGroup) + (*in).DeepCopyInto(*out) } return } @@ -4658,6 +4724,13 @@ func (in *PodStatus) DeepCopyInto(out *PodStatus) { *out = new(ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.NodeAllocatableResourceClaimStatuses != nil { + in, out := &in.NodeAllocatableResourceClaimStatuses, &out.NodeAllocatableResourceClaimStatuses + *out = make([]NodeAllocatableResourceClaimStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -5224,6 +5297,11 @@ func (in *ResourceFieldSelector) DeepCopy() *ResourceFieldSelector { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceHealth) DeepCopyInto(out *ResourceHealth) { *out = *in + if in.Message != nil { + in, out := &in.Message, &out.Message + *out = new(string) + **out = **in + } return } @@ -5424,7 +5502,9 @@ func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) { if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = make([]ResourceHealth, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } @@ -6519,6 +6599,11 @@ func (in *VolumeMountStatus) DeepCopyInto(out *VolumeMountStatus) { *out = new(RecursiveReadOnlyMode) **out = **in } + if in.VolumeStatus != nil { + in, out := &in.VolumeStatus, &out.VolumeStatus + *out = new(VolumeStatus) + (*in).DeepCopyInto(*out) + } return } @@ -6795,6 +6880,27 @@ func (in *VolumeSource) DeepCopy() *VolumeSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeStatus) DeepCopyInto(out *VolumeStatus) { + *out = *in + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageVolumeStatus) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeStatus. +func (in *VolumeStatus) DeepCopy() *VolumeStatus { + if in == nil { + return nil + } + out := new(VolumeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VsphereVirtualDiskVolumeSource) DeepCopyInto(out *VsphereVirtualDiskVolumeSource) { *out = *in @@ -6863,19 +6969,3 @@ func (in *WindowsSecurityContextOptions) DeepCopy() *WindowsSecurityContextOptio in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkloadReference) DeepCopyInto(out *WorkloadReference) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadReference. -func (in *WorkloadReference) DeepCopy() *WorkloadReference { - if in == nil { - return nil - } - out := new(WorkloadReference) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/register.go b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/register.go index ae4c71a6ca..f36459b279 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/register.go @@ -46,6 +46,8 @@ var ( func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, + &PodGroup{}, + &PodGroupList{}, &PriorityClass{}, &PriorityClassList{}, &Workload{}, diff --git a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/types.go b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/types.go index 12730404c5..dd7950f702 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/types.go @@ -39,6 +39,10 @@ const ( SystemClusterCritical = SystemPriorityClassPrefix + "cluster-critical" // SystemNodeCritical is the system priority class name that represents node-critical. SystemNodeCritical = SystemPriorityClassPrefix + "node-critical" + + // PodGroupProtectionFinalizer is the finalizer added to PodGroups to prevent + // premature deletion while pods still reference them. + PodGroupProtectionFinalizer = GroupName + "/podgroup-protection" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -92,12 +96,13 @@ type PriorityClassList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Workload allows for expressing scheduling constraints that should be used -// when managing lifecycle of workloads from scheduling perspective, +// when managing the lifecycle of workloads from the scheduling perspective, // including scheduling, preemption, eviction and other phases. +// Workload API enablement is toggled by the GenericWorkload feature gate. type Workload struct { metav1.TypeMeta // Standard object's metadata. - // Name must be a DNS subdomain. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // // +optional metav1.ObjectMeta @@ -122,26 +127,26 @@ type WorkloadList struct { Items []Workload } -// WorkloadMaxPodGroups is the maximum number of pod groups per Workload. -const WorkloadMaxPodGroups = 8 +// WorkloadMaxPodGroupTemplates is the maximum number of pod group templates per Workload. +const WorkloadMaxPodGroupTemplates = 8 // WorkloadSpec defines the desired state of a Workload. type WorkloadSpec struct { // ControllerRef is an optional reference to the controlling object, such as a // Deployment or Job. This field is intended for use by tools like CLIs // to provide a link back to the original workload definition. - // When set, it cannot be changed. + // This field is immutable. // // +optional ControllerRef *TypedLocalObjectReference - // PodGroups is the list of pod groups that make up the Workload. - // The maximum number of pod groups is 8. This field is immutable. + // PodGroupTemplates is the list of templates that make up the Workload. + // The maximum number of templates is 8. This field is immutable. // // +required // +listType=map // +listMapKey=name - PodGroups []PodGroup + PodGroupTemplates []PodGroupTemplate } // TypedLocalObjectReference allows to reference typed object inside the same namespace. @@ -165,34 +170,96 @@ type TypedLocalObjectReference struct { Name string } -// PodGroup represents a set of pods with a common scheduling policy. -type PodGroup struct { - // Name is a unique identifier for the PodGroup within the Workload. +// MaxPodGroupResourceClaims is the maximum number of resource claims for a +// PodGroup or a Workload's PodGroupTemplate. +const MaxPodGroupResourceClaims = 4 + +// PodGroupTemplate represents a template for a set of pods with a scheduling policy. +type PodGroupTemplate struct { + // Name is a unique identifier for the PodGroupTemplate within the Workload. // It must be a DNS label. This field is immutable. // // +required Name string - // Policy defines the scheduling policy for this PodGroup. + // SchedulingPolicy defines the scheduling policy for this PodGroupTemplate. // // +required - Policy PodGroupPolicy + SchedulingPolicy PodGroupSchedulingPolicy + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +optional + // +featureGate=TopologyAwareWorkloadScheduling + SchedulingConstraints *PodGroupSchedulingConstraints + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods consume the devices allocated to a PodGroup's claim by + // defining a claim in its own Spec.ResourceClaims that matches the + // PodGroup's claim exactly. The claim must have the same name and refer to + // the same ResourceClaim or ResourceClaimTemplate. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +featureGate=DRAWorkloadResourceClaims + ResourceClaims []PodGroupResourceClaim + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // One of Pod, PodGroup. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + DisruptionMode *DisruptionMode + + // PriorityClassName indicates the priority that should be considered when scheduling + // a pod group created from this template. If no priority class is specified, admission + // control can set this to the global default priority class if it exists. Otherwise, + // pod groups created from this template will have the priority set to zero. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + PriorityClassName string + + // Priority is the value of priority of pod groups created from this template. Various + // system components use this field to find the priority of the pod group. When + // Priority Admission Controller is enabled, it prevents users from setting this field. + // The admission controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + Priority *int32 } -// PodGroupPolicy defines the scheduling configuration for a PodGroup. -type PodGroupPolicy struct { +// PodGroupSchedulingPolicy defines the scheduling configuration for a PodGroup. +// Exactly one policy must be set. +// +union +type PodGroupSchedulingPolicy struct { // Basic specifies that the pods in this group should be scheduled using // standard Kubernetes scheduling behavior. // // +optional - // +oneOf=PolicySelection Basic *BasicSchedulingPolicy // Gang specifies that the pods in this group should be scheduled using // all-or-nothing semantics. // // +optional - // +oneOf=PolicySelection Gang *GangSchedulingPolicy } @@ -214,3 +281,302 @@ type GangSchedulingPolicy struct { // +required MinCount int32 } + +// PodGroupResourceClaim references exactly one ResourceClaim, either directly +// or by naming a ResourceClaimTemplate which is then turned into a ResourceClaim +// for the PodGroup. +// +// It adds a name to it that uniquely identifies the ResourceClaim inside the PodGroup. +// Pods that need access to the ResourceClaim define a matching reference in its +// own Spec.ResourceClaims. The Pod's claim must match all fields of the +// PodGroup's claim exactly. +type PodGroupResourceClaim struct { + // Name uniquely identifies this resource claim inside the PodGroup. + // This must be a DNS_LABEL. + // + // +required + Name string + + // ResourceClaimName is the name of a ResourceClaim object in the same + // namespace as this PodGroup. The ResourceClaim will be reserved for the + // PodGroup instead of its individual pods. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + ResourceClaimName *string + + // ResourceClaimTemplateName is the name of a ResourceClaimTemplate + // object in the same namespace as this PodGroup. + // + // The template will be used to create a new ResourceClaim, which will + // be bound to this PodGroup. When this PodGroup is deleted, the ResourceClaim + // will also be deleted. The PodGroup name and resource name, along with a + // generated component, will be used to form a unique name for the + // ResourceClaim, which will be recorded in podgroup.status.resourceClaimStatuses. + // + // This field is immutable and no changes will be made to the + // corresponding ResourceClaim by the control plane after creating the + // ResourceClaim. + // + // Exactly one of ResourceClaimName and ResourceClaimTemplateName must + // be set. + // + // +optional + ResourceClaimTemplateName *string +} + +// DisruptionMode describes the mode in which a PodGroup can be disrupted (e.g. preempted). +// +enum +type DisruptionMode string + +const ( + // DisruptionModePod means that individual pods can be disrupted or preempted independently. + // It doesn't depend on exact set of pods currently running in this PodGroup. + DisruptionModePod DisruptionMode = "Pod" + // DisruptionModePodGroup means that the whole PodGroup needs to be disrupted + // or preempted together. + DisruptionModePodGroup DisruptionMode = "PodGroup" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodGroup represents a runtime instance of pods grouped together. +// PodGroups are created by workload controllers (Job, LWS, JobSet, etc...) from +// Workload.podGroupTemplates. +// PodGroup API enablement is toggled by the GenericWorkload feature gate. +type PodGroup struct { + metav1.TypeMeta + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // + // +optional + metav1.ObjectMeta + + // Spec defines the desired state of the PodGroup. + // + // +required + Spec PodGroupSpec + + // Status represents the current observed state of the PodGroup. + // + // +optional + Status PodGroupStatus +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodGroupList contains a list of PodGroup resources. +type PodGroupList struct { + metav1.TypeMeta + // Standard list metadata. + // + // +optional + metav1.ListMeta + + // Items is the list of PodGroups. + Items []PodGroup +} + +// PodGroupSpec defines the desired state of a PodGroup. +type PodGroupSpec struct { + // PodGroupTemplateRef references an optional PodGroup template within other object + // (e.g. Workload) that was used to create the PodGroup. This field is immutable. + // + // +optional + PodGroupTemplateRef *PodGroupTemplateReference + + // SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // + // +required + SchedulingPolicy PodGroupSchedulingPolicy + + // SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // This field is immutable. + // This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled. + // + // +optional + // +featureGate=TopologyAwareWorkloadScheduling + SchedulingConstraints *PodGroupSchedulingConstraints + + // ResourceClaims defines which ResourceClaims may be shared among Pods in + // the group. Pods must reference these claims in order to consume the + // allocated devices. + // + // This is an alpha-level field and requires that the + // DRAWorkloadResourceClaims feature gate is enabled. + // + // This field is immutable. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +featureGate=DRAWorkloadResourceClaims + ResourceClaims []PodGroupResourceClaim + + // DisruptionMode defines the mode in which a given PodGroup can be disrupted. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // One of Pod, PodGroup. Defaults to Pod if unset. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + DisruptionMode *DisruptionMode + + // PriorityClassName defines the priority that should be considered when scheduling this pod group. + // Controllers are expected to fill this field by copying it from a PodGroupTemplate. + // Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate + // (i.e. if no priority class is specified, admission control can set this to the global default + // priority class if it exists. Otherwise, the pod group's priority will be zero). + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + PriorityClassName string + + // Priority is the value of priority of this pod group. Various system components + // use this field to find the priority of the pod group. When Priority Admission + // Controller is enabled, it prevents users from setting this field. The admission + // controller populates this field from PriorityClassName. + // The higher the value, the higher the priority. + // This field is immutable. + // This field is available only when the WorkloadAwarePreemption feature gate + // is enabled. + // + // +featureGate=WorkloadAwarePreemption + // +optional + Priority *int32 +} + +// PodGroupStatus represents information about the status of a pod group. +type PodGroupStatus struct { + // Conditions represent the latest observations of the PodGroup's state. + // + // Known condition types: + // - "PodGroupScheduled": Indicates whether the scheduling requirement has been satisfied. + // - "DisruptionTarget": Indicates whether the PodGroup is about to be terminated + // due to disruption such as preemption. + // + // Known reasons for the PodGroupScheduled condition: + // - "Unschedulable": The PodGroup cannot be scheduled due to resource constraints, + // affinity/anti-affinity rules, or insufficient capacity for the gang. + // - "SchedulerError": The PodGroup cannot be scheduled due to some internal error + // that happened during scheduling, for example due to nodeAffinity parsing errors. + // + // Known reasons for the DisruptionTarget condition: + // - "PreemptionByScheduler": The PodGroup was preempted by the scheduler to make room for + // higher-priority PodGroups or Pods. + // + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition + + // Status of resource claims. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +featureGate=DRAWorkloadResourceClaims + ResourceClaimStatuses []PodGroupResourceClaimStatus +} + +// Well-known condition types for PodGroups. +const ( + // PodGroupScheduled represents status of the scheduling process for this PodGroup. + PodGroupScheduled string = "PodGroupScheduled" + // DisruptionTarget indicates the PodGroup is about to be terminated due to disruption + // such as preemption. + DisruptionTarget string = "DisruptionTarget" +) + +// Well-known condition reasons for PodGroups. +const ( + // Unschedulable reason in the PodGroupScheduled condition indicates that the PodGroup cannot be scheduled + // due to resource constraints, affinity/anti-affinity rules, or insufficient capacity for the PodGroup. + PodGroupReasonUnschedulable string = "Unschedulable" + // SchedulerError reason in the PodGroupScheduled condition means that some internal error happens + // during scheduling, for example due to nodeAffinity parsing errors. + PodGroupReasonSchedulerError string = "SchedulerError" + // PreemptionByScheduler reason in the DisruptionTarget condition indicates the PodGroup was preempted + // to make room for higher-priority PodGroups or Pods. + PodGroupReasonPreemptionByScheduler string = "PreemptionByScheduler" +) + +// PodGroupResourceClaimStatus is stored in the PodGroupStatus for each +// PodGroupResourceClaim which references a ResourceClaimTemplate. It stores the +// generated name for the corresponding ResourceClaim. +type PodGroupResourceClaimStatus struct { + // Name uniquely identifies this resource claim inside the PodGroup. This + // must match the name of an entry in podgroup.spec.resourceClaims, which + // implies that the string must be a DNS_LABEL. + // + // +required + Name string + + // ResourceClaimName is the name of the ResourceClaim that was generated for + // the PodGroup in the namespace of the PodGroup. If this is unset, then + // generating a ResourceClaim was not necessary. The + // podgroup.spec.resourceClaims entry can be ignored in this case. + // + // +optional + ResourceClaimName *string +} + +// PodGroupTemplateReference references a PodGroup template defined in some object (e.g. Workload). +// Exactly one reference must be set. +// +union +type PodGroupTemplateReference struct { + // Workload references the PodGroupTemplate within the Workload object that was used to create + // the PodGroup. + // + // +optional + Workload *WorkloadPodGroupTemplateReference +} + +// WorkloadPodGroupTemplateReference references the PodGroupTemplate within the Workload object. +type WorkloadPodGroupTemplateReference struct { + // WorkloadName defines the name of the Workload object. + // + // +required + WorkloadName string + + // PodGroupTemplateName defines the PodGroupTemplate name within the Workload object. + // + // +required + PodGroupTemplateName string +} + +// PodGroupSchedulingConstraints defines scheduling constraints (e.g. topology) for a PodGroup. +type PodGroupSchedulingConstraints struct { + // Topology defines the topology constraints for the pod group. + // Currently only a single topology constraint can be specified. This may change in the future. + // + // +optional + // +listType=atomic + Topology []TopologyConstraint +} + +// TopologyConstraint defines a topology constraint for a PodGroup. +type TopologyConstraint struct { + // Key specifies the key of the node label representing the topology domain. + // All pods within the PodGroup must be colocated within the same domain instance. + // Different PodGroups can land on different domain instances even if they derive from the same PodGroupTemplate. + // Examples: "topology.kubernetes.io/rack" + // + // +required + Key string +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/zz_generated.deepcopy.go index 853afd8c1c..636a9590ae 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/scheduling/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/scheduling/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ limitations under the License. package scheduling import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" core "k8s.io/kubernetes/pkg/apis/core" ) @@ -61,7 +62,10 @@ func (in *GangSchedulingPolicy) DeepCopy() *GangSchedulingPolicy { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodGroup) DeepCopyInto(out *PodGroup) { *out = *in - in.Policy.DeepCopyInto(&out.Policy) + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -75,8 +79,117 @@ func (in *PodGroup) DeepCopy() *PodGroup { return out } +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodGroup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupList) DeepCopyInto(out *PodGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupList. +func (in *PodGroupList) DeepCopy() *PodGroupList { + if in == nil { + return nil + } + out := new(PodGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodGroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupResourceClaim) DeepCopyInto(out *PodGroupResourceClaim) { + *out = *in + if in.ResourceClaimName != nil { + in, out := &in.ResourceClaimName, &out.ResourceClaimName + *out = new(string) + **out = **in + } + if in.ResourceClaimTemplateName != nil { + in, out := &in.ResourceClaimTemplateName, &out.ResourceClaimTemplateName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupResourceClaim. +func (in *PodGroupResourceClaim) DeepCopy() *PodGroupResourceClaim { + if in == nil { + return nil + } + out := new(PodGroupResourceClaim) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupResourceClaimStatus) DeepCopyInto(out *PodGroupResourceClaimStatus) { + *out = *in + if in.ResourceClaimName != nil { + in, out := &in.ResourceClaimName, &out.ResourceClaimName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupResourceClaimStatus. +func (in *PodGroupResourceClaimStatus) DeepCopy() *PodGroupResourceClaimStatus { + if in == nil { + return nil + } + out := new(PodGroupResourceClaimStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupSchedulingConstraints) DeepCopyInto(out *PodGroupSchedulingConstraints) { + *out = *in + if in.Topology != nil { + in, out := &in.Topology, &out.Topology + *out = make([]TopologyConstraint, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSchedulingConstraints. +func (in *PodGroupSchedulingConstraints) DeepCopy() *PodGroupSchedulingConstraints { + if in == nil { + return nil + } + out := new(PodGroupSchedulingConstraints) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodGroupPolicy) DeepCopyInto(out *PodGroupPolicy) { +func (in *PodGroupSchedulingPolicy) DeepCopyInto(out *PodGroupSchedulingPolicy) { *out = *in if in.Basic != nil { in, out := &in.Basic, &out.Basic @@ -91,12 +204,146 @@ func (in *PodGroupPolicy) DeepCopyInto(out *PodGroupPolicy) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupPolicy. -func (in *PodGroupPolicy) DeepCopy() *PodGroupPolicy { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSchedulingPolicy. +func (in *PodGroupSchedulingPolicy) DeepCopy() *PodGroupSchedulingPolicy { if in == nil { return nil } - out := new(PodGroupPolicy) + out := new(PodGroupSchedulingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupSpec) DeepCopyInto(out *PodGroupSpec) { + *out = *in + if in.PodGroupTemplateRef != nil { + in, out := &in.PodGroupTemplateRef, &out.PodGroupTemplateRef + *out = new(PodGroupTemplateReference) + (*in).DeepCopyInto(*out) + } + in.SchedulingPolicy.DeepCopyInto(&out.SchedulingPolicy) + if in.SchedulingConstraints != nil { + in, out := &in.SchedulingConstraints, &out.SchedulingConstraints + *out = new(PodGroupSchedulingConstraints) + (*in).DeepCopyInto(*out) + } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]PodGroupResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DisruptionMode != nil { + in, out := &in.DisruptionMode, &out.DisruptionMode + *out = new(DisruptionMode) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupSpec. +func (in *PodGroupSpec) DeepCopy() *PodGroupSpec { + if in == nil { + return nil + } + out := new(PodGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupStatus) DeepCopyInto(out *PodGroupStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ResourceClaimStatuses != nil { + in, out := &in.ResourceClaimStatuses, &out.ResourceClaimStatuses + *out = make([]PodGroupResourceClaimStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupStatus. +func (in *PodGroupStatus) DeepCopy() *PodGroupStatus { + if in == nil { + return nil + } + out := new(PodGroupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupTemplate) DeepCopyInto(out *PodGroupTemplate) { + *out = *in + in.SchedulingPolicy.DeepCopyInto(&out.SchedulingPolicy) + if in.SchedulingConstraints != nil { + in, out := &in.SchedulingConstraints, &out.SchedulingConstraints + *out = new(PodGroupSchedulingConstraints) + (*in).DeepCopyInto(*out) + } + if in.ResourceClaims != nil { + in, out := &in.ResourceClaims, &out.ResourceClaims + *out = make([]PodGroupResourceClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DisruptionMode != nil { + in, out := &in.DisruptionMode, &out.DisruptionMode + *out = new(DisruptionMode) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupTemplate. +func (in *PodGroupTemplate) DeepCopy() *PodGroupTemplate { + if in == nil { + return nil + } + out := new(PodGroupTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodGroupTemplateReference) DeepCopyInto(out *PodGroupTemplateReference) { + *out = *in + if in.Workload != nil { + in, out := &in.Workload, &out.Workload + *out = new(WorkloadPodGroupTemplateReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodGroupTemplateReference. +func (in *PodGroupTemplateReference) DeepCopy() *PodGroupTemplateReference { + if in == nil { + return nil + } + out := new(PodGroupTemplateReference) in.DeepCopyInto(out) return out } @@ -165,6 +412,22 @@ func (in *PriorityClassList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyConstraint) DeepCopyInto(out *TopologyConstraint) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyConstraint. +func (in *TopologyConstraint) DeepCopy() *TopologyConstraint { + if in == nil { + return nil + } + out := new(TopologyConstraint) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TypedLocalObjectReference) DeepCopyInto(out *TypedLocalObjectReference) { *out = *in @@ -241,6 +504,22 @@ func (in *WorkloadList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadPodGroupTemplateReference) DeepCopyInto(out *WorkloadPodGroupTemplateReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadPodGroupTemplateReference. +func (in *WorkloadPodGroupTemplateReference) DeepCopy() *WorkloadPodGroupTemplateReference { + if in == nil { + return nil + } + out := new(WorkloadPodGroupTemplateReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WorkloadSpec) DeepCopyInto(out *WorkloadSpec) { *out = *in @@ -249,9 +528,9 @@ func (in *WorkloadSpec) DeepCopyInto(out *WorkloadSpec) { *out = new(TypedLocalObjectReference) **out = **in } - if in.PodGroups != nil { - in, out := &in.PodGroups, &out.PodGroups - *out = make([]PodGroup, len(*in)) + if in.PodGroupTemplates != nil { + in, out := &in.PodGroupTemplates, &out.PodGroupTemplates + *out = make([]PodGroupTemplate, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go index c6c3b31f0d..dd5268ae5a 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go @@ -482,6 +482,7 @@ type PodControlInterface interface { type RealPodControl struct { KubeClient clientset.Interface Recorder record.EventRecorder + OnWrite func(*v1.Pod, *metav1.OwnerReference) } var _ PodControlInterface = &RealPodControl{} @@ -551,11 +552,15 @@ func (r RealPodControl) CreatePodsWithGenerateName(ctx context.Context, namespac if len(generateName) > 0 { pod.ObjectMeta.GenerateName = generateName } - return r.createPods(ctx, namespace, pod, controllerObject) + return r.createPods(ctx, namespace, pod, controllerObject, controllerRef) } func (r RealPodControl) PatchPod(ctx context.Context, namespace, name string, data []byte) error { - _, err := r.KubeClient.CoreV1().Pods(namespace).Patch(ctx, name, types.StrategicMergePatchType, data, metav1.PatchOptions{}) + pod, err := r.KubeClient.CoreV1().Pods(namespace).Patch(ctx, name, types.StrategicMergePatchType, data, metav1.PatchOptions{}) + if err == nil && r.OnWrite != nil { + ownerRef := metav1.GetControllerOfNoCopy(pod) + r.OnWrite(pod, ownerRef) + } return err } @@ -584,7 +589,7 @@ func GetPodFromTemplate(template *v1.PodTemplateSpec, parentObject runtime.Objec return pod, nil } -func (r RealPodControl) createPods(ctx context.Context, namespace string, pod *v1.Pod, object runtime.Object) error { +func (r RealPodControl) createPods(ctx context.Context, namespace string, pod *v1.Pod, object runtime.Object, controllerRef *metav1.OwnerReference) error { if len(labels.Set(pod.Labels)) == 0 { return fmt.Errorf("unable to create pods, no labels") } @@ -597,6 +602,9 @@ func (r RealPodControl) createPods(ctx context.Context, namespace string, pod *v return err } logger := klog.FromContext(ctx) + if r.OnWrite != nil { + r.OnWrite(newPod, controllerRef) + } accessor, err := meta.Accessor(object) if err != nil { logger.Error(err, "parentObject does not have ObjectMeta") diff --git a/vendor/k8s.io/kubernetes/pkg/controller/daemon/daemon_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/daemon/daemon_controller.go index 5bcf013020..eed0b5b16a 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/daemon/daemon_controller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/daemon/daemon_controller.go @@ -18,6 +18,7 @@ package daemon import ( "context" + "errors" "fmt" "reflect" "sort" @@ -30,6 +31,8 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" @@ -51,7 +54,9 @@ import ( "k8s.io/klog/v2" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/controller/daemon/metrics" "k8s.io/kubernetes/pkg/controller/daemon/util" + consistencyutil "k8s.io/kubernetes/pkg/controller/util/consistency" "k8s.io/kubernetes/pkg/features" ) @@ -79,6 +84,17 @@ const ( SucceededDaemonPodReason = "SucceededDaemonPod" ) +var ( + daemonsetGroupResource = schema.GroupResource{ + Group: "apps", + Resource: "daemonsets", + } + podGroupResource = schema.GroupResource{ + Group: "", + Resource: "pods", + } +) + // controllerKind contains the schema.GroupVersionKind for this controller type. var controllerKind = apps.SchemeGroupVersion.WithKind("DaemonSet") @@ -140,6 +156,8 @@ type DaemonSetsController struct { nodeUpdateQueue workqueue.TypedRateLimitingInterface[string] failedPodsBackoff *flowcontrol.Backoff + + consistencyStore consistencyutil.ConsistencyStore } // NewDaemonSetsController creates a new DaemonSetsController @@ -154,6 +172,31 @@ func NewDaemonSetsController( ) (*DaemonSetsController, error) { eventBroadcaster := record.NewBroadcaster(record.WithContext(ctx)) logger := klog.FromContext(ctx) + var consistencyStore consistencyutil.ConsistencyStore + var podWriteCallback func(pod *v1.Pod, ds *metav1.OwnerReference) + if utilfeature.DefaultFeatureGate.Enabled(features.StaleControllerConsistencyDaemonSet) { + consistencyStore = consistencyutil.NewConsistencyStore(map[schema.GroupResource]consistencyutil.LastSyncRVGetter{ + podGroupResource: podInformer.Informer().GetStore(), + daemonsetGroupResource: daemonSetInformer.Informer().GetStore(), + }) + podWriteCallback = func(pod *v1.Pod, ds *metav1.OwnerReference) { + if ds == nil { + return + } + consistencyStore.WroteAt( + types.NamespacedName{ + Namespace: pod.Namespace, + Name: ds.Name, + }, + ds.UID, + podGroupResource, + pod.ResourceVersion, + ) + } + } else { + consistencyStore = consistencyutil.NewNoopConsistencyStore() + } + dsc := &DaemonSetsController{ kubeClient: kubeClient, eventBroadcaster: eventBroadcaster, @@ -161,7 +204,9 @@ func NewDaemonSetsController( podControl: controller.RealPodControl{ KubeClient: kubeClient, Recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "daemonset-controller"}), + OnWrite: podWriteCallback, }, + crControl: controller.RealControllerRevisionControl{ KubeClient: kubeClient, }, @@ -179,6 +224,7 @@ func NewDaemonSetsController( Name: "daemonset-node-updates", }, ), + consistencyStore: consistencyStore, } daemonSetInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ @@ -211,6 +257,7 @@ func NewDaemonSetsController( // Watch for creation/deletion of pods. The reason we watch is that we don't want a daemon set to create/delete // more pods until all the effects (expectations) of a daemon set's create/delete have been observed. + podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { dsc.addPod(logger, obj) @@ -245,6 +292,7 @@ func NewDaemonSetsController( dsc.failedPodsBackoff = failedPodsBackoff + metrics.Register() return dsc, nil } @@ -296,6 +344,13 @@ func (dsc *DaemonSetsController) deleteDaemonset(logger klog.Logger, obj interfa utilruntime.HandleError(fmt.Errorf("couldn't get key for object %#v: %v", ds, err)) return } + dsc.consistencyStore.Clear( + types.NamespacedName{ + Name: ds.Name, + Namespace: ds.Namespace, + }, + ds.UID, + ) // Delete expectations for the DaemonSet so if we create a new one with the same name it starts clean dsc.expectations.DeleteExpectations(logger, key) @@ -842,13 +897,13 @@ func (dsc *DaemonSetsController) podsShouldBeOnNode( msg := fmt.Sprintf("Found failed daemon pod %s/%s on node %s, will try to kill it", pod.Namespace, pod.Name, node.Name) logger.V(2).Info("Found failed daemon pod on node, will try to kill it", "pod", klog.KObj(pod), "node", klog.KObj(node)) // Emit an event so that it's discoverable to users. - dsc.eventRecorder.Eventf(ds, v1.EventTypeWarning, FailedDaemonPodReason, msg) + dsc.eventRecorder.Eventf(ds, v1.EventTypeWarning, FailedDaemonPodReason, "%s", msg) podsToDelete = append(podsToDelete, pod.Name) } else if pod.Status.Phase == v1.PodSucceeded { msg := fmt.Sprintf("Found succeeded daemon pod %s/%s on node %s, will try to delete it", pod.Namespace, pod.Name, node.Name) logger.V(2).Info("Found succeeded daemon pod on node, will try to delete it", "pod", klog.KObj(pod), "node", klog.KObj(node)) // Emit an event so that it's discoverable to users. - dsc.eventRecorder.Eventf(ds, v1.EventTypeNormal, SucceededDaemonPodReason, msg) + dsc.eventRecorder.Eventf(ds, v1.EventTypeNormal, SucceededDaemonPodReason, "%s", msg) podsToDelete = append(podsToDelete, pod.Name) } else { daemonPodsRunning = append(daemonPodsRunning, pod) @@ -1106,7 +1161,7 @@ func storeDaemonSetStatus( updatedNumberScheduled, numberAvailable, numberUnavailable int, - updateObservedGen bool) error { + updateObservedGen bool) (*apps.DaemonSet, error) { if int(ds.Status.DesiredNumberScheduled) == desiredNumberScheduled && int(ds.Status.CurrentNumberScheduled) == currentNumberScheduled && int(ds.Status.NumberMisscheduled) == numberMisscheduled && @@ -1115,7 +1170,7 @@ func storeDaemonSetStatus( int(ds.Status.NumberAvailable) == numberAvailable && int(ds.Status.NumberUnavailable) == numberUnavailable && ds.Status.ObservedGeneration >= ds.Generation { - return nil + return nil, nil } toUpdate := ds.DeepCopy() @@ -1133,8 +1188,9 @@ func storeDaemonSetStatus( toUpdate.Status.NumberAvailable = int32(numberAvailable) toUpdate.Status.NumberUnavailable = int32(numberUnavailable) - if _, updateErr = dsClient.UpdateStatus(ctx, toUpdate, metav1.UpdateOptions{}); updateErr == nil { - return nil + var result *apps.DaemonSet + if result, updateErr = dsClient.UpdateStatus(ctx, toUpdate, metav1.UpdateOptions{}); updateErr == nil { + return result, nil } // Stop retrying if we exceed statusUpdateRetries - the DaemonSet will be requeued with a rate limit. @@ -1145,10 +1201,10 @@ func storeDaemonSetStatus( if toUpdate, getErr = dsClient.Get(ctx, ds.Name, metav1.GetOptions{}); getErr != nil { // If the GET fails we can't trust status.Replicas anymore. This error // is bound to be more interesting than the update failure. - return getErr + return nil, getErr } } - return updateErr + return nil, updateErr } func (dsc *DaemonSetsController) updateDaemonSetStatus(ctx context.Context, ds *apps.DaemonSet, nodeList []*v1.Node, hash string, updateObservedGen bool) error { @@ -1199,10 +1255,18 @@ func (dsc *DaemonSetsController) updateDaemonSetStatus(ctx context.Context, ds * } numberUnavailable := desiredNumberScheduled - numberAvailable - err = storeDaemonSetStatus(ctx, dsc.kubeClient.AppsV1().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable, updateObservedGen) + updatedDS, err := storeDaemonSetStatus(ctx, dsc.kubeClient.AppsV1().DaemonSets(ds.Namespace), ds, desiredNumberScheduled, currentNumberScheduled, numberMisscheduled, numberReady, updatedNumberScheduled, numberAvailable, numberUnavailable, updateObservedGen) if err != nil { return fmt.Errorf("error storing status for daemon set %#v: %w", ds, err) } + if updatedDS != nil { + dsc.consistencyStore.WroteAt( + types.NamespacedName{Name: ds.Name, Namespace: ds.Namespace}, + updatedDS.UID, + daemonsetGroupResource, + updatedDS.ResourceVersion, + ) + } // Resync the DaemonSet after MinReadySeconds as a last line of defense to guard against clock-skew. if ds.Spec.MinReadySeconds > 0 && numberReady != numberAvailable { @@ -1223,10 +1287,31 @@ func (dsc *DaemonSetsController) syncDaemonSet(ctx context.Context, key string) if err != nil { return err } + + dsNamespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + + // If our writes have not yet been observed by our informers, we should not + // continue since our reads will not be in sync with our previously enacted + // state. + if err := dsc.consistencyStore.EnsureReady(dsNamespacedName); err != nil { + var consistencyErr *consistencyutil.ConsistencyError + if errors.As(err, &consistencyErr) { + metrics.DaemonsetRequeueSkips.WithLabelValues( + consistencyErr.GroupResource.Group, + consistencyErr.GroupResource.Resource, + ).Inc() + } + return err + } + ds, err := dsc.dsLister.DaemonSets(namespace).Get(name) if apierrors.IsNotFound(err) { logger.V(3).Info("Daemon set has been deleted", "daemonset", key) dsc.expectations.DeleteExpectations(logger, key) + dsc.consistencyStore.Clear(dsNamespacedName, "") return nil } if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/controller/daemon/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/controller/daemon/metrics/metrics.go new file mode 100644 index 0000000000..ba76c76443 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/daemon/metrics/metrics.go @@ -0,0 +1,48 @@ +/* +Copyright 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 metrics + +import ( + "sync" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const DaemonControllerSubsystem = "daemonset_controller" + +var ( + DaemonsetRequeueSkips = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: DaemonControllerSubsystem, + Name: "stale_sync_skips_total", + Help: "Total number of DaemonSet syncs skipped due to a stale watch cache.", + StabilityLevel: metrics.ALPHA, + }, + // These are the labels (dimensions) + []string{"group", "resource"}, + ) +) + +var registerMetrics sync.Once + +// Register registers DaemonSet Controller metrics. +func Register() { + registerMetrics.Do(func() { + legacyregistry.MustRegister(DaemonsetRequeueSkips) + }) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/util/consistency/consistency.go b/vendor/k8s.io/kubernetes/pkg/controller/util/consistency/consistency.go new file mode 100644 index 0000000000..7c727fb21b --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/util/consistency/consistency.go @@ -0,0 +1,217 @@ +/* +Copyright 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 consistency + +import ( + "fmt" + "sync" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/resourceversion" +) + +type ConsistencyStore interface { + // WroteAt records a written RV for an owned resource. + WroteAt(owner types.NamespacedName, ownerUID types.UID, resource schema.GroupResource, rv string) + // Clear wipes the owner if the UID matches, if left empty it will wipe no + // matter what the UID is. + Clear(owner types.NamespacedName, ownerUID types.UID) + // EnsureReady queries the ConsistencyStore to check whether or not the + // stores records are up to date, returning an error if they are not. + EnsureReady(owner types.NamespacedName) error +} + +// ConsistencyError is an error type returned by EnsureReady with information +// about the resource versions and GroupKind that caused the error. +type ConsistencyError struct { + ReadRV string + WroteRV string + GroupResource schema.GroupResource +} + +func (c *ConsistencyError) Error() string { + return fmt.Sprintf("read version: %s is not as new as written version: %s for group resource %s", c.ReadRV, c.WroteRV, c.GroupResource.String()) +} + +var _ ConsistencyStore = &RealConsistencyStore{} + +type LastSyncRVGetter interface { + LastStoreSyncResourceVersion() string +} + +type RealConsistencyStore struct { + // writesLock guards reads/additions/deletions to the writes map. + // individual records are responsible for managing their own thread safety. + writesLock sync.RWMutex + // writes is a map of owner -> ownerRecord + writes map[types.NamespacedName]*ownerRecord + + stores map[schema.GroupResource]LastSyncRVGetter +} + +func NewConsistencyStore(stores map[schema.GroupResource]LastSyncRVGetter) *RealConsistencyStore { + return &RealConsistencyStore{ + writes: map[types.NamespacedName]*ownerRecord{}, + stores: stores, + } +} + +// getWrittenRecord returns the record for the given owner, or nil if no record exists. +func (c *RealConsistencyStore) getWrittenRecord(owner types.NamespacedName) *ownerRecord { + c.writesLock.RLock() + defer c.writesLock.RUnlock() + return c.writes[owner] +} + +// ensureWrittenRecord returns a ownerRecord for the given owner and ownerUID. +// If there is no current record, one is created. +// If there is a current record with a different ownerUID, it is replaced with an empty record for the specified ownerUID. +func (c *RealConsistencyStore) ensureWrittenRecord(owner types.NamespacedName, ownerUID types.UID) *ownerRecord { + // fast path, already exists + if record := c.getWrittenRecord(owner); record != nil && record.ownerUID == ownerUID { + return record + } + + // slow path, init + c.writesLock.Lock() + defer c.writesLock.Unlock() + // check again after write lock + if record := c.writes[owner]; record != nil && record.ownerUID == ownerUID { + return record + } + // initialize to the given uid + record := newOwnerRecord(ownerUID) + c.writes[owner] = record + return record +} + +// WroteAt writes the latest written RV if it is greater than the currently +// written RV for the owner. +func (c *RealConsistencyStore) WroteAt(owner types.NamespacedName, ownerUID types.UID, resource schema.GroupResource, rv string) { + c.ensureWrittenRecord(owner, ownerUID).WroteAt(resource, rv) +} + +// Clear deletes the record for owner if it exists and matches the specified +// ownerUID (or the specified ownerUID is empty) +func (c *RealConsistencyStore) Clear(owner types.NamespacedName, ownerUID types.UID) { + // deleted owners typically have an existing record, not worth checking the fast path for missing records + c.writesLock.Lock() + defer c.writesLock.Unlock() + if record := c.writes[owner]; record != nil && (len(ownerUID) == 0 || record.ownerUID == ownerUID) { + delete(c.writes, owner) + } +} + +// EnsureReady returns nil if observed resource versions are at least as new as +// any recorded versions for the given owner, otherwise returning the error of +// what happened. Must not be called concurrent with WroteAt for the same owner. +func (c *RealConsistencyStore) EnsureReady(owner types.NamespacedName) error { + record := c.getWrittenRecord(owner) + if record == nil { + return nil + } + err := record.EnsureReady(c) + if err == nil { + c.Clear(owner, record.ownerUID) + return nil + } + return err +} + +type ownerRecord struct { + // ownerUID must not be mutated after creation + ownerUID types.UID + + versionsLock sync.Mutex + versions map[schema.GroupResource]string +} + +func newOwnerRecord(ownerUID types.UID) *ownerRecord { + return &ownerRecord{ownerUID: ownerUID, versions: map[schema.GroupResource]string{}} +} + +// WroteAt increments the written resource version of an ownerRecord if it is +// the newest seen resource version for that resource. +func (w *ownerRecord) WroteAt(resource schema.GroupResource, rv string) { + w.versionsLock.Lock() + defer w.versionsLock.Unlock() + if _, ok := w.versions[resource]; !ok { + w.versions[resource] = rv + return + } + cmp, err := resourceversion.CompareResourceVersion(w.versions[resource], rv) + if err == nil && cmp >= 0 { + return + } + w.versions[resource] = rv +} + +// EnsureReady checks whether or not the ownerRecord is ready compared to the +// read resource versions in the consistency store. +func (w *ownerRecord) EnsureReady(c *RealConsistencyStore) error { + w.versionsLock.Lock() + defer w.versionsLock.Unlock() + for gr, wroteRV := range w.versions { + store, exists := c.stores[gr] + if !exists || store == nil { + continue + } + readRV := store.LastStoreSyncResourceVersion() + if readRV == "" { + // Since we wait for the store to be ready, the only time "" is if the + // LastStoreSyncResourceVersion() feature is not enabled. + continue + } + i, err := resourceversion.CompareResourceVersion(wroteRV, readRV) + if err != nil { + // comparison errors indicate there's a data problem with resource versions, continue so we don't block syncing + continue + } + if i > 0 { + // read version is not as new as owner version, not ready + return &ConsistencyError{ + WroteRV: wroteRV, + ReadRV: readRV, + GroupResource: gr, + } + } + } + return nil +} + +// NoopConsistencyStore is a consistency store that stores nothing and always +// returns IsReady as true. To be used when the associated feature gate is not +// enabled. +type NoopConsistencyStore struct{} + +var _ ConsistencyStore = &NoopConsistencyStore{} + +func (*NoopConsistencyStore) WroteAt(owner types.NamespacedName, ownerUID types.UID, resource schema.GroupResource, rv string) { +} + +func (*NoopConsistencyStore) ReadAt(resource schema.GroupResource, rv string) {} + +func (*NoopConsistencyStore) Clear(owner types.NamespacedName, ownerUID types.UID) {} + +func (*NoopConsistencyStore) EnsureReady(owner types.NamespacedName) error { + return nil +} + +func NewNoopConsistencyStore() *NoopConsistencyStore { + return &NoopConsistencyStore{} +} diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go index 5a6ee84351..1a9de05efc 100644 --- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go @@ -56,6 +56,14 @@ const ( // Allow spec.terminationGracePeriodSeconds to be overridden by MaxPodGracePeriodSeconds in soft evictions. AllowOverwriteTerminationGracePeriodSeconds featuregate.Feature = "AllowOverwriteTerminationGracePeriodSeconds" + // owner: @adrianmoisey + // kep: https://kep.k8s.io/5707 + // + // When enabled, kube-proxy will program iptables/nftables/ipvs rules for Service.spec.externalIPs. + // When disabled, kube-proxy will not program rules for externalIPs, effectively disabling this + // deprecated feature. + AllowServiceExternalIPs featuregate.Feature = "AllowServiceExternalIPs" + // owner: @bswartz // // Enables usage of any object for volume data source in PVCs @@ -110,11 +118,11 @@ const ( // Allow the usage of options to fine-tune the cpumanager policies. CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions" - // owner: @trierra - // kep: http://kep.k8s.io/2589 + // owner: @bitoku + // kep: https://kep.k8s.io/5825 // - // Enables the Portworx in-tree driver to Portworx migration feature. - CSIMigrationPortworx featuregate.Feature = "CSIMigrationPortworx" + // Enables using streaming RPCs for CRI list operations. + CRIListStreaming featuregate.Feature = "CRIListStreaming" // owner: @aramase // kep: http://kep.k8s.io/5538 @@ -131,7 +139,7 @@ const ( // owner: @HirazawaUi // // Enabling this feature gate will cause the pod's status to change due to a kubelet restart. - ChangeContainerStatusOnKubeletRestart = "ChangeContainerStatusOnKubeletRestart" + ChangeContainerStatusOnKubeletRestart featuregate.Feature = "ChangeContainerStatusOnKubeletRestart" // owner: @sanposhiho @wojtek-t // kep: https://kep.k8s.io/5278 @@ -188,6 +196,7 @@ const ( // depending on the DRA driver, may enable additional permissions // when a container uses the allocated device. DRAAdminAccess featuregate.Feature = "DRAAdminAccess" + // owner: @sunya-ch // kep: https://kep.k8s.io/5075 // @@ -224,6 +233,20 @@ const ( // Enables support for providing extended resource requests backed by DRA. DRAExtendedResource featuregate.Feature = "DRAExtendedResource" + // owner: @everpeace + // kep: http://kep.k8s.io/5491 + // + // Enable list type attributes for DRA devices in ResourceSlice + // and extends ResourceClaim's matchAttribute/distinctAttribute + // semantics so that they can work with list type attributes. + DRAListTypeAttributes featuregate.Feature = "DRAListTypeAttributes" + + // owner: @pravk03 + // kep: https://kep.k8s.io/5517 + // + // Enables support for node allocatable resources backed by DRA. + DRANodeAllocatableResources featuregate.Feature = "DRANodeAllocatableResources" + // owner: @mortent, @cici37 // kep: http://kep.k8s.io/4815 // @@ -247,6 +270,23 @@ const ( // status from DRA drivers. DRAResourceClaimDeviceStatus featuregate.Feature = "DRAResourceClaimDeviceStatus" + // owner: @aojea + // kep: http://kep.k8s.io/4817 + // + // Enables fine-grained authorization checks for ResourceClaim status updates. + // Requires separate permission on resourceclaims/binding to update + // status.allocation and status.reservedFor, and per-driver permission on + // resourceclaims/driver using associated-node / arbitrary-node verb prefixes + // to update status.devices. + DRAResourceClaimGranularStatusAuthorization featuregate.Feature = "DRAResourceClaimGranularStatusAuthorization" + + // owner: @nmn3m + // kep: http://kep.k8s.io/5677 + // + // Enables ResourcePoolStatusRequest API for querying DRA resource pool + // availability status. + DRAResourcePoolStatus featuregate.Feature = "DRAResourcePoolStatus" + // owner: @pohly // kep: http://kep.k8s.io/4381 // @@ -255,6 +295,12 @@ const ( // scheduler plugin configuration). DRASchedulerFilterTimeout featuregate.Feature = "DRASchedulerFilterTimeout" + // owner: @nojnhuh + // kep: https://kep.k8s.io/5729 + // + // Enables support for reserving and replicating templated ResourceClaims for an entire PodGroup. + DRAWorkloadResourceClaims featuregate.Feature = "DRAWorkloadResourceClaims" + // owner: @atiratree // kep: http://kep.k8s.io/3973 // @@ -321,6 +367,13 @@ const ( // Locked to default, will remove in v1.38. Progress is reflected in KEP #1972 update ExecProbeTimeout featuregate.Feature = "ExecProbeTimeout" + // owner: @seans3 + // kep: http://kep.k8s.io/4006 + // + // Enables the API server to proxy websockets to the kubelet for exec/attach + // if the kubelet has advertised that it supports them. + ExtendWebSocketsToKubelet featuregate.Feature = "ExtendWebSocketsToKubelet" + // owner: @HarshalNeelkamal // // Enables external service account JWT signing and key management. @@ -358,18 +411,12 @@ const ( // Enables support of configurable HPA scale-up and scale-down tolerances. HPAConfigurableTolerance featuregate.Feature = "HPAConfigurableTolerance" - // owner: @dxist + // owner: @johanneswuerbach + // kep: https://kep.k8s.io/2021 // // Enables support of HPA scaling to zero pods when an object or custom metric is configured. HPAScaleToZero featuregate.Feature = "HPAScaleToZero" - // owner: @deepakkinni @xing-yang - // kep: https://kep.k8s.io/2644 - // - // Honor Persistent Volume Reclaim Policy when it is "Delete" irrespective of PV-PVC - // deletion ordering. - HonorPVReclaimPolicy featuregate.Feature = "HonorPVReclaimPolicy" - // owner: @HirazawaUi // kep: https://kep.k8s.io/4762 // @@ -388,6 +435,12 @@ const ( // Enables the image volume source. ImageVolume featuregate.Feature = "ImageVolume" + // owner: @iholder101 + // kep: https://kep.k8s.io/4639 + // + // Enables adding the ImageVolume's digest to the pod's status. + ImageVolumeWithDigest featuregate.Feature = "ImageVolumeWithDigest" + // owner: @ndixita // kep: https://kep.k8s.io/5419 // @@ -400,14 +453,6 @@ const ( // Enables In-Place Pod Vertical Scaling InPlacePodVerticalScaling featuregate.Feature = "InPlacePodVerticalScaling" - // owner: @tallclair - // kep: http://kep.k8s.io/1287 - // - // Deprecated: This feature gate is no longer used. - // Was: Enables the AllocatedResources field in container status. This feature requires - // InPlacePodVerticalScaling also be enabled. - InPlacePodVerticalScalingAllocatedStatus featuregate.Feature = "InPlacePodVerticalScalingAllocatedStatus" - // owner: @tallclair @esotsal // // Allow resource resize for containers in Guaranteed pods with integer CPU requests ( default false ). @@ -421,10 +466,10 @@ const ( // Applies only in nodes with InPlacePodVerticalScaling and Memory Manager features enabled. InPlacePodVerticalScalingExclusiveMemory featuregate.Feature = "InPlacePodVerticalScalingExclusiveMemory" - // owner: @trierra + // owner: @natasha41575 // - // Disables the Portworx in-tree driver. - InTreePluginPortworxUnregister featuregate.Feature = "InTreePluginPortworxUnregister" + // Allow in-place pod resize of running non-sidecar init containers. + InPlacePodVerticalScalingInitContainers featuregate.Feature = "InPlacePodVerticalScalingInitContainers" // owner: @mimowo // kep: https://kep.k8s.io/3850 @@ -588,11 +633,6 @@ const ( // Enables maxUnavailable for StatefulSet MaxUnavailableStatefulSet featuregate.Feature = "MaxUnavailableStatefulSet" - // owner: @cynepco3hahue(alukiano) @cezaryzukowski @k-wiatrzyk, @Tal-or (only for GA graduation) - // - // Allows setting memory affinity for a container based on NUMA topology - MemoryManager featuregate.Feature = "MemoryManager" - // owner: @xiaoxubeii // kep: https://kep.k8s.io/2570 // @@ -685,6 +725,17 @@ const ( // Enables ordered namespace deletion. OrderedNamespaceDeletion featuregate.Feature = "OrderedNamespaceDeletion" + // owner: @tallclair + // + // Enables relisting individual pods on-demand. + PLEGOnDemandRelist featuregate.Feature = "PLEGOnDemandRelist" + + // owner: @ArvindParekh + // kep: https://kep.k8s.io/5541 + // + // Adds an Unused condition to PersistentVolumeClaim status that indicates when the PVC was last used by a pod. + PersistentVolumeClaimUnusedSinceTime featuregate.Feature = "PersistentVolumeClaimUnusedSinceTime" + // owner: @haircommander // kep: https://kep.k8s.io/2364 // @@ -703,6 +754,13 @@ const ( // Enables controlling pod ranking on replicaset scale-down. PodDeletionCost featuregate.Feature = "PodDeletionCost" + // owner: @KevinTMtz + // kep: https://kep.k8s.io/5526 + // + // PodLevelResourceManagers enables pod-level resource management in the Topology, CPU, and Memory managers. + // This feature depends on the PodLevelResources feature. + PodLevelResourceManagers featuregate.Feature = "PodLevelResourceManagers" + // owner: @ndixita // key: https://kep.k8s.io/2837 // @@ -760,6 +818,12 @@ const ( // similar to how `metadata.annotations` behaves. PodTopologyLabelsAdmission featuregate.Feature = "PodTopologyLabelsAdmission" + // owner: @briansonnenberg + // kep: https://kep.k8s.io/4188 + // + // Enables the PodsAPI feature to expose pod information via a gRPC API on the kubelet. + PodsAPI featuregate.Feature = "PodsAPI" + // owner: @seans3 // kep: http://kep.k8s.io/4006 // @@ -825,6 +889,11 @@ const ( // Relaxed DNS search string validation. RelaxedServiceNameValidation featuregate.Feature = "RelaxedServiceNameValidation" + // owner: @harshaln + // + // Enables running kubelet in a configuration that monitors and loads ClientCA from file paths + ReloadKubeletClientCAFile = "ReloadKubeletClientCAFile" + // owner: @zhangweikop // // Enable kubelet tls server to update certificate if the specified certificate files are changed. @@ -838,6 +907,12 @@ const ( // Adds the AllocatedResourcesStatus to the container status. ResourceHealthStatus featuregate.Feature = "ResourceHealthStatus" + // owner: @SergeyKanzhelev + // kep: https://kep.k8s.io/4680 + // + // Adds a message to the AllocatedResourcesStatus entries. + ResourceHealthStatusMessage featuregate.Feature = "ResourceHealthStatusMessage" + // owner: @yuanwang04 // kep: https://kep.k8s.io/5532 // @@ -944,11 +1019,10 @@ const ( // service account tokens bound to Pod objects. ServiceAccountTokenPodNodeInfo featuregate.Feature = "ServiceAccountTokenPodNodeInfo" - // owner: @gauravkghildiyal @robscott - // kep: https://kep.k8s.io/4444 + // owner: @jpbetz // - // Enables trafficDistribution field on Services. - ServiceTrafficDistribution featuregate.Feature = "ServiceTrafficDistribution" + // When enabled, the apiserver ignores changes to status fields in writes to the ServiceCIDR root resource. + ServiceCIDRStatusFieldWiping featuregate.Feature = "ServiceCIDRStatusFieldWiping" // owner: @gjkim42 @SergeyKanzhelev @matthyx @tzneal // kep: http://kep.k8s.io/753 @@ -958,11 +1032,39 @@ const ( // pod's lifecycle and will not block pod termination. SidecarContainers featuregate.Feature = "SidecarContainers" + // owner: @michaelasp + // kep: http://kep.k8s.io/5647 + // + // Introduces the ability for the DaemonSet controller to be able to read its writes + // prior to running a reconcile on the same object. + StaleControllerConsistencyDaemonSet featuregate.Feature = "StaleControllerConsistencyDaemonSet" + + // owner: @michaelasp + // kep: http://kep.k8s.io/5647 + // + // Introduces the ability for the Job controller to be able to read its writes + // prior to running a reconcile on the same object. + StaleControllerConsistencyJob featuregate.Feature = "StaleControllerConsistencyJob" + + // owner: @michaelasp + // kep: http://kep.k8s.io/5647 + // + // Introduces the ability for the ReplicaSet controller to be able to read its writes + // prior to running a reconcile on the same object. + StaleControllerConsistencyReplicaSet featuregate.Feature = "StaleControllerConsistencyReplicaSet" + + // owner: @michaelasp + // kep: http://kep.k8s.io/5647 + // + // Introduces the ability for the StatefulSet controller to be able to read its writes + // prior to running a reconcile on the same object. + StaleControllerConsistencyStatefulSet featuregate.Feature = "StaleControllerConsistencyStatefulSet" + // owner: @liggitt // // Mitigates spurious statefulset rollouts due to controller revision comparison mismatches // which are not semantically significant (e.g. serialization differences or missing defaulted fields). - StatefulSetSemanticRevisionComparison = "StatefulSetSemanticRevisionComparison" + StatefulSetSemanticRevisionComparison featuregate.Feature = "StatefulSetSemanticRevisionComparison" // owner: @cupnes // kep: https://kep.k8s.io/4049 @@ -1018,11 +1120,12 @@ const ( // Enables numeric comparison operators (Lt, Gt) for tolerations to match taints with threshold-based values. TaintTolerationComparisonOperators featuregate.Feature = "TaintTolerationComparisonOperators" - // owner: @robscott - // kep: https://kep.k8s.io/2433 + // owner: @44past4 + // kep: https://kep.k8s.io/5732 // - // Enables topology aware hints for EndpointSlices - TopologyAwareHints featuregate.Feature = "TopologyAwareHints" + // Enables topology-aware workload scheduling feature in kube-scheduler and related PodGroup API fields. + // When enabled, scheduler will try various placements for a pod group and pick the best one. + TopologyAwareWorkloadScheduling featuregate.Feature = "TopologyAwareWorkloadScheduling" // owner: @PiotrProkop // kep: https://kep.k8s.io/3545 @@ -1108,6 +1211,20 @@ const ( // // Enables support for joining Windows containers to a hosts' network namespace. WindowsHostNetwork featuregate.Feature = "WindowsHostNetwork" + + // owner: @wojtek-t + // kep: https://kep.k8s.io/5710 + // + // Enables support for workload-aware preemption in pod group scheduling cycle + // and related PodGroup and Workload API fields. + WorkloadAwarePreemption featuregate.Feature = "WorkloadAwarePreemption" + + // owner: @helayoty @mm4tt @wojtek-t + // kep: https://kep.k8s.io/5547 + // + // Enables the Job controller to automatically create Workload and PodGroup + // objects for Jobs that qualify for gang scheduling. + WorkloadWithJob featuregate.Feature = "WorkloadWithJob" ) // defaultVersionedKubernetesFeatureGates consists of all known Kubernetes-specific feature keys with VersionedSpecs. @@ -1137,6 +1254,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, // remove in 1.38 }, + AllowServiceExternalIPs: { + {Version: version.MustParse("1.0"), Default: true, PreRelease: featuregate.GA}, + }, + AnyVolumeDataSource: { {Version: version.MustParse("1.18"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta}, @@ -1155,6 +1276,8 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate CPUCFSQuotaPeriod: { {Version: version.MustParse("1.12"), Default: false, PreRelease: featuregate.Alpha}, + // see https://github.com/kubernetes/kubernetes/pull/136339 for full context + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA}, // LockToDefault in 1.37, remove in 1.40 }, CPUManagerPolicyAlphaOptions: { @@ -1171,15 +1294,13 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.36 }, - CSIMigrationPortworx: { - {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta}, // On by default (requires Portworx CSI driver) - {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.36 + CRIListStreaming: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, CSIServiceAccountTokenSecrets: { {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.36; remove in 1.39 }, CSIVolumeHealth: { @@ -1227,35 +1348,51 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate DRAAdminAccess: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.36; remove in 1.39 }, DRAConsumableCapacity: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, DRADeviceBindingConditions: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, DRADeviceTaintRules: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Beta}, // Depends on an off-by-default beta API. }, DRADeviceTaints: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, DRAExtendedResource: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + DRAListTypeAttributes: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + + DRANodeAllocatableResources: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, DRAPartitionableDevices: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, DRAPrioritizedList: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA}, }, DRAResourceClaimDeviceStatus: { @@ -1263,10 +1400,22 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, }, + DRAResourceClaimGranularStatusAuthorization: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + DRAResourcePoolStatus: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + DRASchedulerFilterTimeout: { {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, }, + DRAWorkloadResourceClaims: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + DeploymentReplicaSetTerminatingReplicas: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, @@ -1281,12 +1430,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate DisableCPUQuotaWithExclusiveCPUs: { {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Deprecated}, // LockToDefault(true) in 1.37, remove in 1.38 }, DisableNodeKubeProxyVersion: { {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Deprecated}, - {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Deprecated}, // lock to default in 1.34 and remove in v1.37 + {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Deprecated}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Deprecated, LockToDefault: true}, // lock to default in 1.36 and remove in v1.39 }, DynamicResourceAllocation: { @@ -1296,6 +1447,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // TODO (https://github.com/kubernetes/kubernetes/issues/134459): remove completely in 1.38 }, + EnvFiles: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, @@ -1309,9 +1461,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.38 }, + ExtendWebSocketsToKubelet: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + ExternalServiceAccountTokenSigner: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, GangScheduling: { @@ -1325,6 +1482,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate GitRepoVolumeDriver: { {Version: version.MustParse("1.0"), Default: true, PreRelease: featuregate.GA}, {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, }, GracefulNodeShutdown: { @@ -1346,12 +1504,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.16"), Default: false, PreRelease: featuregate.Alpha}, }, - HonorPVReclaimPolicy: { - {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.36 - }, - HostnameOverride: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, @@ -1367,10 +1519,16 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.36, remove in 1.39 + }, + + ImageVolumeWithDigest: { + {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, }, InPlacePodLevelResourcesVerticalScaling: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, InPlacePodVerticalScaling: { @@ -1379,11 +1537,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.38 }, - InPlacePodVerticalScalingAllocatedStatus: { - {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, // remove in 1.36 - }, - InPlacePodVerticalScalingExclusiveCPUs: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, }, @@ -1392,8 +1545,8 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, }, - InTreePluginPortworxUnregister: { - {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha}, // remove it along with CSIMigrationPortworx in 1.36 + InPlacePodVerticalScalingInitContainers: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, JobBackoffLimitPerIndex: { @@ -1439,6 +1592,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate KubeletFineGrainedAuthz: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, KubeletInUserNamespace: { @@ -1448,16 +1602,19 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate KubeletPSI: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, KubeletPodResourcesDynamicResources: { {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.37 }, KubeletPodResourcesGet: { {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.37 }, KubeletPodResourcesListUseActivePods: { @@ -1514,13 +1671,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate MaxUnavailableStatefulSet: { {Version: version.MustParse("1.24"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, - }, - - MemoryManager: { - {Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Beta}, }, MemoryQoS: { @@ -1538,6 +1689,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.38 }, MutablePVNodeAffinity: { @@ -1546,10 +1698,12 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate MutablePodResourcesForSuspendedJobs: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, MutableSchedulingDirectivesForSuspendedJobs: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, NFTablesProxyMode: { @@ -1560,6 +1714,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate NodeDeclaredFeatures: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, NodeInclusionPolicyInPodTopologySpread: { @@ -1571,6 +1726,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate NodeLogQuery: { {Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39, locked to default in 1.36 }, NodeSwap: { @@ -1595,6 +1751,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.37 }, + PLEGOnDemandRelist: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + PersistentVolumeClaimUnusedSinceTime: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + PodAndContainerStatsFromCRI: { {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Alpha}, }, @@ -1609,6 +1773,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta}, }, + PodLevelResourceManagers: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + PodLevelResources: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, @@ -1652,6 +1820,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, }, + PodsAPI: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + PortForwardWebsockets: { {Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta}, @@ -1671,6 +1843,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.12"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39 }, QOSReserved: { @@ -1707,6 +1880,11 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate RelaxedServiceNameValidation: { {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + ReloadKubeletClientCAFile: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, ReloadKubeletServerCertificateFile: { @@ -1715,10 +1893,16 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate ResourceHealthStatus: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + ResourceHealthStatusMessage: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, RestartAllContainersOnContainerExits: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, RotateKubeletServerCertificate: { @@ -1733,6 +1917,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate SELinuxChangePolicy: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39, locked to default in 1.36 }, SELinuxMount: { @@ -1744,6 +1929,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39, locked to default in 1.36 }, SchedulerAsyncAPICalls: { @@ -1799,10 +1985,9 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, - ServiceTrafficDistribution: { - {Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.33, remove in 1.36 + ServiceCIDRStatusFieldWiping: { + {Version: version.MustParse("1.0"), Default: false, PreRelease: featuregate.GA}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Deprecated}, }, SidecarContainers: { @@ -1811,6 +1996,22 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: true, LockToDefault: true, PreRelease: featuregate.GA}, // GA in 1.33 remove in 1.36 }, + StaleControllerConsistencyDaemonSet: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + StaleControllerConsistencyJob: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + StaleControllerConsistencyReplicaSet: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + + StaleControllerConsistencyStatefulSet: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, + }, + StatefulSetSemanticRevisionComparison: { // This is a mitigation for a 1.34 regression due to serialization differences that cannot be feature-gated, // so this mitigation should not auto-disable even if emulating versions prior to 1.34 with --emulation-version. @@ -1843,6 +2044,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate StrictIPCIDRValidation: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, SupplementalGroupsPolicy: { @@ -1860,11 +2062,8 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, }, - TopologyAwareHints: { - {Version: version.MustParse("1.21"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.23"), Default: false, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.24"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + TopologyAwareWorkloadScheduling: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, TopologyManagerPolicyAlphaOptions: { @@ -1879,7 +2078,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate TopologyManagerPolicyOptions: { {Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA}, + {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.37 }, TranslateStreamCloseWebsocketRequests: { @@ -1895,12 +2094,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.39. }, VolumeAttributesClass: { {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.GA}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, VolumeLimitScaling: { @@ -1933,8 +2134,17 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, }, + WorkloadAwarePreemption: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + + WorkloadWithJob: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + apiextensionsfeatures.CRDObservedGenerationTracking: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, apiextensionsfeatures.CRDValidationRatcheting: { @@ -2016,6 +2226,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate genericfeatures.ConstrainedImpersonation: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, genericfeatures.CoordinatedLeaderElection: { @@ -2025,10 +2236,16 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate genericfeatures.DeclarativeValidation: { {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.36, remove in 1.39 + }, + + genericfeatures.DeclarativeValidationBeta: { + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, genericfeatures.DeclarativeValidationTakeover: { {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Deprecated}, }, genericfeatures.DetectCacheInconsistency: { @@ -2046,9 +2263,14 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, }, + genericfeatures.ManifestBasedAdmissionControlConfig: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, + }, + genericfeatures.MutatingAdmissionPolicy: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA}, }, genericfeatures.OpenAPIEnums: { @@ -2075,6 +2297,11 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate genericfeatures.SeparateCacheWatchRPC: { {Version: version.MustParse("1.28"), Default: true, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, + {Version: version.MustParse("1.36"), Default: false, LockToDefault: true, PreRelease: featuregate.Deprecated}, + }, + + genericfeatures.ShardedListAndWatch: { + {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, genericfeatures.SizeBasedListCostEstimate: { @@ -2104,12 +2331,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.Beta}, }, - genericfeatures.StructuredAuthorizationConfiguration: { - {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha}, - {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - }, - genericfeatures.TokenRequestServiceAccountUIDValidation: { {Version: version.MustParse("1.34"), Default: true, PreRelease: featuregate.Beta}, }, @@ -2121,15 +2342,12 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate genericfeatures.UnknownVersionInteroperabilityProxy: { {Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, genericfeatures.WatchCacheInitializationPostStartHook: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta}, - }, - - genericfeatures.WatchFromStorageWithoutResourceVersion: { - {Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Beta}, - {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated, LockToDefault: true}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, genericfeatures.WatchList: { @@ -2150,10 +2368,12 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate zpagesfeatures.ComponentFlagz: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, zpagesfeatures.ComponentStatusz: { {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta}, }, } @@ -2170,6 +2390,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature AllowOverwriteTerminationGracePeriodSeconds: {}, + AllowServiceExternalIPs: {}, + AnyVolumeDataSource: {}, AuthorizeNodeWithSelectors: {genericfeatures.AuthorizeWithSelectors}, @@ -2184,7 +2406,7 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature CPUManagerPolicyOptions: {}, - CSIMigrationPortworx: {}, + CRIListStreaming: {}, CSIServiceAccountTokenSecrets: {}, @@ -2220,14 +2442,24 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature DRAExtendedResource: {DynamicResourceAllocation}, + DRAListTypeAttributes: {DynamicResourceAllocation}, + + DRANodeAllocatableResources: {DynamicResourceAllocation}, + DRAPartitionableDevices: {DynamicResourceAllocation}, DRAPrioritizedList: {DynamicResourceAllocation}, DRAResourceClaimDeviceStatus: {}, // Soft dependency on DynamicResourceAllocation due to on/off-by-default conflict. + DRAResourceClaimGranularStatusAuthorization: {DynamicResourceAllocation, DRAResourceClaimDeviceStatus}, + + DRAResourcePoolStatus: {DynamicResourceAllocation}, + DRASchedulerFilterTimeout: {DynamicResourceAllocation}, + DRAWorkloadResourceClaims: {DynamicResourceAllocation, GenericWorkload}, + DeploymentReplicaSetTerminatingReplicas: {}, DisableAllocatorDualWrite: {MultiCIDRServiceAllocator}, @@ -2244,6 +2476,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature ExecProbeTimeout: {}, + ExtendWebSocketsToKubelet: {NodeDeclaredFeatures}, + ExternalServiceAccountTokenSigner: {}, GangScheduling: {GenericWorkload}, @@ -2260,25 +2494,23 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature HPAScaleToZero: {}, - HonorPVReclaimPolicy: {}, - HostnameOverride: {}, ImageMaximumGCAge: {}, ImageVolume: {}, + ImageVolumeWithDigest: {ImageVolume}, + InPlacePodLevelResourcesVerticalScaling: {InPlacePodVerticalScaling, PodLevelResources, NodeDeclaredFeatures}, InPlacePodVerticalScaling: {}, - InPlacePodVerticalScalingAllocatedStatus: {InPlacePodVerticalScaling}, - InPlacePodVerticalScalingExclusiveCPUs: {InPlacePodVerticalScaling}, - InPlacePodVerticalScalingExclusiveMemory: {InPlacePodVerticalScaling, MemoryManager}, + InPlacePodVerticalScalingExclusiveMemory: {InPlacePodVerticalScaling}, - InTreePluginPortworxUnregister: {}, + InPlacePodVerticalScalingInitContainers: {InPlacePodVerticalScaling, NodeDeclaredFeatures}, JobBackoffLimitPerIndex: {}, @@ -2326,8 +2558,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature MaxUnavailableStatefulSet: {}, - MemoryManager: {}, - MemoryQoS: {}, MultiCIDRServiceAllocator: {}, @@ -2356,12 +2586,18 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature OrderedNamespaceDeletion: {}, + PLEGOnDemandRelist: {}, + + PersistentVolumeClaimUnusedSinceTime: {}, + PodAndContainerStatsFromCRI: {}, PodCertificateRequest: {AuthorizeNodeWithSelectors}, PodDeletionCost: {}, + PodLevelResourceManagers: {PodLevelResources}, + PodLevelResources: {}, PodLifecycleSleepAction: {}, @@ -2378,6 +2614,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature PodTopologyLabelsAdmission: {}, + PodsAPI: {}, + PortForwardWebsockets: {}, PreferSameTrafficDistribution: {}, @@ -2400,10 +2638,14 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature RelaxedServiceNameValidation: {}, + ReloadKubeletClientCAFile: {}, + ReloadKubeletServerCertificateFile: {}, ResourceHealthStatus: {DynamicResourceAllocation}, + ResourceHealthStatusMessage: {ResourceHealthStatus}, + // RestartAllContainersOnContainerExits introduces a new container restart rule action. // All restart rules will be dropped by API if ContainerRestartRules feature is not enabled. RestartAllContainersOnContainerExits: {ContainerRestartRules, NodeDeclaredFeatures}, @@ -2438,10 +2680,18 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature ServiceAccountTokenPodNodeInfo: {}, - ServiceTrafficDistribution: {}, + ServiceCIDRStatusFieldWiping: {}, SidecarContainers: {}, + StaleControllerConsistencyDaemonSet: {featuregate.Feature(clientfeatures.AtomicFIFO)}, + + StaleControllerConsistencyJob: {featuregate.Feature(clientfeatures.AtomicFIFO)}, + + StaleControllerConsistencyReplicaSet: {featuregate.Feature(clientfeatures.AtomicFIFO)}, + + StaleControllerConsistencyStatefulSet: {featuregate.Feature(clientfeatures.AtomicFIFO)}, + StatefulSetSemanticRevisionComparison: {}, StorageCapacityScoring: {}, @@ -2462,7 +2712,7 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature TaintTolerationComparisonOperators: {}, - TopologyAwareHints: {}, + TopologyAwareWorkloadScheduling: {GenericWorkload}, TopologyManagerPolicyAlphaOptions: {}, @@ -2472,7 +2722,7 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature TranslateStreamCloseWebsocketRequests: {}, - UserNamespacesHostNetworkSupport: {UserNamespacesSupport}, + UserNamespacesHostNetworkSupport: {UserNamespacesSupport, NodeDeclaredFeatures}, UserNamespacesSupport: {}, @@ -2484,12 +2734,16 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature WinOverlay: {}, - WindowsCPUAndMemoryAffinity: {MemoryManager}, + WindowsCPUAndMemoryAffinity: {}, WindowsGracefulNodeShutdown: {GracefulNodeShutdown}, WindowsHostNetwork: {}, + WorkloadAwarePreemption: {GangScheduling}, + + WorkloadWithJob: {GenericWorkload}, + apiextensionsfeatures.CRDObservedGenerationTracking: {}, apiextensionsfeatures.CRDValidationRatcheting: {}, @@ -2526,6 +2780,7 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature genericfeatures.DeclarativeValidation: {}, + genericfeatures.DeclarativeValidationBeta: {genericfeatures.DeclarativeValidation}, genericfeatures.DeclarativeValidationTakeover: {genericfeatures.DeclarativeValidation}, genericfeatures.DetectCacheInconsistency: {}, @@ -2534,6 +2789,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature genericfeatures.ListFromCacheSnapshot: {}, + genericfeatures.ManifestBasedAdmissionControlConfig: {}, + genericfeatures.MutatingAdmissionPolicy: {}, genericfeatures.OpenAPIEnums: {}, @@ -2546,6 +2803,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature genericfeatures.SeparateCacheWatchRPC: {}, + genericfeatures.ShardedListAndWatch: {}, + genericfeatures.SizeBasedListCostEstimate: {}, genericfeatures.StorageVersionAPI: {genericfeatures.APIServerIdentity}, @@ -2558,8 +2817,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature genericfeatures.StructuredAuthenticationConfigurationJWKSMetrics: {genericfeatures.StructuredAuthenticationConfiguration}, - genericfeatures.StructuredAuthorizationConfiguration: {}, - genericfeatures.TokenRequestServiceAccountUIDValidation: {}, genericfeatures.UnauthenticatedHTTP2DOSMitigation: {}, @@ -2568,8 +2825,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature genericfeatures.WatchCacheInitializationPostStartHook: {}, - genericfeatures.WatchFromStorageWithoutResourceVersion: {}, - genericfeatures.WatchList: {}, kcmfeatures.CloudControllerManagerWatchBasedRoutesReconciliation: {}, @@ -2583,9 +2838,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature func init() { registerOpenshiftFeatures() - runtime.Must(utilfeature.DefaultMutableFeatureGate.AddVersioned(defaultVersionedKubernetesFeatureGates)) - runtime.Must(utilfeature.DefaultMutableFeatureGate.AddDependencies(defaultKubernetesFeatureGateDependencies)) - runtime.Must(zpagesfeatures.AddFeatureGates(utilfeature.DefaultMutableFeatureGate)) // Register all client-go features with kube's feature gate instance and make all client-go // feature checks use kube's instance. The effect is that for kube binaries, client-go @@ -2595,4 +2847,8 @@ func init() { ca := &clientAdapter{utilfeature.DefaultMutableFeatureGate} runtime.Must(clientfeatures.AddVersionedFeaturesToExistingFeatureGates(ca)) clientfeatures.ReplaceFeatureGates(ca) + + runtime.Must(utilfeature.DefaultMutableFeatureGate.AddVersioned(defaultVersionedKubernetesFeatureGates)) + runtime.Must(utilfeature.DefaultMutableFeatureGate.AddDependencies(defaultKubernetesFeatureGateDependencies)) + runtime.Must(zpagesfeatures.AddFeatureGates(utilfeature.DefaultMutableFeatureGate)) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/allocation_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/allocation_manager.go index a6167f2694..9e8a61470c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/allocation_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/allocation_manager.go @@ -18,7 +18,6 @@ package allocation import ( "context" - "fmt" "path/filepath" "slices" "sync" @@ -34,21 +33,15 @@ import ( resourcehelper "k8s.io/component-helpers/resource" "k8s.io/klog/v2" podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/api/v1/resource" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/allocation/state" - "k8s.io/kubernetes/pkg/kubelet/cm" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" "k8s.io/kubernetes/pkg/kubelet/config" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/status" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/kubelet/util/format" ) // podStatusManagerStateFile is the file name where status manager stores its state @@ -58,10 +51,11 @@ const ( initialRetryDelay = 30 * time.Second retryDelay = 3 * time.Minute - TriggerReasonPodResized = "pod_resized" - TriggerReasonPodUpdated = "pod_updated" - TriggerReasonPodsAdded = "pods_added" - TriggerReasonPodsRemoved = "pods_removed" + TriggerReasonPodResized = "pod_resized" + TriggerReasonPodUpdated = "pod_updated" + TriggerReasonPodsAdded = "pods_added" + TriggerReasonPodsRemoved = "pods_removed" + TriggerReasonPodTerminated = "pod_terminated" triggerReasonPeriodic = "periodic_retry" ) @@ -121,12 +115,10 @@ type Manager interface { type manager struct { allocated state.State - admitHandlers lifecycle.PodAdmitHandlers - containerRuntime kubecontainer.Runtime - statusManager status.Manager - sourcesReady config.SourcesReady - nodeConfig cm.NodeConfig - nodeAllocatableAbsolute v1.ResourceList + admitHandlers lifecycle.PodAdmitHandlers + containerRuntime kubecontainer.Runtime + statusManager status.Manager + sourcesReady config.SourcesReady ticker *time.Ticker triggerPodSync func(pod *v1.Pod) @@ -136,27 +128,26 @@ type manager struct { allocationMutex sync.Mutex podsWithPendingResizes []types.UID - recorder record.EventRecorder + recorder record.EventRecorderLogger } func NewManager(checkpointDirectory string, - nodeConfig cm.NodeConfig, - nodeAllocatableAbsolute v1.ResourceList, statusManager status.Manager, triggerPodSync func(pod *v1.Pod), getActivePods func() []*v1.Pod, getPodByUID func(types.UID) (*v1.Pod, bool), sourcesReady config.SourcesReady, - recorder record.EventRecorder, + recorder record.EventRecorderLogger, ) Manager { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() return &manager{ - allocated: newStateImpl(checkpointDirectory, allocatedPodsStateFile), + allocated: newStateImpl(logger, checkpointDirectory, allocatedPodsStateFile), - statusManager: statusManager, - admitHandlers: lifecycle.PodAdmitHandlers{}, - sourcesReady: sourcesReady, - nodeConfig: nodeConfig, - nodeAllocatableAbsolute: nodeAllocatableAbsolute, + statusManager: statusManager, + admitHandlers: lifecycle.PodAdmitHandlers{}, + sourcesReady: sourcesReady, ticker: time.NewTicker(initialRetryDelay), triggerPodSync: triggerPodSync, @@ -166,7 +157,7 @@ func NewManager(checkpointDirectory string, } } -func newStateImpl(checkpointDirectory, checkpointName string) state.State { +func newStateImpl(logger klog.Logger, checkpointDirectory, checkpointName string) state.State { if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { return state.NewNoopStateCheckpoint() } @@ -174,7 +165,7 @@ func newStateImpl(checkpointDirectory, checkpointName string) state.State { stateImpl, err := state.NewStateCheckpoint(checkpointDirectory, checkpointName) if err != nil { // This is a critical, non-recoverable failure. - klog.ErrorS(err, "Failed to initialize allocation checkpoint manager", + logger.Error(err, "Failed to initialize allocation checkpoint manager", "checkpointPath", filepath.Join(checkpointDirectory, checkpointName)) panic(err) } @@ -184,23 +175,20 @@ func newStateImpl(checkpointDirectory, checkpointName string) state.State { // NewInMemoryManager returns an allocation manager that doesn't persist state. // For testing purposes only! -func NewInMemoryManager(nodeConfig cm.NodeConfig, - nodeAllocatableAbsolute v1.ResourceList, +func NewInMemoryManager( statusManager status.Manager, triggerPodSync func(pod *v1.Pod), getActivePods func() []*v1.Pod, getPodByUID func(types.UID) (*v1.Pod, bool), sourcesReady config.SourcesReady, - recorder record.EventRecorder, + recorder record.EventRecorderLogger, ) Manager { return &manager{ allocated: state.NewStateMemory(nil), - statusManager: statusManager, - admitHandlers: lifecycle.PodAdmitHandlers{}, - sourcesReady: sourcesReady, - nodeConfig: nodeConfig, - nodeAllocatableAbsolute: nodeAllocatableAbsolute, + statusManager: statusManager, + admitHandlers: lifecycle.PodAdmitHandlers{}, + sourcesReady: sourcesReady, ticker: time.NewTicker(initialRetryDelay), triggerPodSync: triggerPodSync, @@ -213,12 +201,13 @@ func NewInMemoryManager(nodeConfig cm.NodeConfig, func (m *manager) Run(ctx context.Context) { // Start a goroutine to periodically check for pending resizes and process them if needed. go func() { + logger := klog.FromContext(ctx) for { select { case <-m.ticker.C: - successfulResizes := m.retryPendingResizes(triggerReasonPeriodic) + successfulResizes := m.retryPendingResizes(logger, triggerReasonPeriodic) for _, po := range successfulResizes { - klog.InfoS("Successfully retried resize after timeout", "pod", klog.KObj(po)) + logger.Info("Successfully retried resize after timeout", "pod", klog.KObj(po)) } case <-ctx.Done(): m.ticker.Stop() @@ -229,15 +218,18 @@ func (m *manager) Run(ctx context.Context) { } func (m *manager) RetryPendingResizes(trigger string) { - m.retryPendingResizes(trigger) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + m.retryPendingResizes(logger, trigger) } -func (m *manager) retryPendingResizes(trigger string) []*v1.Pod { +func (m *manager) retryPendingResizes(logger klog.Logger, trigger string) []*v1.Pod { m.allocationMutex.Lock() defer m.allocationMutex.Unlock() if !m.sourcesReady.AllReady() { - klog.V(4).InfoS("Skipping evaluation of pending resizes; sources are not ready") + logger.V(4).Info("Skipping evaluation of pending resizes; sources are not ready") m.ticker.Reset(initialRetryDelay) return nil } @@ -251,25 +243,25 @@ func (m *manager) retryPendingResizes(trigger string) []*v1.Pod { for _, uid := range m.podsWithPendingResizes { pod, found := m.getPodByUID(uid) if !found { - klog.V(4).InfoS("Pod not found; removing from pending resizes", "podUID", uid) + logger.V(4).Info("Pod not found; removing from pending resizes", "podUID", uid) continue } oldResizeStatus := m.statusManager.GetPodResizeConditions(uid) isDeferred := m.statusManager.IsPodResizeDeferred(uid) - resizeAllocated, err := m.handlePodResourcesResize(pod) + resizeAllocated, err := m.handlePodResourcesResize(logger, pod) switch { case err != nil: - klog.ErrorS(err, "Failed to handle pod resources resize", "pod", klog.KObj(pod)) + logger.Error(err, "Failed to handle pod resources resize", "pod", klog.KObj(pod)) newPendingResizes = append(newPendingResizes, uid) case m.statusManager.IsPodResizeDeferred(uid): - klog.V(4).InfoS("Pod resize is deferred; will reevaluate later", "pod", klog.KObj(pod)) + logger.V(4).Info("Pod resize is deferred; will reevaluate later", "pod", klog.KObj(pod)) newPendingResizes = append(newPendingResizes, uid) case m.statusManager.IsPodResizeInfeasible(uid): - klog.V(4).InfoS("Pod resize is infeasible", "pod", klog.KObj(pod)) + logger.V(4).Info("Pod resize is infeasible", "pod", klog.KObj(pod)) default: - klog.V(4).InfoS("Pod resize successfully allocated", "pod", klog.KObj(pod)) + logger.V(4).Info("Pod resize successfully allocated", "pod", klog.KObj(pod)) successfulResizes = append(successfulResizes, pod) if isDeferred { metrics.PodDeferredAcceptedResizes.WithLabelValues(trigger).Inc() @@ -288,6 +280,9 @@ func (m *manager) retryPendingResizes(trigger string) []*v1.Pod { } func (m *manager) PushPendingResize(uid types.UID) { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() m.allocationMutex.Lock() defer m.allocationMutex.Unlock() @@ -300,7 +295,7 @@ func (m *manager) PushPendingResize(uid types.UID) { // Add the pod to the pending resizes list and sort by priority. m.podsWithPendingResizes = append(m.podsWithPendingResizes, uid) - m.sortPendingResizes() + m.sortPendingResizes(logger) } // sortPendingResizes sorts the list of pending resizes: @@ -308,12 +303,12 @@ func (m *manager) PushPendingResize(uid types.UID) { // - Second, based on the pod's PriorityClass. // - Third, based on the pod's QoS class. // - Last, prioritizing resizes that have been in the deferred state the longest. -func (m *manager) sortPendingResizes() { +func (m *manager) sortPendingResizes(logger klog.Logger) { var pendingPods []*v1.Pod for _, uid := range m.podsWithPendingResizes { pod, found := m.getPodByUID(uid) if !found { - klog.V(4).InfoS("Pod not found; removing from pending resizes", "podUID", uid) + logger.V(4).Info("Pod not found; removing from pending resizes", "podUID", uid) continue } pendingPods = append(pendingPods, pod) @@ -490,7 +485,10 @@ func updatePodFromAllocation(pod *v1.Pod, allocated state.PodResourceInfo) (*v1. // SetAllocatedResources checkpoints the resources allocated to a pod's containers func (m *manager) SetAllocatedResources(pod *v1.Pod) error { - return m.allocated.SetPodResourceInfo(pod.UID, allocationFromPod(pod)) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + return m.allocated.SetPodResourceInfo(logger, pod.UID, allocationFromPod(pod)) } func allocationFromPod(pod *v1.Pod) state.PodResourceInfo { @@ -499,18 +497,14 @@ func allocationFromPod(pod *v1.Pod) state.PodResourceInfo { podAlloc.PodLevelResources = pod.Spec.Resources.DeepCopy() } podAlloc.ContainerResources = make(map[string]v1.ResourceRequirements) - for _, container := range pod.Spec.Containers { + for container, containerType := range podutil.ContainerIter(&pod.Spec, podutil.InitContainers|podutil.Containers) { + if !IsResizableContainer(container, containerType) { + continue + } alloc := *container.Resources.DeepCopy() podAlloc.ContainerResources[container.Name] = alloc } - for _, container := range pod.Spec.InitContainers { - if podutil.IsRestartableInitContainer(&container) { - alloc := *container.Resources.DeepCopy() - podAlloc.ContainerResources[container.Name] = alloc - } - } - return podAlloc } @@ -525,6 +519,9 @@ func (m *manager) SetContainerRuntime(runtime kubecontainer.Runtime) { } func (m *manager) AddPod(activePods []*v1.Pod, pod *v1.Pod) (bool, string, string) { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() m.allocationMutex.Lock() defer m.allocationMutex.Unlock() @@ -536,13 +533,13 @@ func (m *manager) AddPod(activePods []*v1.Pod, pod *v1.Pod) (bool, string, strin // Check if we can admit the pod; if so, update the allocation. allocatedPods := m.getAllocatedPods(activePods) - ok, reason, message := m.canAdmitPod(allocatedPods, pod) + ok, reason, message := m.canAdmitPod(logger, allocatedPods, pod, lifecycle.AddOperation) if ok && utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { // Checkpoint the resource values at which the Pod has been admitted or resized. if err := m.SetAllocatedResources(pod); err != nil { // TODO(vinaykul,InPlacePodVerticalScaling): Can we recover from this in some way? Investigate - klog.ErrorS(err, "SetPodAllocation failed", "pod", klog.KObj(pod)) + logger.Error(err, "SetPodAllocation failed", "pod", klog.KObj(pod)) } } @@ -550,9 +547,12 @@ func (m *manager) AddPod(activePods []*v1.Pod, pod *v1.Pod) (bool, string, strin } func (m *manager) RemovePod(uid types.UID) { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() if err := m.allocated.RemovePod(uid); err != nil { // If the deletion fails, it will be retried by RemoveOrphanedPods, so we can safely ignore the error. - klog.V(3).ErrorS(err, "Failed to delete pod allocation", "podUID", uid) + logger.V(3).Info("Failed to delete pod allocation", "podUID", uid, "err", err) } } @@ -560,43 +560,21 @@ func (m *manager) RemoveOrphanedPods(remainingPods sets.Set[types.UID]) { m.allocated.RemoveOrphanedPods(remainingPods) } -func (m *manager) handlePodResourcesResize(pod *v1.Pod) (bool, error) { - allocatedPod, updated := m.UpdatePodFromAllocation(pod) +func (m *manager) handlePodResourcesResize(logger klog.Logger, pod *v1.Pod) (bool, error) { + _, updated := m.UpdatePodFromAllocation(pod) if !updated { // Desired resources == allocated resources. Pod allocation does not need to be updated. m.statusManager.ClearPodResizePendingCondition(pod.UID) return false, nil - - } else if resizable, msg, reason := IsInPlacePodVerticalScalingAllowed(pod); !resizable { - // If there is a pending resize but the resize is not allowed, always use the allocated resources. - metrics.PodInfeasibleResizes.WithLabelValues(reason).Inc() - m.statusManager.SetPodResizePendingCondition(pod.UID, v1.PodReasonInfeasible, msg, pod.Generation) - return false, nil - - } else if resizeNotAllowed, msg := disallowResizeForSwappableContainers(m.containerRuntime, pod, allocatedPod); resizeNotAllowed { - // If this resize involve swap recalculation, set as infeasible, as IPPR with swap is not supported for beta. - metrics.PodInfeasibleResizes.WithLabelValues("swap_limitation").Inc() - m.statusManager.SetPodResizePendingCondition(pod.UID, v1.PodReasonInfeasible, msg, pod.Generation) - return false, nil - } - - if !apiequality.Semantic.DeepEqual(pod.Spec.Resources, allocatedPod.Spec.Resources) { - if resizable, msg, reason := IsInPlacePodLevelResourcesVerticalScalingAllowed(pod); !resizable { - // If there is a pending pod-level resources resize but the resize is not allowed, always use the allocated resources. - metrics.PodInfeasibleResizes.WithLabelValues(reason).Inc() - m.statusManager.SetPodResizePendingCondition(pod.UID, v1.PodReasonInfeasible, msg, pod.Generation) - return false, nil - } } // Desired resources != allocated resources. Can we update the allocation to the desired resources? - fit, reason, message := m.canResizePod(m.getAllocatedPods(m.getActivePods()), pod) + fit, reason, message := m.canAdmitPod(logger, m.getAllocatedPods(m.getActivePods()), pod, lifecycle.ResizeOperation) if fit { // Update pod resource allocation checkpoint if err := m.SetAllocatedResources(pod); err != nil { return false, err } - allocatedPod = pod m.statusManager.ClearPodResizePendingCondition(pod.UID) // Clear any errors that may have been surfaced from a previous resize and update the @@ -604,9 +582,8 @@ func (m *manager) handlePodResourcesResize(pod *v1.Pod) (bool, error) { m.statusManager.ClearPodResizeInProgressCondition(pod.UID) m.statusManager.SetPodResizeInProgressCondition(pod.UID, "", "", pod.Generation) - msg := events.PodResizeStartedMsg(allocatedPod, pod.Generation) - m.recorder.Eventf(pod, v1.EventTypeNormal, events.ResizeStarted, msg) - + msg := events.PodResizeStartedMsg(logger, pod, pod.Generation) + m.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeNormal, events.ResizeStarted, "%s", msg) return true, nil } @@ -616,48 +593,14 @@ func (m *manager) handlePodResourcesResize(pod *v1.Pod) (bool, error) { if reason == v1.PodReasonInfeasible { eventType = events.ResizeInfeasible } - msg := events.PodResizePendingMsg(pod, reason, message, pod.Generation) - m.recorder.Eventf(pod, v1.EventTypeWarning, eventType, msg) + msg := events.PodResizePendingMsg(logger, pod, reason, message, pod.Generation) + m.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, eventType, "%s", msg) } } return false, nil } -func disallowResizeForSwappableContainers(runtime kubecontainer.Runtime, desiredPod, allocatedPod *v1.Pod) (bool, string) { - if desiredPod == nil || allocatedPod == nil { - return false, "" - } - restartableMemoryResizePolicy := func(resizePolicies []v1.ContainerResizePolicy) bool { - for _, policy := range resizePolicies { - if policy.ResourceName == v1.ResourceMemory { - return policy.RestartPolicy == v1.RestartContainer - } - } - return false - } - allocatedContainers := make(map[string]v1.Container) - for _, container := range append(allocatedPod.Spec.Containers, allocatedPod.Spec.InitContainers...) { - allocatedContainers[container.Name] = container - } - for _, desiredContainer := range append(desiredPod.Spec.Containers, desiredPod.Spec.InitContainers...) { - allocatedContainer, ok := allocatedContainers[desiredContainer.Name] - if !ok { - continue - } - origMemRequest := desiredContainer.Resources.Requests[v1.ResourceMemory] - newMemRequest := allocatedContainer.Resources.Requests[v1.ResourceMemory] - if !origMemRequest.Equal(newMemRequest) && !restartableMemoryResizePolicy(allocatedContainer.ResizePolicy) { - aSwapBehavior := runtime.GetContainerSwapBehavior(desiredPod, &desiredContainer) - bSwapBehavior := runtime.GetContainerSwapBehavior(allocatedPod, &allocatedContainer) - if aSwapBehavior != kubetypes.NoSwap || bSwapBehavior != kubetypes.NoSwap { - return true, "In-place resize of containers with swap is not supported." - } - } - } - return false, "" -} - // canAdmitPod determines if a pod can be admitted, and gives a reason if it // cannot. "pod" is new pod, while "pods" are all admitted pods // The function returns a boolean value indicating whether the pod @@ -665,15 +608,15 @@ func disallowResizeForSwappableContainers(runtime kubecontainer.Runtime, desired // the pod cannot be admitted. // allocatedPods should represent the pods that have already been admitted, along with their // admitted (allocated) resources. -func (m *manager) canAdmitPod(allocatedPods []*v1.Pod, pod *v1.Pod) (bool, string, string) { +func (m *manager) canAdmitPod(logger klog.Logger, allocatedPods []*v1.Pod, pod *v1.Pod, operation lifecycle.Operation) (bool, string, string) { // Filter out the pod being evaluated. allocatedPods = slices.DeleteFunc(allocatedPods, func(p *v1.Pod) bool { return p.UID == pod.UID }) // If any handler rejects, the pod is rejected. - attrs := &lifecycle.PodAdmitAttributes{Pod: pod, OtherPods: allocatedPods} + attrs := &lifecycle.PodAdmitAttributes{Pod: pod, OtherPods: allocatedPods, Operation: operation} for _, podAdmitHandler := range m.admitHandlers { if result := podAdmitHandler.Admit(attrs); !result.Admit { - klog.InfoS("Pod admission denied", "podUID", attrs.Pod.UID, "pod", klog.KObj(attrs.Pod), "reason", result.Reason, "message", result.Message) + logger.Info("Pod admission denied", "podUID", attrs.Pod.UID, "pod", klog.KObj(attrs.Pod), "reason", result.Reason, "message", result.Message, "operation", operation) return false, result.Reason, result.Message } } @@ -681,74 +624,6 @@ func (m *manager) canAdmitPod(allocatedPods []*v1.Pod, pod *v1.Pod) (bool, strin return true, "", "" } -// canResizePod determines if the requested resize is currently feasible. -// pod should hold the desired (pre-allocated) spec. -// Returns true if the resize can proceed; returns a reason and message -// otherwise. -func (m *manager) canResizePod(allocatedPods []*v1.Pod, pod *v1.Pod) (bool, string, string) { - // TODO: Move this logic into a PodAdmitHandler by introducing an operation field to - // lifecycle.PodAdmitAttributes, and combine canResizePod with canAdmitPod. - if v1qos.GetPodQOS(pod) == v1.PodQOSGuaranteed { - if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingExclusiveCPUs) && - m.nodeConfig.CPUManagerPolicy == string(cpumanager.PolicyStatic) && - m.guaranteedPodResourceResizeRequired(pod, v1.ResourceCPU) { - msg := fmt.Sprintf("Resize is infeasible for Guaranteed Pods alongside CPU Manager policy \"%s\"", string(cpumanager.PolicyStatic)) - klog.V(3).InfoS(msg, "pod", format.Pod(pod)) - metrics.PodInfeasibleResizes.WithLabelValues("guaranteed_pod_cpu_manager_static_policy").Inc() - return false, v1.PodReasonInfeasible, msg - } - if utilfeature.DefaultFeatureGate.Enabled(features.MemoryManager) && - !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingExclusiveMemory) && - m.nodeConfig.MemoryManagerPolicy == string(memorymanager.PolicyTypeStatic) && - m.guaranteedPodResourceResizeRequired(pod, v1.ResourceMemory) { - msg := fmt.Sprintf("Resize is infeasible for Guaranteed Pods alongside Memory Manager policy \"%s\"", string(memorymanager.PolicyTypeStatic)) - klog.V(3).InfoS(msg, "pod", format.Pod(pod)) - metrics.PodInfeasibleResizes.WithLabelValues("guaranteed_pod_memory_manager_static_policy").Inc() - return false, v1.PodReasonInfeasible, msg - } - } - - cpuAvailable := m.nodeAllocatableAbsolute.Cpu().MilliValue() - memAvailable := m.nodeAllocatableAbsolute.Memory().Value() - cpuRequests := resource.GetResourceRequest(pod, v1.ResourceCPU) - memRequests := resource.GetResourceRequest(pod, v1.ResourceMemory) - if cpuRequests > cpuAvailable || memRequests > memAvailable { - var msg string - if memRequests > memAvailable { - msg = fmt.Sprintf("memory, requested: %d, capacity: %d", memRequests, memAvailable) - } else { - msg = fmt.Sprintf("cpu, requested: %d, capacity: %d", cpuRequests, cpuAvailable) - } - msg = "Node didn't have enough capacity: " + msg - klog.V(3).InfoS(msg, "pod", klog.KObj(pod)) - metrics.PodInfeasibleResizes.WithLabelValues("insufficient_node_allocatable").Inc() - return false, v1.PodReasonInfeasible, msg - } - - if ok, failReason, failMessage := m.canAdmitPod(allocatedPods, pod); !ok { - // Log reason and return. - klog.V(3).InfoS("Resize cannot be accommodated", "pod", klog.KObj(pod), "reason", failReason, "message", failMessage) - return false, v1.PodReasonDeferred, failMessage - } - - return true, "", "" -} - -func (m *manager) guaranteedPodResourceResizeRequired(pod *v1.Pod, resourceName v1.ResourceName) bool { - for container, containerType := range podutil.ContainerIter(&pod.Spec, podutil.InitContainers|podutil.Containers) { - if !IsResizableContainer(container, containerType) { - continue - } - requestedResources := container.Resources - allocatedresources, _ := m.GetContainerResourceAllocation(pod.UID, container.Name) - // For Guaranteed pods, requests must equal limits, so checking requests is sufficient. - if !requestedResources.Requests[resourceName].Equal(allocatedresources.Requests[resourceName]) { - return true - } - } - return false -} - func (m *manager) getAllocatedPods(activePods []*v1.Pod) []*v1.Pod { if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { return activePods @@ -764,7 +639,7 @@ func (m *manager) getAllocatedPods(activePods []*v1.Pod) []*v1.Pod { func IsResizableContainer(container *v1.Container, containerType podutil.ContainerType) bool { switch containerType { case podutil.InitContainers: - return podutil.IsRestartableInitContainer(container) + return utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingInitContainers) || podutil.IsRestartableInitContainer(container) case podutil.Containers: return true default: diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_linux.go index fad24ace7e..142afc415c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2025 The Kubernetes Authors. @@ -23,16 +22,12 @@ import ( v1 "k8s.io/api/core/v1" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/features" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) func IsInPlacePodVerticalScalingAllowed(pod *v1.Pod) (allowed bool, msg, reason string) { if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { return false, "InPlacePodVerticalScaling is disabled", "feature_gate_off" } - if kubetypes.IsStaticPod(pod) { - return false, "In-place resize of static-pods is not supported", "static_pod" - } return true, "", "" } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_unsupported.go index 127b062326..a81a51b400 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_windows.go index 15b6855f39..eda519b974 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/features_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/handlers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/handlers.go new file mode 100644 index 0000000000..4bbe7bfcbb --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/handlers.go @@ -0,0 +1,151 @@ +/* +Copyright 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 allocation + +import ( + "fmt" + + v1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/klog/v2" + podutil "k8s.io/kubernetes/pkg/api/v1/pod" + v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" + "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/pkg/kubelet/cm" + "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" + "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/lifecycle" + "k8s.io/kubernetes/pkg/kubelet/metrics" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + "k8s.io/kubernetes/pkg/kubelet/util/format" +) + +// NewPodResizesAdmitHandler returns a PodAdmitHandler which is used to evaluate +// if a pod resize can be allocated by the kubelet. +func NewPodResizesAdmitHandler(containerManager cm.ContainerManager, containerRuntime kubecontainer.Runtime, allocationManager Manager, logger klog.Logger) lifecycle.PodAdmitHandler { + return &podResizesAdmitHandler{ + containerManager: containerManager, + containerRuntime: containerRuntime, + allocationManager: allocationManager, + logger: logger, + } +} + +type podResizesAdmitHandler struct { + containerManager cm.ContainerManager + containerRuntime kubecontainer.Runtime + allocationManager Manager + logger klog.Logger +} + +func (h *podResizesAdmitHandler) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult { + if attrs.Operation != lifecycle.ResizeOperation { + return lifecycle.PodAdmitResult{Admit: true} + } + + pod := attrs.Pod + allocatedPod, _ := h.allocationManager.UpdatePodFromAllocation(pod) + if resizable, msg, reason := IsInPlacePodVerticalScalingAllowed(pod); !resizable { + // If there is a pending resize but the resize is not allowed, always use the allocated resources. + metrics.PodInfeasibleResizes.WithLabelValues(reason).Inc() + return lifecycle.PodAdmitResult{Admit: false, Reason: v1.PodReasonInfeasible, Message: msg} + } + if resizeNotAllowed, msg := disallowResizeForSwappableContainers(h.containerRuntime, pod, allocatedPod); resizeNotAllowed { + // If this resize involve swap recalculation, set as infeasible, as IPPR with swap is not supported for beta. + metrics.PodInfeasibleResizes.WithLabelValues("swap_limitation").Inc() + return lifecycle.PodAdmitResult{Admit: false, Reason: v1.PodReasonInfeasible, Message: msg} + } + if !apiequality.Semantic.DeepEqual(pod.Spec.Resources, allocatedPod.Spec.Resources) { + if resizable, msg, reason := IsInPlacePodLevelResourcesVerticalScalingAllowed(pod); !resizable { + // If there is a pending pod-level resources resize but the resize is not allowed, always use the allocated resources. + metrics.PodInfeasibleResizes.WithLabelValues(reason).Inc() + return lifecycle.PodAdmitResult{Admit: false, Reason: v1.PodReasonInfeasible, Message: msg} + } + } + + if v1qos.GetPodQOS(pod) == v1.PodQOSGuaranteed { + if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingExclusiveCPUs) && + h.containerManager.GetNodeConfig().CPUManagerPolicy == string(cpumanager.PolicyStatic) && + h.guaranteedPodResourceResizeRequired(pod, v1.ResourceCPU) { + msg := fmt.Sprintf("Resize is infeasible for Guaranteed Pods alongside CPU Manager policy \"%s\"", string(cpumanager.PolicyStatic)) + h.logger.V(3).Info(msg, "pod", format.Pod(pod)) + metrics.PodInfeasibleResizes.WithLabelValues("guaranteed_pod_cpu_manager_static_policy").Inc() + return lifecycle.PodAdmitResult{Admit: false, Reason: v1.PodReasonInfeasible, Message: msg} + } + if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingExclusiveMemory) && + h.containerManager.GetNodeConfig().MemoryManagerPolicy == string(memorymanager.PolicyTypeStatic) && + h.guaranteedPodResourceResizeRequired(pod, v1.ResourceMemory) { + msg := fmt.Sprintf("Resize is infeasible for Guaranteed Pods alongside Memory Manager policy \"%s\"", string(memorymanager.PolicyTypeStatic)) + h.logger.V(3).Info(msg, "pod", format.Pod(pod)) + metrics.PodInfeasibleResizes.WithLabelValues("guaranteed_pod_memory_manager_static_policy").Inc() + return lifecycle.PodAdmitResult{Admit: false, Reason: v1.PodReasonInfeasible, Message: msg} + } + } + + return lifecycle.PodAdmitResult{Admit: true} +} + +func disallowResizeForSwappableContainers(runtime kubecontainer.Runtime, desiredPod, allocatedPod *v1.Pod) (bool, string) { + if desiredPod == nil || allocatedPod == nil { + return false, "" + } + restartableMemoryResizePolicy := func(resizePolicies []v1.ContainerResizePolicy) bool { + for _, policy := range resizePolicies { + if policy.ResourceName == v1.ResourceMemory { + return policy.RestartPolicy == v1.RestartContainer + } + } + return false + } + allocatedContainers := make(map[string]v1.Container) + for _, container := range append(allocatedPod.Spec.Containers, allocatedPod.Spec.InitContainers...) { + allocatedContainers[container.Name] = container + } + for _, desiredContainer := range append(desiredPod.Spec.Containers, desiredPod.Spec.InitContainers...) { + allocatedContainer, ok := allocatedContainers[desiredContainer.Name] + if !ok { + continue + } + origMemRequest := desiredContainer.Resources.Requests[v1.ResourceMemory] + newMemRequest := allocatedContainer.Resources.Requests[v1.ResourceMemory] + if !origMemRequest.Equal(newMemRequest) && !restartableMemoryResizePolicy(allocatedContainer.ResizePolicy) { + aSwapBehavior := runtime.GetContainerSwapBehavior(desiredPod, &desiredContainer) + bSwapBehavior := runtime.GetContainerSwapBehavior(allocatedPod, &allocatedContainer) + if aSwapBehavior != kubetypes.NoSwap || bSwapBehavior != kubetypes.NoSwap { + return true, "In-place resize of containers with swap is not supported." + } + } + } + return false, "" +} + +func (h *podResizesAdmitHandler) guaranteedPodResourceResizeRequired(pod *v1.Pod, resourceName v1.ResourceName) bool { + for container, containerType := range podutil.ContainerIter(&pod.Spec, podutil.InitContainers|podutil.Containers) { + if !IsResizableContainer(container, containerType) { + continue + } + requestedResources := container.Resources + allocatedresources, _ := h.allocationManager.GetContainerResourceAllocation(pod.UID, container.Name) + // For Guaranteed pods, requests must equal limits, so checking requests is sufficient. + if !requestedResources.Requests[resourceName].Equal(allocatedresources.Requests[resourceName]) { + return true + } + } + return false +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state.go index d21b476595..6c9588ebf6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state.go @@ -20,6 +20,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/klog/v2" ) // PodResourceInfo stores resource requirements for containers within a pod. @@ -58,7 +59,7 @@ type Reader interface { type writer interface { SetContainerResources(podUID types.UID, containerName string, resources v1.ResourceRequirements) error - SetPodResourceInfo(podUID types.UID, resourceInfo PodResourceInfo) error + SetPodResourceInfo(logger klog.Logger, podUID types.UID, resourceInfo PodResourceInfo) error SetPodLevelResources(podUID types.UID, alloc *v1.ResourceRequirements) error RemovePod(podUID types.UID) error // RemoveOrphanedPods removes the stored state for any pods not included in the set of remaining pods. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_checkpoint.go index cdfff8b164..5aea24d82d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_checkpoint.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_checkpoint.go @@ -42,12 +42,15 @@ type stateCheckpoint struct { // NewStateCheckpoint creates new State for keeping track of pod resource information with checkpoint backend func NewStateCheckpoint(stateDir, checkpointName string) (State, error) { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir) if err != nil { return nil, fmt.Errorf("failed to initialize checkpoint manager for pod resource information tracking: %w", err) } - pra, checksum, err := restoreState(checkpointManager, checkpointName) + pra, checksum, err := restoreState(logger, checkpointManager, checkpointName) if err != nil { //lint:ignore ST1005 user-facing error message return nil, fmt.Errorf("could not restore state from checkpoint: %w, please drain this node and delete pod resource information checkpoint file %q before restarting Kubelet", @@ -64,7 +67,7 @@ func NewStateCheckpoint(stateDir, checkpointName string) (State, error) { } // restores state from a checkpoint and creates it if it doesn't exist -func restoreState(checkpointManager checkpointmanager.CheckpointManager, checkpointName string) (PodResourceInfoMap, checksum.Checksum, error) { +func restoreState(logger klog.Logger, checkpointManager checkpointmanager.CheckpointManager, checkpointName string) (PodResourceInfoMap, checksum.Checksum, error) { checkpoint := &Checkpoint{} if err := checkpointManager.GetCheckpoint(checkpointName, checkpoint); err != nil { if err == errors.ErrCheckpointNotFound { @@ -78,12 +81,12 @@ func restoreState(checkpointManager checkpointmanager.CheckpointManager, checkpo return nil, 0, fmt.Errorf("failed to get pod resource information: %w", err) } - klog.V(2).InfoS("State checkpoint: restored pod resource state from checkpoint") + logger.V(2).Info("State checkpoint: restored pod resource state from checkpoint") return praInfo.Entries, checkpoint.Checksum, nil } // saves state to a checkpoint, caller is responsible for locking -func (sc *stateCheckpoint) storeState() error { +func (sc *stateCheckpoint) storeState(logger klog.Logger) error { resourceInfo := sc.cache.GetPodResourceInfoMap() checkpoint, err := NewCheckpoint(&PodResourceCheckpointInfo{ @@ -98,7 +101,7 @@ func (sc *stateCheckpoint) storeState() error { } err = sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint) if err != nil { - klog.ErrorS(err, "Failed to save pod resource information checkpoint") + logger.Error(err, "Failed to save pod resource information checkpoint") return err } sc.lastChecksum = checkpoint.Checksum @@ -135,35 +138,41 @@ func (sc *stateCheckpoint) GetPodResourceInfo(podUID types.UID) (PodResourceInfo // SetContainerResoruces sets resources information for a pod's container func (sc *stateCheckpoint) SetContainerResources(podUID types.UID, containerName string, resources v1.ResourceRequirements) error { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() sc.mux.Lock() defer sc.mux.Unlock() err := sc.cache.SetContainerResources(podUID, containerName, resources) if err != nil { return err } - return sc.storeState() + return sc.storeState(logger) } // SetPodLevelResources sets resources information for a pod's resources at pod-level. func (sc *stateCheckpoint) SetPodLevelResources(podUID types.UID, resInfo *v1.ResourceRequirements) error { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() sc.mux.Lock() defer sc.mux.Unlock() err := sc.cache.SetPodLevelResources(podUID, resInfo) if err != nil { return err } - return sc.storeState() + return sc.storeState(logger) } // SetPodResourceInfo sets pod resource information -func (sc *stateCheckpoint) SetPodResourceInfo(podUID types.UID, resourceInfo PodResourceInfo) error { +func (sc *stateCheckpoint) SetPodResourceInfo(logger klog.Logger, podUID types.UID, resourceInfo PodResourceInfo) error { sc.mux.Lock() defer sc.mux.Unlock() - err := sc.cache.SetPodResourceInfo(podUID, resourceInfo) + err := sc.cache.SetPodResourceInfo(logger, podUID, resourceInfo) if err != nil { return err } - return sc.storeState() + return sc.storeState(logger) } // Delete deletes resource information for specified pod @@ -213,7 +222,7 @@ func (sc *noopStateCheckpoint) SetPodLevelResources(_ types.UID, _ *v1.ResourceR return nil } -func (sc *noopStateCheckpoint) SetPodResourceInfo(_ types.UID, _ PodResourceInfo) error { +func (sc *noopStateCheckpoint) SetPodResourceInfo(_ klog.Logger, _ types.UID, _ PodResourceInfo) error { return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_mem.go b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_mem.go index 3dfad44837..89b7f280bc 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_mem.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/allocation/state/state_mem.go @@ -34,10 +34,13 @@ var _ State = &stateMemory{} // NewStateMemory creates new State to track resources resourcesated to pods func NewStateMemory(resources PodResourceInfoMap) State { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() if resources == nil { resources = PodResourceInfoMap{} } - klog.V(2).InfoS("Initialized new in-memory state store for pod resource information tracking") + logger.V(2).Info("Initialized new in-memory state store for pod resource information tracking") return &stateMemory{ podResources: resources, } @@ -87,6 +90,10 @@ func (s *stateMemory) GetPodResourceInfo(podUID types.UID) (PodResourceInfo, boo } func (s *stateMemory) SetContainerResources(podUID types.UID, containerName string, resources v1.ResourceRequirements) error { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + s.Lock() defer s.Unlock() @@ -104,11 +111,14 @@ func (s *stateMemory) SetContainerResources(podUID types.UID, containerName stri podInfo.ContainerResources[containerName] = resources s.podResources[podUID] = podInfo - klog.V(3).InfoS("Updated container resource information", "podUID", podUID, "containerName", containerName, "resources", resources) + logger.V(3).Info("Updated container resource information", "podUID", podUID, "containerName", containerName, "resources", resources) return nil } func (s *stateMemory) SetPodLevelResources(podUID types.UID, resources *v1.ResourceRequirements) error { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() s.Lock() defer s.Unlock() @@ -121,24 +131,27 @@ func (s *stateMemory) SetPodLevelResources(podUID types.UID, resources *v1.Resou s.podResources[podUID] = podInfo - klog.V(3).InfoS("Updated pod-level resource info", "podUID", podUID, "resources", resources) + logger.V(3).Info("Updated pod-level resource info", "podUID", podUID, "resources", resources) return nil } -func (s *stateMemory) SetPodResourceInfo(podUID types.UID, resourceInfo PodResourceInfo) error { +func (s *stateMemory) SetPodResourceInfo(logger klog.Logger, podUID types.UID, resourceInfo PodResourceInfo) error { s.Lock() defer s.Unlock() s.podResources[podUID] = resourceInfo - klog.V(3).InfoS("Updated pod resource information", "podUID", podUID, "information", resourceInfo) + logger.V(3).Info("Updated pod resource information", "podUID", podUID, "information", resourceInfo) return nil } func (s *stateMemory) RemovePod(podUID types.UID) error { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() s.Lock() defer s.Unlock() delete(s.podResources, podUID) - klog.V(3).InfoS("Deleted pod resource information", "podUID", podUID) + logger.V(3).Info("Deleted pod resource information", "podUID", podUID) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go index 6ab19ac1c6..c032cfe511 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go @@ -131,6 +131,14 @@ type KubeletConfiguration struct { // Note that TLS 1.3 ciphersuites are not configurable. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). TLSCipherSuites []string + // TLSCurvePreferences is the set of allowed key exchange mechanisms for the server, + // specified as numeric Go crypto/tls CurveID values. + // The supported values depend on the Go version used. + // See https://pkg.go.dev/crypto/tls#CurveID for values supported for each Go version. + // The order of the list is ignored, and key exchange mechanisms are + // chosen by Go from this list using an internal preference order. + // If empty, the default Go curves will be used. + TLSCurvePreferences []int32 // TLSMinVersion is the minimum TLS version supported. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). TLSMinVersion string @@ -219,6 +227,8 @@ type KubeletConfiguration struct { NodeLeaseDurationSeconds int32 // ImageMinimumGCAge is the minimum age for an unused image before it is // garbage collected. + // The field value must be greater than 0. + // If unset or 0, defaults to 2m. ImageMinimumGCAge metav1.Duration // ImageMaximumGCAge is the maximum age an image can be unused before it is garbage collected. // The default of this field is "0s", which disables this field--meaning images won't be garbage @@ -308,6 +318,7 @@ type KubeletConfiguration struct { // specify CPU limits CPUCFSQuota bool // CPUCFSQuotaPeriod sets the CPU CFS quota period value, cpu.cfs_period_us, defaults to 100ms + // Default: "100ms". Changing this value requires enabling the CustomCPUCFSQuotaPeriod feature gate. CPUCFSQuotaPeriod metav1.Duration // maxOpenFiles is Number of files that can be opened by Kubelet process. MaxOpenFiles int64 @@ -418,7 +429,7 @@ type KubeletConfiguration struct { // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information. KubeReservedCgroup string // This flag specifies the various Node Allocatable enforcements that Kubelet needs to perform. - // This flag accepts a list of options. Acceptable options are `pods`, `system-reserved` & `kube-reserved`. + // This flag accepts a list of options. Acceptable options are `pods`, `system-reserved`, `system-reserved-compressible`, `kube-reserved`, and `kube-reserved-compressible`. // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information. EnforceNodeAllocatable []string // This option specifies the cpu list reserved for the host level system threads and kubernetes related threads. @@ -440,7 +451,6 @@ type KubeletConfiguration struct { // EnableSystemLogHandler has to be enabled in addition for this feature to work. // Enabling this feature has security implications. The recommendation is to enable it on a need basis for debugging // purposes and disabling otherwise. - // +featureGate=NodeLogQuery // +optional EnableSystemLogQuery bool // ShutdownGracePeriod specifies the total duration that the node should delay the shutdown and total grace period for pod termination during a node shutdown. @@ -492,6 +502,16 @@ type KubeletConfiguration struct { // +featureGate=MemoryQoS // +optional MemoryThrottlingFactor *float64 + // MemoryReservationPolicy controls how the kubelet applies cgroup v2 memory protection. + // "None" (default): The kubelet does not set memory.min for containers and pods, + // ensuring no hard memory is locked by the kernel. + // "TieredReservation": The kubelet sets cgroup v2 memory.min for Guaranteed pods and memory.low for Burstable pods based on memory requests. + // Guaranteed memory is never reclaimed by the kernel; Burstable memory is preferentially retained but may be reclaimed under extreme pressure. + // See https://kep.k8s.io/2570 for more details. + // Default: None + // +featureGate=MemoryQoS + // +optional + MemoryReservationPolicy MemoryReservationPolicy // registerWithTaints are an array of taints to add to a node object when // the kubelet registers itself. This only takes effect when registerNode // is true and upon the initial registration of the node. @@ -841,6 +861,18 @@ const ( AlwaysVerify ImagePullCredentialsVerificationPolicy = "AlwaysVerify" ) +// MemoryReservationPolicy defines how the kubelet applies cgroup v2 memory protection. +type MemoryReservationPolicy string + +const ( + // NoneMemoryReservationPolicy disables memory.min protection for containers and pods. + // This is the default to maintain node stability by preventing "locked" memory. + NoneMemoryReservationPolicy MemoryReservationPolicy = "None" + // TieredReservationMemoryReservationPolicy enables tiered memory protection: + // memory.min for Guaranteed pods, memory.low for Burstable pods. + TieredReservationMemoryReservationPolicy MemoryReservationPolicy = "TieredReservation" +) + // ImagePullIntent is a record of the kubelet attempting to pull an image. // // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/defaults.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/defaults.go index ba5e7aeb60..2d30c50a38 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/defaults.go @@ -41,7 +41,8 @@ const ( DefaultVolumePluginDir = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/" DefaultPodLogsDir = "/var/log/pods" // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2570-memory-qos - DefaultMemoryThrottlingFactor = 0.9 + DefaultMemoryThrottlingFactor = 0.9 + DefaultMemoryReservationPolicy = kubeletconfigv1beta1.NoneMemoryReservationPolicy // MaxContainerBackOff is the max backoff period for container restarts, exported for the e2e test MaxContainerBackOff = 300 * time.Second ) @@ -295,6 +296,9 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura if obj.MemoryThrottlingFactor == nil { obj.MemoryThrottlingFactor = ptr.To(DefaultMemoryThrottlingFactor) } + if obj.MemoryReservationPolicy == "" { + obj.MemoryReservationPolicy = DefaultMemoryReservationPolicy + } if obj.RegisterNode == nil { obj.RegisterNode = ptr.To(true) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go index 96c6d7df9c..05bf134e67 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go @@ -582,6 +582,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in out.TLSCertFile = in.TLSCertFile out.TLSPrivateKeyFile = in.TLSPrivateKeyFile out.TLSCipherSuites = *(*[]string)(unsafe.Pointer(&in.TLSCipherSuites)) + out.TLSCurvePreferences = *(*[]int32)(unsafe.Pointer(&in.TLSCurvePreferences)) out.TLSMinVersion = in.TLSMinVersion out.RotateCertificates = in.RotateCertificates out.ServerTLSBootstrap = in.ServerTLSBootstrap @@ -749,6 +750,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in return err } out.MemoryThrottlingFactor = (*float64)(unsafe.Pointer(in.MemoryThrottlingFactor)) + out.MemoryReservationPolicy = config.MemoryReservationPolicy(in.MemoryReservationPolicy) out.RegisterWithTaints = *(*[]corev1.Taint)(unsafe.Pointer(&in.RegisterWithTaints)) if err := v1.Convert_Pointer_bool_To_bool(&in.RegisterNode, &out.RegisterNode, s); err != nil { return err @@ -790,6 +792,7 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in out.TLSCertFile = in.TLSCertFile out.TLSPrivateKeyFile = in.TLSPrivateKeyFile out.TLSCipherSuites = *(*[]string)(unsafe.Pointer(&in.TLSCipherSuites)) + out.TLSCurvePreferences = *(*[]int32)(unsafe.Pointer(&in.TLSCurvePreferences)) out.TLSMinVersion = in.TLSMinVersion out.RotateCertificates = in.RotateCertificates out.ServerTLSBootstrap = in.ServerTLSBootstrap @@ -952,6 +955,7 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in return err } out.MemoryThrottlingFactor = (*float64)(unsafe.Pointer(in.MemoryThrottlingFactor)) + out.MemoryReservationPolicy = configv1beta1.MemoryReservationPolicy(in.MemoryReservationPolicy) out.RegisterWithTaints = *(*[]corev1.Taint)(unsafe.Pointer(&in.RegisterWithTaints)) if err := v1.Convert_bool_To_Pointer_bool(&in.RegisterNode, &out.RegisterNode, s); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation.go index 5fc256fc79..625f77ac8f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation.go @@ -96,6 +96,9 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration, featur if kc.ImageMaximumGCAge.Duration != 0 && !localFeatureGate.Enabled(features.ImageMaximumGCAge) { allErrors = append(allErrors, fmt.Errorf("invalid configuration: ImageMaximumGCAge feature gate is required for Kubelet configuration option imageMaximumGCAge")) } + if kc.ImageMinimumGCAge.Duration < 0 { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: imageMinimumGCAge %v must not be negative", kc.ImageMinimumGCAge.Duration)) + } if kc.ImageMaximumGCAge.Duration < 0 { allErrors = append(allErrors, fmt.Errorf("invalid configuration: imageMaximumGCAge %v must not be negative", kc.ImageMaximumGCAge.Duration)) } @@ -348,6 +351,17 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration, featur allErrors = append(allErrors, fmt.Errorf("invalid configuration: memoryThrottlingFactor %v must be greater than 0 and less than or equal to 1.0", *kc.MemoryThrottlingFactor)) } + if !localFeatureGate.Enabled(features.MemoryQoS) && + kc.MemoryReservationPolicy == kubeletconfig.TieredReservationMemoryReservationPolicy { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: memoryReservationPolicy %q requires MemoryQoS feature gate to be enabled", + kc.MemoryReservationPolicy)) + } + switch kc.MemoryReservationPolicy { + case kubeletconfig.NoneMemoryReservationPolicy, kubeletconfig.TieredReservationMemoryReservationPolicy: + default: + allErrors = append(allErrors, fmt.Errorf("invalid configuration: option %q specified for memoryReservationPolicy. Valid options are %q or %q", kc.MemoryReservationPolicy, kubeletconfig.NoneMemoryReservationPolicy, kubeletconfig.TieredReservationMemoryReservationPolicy)) + } + if kc.ContainerRuntimeEndpoint == "" { allErrors = append(allErrors, fmt.Errorf("invalid configuration: the containerRuntimeEndpoint was not specified or empty")) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_linux.go index 76c976f6c0..e7a9552636 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_others.go index 34adffb844..876c749f66 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_others.go @@ -1,5 +1,4 @@ //go:build !windows && !linux -// +build !windows,!linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_windows.go index 510d315da0..3a5b85abe9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/validation/validation_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go index 8acf533277..26c3758636 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go @@ -333,6 +333,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.TLSCurvePreferences != nil { + in, out := &in.TLSCurvePreferences, &out.TLSCurvePreferences + *out = make([]int32, len(*in)) + copy(*out, *in) + } out.Authentication = in.Authentication out.Authorization = in.Authorization if in.PreloadedImagesVerificationAllowlist != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/OWNERS new file mode 100644 index 0000000000..17d8895059 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-node-approvers # https://github.com/kubernetes/kubernetes/blob/master/OWNERS_ALIASES#LC220:~:text=sig%2Dnode%2Dapprovers + - ffromani +reviewers: + - sig-node-reviewers # see https://github.com/kubernetes/kubernetes/blob/master/OWNERS_ALIASES#LC220:~:text=sig%2Dnode%2Dreviewers +labels: + - area/kubelet + - sig/node diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go index d5524e68ba..19ea25ce73 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go @@ -64,6 +64,7 @@ func (p *v1PodResourcesServer) List(ctx context.Context, req *podresourcesv1.Lis var pods []*v1.Pod if p.useActivePods { + // GetActivePods already filters out terminal pods, so no need for additional filtering. pods = p.podsProvider.GetActivePods() } else { pods = p.podsProvider.GetPods() @@ -119,11 +120,6 @@ func (p *v1PodResourcesServer) Get(ctx context.Context, req *podresourcesv1.GetP metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1").Inc() metrics.PodResourcesEndpointRequestsGetCount.WithLabelValues("v1").Inc() - if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletPodResourcesGet) { - metrics.PodResourcesEndpointErrorsGetCount.WithLabelValues("v1").Inc() - return nil, fmt.Errorf("PodResources API Get method disabled") - } - pod, exist := p.podsProvider.GetPodByName(req.PodNamespace, req.PodName) if !exist { metrics.PodResourcesEndpointErrorsGetCount.WithLabelValues("v1").Inc() @@ -157,14 +153,11 @@ func (p *v1PodResourcesServer) Get(ctx context.Context, req *podresourcesv1.GetP func (p *v1PodResourcesServer) getContainerResources(pod *v1.Pod, container *v1.Container) *podresourcesv1.ContainerResources { containerResources := &podresourcesv1.ContainerResources{ - Name: container.Name, - Devices: p.devicesProvider.GetDevices(string(pod.UID), container.Name), - CpuIds: p.cpusProvider.GetCPUs(string(pod.UID), container.Name), - Memory: p.memoryProvider.GetMemory(string(pod.UID), container.Name), + Name: container.Name, + Devices: p.devicesProvider.GetDevices(string(pod.UID), container.Name), + CpuIds: p.cpusProvider.GetCPUs(string(pod.UID), container.Name), + Memory: p.memoryProvider.GetMemory(string(pod.UID), container.Name), + DynamicResources: p.dynamicResourcesProvider.GetDynamicResources(pod, container), } - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletPodResourcesDynamicResources) { - containerResources.DynamicResources = p.dynamicResourcesProvider.GetDynamicResources(pod, container) - } - return containerResources } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/constants.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/constants.go new file mode 100644 index 0000000000..43d5bcc38b --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/constants.go @@ -0,0 +1,26 @@ +/* +Copyright 2025 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 pods + +const ( + Resource = "/pods" + Socket = "pods-api" + + // Duplicated from PodResources API + DefaultQPS = 100 + DefaultBurstTokens = 10 +) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/server.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/server.go new file mode 100644 index 0000000000..5b9fff3e7f --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/pods/server.go @@ -0,0 +1,348 @@ +/* +Copyright 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 pods + +import ( + "context" + "sort" + "sync" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/status" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/klog/v2" + podsv1alpha1 "k8s.io/kubelet/pkg/apis/pods/v1alpha1" + "k8s.io/kubernetes/pkg/kubelet/metrics" + "k8s.io/kubernetes/pkg/kubelet/pod" + podstatus "k8s.io/kubernetes/pkg/kubelet/status" +) + +type PodWatchEvent struct { + Type watch.EventType + UID types.UID + Pod *v1.Pod +} + +type broadcaster struct { + lock sync.RWMutex + clients map[chan PodWatchEvent]struct{} + incoming chan PodWatchEvent +} + +func NewBroadcaster() *broadcaster { + b := &broadcaster{ + clients: make(map[chan PodWatchEvent]struct{}), + incoming: make(chan PodWatchEvent, 1000), + } + go b.run() + return b +} + +func (b *broadcaster) run() { + logger := klog.FromContext(context.Background()) + for event := range b.incoming { + b.lock.RLock() + // We collect clients to drop to avoid modifying the map during iteration + // which would require a Write lock and block other RLockers. + var clientsToDrop []chan PodWatchEvent + + for client := range b.clients { + select { + case client <- event: + default: + logger.Info("Watch client channel is full, dropping client.") + metrics.PodWatchEventsDroppedTotal.Inc() + clientsToDrop = append(clientsToDrop, client) + } + } + b.lock.RUnlock() + + if len(clientsToDrop) > 0 { + b.lock.Lock() + for _, client := range clientsToDrop { + if _, ok := b.clients[client]; ok { + delete(b.clients, client) + close(client) + } + } + b.lock.Unlock() + } + } +} + +func (b *broadcaster) Register(client chan PodWatchEvent) { + b.lock.Lock() + defer b.lock.Unlock() + b.clients[client] = struct{}{} + logger := klog.FromContext(context.Background()) + logger.Info("Registered new watch client", "totalClients", len(b.clients)) +} + +func (b *broadcaster) Unregister(client chan PodWatchEvent) { + b.lock.Lock() + defer b.lock.Unlock() + if _, ok := b.clients[client]; ok { + delete(b.clients, client) + close(client) + } + logger := klog.FromContext(context.Background()) + logger.Info("Unregistered watch client", "totalClients", len(b.clients)) +} + +func (b *broadcaster) Broadcast(event PodWatchEvent) { + select { + case b.incoming <- event: + default: + // This should realistically never happen because run() purges slow clients. + logger := klog.FromContext(context.Background()) + logger.Info("Broadcaster internal buffer full, dropping event.") + metrics.PodWatchEventsDroppedTotal.Inc() + } +} + +// PodsServer is the gRPC server that provides pod information. +type PodsServer struct { + podsv1alpha1.UnimplementedPodsServer + podManager pod.Manager + statusProvider podstatus.PodStatusProvider + broadcaster *broadcaster +} + +// NewPodsServer creates a new PodServer for production use. +func NewPodsServer(broadcaster *broadcaster, podManager pod.Manager, statusProvider podstatus.PodStatusProvider) *PodsServer { + return &PodsServer{ + podManager: podManager, + statusProvider: statusProvider, + broadcaster: broadcaster, + } +} + +// NewPodsServerForTest creates a new PodServer with an injectable ticker for testing. +func NewPodsServerForTest(broadcaster *broadcaster, podManager pod.Manager, statusProvider podstatus.PodStatusProvider) *PodsServer { + return &PodsServer{ + podManager: podManager, + statusProvider: statusProvider, + broadcaster: broadcaster, + } +} + +// OnPodUpdated is called when a pod's spec and status are coherent. +func (s *PodsServer) OnPodUpdated(pod *v1.Pod, status v1.PodStatus, isAdded bool) { + eventType := watch.Modified + if isAdded { + eventType = watch.Added + } + podCopy := *pod + podCopy.Status = status + s.broadcaster.Broadcast(PodWatchEvent{Type: eventType, UID: pod.UID, Pod: &podCopy}) + logger := klog.FromContext(context.Background()) + logger.Info("Pod update broadcasted", "podUID", pod.UID, "type", eventType) +} + +// OnPodRemoved is called when a pod is removed. +func (s *PodsServer) OnPodRemoved(pod *v1.Pod) { + minimalPod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: pod.Name, + Namespace: pod.Namespace, + UID: pod.UID, + }, + } + s.broadcaster.Broadcast(PodWatchEvent{Type: watch.Deleted, UID: pod.UID, Pod: minimalPod}) + logger := klog.FromContext(context.Background()) + logger.Info("Pod removed broadcasted", "podUID", pod.UID) +} + +// ListPods returns a list of pods. +func (s *PodsServer) ListPods(ctx context.Context, req *podsv1alpha1.ListPodsRequest) (*podsv1alpha1.ListPodsResponse, error) { + logger := klog.FromContext(ctx) + logger.Info("ListPods called") + + // TODO: Implement filtering based on req.Filter, pagination with req.PageToken and req.PageSize + podsToReturn := s.podManager.GetPods() + sort.Slice(podsToReturn, func(i, j int) bool { + return podsToReturn[i].UID < podsToReturn[j].UID + }) + + protoPods := make([][]byte, len(podsToReturn)) + for i, p := range podsToReturn { + podToMarshal := p + if podStatus, ok := s.statusProvider.GetPodStatus(p.UID); ok { + podCopy := *p + podCopy.Status = podStatus + podToMarshal = &podCopy + } + podBytes, err := podToMarshal.Marshal() + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to marshal pod: %v", err) + } + protoPods[i] = podBytes + } + + return &podsv1alpha1.ListPodsResponse{Pods: protoPods}, nil +} + +// GetPod returns a single pod by UID. +func (s *PodsServer) GetPod(ctx context.Context, req *podsv1alpha1.GetPodRequest) (*podsv1alpha1.GetPodResponse, error) { + logger := klog.FromContext(ctx) + logger.Info("GetPod called", "podUID", req.PodUID) + + podUID := types.UID(req.PodUID) + pod, ok := s.podManager.GetPodByUID(podUID) + if !ok { + return nil, status.Errorf(codes.NotFound, "pod with UID %s not found", req.PodUID) + } + + podToMarshal := pod + if podStatus, ok := s.statusProvider.GetPodStatus(podUID); ok { + podCopy := *pod + podCopy.Status = podStatus + podToMarshal = &podCopy + } + + podBytes, err := podToMarshal.Marshal() + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to marshal pod: %v", err) + } + + return &podsv1alpha1.GetPodResponse{Pod: podBytes}, nil +} + +// WatchPods streams pod events. +func (s *PodsServer) WatchPods(req *podsv1alpha1.WatchPodsRequest, stream podsv1alpha1.Pods_WatchPodsServer) error { + clientAddr := "unknown" + if p, ok := peer.FromContext(stream.Context()); ok { + clientAddr = p.Addr.String() + } + logger := klog.FromContext(stream.Context()) + logger.Info("WatchPods called", "client", clientAddr) + + clientChannel := make(chan PodWatchEvent, 100) + s.broadcaster.Register(clientChannel) + defer func() { + s.broadcaster.Unregister(clientChannel) + logger.Info("Watch client disconnected", "client", clientAddr) + }() + + // Send initial ADDED events + initialPods := s.podManager.GetPods() + sort.Slice(initialPods, func(i, j int) bool { + return initialPods[i].UID < initialPods[j].UID + }) + + for _, p := range initialPods { + podToMarshal := p + if podStatus, ok := s.statusProvider.GetPodStatus(p.UID); ok { + podCopy := *p + podCopy.Status = podStatus + podToMarshal = &podCopy + } + podBytes, err := podToMarshal.Marshal() + if err != nil { + logger.Error(err, "Error marshalling initial watch event pod") + metrics.PodWatchEventsDroppedTotal.Inc() + return status.Errorf(codes.Internal, "error marshalling initial watch event pod: %v", err) + } + if err := stream.Send(&podsv1alpha1.WatchPodsEvent{ + Type: podsv1alpha1.EventType_ADDED, + Pod: podBytes, + }); err != nil { + logger.Error(err, "Error sending initial watch event") + return err + } + } + + // Send INITIAL_SYNC_COMPLETE event to indicate that the initial list is complete + if err := stream.Send(&podsv1alpha1.WatchPodsEvent{ + Type: podsv1alpha1.EventType_INITIAL_SYNC_COMPLETE, + }); err != nil { + logger.Error(err, "Error sending initial sync watch event") + return err + } + + for { + select { + case <-stream.Context().Done(): + logger.Info("Watch context cancelled", "client", clientAddr) + return stream.Context().Err() + case event, ok := <-clientChannel: + if !ok { + logger.Info("Watch client channel closed", "client", clientAddr) + return status.Errorf(codes.ResourceExhausted, "watch client channel closed") + } + var podToMarshal *v1.Pod + if event.Pod != nil { + podToMarshal = event.Pod + } else if event.Type != watch.Bookmark { + // Fallback to looking up the pod if it is not provided in the event. + // This should not happen with the current implementation but is kept for safety. + p, ok := s.podManager.GetPodByUID(event.UID) + if ok { + podToMarshal = p + } else { + logger.Info("Pod not found in manager during watch event processing", "uid", event.UID, "type", event.Type) + continue + } + } + + var podBytes []byte + if podToMarshal != nil { + var err error + podBytes, err = podToMarshal.Marshal() + if err != nil { + logger.Error(err, "Error marshalling watch event pod") + metrics.PodWatchEventsDroppedTotal.Inc() + return status.Errorf(codes.Internal, "error marshalling watch event pod: %v", err) + } + } + + eventType, err := convertWatchEventType(event.Type) + if err != nil { + logger.Error(err, "Unknown watch event type") + continue + } + + if err := stream.Send(&podsv1alpha1.WatchPodsEvent{ + Type: eventType, + Pod: podBytes, + }); err != nil { + logger.Error(err, "Error sending watch event to client", "client", clientAddr) + return err + } + } + } +} + +func convertWatchEventType(watchType watch.EventType) (podsv1alpha1.EventType, error) { + switch watchType { + case watch.Added: + return podsv1alpha1.EventType_ADDED, nil + case watch.Modified: + return podsv1alpha1.EventType_MODIFIED, nil + case watch.Deleted: + return podsv1alpha1.EventType_DELETED, nil + case watch.Bookmark: + return podsv1alpha1.EventType_INITIAL_SYNC_COMPLETE, nil + default: + return podsv1alpha1.EventType_UNSPECIFIED, status.Errorf(codes.Internal, "unknown watch event type: %v", watchType) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go index 4b494131d4..f2fd621d39 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2015 The Kubernetes Authors. @@ -33,12 +32,23 @@ import ( _ "github.com/google/cadvisor/container/crio/install" _ "github.com/google/cadvisor/container/systemd/install" + // Register filesystem plugins needed for container stats. + _ "github.com/google/cadvisor/fs/btrfs/install" + _ "github.com/google/cadvisor/fs/devicemapper/install" + _ "github.com/google/cadvisor/fs/nfs/install" + _ "github.com/google/cadvisor/fs/overlay/install" + _ "github.com/google/cadvisor/fs/tmpfs/install" + _ "github.com/google/cadvisor/fs/vfs/install" + _ "github.com/google/cadvisor/fs/zfs/install" + "github.com/google/cadvisor/cache/memory" cadvisormetrics "github.com/google/cadvisor/container" cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" "github.com/google/cadvisor/manager" "github.com/google/cadvisor/utils/sysfs" + "github.com/opencontainers/cgroups" + cgroupfs2 "github.com/opencontainers/cgroups/fs2" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/features" @@ -88,13 +98,12 @@ func init() { } // New creates a new cAdvisor Interface for linux systems. -func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { +func New(logger klog.Logger, imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { sysFs := sysfs.NewRealSysFs() includedMetrics := cadvisormetrics.MetricSet{ cadvisormetrics.CpuUsageMetrics: struct{}{}, cadvisormetrics.MemoryUsageMetrics: struct{}{}, - cadvisormetrics.CpuLoadMetrics: struct{}{}, cadvisormetrics.DiskIOMetrics: struct{}{}, cadvisormetrics.NetworkUsageMetrics: struct{}{}, cadvisormetrics.AppMetrics: struct{}{}, @@ -103,7 +112,11 @@ func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots [ } if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPSI) { - includedMetrics[cadvisormetrics.PressureMetrics] = struct{}{} + if IsPsiEnabled(logger) { + includedMetrics[cadvisormetrics.PressureMetrics] = struct{}{} + } else { + logger.Info("PSI support not available") + } } if usingLegacyStats || localStorageCapacityIsolation { @@ -163,6 +176,26 @@ func (cc *cadvisorClient) ImagesFsInfo(ctx context.Context) (cadvisorapiv2.FsInf return cc.getFsInfo(ctx, label) } +// IsPsiEnabled checks whether PSI (Pressure Stall Information) is available on +// the host by opening the root cgroup's cpu.pressure file using the same +// opencontainers/cgroups library that cAdvisor uses to read actual PSI values. +// PSI is a single kernel feature (CONFIG_PSI / boot param "psi=") so checking +// cpu.pressure alone is sufficient to determine support for all three resources +// (cpu, memory, io). +func IsPsiEnabled(logger klog.Logger) bool { + return isPsiEnabled(logger, cgroupfs2.UnifiedMountpoint, "cpu.pressure") +} + +func isPsiEnabled(logger klog.Logger, cgroupDir, psiFile string) bool { + f, err := cgroups.OpenFile(cgroupDir, psiFile, os.O_RDONLY) + if err != nil { + logger.V(4).Info("PSI not available", "dir", cgroupDir, "file", psiFile, "err", err) + return false + } + _ = f.Close() + return true +} + func (cc *cadvisorClient) RootFsInfo() (cadvisorapiv2.FsInfo, error) { return cc.GetDirFsInfo(cc.rootPath) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go index e555f2e579..5c7b63e040 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2015 The Kubernetes Authors. @@ -25,6 +24,7 @@ import ( cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" + "k8s.io/klog/v2" ) type cadvisorUnsupported struct { @@ -33,7 +33,7 @@ type cadvisorUnsupported struct { var _ Interface = new(cadvisorUnsupported) // New creates a new cAdvisor Interface for unsupported systems. -func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupsRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { +func New(_ klog.Logger, imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupsRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { return &cadvisorUnsupported{}, nil } @@ -74,3 +74,7 @@ func (cu *cadvisorUnsupported) ContainerFsInfo(context.Context) (cadvisorapiv2.F func (cu *cadvisorUnsupported) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) { return cadvisorapiv2.FsInfo{}, nil } + +func IsPsiEnabled(_ klog.Logger) bool { + return false +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_windows.go index 5e688cbe84..c9003b6963 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2015 The Kubernetes Authors. @@ -24,7 +23,6 @@ import ( cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" - "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/kubelet/winstats" ) @@ -37,7 +35,7 @@ type cadvisorClient struct { var _ Interface = new(cadvisorClient) // New creates a cAdvisor and exports its API on the specified port if port > 0. -func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { +func New(_ klog.Logger, imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { client, err := winstats.NewPerfCounterClient(klog.TODO()) return &cadvisorClient{ rootPath: rootPath, @@ -81,3 +79,7 @@ func (cu *cadvisorClient) RootFsInfo() (cadvisorapiv2.FsInfo, error) { func (cu *cadvisorClient) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) { return cu.winStatsClient.GetDirFsInfo(path) } + +func IsPsiEnabled(_ klog.Logger) bool { + return false +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_linux.go index 684274787e..fb19f47ec4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_unsupported.go index 7d4dd4f7c4..a8e3dca97e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/admission/errors.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/admission/errors.go index 5e54922039..1072e7938b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/admission/errors.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/admission/errors.go @@ -24,7 +24,8 @@ import ( ) const ( - ErrorReasonUnexpected = "UnexpectedAdmissionError" + ErrorReasonUnexpected = "UnexpectedAdmissionError" + ErrorReasonEmptyPodSharedPool = "EmptyPodSharedPoolError" ) type Error interface { @@ -44,6 +45,26 @@ func (e *unexpectedAdmissionError) Type() string { return ErrorReasonUnexpected } +// EmptyPodSharedPoolError represents an error due to a pod spec being invalid +// when the Topology manager's scope is set to pod, because the pod spec +// produces an empty pod shared pool and there are containers that require it. +type EmptyPodSharedPoolError struct { + message string +} + +// NewEmptyPodSharedPoolError returns a new EmptyPodSharedPoolError. +func NewEmptyPodSharedPoolError(err error) *EmptyPodSharedPoolError { + return &EmptyPodSharedPoolError{message: err.Error()} +} + +func (e *EmptyPodSharedPoolError) Error() string { + return e.message +} + +func (e *EmptyPodSharedPoolError) Type() string { + return ErrorReasonEmptyPodSharedPool +} + func GetPodAdmitResult(err error) lifecycle.PodAdmitResult { if err == nil { return lifecycle.PodAdmitResult{Admit: true} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go index 45b63a88d4..c698d3cb40 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go @@ -42,6 +42,8 @@ const ( systemdSuffix string = ".slice" // Cgroup2MemoryMin is memory.min for cgroup v2 Cgroup2MemoryMin string = "memory.min" + // Cgroup2MemoryLow is memory.low for cgroup v2 + Cgroup2MemoryLow string = "memory.low" // Cgroup2MemoryHigh is memory.high for cgroup v2 Cgroup2MemoryHigh string = "memory.high" Cgroup2MaxCpuLimit string = "max" @@ -308,7 +310,7 @@ func (m *cgroupCommon) toResources(logger klog.Logger, resourceConfig *ResourceC resources.CpuPeriod = *resourceConfig.CPUPeriod } if resourceConfig.PidsLimit != nil { - resources.PidsLimit = *resourceConfig.PidsLimit + resources.PidsLimit = resourceConfig.PidsLimit } if !resourceConfig.CPUSet.IsEmpty() { resources.CpusetCpus = resourceConfig.CPUSet.String() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_unsupported.go index 5088e7b132..dd8cab7942 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager.go index b1719fe85a..b761f6d952 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager.go @@ -60,7 +60,7 @@ const ( type ActivePodsFunc func() []*v1.Pod -type GetNodeFunc func() (*v1.Node, error) +type GetNodeFunc func(context.Context) (*v1.Node, error) // Manages the containers running on a machine. type ContainerManager interface { @@ -193,6 +193,7 @@ type NodeConfig struct { CPUManagerReconcilePeriod time.Duration MemoryManagerPolicy string MemoryManagerReservedMemory []kubeletconfig.MemoryReservation + MemoryReservationPolicy kubeletconfig.MemoryReservationPolicy PodPidsLimit int64 EnforceCPULimits bool CPUCFSQuotaPeriod time.Duration @@ -224,25 +225,25 @@ func int64Slice(in []int) []int64 { return out } -func podHasExclusiveCPUs(cr cpuAllocationReader, pod *v1.Pod) bool { +func podHasExclusiveCPUs(logger klog.Logger, cr cpuAllocationReader, pod *v1.Pod) bool { for _, container := range pod.Spec.InitContainers { - if containerHasExclusiveCPUs(cr, pod, &container) { + if containerHasExclusiveCPUs(logger, cr, pod, &container) { return true } } for _, container := range pod.Spec.Containers { - if containerHasExclusiveCPUs(cr, pod, &container) { + if containerHasExclusiveCPUs(logger, cr, pod, &container) { return true } } - klog.V(4).InfoS("Pod contains no container with pinned cpus", "podName", pod.Name) + logger.V(4).Info("Pod contains no container with pinned cpus", "podName", pod.Name) return false } -func containerHasExclusiveCPUs(cr cpuAllocationReader, pod *v1.Pod, container *v1.Container) bool { +func containerHasExclusiveCPUs(logger klog.Logger, cr cpuAllocationReader, pod *v1.Pod, container *v1.Container) bool { exclusiveCPUs := cr.GetExclusiveCPUs(string(pod.UID), container.Name) if !exclusiveCPUs.IsEmpty() { - klog.V(4).InfoS("Container has pinned cpus", "podName", pod.Name, "containerName", container.Name) + logger.V(4).Info("Container has pinned cpus", "podName", pod.Name, "containerName", container.Name) return true } return false diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go index 0b19cd7a7d..161a973fe4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2015 The Kubernetes Authors. @@ -45,6 +44,7 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/record" utilsysctl "k8s.io/component-helpers/node/util/sysctl" + resourcehelper "k8s.io/component-helpers/resource" internalapi "k8s.io/cri-api/pkg/apis" pluginwatcherapi "k8s.io/kubelet/pkg/apis/pluginregistration/v1" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" @@ -55,6 +55,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/cm/dra" "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" memorymanagerstate "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" + cmqos "k8s.io/kubernetes/pkg/kubelet/cm/qos" "k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" cmutil "k8s.io/kubernetes/pkg/kubelet/cm/util" @@ -149,7 +150,7 @@ var _ ContainerManager = &containerManagerImpl{} // checks if the required cgroups subsystems are mounted. // As of now, only 'cpu' and 'memory' are required. // cpu quota is a soft requirement. -func validateSystemRequirements(mountUtil mount.Interface) (features, error) { +func validateSystemRequirements(logger klog.Logger, mountUtil mount.Interface) (features, error) { const ( cgroupMountType = "cgroup" localErr = "system validation failed" @@ -190,11 +191,11 @@ func validateSystemRequirements(mountUtil mount.Interface) (features, error) { // CPU cgroup is required and so it expected to be mounted at this point. periodExists, err := utilpath.Exists(utilpath.CheckFollowSymlink, path.Join(cpuMountPoint, "cpu.cfs_period_us")) if err != nil { - klog.ErrorS(err, "Failed to detect if CPU cgroup cpu.cfs_period_us is available") + logger.Error(err, "Failed to detect if CPU cgroup cpu.cfs_period_us is available") } quotaExists, err := utilpath.Exists(utilpath.CheckFollowSymlink, path.Join(cpuMountPoint, "cpu.cfs_quota_us")) if err != nil { - klog.ErrorS(err, "Failed to detect if CPU cgroup cpu.cfs_quota_us is available") + logger.Error(err, "Failed to detect if CPU cgroup cpu.cfs_quota_us is available") } if quotaExists && periodExists { f.cpuHardcapping = true @@ -408,8 +409,9 @@ func (cm *containerManagerImpl) NewPodContainerManager() PodContainerManager { enforceCPULimits: cm.EnforceCPULimits, // cpuCFSQuotaPeriod is in microseconds. NodeConfig.CPUCFSQuotaPeriod is time.Duration (measured in nano seconds). // Convert (cm.CPUCFSQuotaPeriod) [nanoseconds] / time.Microsecond (1000) to get cpuCFSQuotaPeriod in microseconds. - cpuCFSQuotaPeriod: uint64(cm.CPUCFSQuotaPeriod / time.Microsecond), - podContainerManager: cm, + cpuCFSQuotaPeriod: uint64(cm.CPUCFSQuotaPeriod / time.Microsecond), + podContainerManager: cm, + memoryReservationPolicy: cm.MemoryReservationPolicy, } } return &podContainerManagerNoop{ @@ -418,11 +420,39 @@ func (cm *containerManagerImpl) NewPodContainerManager() PodContainerManager { } func (cm *containerManagerImpl) PodHasExclusiveCPUs(pod *v1.Pod) bool { - return podHasExclusiveCPUs(cm.cpuManager, pod) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + + if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { + if cm.cpuManager.GetResourceIsolationLevel(pod, &container) != cmqos.ResourceIsolationContainer { + return false + } + } + + logger.V(4).Info("Pod has pinned cpus", "podName", pod.Name) + return true + } + + return podHasExclusiveCPUs(logger, cm.cpuManager, pod) } func (cm *containerManagerImpl) ContainerHasExclusiveCPUs(pod *v1.Pod, container *v1.Container) bool { - return containerHasExclusiveCPUs(cm.cpuManager, pod, container) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + + if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResourceManagers) { + if cm.cpuManager.GetResourceIsolationLevel(pod, container) != cmqos.ResourceIsolationContainer { + return false + } + + logger.V(4).Info("Container has pinned cpus", "podName", pod.Name, "containerName", container.Name) + return true + } + + return containerHasExclusiveCPUs(logger, cm.cpuManager, pod, container) } func (cm *containerManagerImpl) InternalContainerLifecycle() InternalContainerLifecycle { @@ -453,7 +483,7 @@ const ( // setupKernelTunables validates kernel tunable flags are set as expected // depending upon the specified option, it will either warn, error, or modify the kernel tunable flags -func setupKernelTunables(option KernelTunableBehavior) error { +func setupKernelTunables(logger klog.Logger, option KernelTunableBehavior) error { desiredState := map[string]int{ utilsysctl.VMOvercommitMemory: utilsysctl.VMOvercommitMemoryAlways, utilsysctl.VMPanicOnOOM: utilsysctl.VMPanicOnOOMInvokeOOMKiller, @@ -480,17 +510,17 @@ func setupKernelTunables(option KernelTunableBehavior) error { case KernelTunableError: errList = append(errList, fmt.Errorf("invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val)) case KernelTunableWarn: - klog.V(2).InfoS("Invalid kernel flag", "flag", flag, "expectedValue", expectedValue, "actualValue", val) + logger.V(2).Info("Invalid kernel flag", "flag", flag, "expectedValue", expectedValue, "actualValue", val) case KernelTunableModify: - klog.V(2).InfoS("Updating kernel flag", "flag", flag, "expectedValue", expectedValue, "actualValue", val) + logger.V(2).Info("Updating kernel flag", "flag", flag, "expectedValue", expectedValue, "actualValue", val) err = sysctl.SetSysctl(flag, expectedValue) if err != nil { if inuserns.RunningInUserNS() { if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletInUserNamespace) { - klog.V(2).InfoS("Updating kernel flag failed (running in UserNS, ignoring)", "flag", flag, "err", err) + logger.V(2).Info("Updating kernel flag failed (running in UserNS, ignoring)", "flag", flag, "err", err) continue } - klog.ErrorS(err, "Updating kernel flag failed (Hint: enable KubeletInUserNamespace feature flag to ignore the error)", "flag", flag) + logger.Error(err, "Updating kernel flag failed (Hint: enable KubeletInUserNamespace feature flag to ignore the error)", "flag", flag) } errList = append(errList, err) } @@ -502,7 +532,7 @@ func setupKernelTunables(option KernelTunableBehavior) error { func (cm *containerManagerImpl) setupNode(ctx context.Context, activePods ActivePodsFunc) error { logger := klog.FromContext(ctx) - f, err := validateSystemRequirements(cm.mountUtil) + f, err := validateSystemRequirements(logger, cm.mountUtil) if err != nil { return err } @@ -513,7 +543,7 @@ func (cm *containerManagerImpl) setupNode(ctx context.Context, activePods Active if cm.GetNodeConfig().ProtectKernelDefaults { b = KernelTunableError } - if err := setupKernelTunables(b); err != nil { + if err := setupKernelTunables(logger, b); err != nil { return err } @@ -544,7 +574,7 @@ func (cm *containerManagerImpl) setupNode(ctx context.Context, activePods Active return err } cont.ensureStateFunc = func(manager cgroups.Manager) error { - return ensureSystemCgroups("/", manager) + return ensureSystemCgroups(logger, "/", manager) } systemContainers = append(systemContainers, cont) } @@ -650,9 +680,11 @@ func (cm *containerManagerImpl) Start(ctx context.Context, node *v1.Node, if err != nil { return fmt.Errorf("failed to get rootfs info: %v", err) } + cm.Lock() for rName, rCap := range cadvisor.EphemeralStorageCapacityFromFsInfo(rootfs) { cm.capacity[rName] = rCap } + cm.Unlock() } // Ensure that node allocatable configuration is valid. @@ -772,23 +804,23 @@ func (cm *containerManagerImpl) SystemCgroupsLimit() v1.ResourceList { } } -func isProcessRunningInHost(pid int) (bool, error) { +func isProcessRunningInHost(logger klog.Logger, pid int) (bool, error) { // Get init pid namespace. initPidNs, err := os.Readlink("/proc/1/ns/pid") if err != nil { return false, fmt.Errorf("failed to find pid namespace of init process") } - klog.V(10).InfoS("Found init PID namespace", "namespace", initPidNs) + logger.V(10).Info("Found init PID namespace", "namespace", initPidNs) processPidNs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/pid", pid)) if err != nil { - return false, fmt.Errorf("failed to find pid namespace of process %q", pid) + return false, fmt.Errorf("failed to find pid namespace of process %d", pid) } - klog.V(10).InfoS("Process info", "pid", pid, "namespace", processPidNs) + logger.V(10).Info("Process info", "pid", pid, "namespace", processPidNs) return initPidNs == processPidNs, nil } func ensureProcessInContainerWithOOMScore(logger klog.Logger, pid int, oomScoreAdj int, manager cgroups.Manager) error { - if runningInHost, err := isProcessRunningInHost(pid); err != nil { + if runningInHost, err := isProcessRunningInHost(logger, pid); err != nil { // Err on the side of caution. Avoid moving the docker daemon unless we are able to identify its context. return err } else if !runningInHost { @@ -888,7 +920,7 @@ func getContainer(logger klog.Logger, pid int) (string, error) { // // The reason of leaving kernel threads at root cgroup is that we don't want to tie the // execution of these threads with to-be defined /system quota and create priority inversions. -func ensureSystemCgroups(rootCgroupPath string, manager cgroups.Manager) error { +func ensureSystemCgroups(logger klog.Logger, rootCgroupPath string, manager cgroups.Manager) error { // Move non-kernel PIDs to the system container. // Only keep errors on latest attempt. var finalErr error @@ -914,7 +946,7 @@ func ensureSystemCgroups(rootCgroupPath string, manager cgroups.Manager) error { return nil } - klog.V(3).InfoS("Moving non-kernel processes", "pids", pids) + logger.V(3).Info("Moving non-kernel processes", "pids", pids) for _, pid := range pids { err := manager.Apply(pid) if err != nil { @@ -943,6 +975,11 @@ func isKernelPid(pid int) bool { // GetCapacity returns node capacity data for "cpu", "memory", "ephemeral-storage", and "huge-pages*" // At present this method is only invoked when introspecting ephemeral storage func (cm *containerManagerImpl) GetCapacity(localStorageCapacityIsolation bool) v1.ResourceList { + cm.RLock() + defer cm.RUnlock() + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() if localStorageCapacityIsolation { // We store allocatable ephemeral-storage in the capacity property once we Start() the container manager if _, ok := cm.capacity[v1.ResourceEphemeralStorage]; !ok { @@ -950,7 +987,7 @@ func (cm *containerManagerImpl) GetCapacity(localStorageCapacityIsolation bool) if cm.cadvisorInterface != nil { rootfs, err := cm.cadvisorInterface.RootFsInfo() if err != nil { - klog.ErrorS(err, "Unable to get rootfs data from cAdvisor interface") + logger.Error(err, "Unable to get rootfs data from cAdvisor interface") // If the rootfsinfo retrieval from cAdvisor fails for any reason, fallback to returning the capacity property with no ephemeral storage data return cm.capacity } @@ -1015,6 +1052,9 @@ func (cm *containerManagerImpl) GetAllocatableMemory() []*podresourcesapi.Contai } func (cm *containerManagerImpl) GetDynamicResources(pod *v1.Pod, container *v1.Container) []*podresourcesapi.DynamicResource { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DynamicResourceAllocation) { return []*podresourcesapi.DynamicResource{} } @@ -1022,7 +1062,7 @@ func (cm *containerManagerImpl) GetDynamicResources(pod *v1.Pod, container *v1.C var containerDynamicResources []*podresourcesapi.DynamicResource containerClaimInfos, err := cm.draManager.GetContainerClaimInfos(pod, container) if err != nil { - klog.ErrorS(err, "Unable to get container claim info state") + logger.Error(err, "Unable to get container claim info state") return []*podresourcesapi.DynamicResource{} } for _, containerClaimInfo := range containerClaimInfos { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_unsupported.go index a92f0ce89f..8a5ff199be 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2015 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_windows.go index 1f967620cd..9a7405d3e4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2015 The Kubernetes Authors. @@ -376,9 +375,15 @@ func (cm *containerManagerImpl) PodMightNeedToUnprepareResources(UID types.UID) } func (cm *containerManagerImpl) PodHasExclusiveCPUs(pod *v1.Pod) bool { - return podHasExclusiveCPUs(cm.cpuManager, pod) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + return podHasExclusiveCPUs(logger, cm.cpuManager, pod) } func (cm *containerManagerImpl) ContainerHasExclusiveCPUs(pod *v1.Pod, container *v1.Container) bool { - return containerHasExclusiveCPUs(cm.cpuManager, pod, container) + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() + return containerHasExclusiveCPUs(logger, cm.cpuManager, pod, container) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go index f5a7e249dc..3814300f04 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go @@ -27,12 +27,16 @@ import ( cadvisorapi "github.com/google/cadvisor/info/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" + utilfeature "k8s.io/apiserver/pkg/util/feature" + resourcehelper "k8s.io/component-helpers/resource" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" + kubefeatures "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + cmqos "k8s.io/kubernetes/pkg/kubelet/cm/qos" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/config" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -91,6 +95,9 @@ type Manager interface { // among this and other resource controllers. GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint + // AllocatePod is called to trigger the allocation of CPUs to a pod. + AllocatePod(pod *v1.Pod) error + // GetAllocatableCPUs returns the total set of CPUs available for allocation. GetAllocatableCPUs() cpuset.CPUSet @@ -101,6 +108,9 @@ type Manager interface { // GetAllCPUs returns all the CPUs known by cpumanager, as reported by the // hardware discovery. Maps to the CPU capacity. GetAllCPUs() cpuset.CPUSet + + // GetResourceIsolationLevel returns the isolation level of the container. + GetResourceIsolationLevel(pod *v1.Pod, container *v1.Container) cmqos.ResourceIsolationLevel } type manager struct { @@ -276,6 +286,23 @@ func (m *manager) Allocate(p *v1.Pod, c *v1.Container) error { return nil } +func (m *manager) AllocatePod(pod *v1.Pod) error { + logger := klog.TODO() // until we move topology manager to contextual logging + + // Garbage collect any stranded resources before allocating CPUs. + m.removeStaleState(logger) + + m.Lock() + defer m.Unlock() + + // Call down into the policy to assign this container CPUs if required. + if err := m.policy.AllocatePod(logger, m.state, pod); err != nil { + logger.Error(err, "AllocatePod error", "pod", klog.KObj(pod)) + return err + } + return nil +} + func (m *manager) AddContainer(logger logr.Logger, pod *v1.Pod, container *v1.Container, containerID string) { m.Lock() defer m.Unlock() @@ -542,10 +569,30 @@ func (m *manager) GetExclusiveCPUs(podUID, containerName string) cpuset.CPUSet { if result, ok := m.state.GetCPUSet(podUID, containerName); ok { return result } - - return cpuset.CPUSet{} + return cpuset.New() } func (m *manager) GetCPUAffinity(podUID, containerName string) cpuset.CPUSet { return m.state.GetCPUSetOrDefault(podUID, containerName) } + +func resourcesQualifyForExclusiveCPUs(container *v1.Container) bool { + if !cmqos.IsContainerEquivalentQOSGuaranteed(container) { + return false + } + + cpuLimit := container.Resources.Limits[v1.ResourceCPU] + return cpuLimit.Value()*1000 == cpuLimit.MilliValue() +} + +func (m *manager) GetResourceIsolationLevel(pod *v1.Pod, container *v1.Container) cmqos.ResourceIsolationLevel { + if _, ok := m.state.GetCPUSet(string(pod.UID), container.Name); !ok { + return cmqos.ResourceIsolationHost + } + + if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) && !resourcesQualifyForExclusiveCPUs(container) { + return cmqos.ResourceIsolationPod + } + + return cmqos.ResourceIsolationContainer +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go index 556583b1a7..753cd68359 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go index f9a239ce55..7b73ff3047 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go index 38ce4e655e..a15dfce065 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go @@ -24,6 +24,7 @@ import ( "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" + cmqos "k8s.io/kubernetes/pkg/kubelet/cm/qos" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/status" @@ -74,28 +75,38 @@ func (m *fakeManager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymana return map[string][]topologymanager.TopologyHint{} } +func (m *fakeManager) AllocatePod(pod *v1.Pod) error { + logger := klog.TODO() + logger.Info("AllocatePod", "pod", klog.KObj(pod)) + return nil +} + func (m *fakeManager) State() state.Reader { return m.state } func (m *fakeManager) GetExclusiveCPUs(podUID, containerName string) cpuset.CPUSet { m.logger.Info("GetExclusiveCPUs", "podUID", podUID, "containerName", containerName) - return cpuset.CPUSet{} + return cpuset.New() } func (m *fakeManager) GetAllocatableCPUs() cpuset.CPUSet { m.logger.Info("Get Allocatable CPUs") - return cpuset.CPUSet{} + return cpuset.New() } func (m *fakeManager) GetCPUAffinity(podUID, containerName string) cpuset.CPUSet { m.logger.Info("GetCPUAffinity", "podUID", podUID, "containerName", containerName) - return cpuset.CPUSet{} + return cpuset.New() } func (m *fakeManager) GetAllCPUs() cpuset.CPUSet { m.logger.Info("GetAllCPUs") - return cpuset.CPUSet{} + return cpuset.New() +} + +func (m *fakeManager) GetResourceIsolationLevel(pod *v1.Pod, container *v1.Container) cmqos.ResourceIsolationLevel { + return cmqos.ResourceIsolationContainer } // NewFakeManager creates empty/fake cpu manager diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go index 628b0254af..26afcb3945 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go @@ -41,6 +41,8 @@ type Policy interface { // and is consulted to achieve NUMA aware resource alignment per Pod // among this and other resource controllers. GetPodTopologyHints(logger logr.Logger, s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint + // AllocatePod is called to trigger the allocation of CPUs to a pod. + AllocatePod(logger logr.Logger, s state.State, pod *v1.Pod) error // GetAllocatableCPUs returns the total set of CPUs available for allocation. GetAllocatableCPUs(m state.State) cpuset.CPUSet } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go index e29d0598a3..8a43eb707a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go @@ -67,6 +67,10 @@ func (p *nonePolicy) GetPodTopologyHints(_ logr.Logger, s state.State, pod *v1.P return nil } +func (p *nonePolicy) AllocatePod(_ logr.Logger, s state.State, pod *v1.Pod) error { + return nil +} + // Assignable CPUs are the ones that can be exclusively allocated to pods that meet the exclusivity requirement // (ie guaranteed QoS class and integral CPU request). // Assignability of CPUs as a concept is only applicable in case of static policy i.e. scenarios where workloads diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go index 745c6bf7ca..19da027a8b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go @@ -44,11 +44,11 @@ var ( ) betaOptions = sets.New[string]( DistributeCPUsAcrossNUMAOption, - PreferAlignByUnCoreCacheOption, ) stableOptions = sets.New[string]( FullPCPUsOnlyOption, StrictCPUReservationOption, + PreferAlignByUnCoreCacheOption, ) ) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go index 635570dbf4..2b9daf460b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go @@ -19,18 +19,22 @@ package cpumanager import ( "fmt" "strconv" + "strings" "github.com/go-logr/logr" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" utilfeature "k8s.io/apiserver/pkg/util/feature" resourcehelper "k8s.io/component-helpers/resource" "k8s.io/klog/v2" podutil "k8s.io/kubernetes/pkg/api/v1/pod" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/pkg/kubelet/cm/admission" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" + cmqos "k8s.io/kubernetes/pkg/kubelet/cm/qos" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/managed" @@ -39,7 +43,6 @@ import ( ) const ( - // PolicyStatic is the name of the static policy. // Should options be given, these will be ignored and backward (up to 1.21 included) // compatible behaviour will be enforced @@ -269,6 +272,11 @@ func (p *staticPolicy) validateState(logger logr.Logger, s state.State) error { tmpCPUSets = append(tmpCPUSets, cset) } } + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + for _, podAssigments := range s.GetPodCPUAssignments() { + tmpCPUSets = append(tmpCPUSets, podAssigments.CPUSet) + } + } totalKnownCPUs = totalKnownCPUs.Union(tmpCPUSets...) availableCPUs := p.topology.CPUDetails.CPUs() @@ -330,6 +338,239 @@ func (p *staticPolicy) updateCPUsToReuse(pod *v1.Pod, container *v1.Container, c p.cpusToReuse[string(pod.UID)] = p.cpusToReuse[string(pod.UID)].Difference(cset) } +// validatePodScopeResources checks for the "empty shared pool" scenario. This occurs +// when the sum of exclusive container CPU requests consumes the entire pod-level +// budget, leaving no CPUs for containers that require a shared pool. Such a +// configuration is invalid because it would lead to containers in the shared +// pool having an empty cpuset, causing them to run on the node's shared pool +// and breaking NUMA affinity. +func (p *staticPolicy) validatePodScopeResources(logger logr.Logger, pod *v1.Pod) error { + podTotalCPUs := p.podGuaranteedCPUs(logger, pod) + + hasSharedLongRunningContainers := false + // Sum CPU requests for all containers that run for the full pod lifetime + // (main containers and restartable init containers) to determine the + // total exclusive CPU usage that might impact the shared pool. + sumOfLongRunningExclusiveCPUs := 0 + + // Check for empty shared pool for standard init containers. + for _, container := range pod.Spec.InitContainers { + guaranteedCPUs := p.guaranteedCPUs(logger, pod, &container) + + if !podutil.IsRestartableInitContainer(&container) { + if guaranteedCPUs == 0 && sumOfLongRunningExclusiveCPUs >= podTotalCPUs { + // This check ensures that if there are any standard init containers that need a + // shared pool, that pool is not empty. An empty pool would occur if the pod + // budget is fully consumed by sidecars. + return fmt.Errorf("pod rejected, pod has shared init containers but no cpus available for them") + } + } else { + // If there are restartable init containers, keep track for the empty shared pool check. + if guaranteedCPUs == 0 { + hasSharedLongRunningContainers = true + } else { + sumOfLongRunningExclusiveCPUs += guaranteedCPUs + } + } + } + + // Check for empty shared pool for concurrently running containers (app and restartable init containers). + for _, container := range pod.Spec.Containers { + guaranteedCPUs := p.guaranteedCPUs(logger, pod, &container) + + if guaranteedCPUs == 0 { + hasSharedLongRunningContainers = true + } else { + sumOfLongRunningExclusiveCPUs += guaranteedCPUs + } + } + + // This check ensures that if there are any standard containers that need a shared + // pool, that pool is not empty. An empty pool would occur if the pod budget is + // fully consumed by sidecars and main containers with exclusive resources. + if hasSharedLongRunningContainers && sumOfLongRunningExclusiveCPUs >= podTotalCPUs { + return fmt.Errorf("pod rejected, sum of exclusive container cpu requests equals pod budget, leaving no cpus for shared containers") + } + + return nil +} + +// This function is the entry point for pod-level resource allocation. +// It's called once per pod by the Topology Manager's pod-scope admit handler. +// The logic here allocates a single "bubble" of CPUs for the entire pod +// and then partitions that bubble among the containers. +func (p *staticPolicy) AllocatePod(logger logr.Logger, s state.State, pod *v1.Pod) (rerr error) { + podUID := string(pod.UID) + logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) + logger.V(4).Info("AllocatePod called for pod-level managed pod") + + // 1. Calculate the total number of CPUs required for the pod, considering init container reuse. + totalPodCPUs := p.podGuaranteedCPUs(logger, pod) + if totalPodCPUs == 0 { + // pod belongs in the shared pool (nothing to do; use default cpuset) + return nil + } + logger.V(4).Info("Calculated total pod CPUs", "totalCPUs", totalPodCPUs) + + defer func() { + if rerr != nil { + metrics.CPUManagerPinningErrorsTotal.Inc() + metrics.ResourceManagerAllocationErrorsTotal.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerPod).Inc() + } + }() + + // 2. Validate for the "empty shared pool" case. + // Even though this is checked during hint generation, we must re-evaluate it here. + // If the Topology Manager is running with the "best-effort" or "none" policies, + // it will still admit the pod even if GetPodTopologyHints returns an empty hint list. + // This ensures we explicitly reject the pod during allocation to prevent Kubelet + // from attempting to create invalid cgroups (e.g., an empty cpuset.cpus) for shared containers. + if err := p.validatePodScopeResources(logger, pod); err != nil { + return admission.NewEmptyPodSharedPoolError(err) + } + + // 3. Enforce SMT alignment policy if FullPhysicalCPUsOnly is enabled. + if err := p.enforceSMTAlignment(s, totalPodCPUs); err != nil { + return err + } + + // 4. Allocate the entire CPU "bubble" for the pod using the hint from the Topology Manager. + hint := p.affinity.GetAffinity(podUID, append(pod.Spec.InitContainers, pod.Spec.Containers...)[0].Name) + podAllocation, err := p.allocateCPUs(logger, s, totalPodCPUs, hint.NUMANodeAffinity, cpuset.New()) + if err != nil { + logger.Error(err, "Unable to allocate CPUs for pod", "totalPodCPUs", totalPodCPUs) + return err + } + p.updateMetricsOnAllocate(logger, s, podAllocation) + logger.V(4).Info("Allocated pod-level CPU bubble", "allocation", podAllocation.CPUs) + + // Store the pod-level allocation in the state. + s.SetPodCPUSet(podUID, podAllocation.CPUs) + + // 5. Partition the pod's allocation, handling init container CPU reuse correctly. + exclusiveCPUs := make(map[string]cpuset.CPUSet) + sidecarCPUs := cpuset.New() + + // First, iterate through all init containers and allocate their CPUs from the initial pod bubble. + for _, c := range pod.Spec.InitContainers { + if numCPUs := p.guaranteedCPUs(logger, pod, &c); numCPUs > 0 { + metrics.CPUManagerPinningRequestsTotal.Inc() + // The pool available for this init container is the entire pod allocation + // minus what's already taken by sidecars. + runnablePool := podAllocation.CPUs.Difference(sidecarCPUs) + cset, err := p.takeByTopology(logger, runnablePool, numCPUs) + if err != nil { + return err + } + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerExclusivePod).Inc() + exclusiveCPUs[c.Name] = cset + + // If it's a restartable sidecar, its CPUs are permanently consumed. + if podutil.IsRestartableInitContainer(&c) { + sidecarCPUs = sidecarCPUs.Union(cset) + } + } else { + // Restartable init containers will access the main pod shared pool. + if podutil.IsRestartableInitContainer(&c) { + continue + } + + // Non restartable init containers will have access to the whole pod pool + // amount minus the sidecar exclusive CPUs up to that point. + runnablePool := podAllocation.CPUs.Difference(sidecarCPUs) + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerSharedPod).Inc() + exclusiveCPUs[c.Name] = runnablePool + } + } + + // Explicitly record that the full CPU bubble is available again, minus what sidecars are using. + // This avoids carrying forward complex accounting from standard init containers. + podSharedPool := podAllocation.CPUs.Difference(sidecarCPUs) + + // Second, iterate through regular containers, allocating from the remaining pool. + for _, c := range pod.Spec.Containers { + if numCPUs := p.guaranteedCPUs(logger, pod, &c); numCPUs > 0 { + metrics.CPUManagerPinningRequestsTotal.Inc() + cset, err := p.takeByTopology(logger, podSharedPool, numCPUs) + if err != nil { + return err + } + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerExclusivePod).Inc() + exclusiveCPUs[c.Name] = cset + // Consume CPUs from the app container pool. + podSharedPool = podSharedPool.Difference(cset) + } + } + + logger.V(4).Info("Partitioned pod-level CPU allocation", "exclusiveCPUs", podCPUAllocationToString(exclusiveCPUs), "podSharedPool", podSharedPool) + + // 6. Save all container assignments to the state. + for _, c := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { + if cset, isExclusive := exclusiveCPUs[c.Name]; isExclusive { + s.SetCPUSet(podUID, c.Name, cset) + } else { + s.SetCPUSet(podUID, c.Name, podSharedPool) + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerSharedPod).Inc() + } + + metrics.ResourceManagerAllocationsTotal.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerPod).Inc() + } + + return nil +} + +func podCPUAllocationToString(alloc map[string]cpuset.CPUSet) string { + if len(alloc) == 0 { + return "" + } + var sb strings.Builder + for name, cset := range alloc { + fmt.Fprintf(&sb, ",%s={%s}", name, cset) + } + // if we gone so far, it means we have at least 1 alloc, so the cut is safe + repr := sb.String()[1:] + return "<" + repr + ">" +} + +func (p *staticPolicy) enforceSMTAlignment(s state.State, numCPUs int) error { + if !p.options.FullPhysicalCPUsOnly { + return nil + } + + if (numCPUs % p.cpuGroupSize) != 0 { + // Since CPU Manager has been enabled requesting strict SMT alignment, it means a guaranteed pod can only be admitted + // if the CPU requested is a multiple of the number of virtual cpus per physical cores. + // In case CPU request is not a multiple of the number of virtual cpus per physical cores the Pod will be put + // in Failed state, with SMTAlignmentError as reason. Since the allocation happens in terms of physical cores + // and the scheduler is responsible for ensuring that the workload goes to a node that has enough CPUs, + // the pod would be placed on a node where there are enough physical cores available to be allocated. + // Just like the behaviour in case of static policy, takeByTopology will try to first allocate CPUs from the same socket + // and only in case the request cannot be sattisfied on a single socket, CPU allocation is done for a workload to occupy all + // CPUs on a physical core. Allocation of individual threads would never have to occur. + return SMTAlignmentError{ + RequestedCPUs: numCPUs, + CpusPerCore: p.cpuGroupSize, + CausedByPhysicalCPUs: false, + } + } + + availablePhysicalCPUs := p.GetAvailablePhysicalCPUs(s).Size() + + // It's legal to reserve CPUs which are not core siblings. In this case the CPU allocator can descend to single cores + // when picking CPUs. This will void the guarantee of FullPhysicalCPUsOnly. To prevent this, we need to additionally consider + // all the core siblings of the reserved CPUs as unavailable when computing the free CPUs, before to start the actual allocation. + // This way, by construction all possible CPUs allocation whose number is multiple of the SMT level are now correct again. + if numCPUs > availablePhysicalCPUs { + return SMTAlignmentError{ + RequestedCPUs: numCPUs, + CpusPerCore: p.cpuGroupSize, + AvailablePhysicalCPUs: availablePhysicalCPUs, + CausedByPhysicalCPUs: true, + } + } + return nil +} + func (p *staticPolicy) Allocate(logger logr.Logger, s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod), "podUID", pod.UID, "containerName", container.Name) logger.Info("Allocate start") // V=0 for backward compatibility @@ -341,18 +582,17 @@ func (p *staticPolicy) Allocate(logger logr.Logger, s state.State, pod *v1.Pod, return nil } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { - logger.Info("CPU Manager allocation skipped, pod is using pod-level resources which are not supported by the static CPU manager policy") + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { + logger.V(2).Info("CPU Manager allocation skipped, pod is using pod-level resources but the PodLevelResourceManagers feature gate is not enabled", "pod", klog.KObj(pod), "podUID", pod.UID) return nil } - logger.Info("Static policy: Allocate") - // container belongs in an exclusively allocated pool metrics.CPUManagerPinningRequestsTotal.Inc() defer func() { if rerr != nil { metrics.CPUManagerPinningErrorsTotal.Inc() + metrics.ResourceManagerAllocationErrorsTotal.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerNode).Inc() if p.options.FullPhysicalCPUsOnly { metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedPhysicalCPU).Inc() } @@ -365,39 +605,10 @@ func (p *staticPolicy) Allocate(logger logr.Logger, s state.State, pod *v1.Pod, } }() - if p.options.FullPhysicalCPUsOnly { - if (numCPUs % p.cpuGroupSize) != 0 { - // Since CPU Manager has been enabled requesting strict SMT alignment, it means a guaranteed pod can only be admitted - // if the CPU requested is a multiple of the number of virtual cpus per physical cores. - // In case CPU request is not a multiple of the number of virtual cpus per physical cores the Pod will be put - // in Failed state, with SMTAlignmentError as reason. Since the allocation happens in terms of physical cores - // and the scheduler is responsible for ensuring that the workload goes to a node that has enough CPUs, - // the pod would be placed on a node where there are enough physical cores available to be allocated. - // Just like the behaviour in case of static policy, takeByTopology will try to first allocate CPUs from the same socket - // and only in case the request cannot be sattisfied on a single socket, CPU allocation is done for a workload to occupy all - // CPUs on a physical core. Allocation of individual threads would never have to occur. - return SMTAlignmentError{ - RequestedCPUs: numCPUs, - CpusPerCore: p.cpuGroupSize, - CausedByPhysicalCPUs: false, - } - } - - availablePhysicalCPUs := p.GetAvailablePhysicalCPUs(s).Size() - - // It's legal to reserve CPUs which are not core siblings. In this case the CPU allocator can descend to single cores - // when picking CPUs. This will void the guarantee of FullPhysicalCPUsOnly. To prevent this, we need to additionally consider - // all the core siblings of the reserved CPUs as unavailable when computing the free CPUs, before to start the actual allocation. - // This way, by construction all possible CPUs allocation whose number is multiple of the SMT level are now correct again. - if numCPUs > availablePhysicalCPUs { - return SMTAlignmentError{ - RequestedCPUs: numCPUs, - CpusPerCore: p.cpuGroupSize, - AvailablePhysicalCPUs: availablePhysicalCPUs, - CausedByPhysicalCPUs: true, - } - } + if err := p.enforceSMTAlignment(s, numCPUs); err != nil { + return err } + if cset, ok := s.GetCPUSet(string(pod.UID), container.Name); ok { p.updateCPUsToReuse(pod, container, cset) logger.Info("Static policy: container already present in state, skipping") @@ -418,6 +629,8 @@ func (p *staticPolicy) Allocate(logger logr.Logger, s state.State, pod *v1.Pod, s.SetCPUSet(string(pod.UID), container.Name, cpuAllocation.CPUs) p.updateCPUsToReuse(pod, container, cpuAllocation.CPUs) p.updateMetricsOnAllocate(logger, s, cpuAllocation) + metrics.ResourceManagerAllocationsTotal.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerNode).Inc() + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerCPU, metrics.ResourceManagerExclusiveNode).Inc() logger.V(4).Info("Allocated exclusive CPUs", "cpuset", cpuAllocation.CPUs.String()) return nil @@ -440,12 +653,30 @@ func (p *staticPolicy) RemoveContainer(logger logr.Logger, s state.State, podUID logger = klog.LoggerWithValues(logger, "podUID", podUID, "containerName", containerName) logger.Info("RemoveContainer start") // backward compatibility defer logger.V(4).Info("RemoveContainer start") - cpusInUse := getAssignedCPUsOfSiblings(s, podUID, containerName) toRelease, ok := s.GetCPUSet(podUID, containerName) if !ok { return nil } s.Delete(podUID, containerName) + + // Check if this pod is managed with pod-level CPUs. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + if podCPUSet, isPodLevel := s.GetPodCPUSet(podUID); isPodLevel { + // If this was the last container for the pod, then release the entire pod-level CPU set. + if len(s.GetCPUAssignments()[podUID]) == 0 { + updatedCPUSets := s.GetDefaultCPUSet().Union(podCPUSet) + s.SetDefaultCPUSet(updatedCPUSets) + s.DeletePod(podUID) // Clean up all state for the pod. + p.updateMetricsOnRelease(logger, s, podCPUSet) + logger.Info("Released pod-level CPUs", "defaultCPUSet", updatedCPUSets) + } + // If other containers still exist, do not release any CPUs yet. + // The pod-level CPUs will be released when the last container is removed. + return nil + } + } + + cpusInUse := getAssignedCPUsOfSiblings(s, podUID, containerName) // Mutate the shared pool, adding released cpus. toRelease = toRelease.Difference(cpusInUse) updatedCPUs := s.GetDefaultCPUSet().Union(toRelease) @@ -493,25 +724,57 @@ func (p *staticPolicy) allocateCPUs(logger logr.Logger, s state.State, numCPUs i return result, nil } +func isIntegralCPUAmount(cpuQuantity resource.Quantity) bool { + return cpuQuantity.Value()*1000 == cpuQuantity.MilliValue() +} + func (p *staticPolicy) guaranteedCPUs(logger logr.Logger, pod *v1.Pod, container *v1.Container) int { qos := v1qos.GetPodQOS(pod) if qos != v1.PodQOSGuaranteed { logger.V(5).Info("Exclusive CPU allocation skipped, pod QoS is not guaranteed", "qos", qos) return 0 } + cpuQuantity := container.Resources.Requests[v1.ResourceCPU] + + // For pod-level resource management, a container is only considered for exclusive + // CPUs if its request equals its limit for both the CPU and Memory. This + // aligns with the Guaranteed QoS requirement for container-level resources. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) && !cmqos.IsContainerEquivalentQOSGuaranteed(container) { + logger.V(5).Info("Exclusive CPU allocation skipped, container is not eligible, request and limit are not equal", "pod", klog.KObj(pod), "containerName", container.Name) + return 0 + } + cpuValue := cpuQuantity.Value() - if cpuValue*1000 != cpuQuantity.MilliValue() { - logger.V(5).Info("Exclusive CPU allocation skipped, pod requested non-integral CPUs", "cpu", cpuValue) + if !isIntegralCPUAmount(cpuQuantity) { + logger.V(5).Info("Exclusive CPU allocation skipped, container requested non-integral CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "cpu", cpuValue) return 0 } // Safe downcast to do for all systems with < 2.1 billion CPUs. // Per the language spec, `int` is guaranteed to be at least 32 bits wide. // https://golang.org/ref/spec#Numeric_types - return int(cpuQuantity.Value()) + return int(cpuValue) } func (p *staticPolicy) podGuaranteedCPUs(logger logr.Logger, pod *v1.Pod) int { + // If pod-level resources are set, use them directly. + // This check is important because this function is called from GetPodTopologyHints, + // which runs before the main feature gate check in AllocatePod. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + qos := v1qos.GetPodQOS(pod) + if qos != v1.PodQOSGuaranteed { + return 0 + } + + if cpuQuantity, ok := pod.Spec.Resources.Requests[v1.ResourceCPU]; ok { + // We only consider integer CPU requests for guaranteed CPUs at the pod level. + if isIntegralCPUAmount(cpuQuantity) { + return int(cpuQuantity.Value()) + } + } + return 0 + } + // The maximum of requested CPUs by init containers. requestedByInitContainers := 0 requestedByRestartableInitContainers := 0 @@ -576,8 +839,10 @@ func (p *staticPolicy) GetTopologyHints(logger logr.Logger, s state.State, pod * return nil } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { - logger.V(3).Info("CPU Manager hint generation skipped, pod is using pod-level resources which are not supported by the static CPU manager policy", "pod", klog.KObj(pod), "podUID", pod.UID) + // If the pod has pod-level resources but the feature gate is disabled, + // log it and return nil hints to admit the pod without alignment. + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { + logger.V(3).Info("CPU Manager hint generation skipped, pod is using pod-level resources but the PodLevelResourceManagers feature gate is not enabled") return nil } @@ -596,7 +861,7 @@ func (p *staticPolicy) GetTopologyHints(logger logr.Logger, s state.State, pod * } logger.Info("Regenerating TopologyHints for CPUs already allocated") return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): p.generateCPUTopologyHints(allocated, cpuset.CPUSet{}, requested), + string(v1.ResourceCPU): p.generateCPUTopologyHints(allocated, cpuset.New(), requested), } } @@ -630,11 +895,27 @@ func (p *staticPolicy) GetPodTopologyHints(logger logr.Logger, s state.State, po return nil } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { - logger.V(3).Info("CPU Manager pod hint generation skipped, pod is using pod-level resources which are not supported by the static CPU manager policy") + // If the pod has pod-level resources but the feature gate is disabled, + // log it and return nil hints to admit the pod without alignment. + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { + logger.V(3).Info("CPU Manager pod hint generation skipped, pod is using pod-level resources but the PodLevelResourceManagers feature gate is not enabled", "podUID", pod.UID) return nil } + // Validate that if a pod has containers that will be placed in a shared pool, + // there are actually CPUs left over for that pool after accounting for all + // exclusive allocations. If the sum of exclusive CPU requests consumes the + // entire pod-level CPU budget, no hints will be generated, causing the pod + // to be rejected by the Topology Manager. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + if err := p.validatePodScopeResources(logger, pod); err != nil { + logger.V(2).Info("Invalid pod spec. Sum of exclusive container requests equals pod budget, leaving no CPUs for shared containers") + return map[string][]topologymanager.TopologyHint{ + string(v1.ResourceCPU): {}, + } + } + } + assignedCPUs := cpuset.New() for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { logger_ := klog.LoggerWithValues(logger, "containerName", container.Name) @@ -660,7 +941,7 @@ func (p *staticPolicy) GetPodTopologyHints(logger logr.Logger, s state.State, po if assignedCPUs.Size() == requested { logger.Info("Regenerating TopologyHints for CPUs already allocated") return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): p.generateCPUTopologyHints(assignedCPUs, cpuset.CPUSet{}, requested), + string(v1.ResourceCPU): p.generateCPUTopologyHints(assignedCPUs, cpuset.New(), requested), } } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go index 564c3482c0..6903ef3e9d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go @@ -22,18 +22,33 @@ import ( "hash/fnv" "strings" - "k8s.io/apimachinery/pkg/util/dump" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" + "k8s.io/utils/dump" ) var _ checkpointmanager.Checkpoint = &CPUManagerCheckpointV1{} var _ checkpointmanager.Checkpoint = &CPUManagerCheckpointV2{} +var _ checkpointmanager.Checkpoint = &CPUManagerCheckpointV3{} var _ checkpointmanager.Checkpoint = &CPUManagerCheckpoint{} -// CPUManagerCheckpoint struct is used to store cpu/pod assignments in a checkpoint in v2 format +// CPUManagerCheckpoint struct is used to store cpu/pod assignments in a checkpoint in v3 format type CPUManagerCheckpoint struct { + PolicyName string `json:"policyName"` + DefaultCPUSet string `json:"defaultCpuSet"` + Entries map[string]map[string]string `json:"entries,omitempty"` + PodEntries PodCPUAssignments `json:"podEntries,omitempty"` + Checksum checksum.Checksum `json:"checksum"` +} + +// CPUManagerCheckpoint struct is used to store cpu/pod assignments in a checkpoint in v3 format +type CPUManagerCheckpointV3 = CPUManagerCheckpoint + +// CPUManagerCheckpointV2 struct is used to store cpu/pod assignments in a checkpoint in v2 format +type CPUManagerCheckpointV2 struct { PolicyName string `json:"policyName"` DefaultCPUSet string `json:"defaultCpuSet"` Entries map[string]map[string]string `json:"entries,omitempty"` @@ -48,13 +63,10 @@ type CPUManagerCheckpointV1 struct { Checksum checksum.Checksum `json:"checksum"` } -// CPUManagerCheckpointV2 struct is used to store cpu/pod assignments in a checkpoint in v2 format -type CPUManagerCheckpointV2 = CPUManagerCheckpoint - // NewCPUManagerCheckpoint returns an instance of Checkpoint -func NewCPUManagerCheckpoint() *CPUManagerCheckpoint { +func newCPUManagerCheckpoint() *CPUManagerCheckpoint { //nolint:staticcheck // unexported-type-in-api user-facing error message - return newCPUManagerCheckpointV2() + return newCPUManagerCheckpointV3() } func newCPUManagerCheckpointV1() *CPUManagerCheckpointV1 { @@ -69,6 +81,13 @@ func newCPUManagerCheckpointV2() *CPUManagerCheckpointV2 { } } +func newCPUManagerCheckpointV3() *CPUManagerCheckpoint { + return &CPUManagerCheckpoint{ + Entries: make(map[string]map[string]string), + PodEntries: make(PodCPUAssignments), + } +} + // MarshalCheckpoint returns marshalled checkpoint in v1 format func (cp *CPUManagerCheckpointV1) MarshalCheckpoint() ([]byte, error) { // make sure checksum wasn't set before so it doesn't affect output checksum @@ -81,6 +100,24 @@ func (cp *CPUManagerCheckpointV1) MarshalCheckpoint() ([]byte, error) { func (cp *CPUManagerCheckpointV2) MarshalCheckpoint() ([]byte, error) { // make sure checksum wasn't set before so it doesn't affect output checksum cp.Checksum = 0 + + // In order to preserve rollback compatibility when the feature gate is disabled, + // we must generate a checksum using the legacy struct name "CPUManagerCheckpoint" + // instead of "CPUManagerCheckpointV2". Older Kubelets do not have the string + // replacement logic and expect the original struct name. + object := dump.ForHash(cp) + object = strings.Replace(object, "CPUManagerCheckpointV2", "CPUManagerCheckpoint", 1) + hash := fnv.New32a() + _, _ = fmt.Fprintf(hash, "%v", object) + cp.Checksum = checksum.Checksum(hash.Sum32()) + + return json.Marshal(*cp) +} + +// MarshalCheckpoint returns marshalled checkpoint in v3 format +func (cp *CPUManagerCheckpoint) MarshalCheckpoint() ([]byte, error) { + // make sure checksum wasn't set before so it doesn't affect output checksum + cp.Checksum = 0 cp.Checksum = checksum.New(cp) return json.Marshal(*cp) } @@ -95,6 +132,11 @@ func (cp *CPUManagerCheckpointV2) UnmarshalCheckpoint(blob []byte) error { return json.Unmarshal(blob, cp) } +// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint in v3 format +func (cp *CPUManagerCheckpoint) UnmarshalCheckpoint(blob []byte) error { + return json.Unmarshal(blob, cp) +} + // VerifyChecksum verifies that current checksum of checkpoint is valid in v1 format func (cp *CPUManagerCheckpointV1) VerifyChecksum() error { if cp.Checksum == 0 { @@ -109,7 +151,7 @@ func (cp *CPUManagerCheckpointV1) VerifyChecksum() error { cp.Checksum = ck hash := fnv.New32a() - fmt.Fprintf(hash, "%v", object) + _, _ = fmt.Fprintf(hash, "%v", object) actualCS := checksum.Checksum(hash.Sum32()) if cp.Checksum != actualCS { return &errors.CorruptCheckpointError{ @@ -127,6 +169,38 @@ func (cp *CPUManagerCheckpointV2) VerifyChecksum() error { // accept empty checksum for compatibility with old file backend return nil } + + ck := cp.Checksum + cp.Checksum = 0 + + if !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + err := ck.Verify(cp) + if err == nil { + cp.Checksum = ck + return nil + } + // If the standard verification failed, it could be a legacy checkpoint. + // Fallback to the legacy verification method, when V3 is latest. + } + + object := dump.ForHash(cp) + object = strings.Replace(object, "CPUManagerCheckpointV2", "CPUManagerCheckpoint", 1) + cp.Checksum = ck + + hash := fnv.New32a() + _, _ = fmt.Fprintf(hash, "%v", object) + actualCS := checksum.Checksum(hash.Sum32()) + if cp.Checksum != actualCS { + return &errors.CorruptCheckpointError{ + ActualCS: uint64(actualCS), + ExpectedCS: uint64(cp.Checksum), + } + } + return nil +} + +// VerifyChecksum verifies that current checksum of checkpoint is valid in v3 format +func (cp *CPUManagerCheckpoint) VerifyChecksum() error { ck := cp.Checksum cp.Checksum = 0 err := ck.Verify(cp) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go index 352fddfb9c..00e404c3de 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go @@ -17,6 +17,10 @@ limitations under the License. package state import ( + "encoding/json" + "fmt" + "maps" + "k8s.io/utils/cpuset" ) @@ -28,19 +32,65 @@ func (as ContainerCPUAssignments) Clone() ContainerCPUAssignments { ret := make(ContainerCPUAssignments, len(as)) for pod := range as { ret[pod] = make(map[string]cpuset.CPUSet, len(as[pod])) - for container, cset := range as[pod] { - ret[pod][container] = cset - } + maps.Copy(ret[pod], as[pod]) } return ret } +// PodCPUAssignments contains pod-level CPU assignments. +type PodCPUAssignments map[string]PodEntry + +// PodEntry represents pod-level CPU assignments for a pod +type PodEntry struct { + CPUSet cpuset.CPUSet `json:"cpuSet,omitempty"` +} + +type podEntryJSON struct { + CPUSet string `json:"cpuSet,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +// It is required because CPUSet is stored as a string in the checkpoint JSON, +// but used as a struct in the internal state. +func (p PodEntry) MarshalJSON() ([]byte, error) { + return json.Marshal(podEntryJSON{ + CPUSet: p.CPUSet.String(), + }) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// It is required because CPUSet is stored as a string in the checkpoint JSON, +// but used as a struct in the internal state. +func (p *PodEntry) UnmarshalJSON(b []byte) error { + var entry podEntryJSON + if err := json.Unmarshal(b, &entry); err != nil { + return err + } + cset, err := cpuset.Parse(entry.CPUSet) + if err != nil { + return fmt.Errorf("failed to parse cpuset: %w", err) + } + p.CPUSet = cset + return nil +} + +// Clone returns a copy of PodCPUAssignments +func (a PodCPUAssignments) Clone() PodCPUAssignments { + clone := make(PodCPUAssignments, len(a)) + maps.Copy(clone, a) + return clone +} + // Reader interface used to read current cpu/pod assignment state type Reader interface { GetCPUSet(podUID string, containerName string) (cpuset.CPUSet, bool) GetDefaultCPUSet() cpuset.CPUSet GetCPUSetOrDefault(podUID string, containerName string) cpuset.CPUSet GetCPUAssignments() ContainerCPUAssignments + // GetPodCPUSet returns the pod-level CPU assignments of a pod + GetPodCPUSet(podUID string) (cpuset.CPUSet, bool) + // GetPodCPUAssignments returns all pod-level CPU assignments + GetPodCPUAssignments() PodCPUAssignments } type writer interface { @@ -49,6 +99,12 @@ type writer interface { SetCPUAssignments(ContainerCPUAssignments) Delete(podUID string, containerName string) ClearState() + // SetPodCPUSet stores pod-level CPU assignments of a pod + SetPodCPUSet(podUID string, cpuset cpuset.CPUSet) + // SetPodCPUAssignments sets PodCPUAssignments by using the passed parameter + SetPodCPUAssignments(PodCPUAssignments) + // DeletePod deletes pod-level CPU assignments for specified pod + DeletePod(podUID string) } // State interface provides methods for tracking and setting cpu/pod assignment diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go index 9774bf3728..1b03ee273c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go @@ -17,14 +17,18 @@ limitations under the License. package state import ( + "errors" "fmt" + "maps" "path/filepath" "sync" "github.com/go-logr/logr" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" + cperrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/utils/cpuset" ) @@ -92,48 +96,85 @@ func (sc *stateCheckpoint) migrateV1CheckpointToV2Checkpoint(src *CPUManagerChec return nil } +// migrateV2CheckpointToV3Checkpoint() converts checkpoints from the v1 format to the v2 format +func (sc *stateCheckpoint) migrateV2CheckpointToV3Checkpoint(src *CPUManagerCheckpointV2, dst *CPUManagerCheckpointV3) { + if src.PolicyName != "" { + dst.PolicyName = src.PolicyName + } + if src.DefaultCPUSet != "" { + dst.DefaultCPUSet = src.DefaultCPUSet + } + if len(src.Entries) > 0 { + dst.Entries = make(map[string]map[string]string, len(src.Entries)) + for podUID, containerEntries := range src.Entries { + dst.Entries[podUID] = make(map[string]string, len(containerEntries)) + maps.Copy(dst.Entries[podUID], containerEntries) + } + } +} + // restores state from a checkpoint and creates it if it doesn't exist func (sc *stateCheckpoint) restoreState() error { sc.mux.Lock() defer sc.mux.Unlock() - var err error - checkpointV1 := newCPUManagerCheckpointV1() - checkpointV2 := newCPUManagerCheckpointV2() - - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV1); err != nil { - checkpointV1 = &CPUManagerCheckpointV1{} // reset it back to 0 - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV2); err != nil { - if err == errors.ErrCheckpointNotFound { - return sc.storeState() - } - return err - } - } - - if err = sc.migrateV1CheckpointToV2Checkpoint(checkpointV1, checkpointV2); err != nil { - return fmt.Errorf("error migrating v1 checkpoint state to v2 checkpoint state: %s", err) + var checkpoint any + var err error + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + checkpoint, err = sc.loadAndMigrateCheckpointV3() + } else { + checkpoint, err = sc.loadAndMigrateCheckpointV2() } - if sc.policyName != checkpointV2.PolicyName { - return fmt.Errorf("configured policy %q differs from state checkpoint policy %q", sc.policyName, checkpointV2.PolicyName) + if err != nil { + if errors.Is(err, cperrors.ErrCheckpointNotFound) { + return sc.storeState() + } + return err } var tmpDefaultCPUSet cpuset.CPUSet - if tmpDefaultCPUSet, err = cpuset.Parse(checkpointV2.DefaultCPUSet); err != nil { - return fmt.Errorf("could not parse default cpu set %q: %v", checkpointV2.DefaultCPUSet, err) - } - var tmpContainerCPUSet cpuset.CPUSet tmpAssignments := ContainerCPUAssignments{} - for pod := range checkpointV2.Entries { - tmpAssignments[pod] = make(map[string]cpuset.CPUSet, len(checkpointV2.Entries[pod])) - for container, cpuString := range checkpointV2.Entries[pod] { - if tmpContainerCPUSet, err = cpuset.Parse(cpuString); err != nil { - return fmt.Errorf("could not parse cpuset %q for container %q in pod %q: %v", cpuString, container, pod, err) + tmpPodAssignments := PodCPUAssignments{} + + switch cp := checkpoint.(type) { + case *CPUManagerCheckpointV3: + if sc.policyName != cp.PolicyName { + return fmt.Errorf("configured policy %q differs from state checkpoint policy %q", sc.policyName, cp.PolicyName) + } + if tmpDefaultCPUSet, err = cpuset.Parse(cp.DefaultCPUSet); err != nil { + return fmt.Errorf("could not parse default cpu set %q: %w", cp.DefaultCPUSet, err) + } + for pod := range cp.Entries { + tmpAssignments[pod] = make(map[string]cpuset.CPUSet, len(cp.Entries[pod])) + for container, cpuString := range cp.Entries[pod] { + if tmpContainerCPUSet, err = cpuset.Parse(cpuString); err != nil { + return fmt.Errorf("could not parse cpuset %q for container %q in pod %q: %w", cpuString, container, pod, err) + } + tmpAssignments[pod][container] = tmpContainerCPUSet + } + } + maps.Copy(tmpPodAssignments, cp.PodEntries) + sc.cache.SetPodCPUAssignments(tmpPodAssignments) + case *CPUManagerCheckpointV2: + if sc.policyName != cp.PolicyName { + return fmt.Errorf("configured policy %q differs from state checkpoint policy %q", sc.policyName, cp.PolicyName) + } + if tmpDefaultCPUSet, err = cpuset.Parse(cp.DefaultCPUSet); err != nil { + return fmt.Errorf("could not parse default cpu set %q: %w", cp.DefaultCPUSet, err) + } + for pod := range cp.Entries { + tmpAssignments[pod] = make(map[string]cpuset.CPUSet, len(cp.Entries[pod])) + for container, cpuString := range cp.Entries[pod] { + if tmpContainerCPUSet, err = cpuset.Parse(cpuString); err != nil { + return fmt.Errorf("could not parse cpuset %q for container %q in pod %q: %w", cpuString, container, pod, err) + } + tmpAssignments[pod][container] = tmpContainerCPUSet } - tmpAssignments[pod][container] = tmpContainerCPUSet } + default: + return fmt.Errorf("unknown checkpoint version %T", cp) } sc.cache.SetDefaultCPUSet(tmpDefaultCPUSet) @@ -145,9 +186,117 @@ func (sc *stateCheckpoint) restoreState() error { return nil } +// loadAndMigrateCheckpoint loads the latest checkpoint and migrates it from older versions if needed. +func (sc *stateCheckpoint) loadAndMigrateCheckpointV3() (*CPUManagerCheckpointV3, error) { + // Try to load as V3. + checkpointV3 := newCPUManagerCheckpointV3() + err := sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV3) + if err == nil { + return checkpointV3, nil + } + if errors.Is(err, cperrors.ErrCheckpointNotFound) { + return nil, err + } + + // Log the V3 load error and fall back to V2. + if errors.Is(err, cperrors.CorruptCheckpointError{}) { + sc.logger.Error(err, "V3 checkpoint is corrupt, falling back to V2") + } else { + sc.logger.Info("could not load V3 checkpoint, falling back to V2", "err", err) + } + + // Try to load as V2. + checkpointV2, err := sc.loadAndMigrateCheckpointV2() + if err != nil { + return nil, err + } + + // Loaded V2, now migrate to V3. + sc.logger.Info("migrating cpu manager checkpoint from v2 to v3") + sc.migrateV2CheckpointToV3Checkpoint(checkpointV2, checkpointV3) + + return checkpointV3, nil +} + +func (sc *stateCheckpoint) loadAndMigrateCheckpointV2() (*CPUManagerCheckpointV2, error) { + // Try to load as V2. + checkpointV2 := newCPUManagerCheckpointV2() + err := sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV2) + if err == nil { + return checkpointV2, nil + } + if errors.Is(err, cperrors.ErrCheckpointNotFound) { + return nil, err + } + + // Log the V2 load error and fall back to V1. + if errors.Is(err, cperrors.CorruptCheckpointError{}) { + sc.logger.Error(err, "V2 checkpoint is corrupt, falling back to V1") + } else { + sc.logger.Info("could not load V2 checkpoint, falling back to V1", "err", err) + } + + // Try to load as V1. + checkpointV1, err := sc.loadCheckpointV1() + if err == nil { + // Loaded V1, now migrate V1 -> V2. + sc.logger.Info("migrating cpu manager checkpoint from v1 to v2") + tmpV2 := newCPUManagerCheckpointV2() + if migrationErr := sc.migrateV1CheckpointToV2Checkpoint(checkpointV1, tmpV2); migrationErr != nil { + return nil, fmt.Errorf("failed to migrate checkpoint from v1 to v2: %w", migrationErr) + } + return tmpV2, nil + } + + // All attempts failed. Return the last error we got (from the V1 read attempt). + return nil, err +} + +func (sc *stateCheckpoint) loadCheckpointV1() (*CPUManagerCheckpointV1, error) { + checkpointV1 := newCPUManagerCheckpointV1() + err := sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV1) + if err != nil { + return nil, err + } + return checkpointV1, nil +} + // saves state to a checkpoint, caller is responsible for locking func (sc *stateCheckpoint) storeState() error { - checkpoint := NewCPUManagerCheckpoint() + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + return sc.storeStateV3() + } + return sc.storeStateV2() +} + +// saves state to a checkpoint, caller is responsible for locking +func (sc *stateCheckpoint) storeStateV3() error { + checkpoint := newCPUManagerCheckpoint() + checkpoint.PolicyName = sc.policyName + checkpoint.DefaultCPUSet = sc.cache.GetDefaultCPUSet().String() + + assignments := sc.cache.GetCPUAssignments() + for pod := range assignments { + checkpoint.Entries[pod] = make(map[string]string, len(assignments[pod])) + for container, cset := range assignments[pod] { + checkpoint.Entries[pod][container] = cset.String() + } + } + + podAssignments := sc.cache.GetPodCPUAssignments() + maps.Copy(checkpoint.PodEntries, podAssignments) + + err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint) + if err != nil { + sc.logger.Error(err, "Failed to save checkpoint") + return err + } + return nil +} + +// saves state to a checkpoint, caller is responsible for locking +func (sc *stateCheckpoint) storeStateV2() error { + checkpoint := newCPUManagerCheckpointV2() checkpoint.PolicyName = sc.policyName checkpoint.DefaultCPUSet = sc.cache.GetDefaultCPUSet().String() @@ -200,6 +349,32 @@ func (sc *stateCheckpoint) GetCPUAssignments() ContainerCPUAssignments { return sc.cache.GetCPUAssignments() } +// GetPodCPUAssignments returns pod-level CPU assignments +func (sc *stateCheckpoint) GetPodCPUAssignments() PodCPUAssignments { + sc.mux.RLock() + defer sc.mux.RUnlock() + + return sc.cache.GetPodCPUAssignments() +} + +func (sc *stateCheckpoint) SetPodCPUAssignments(assignments PodCPUAssignments) { + sc.mux.Lock() + defer sc.mux.Unlock() + + sc.cache.SetPodCPUAssignments(assignments) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint") + } +} + +// GetPodCPUSet returns pod-level CPU set +func (sc *stateCheckpoint) GetPodCPUSet(podUID string) (cpuset.CPUSet, bool) { + sc.mux.RLock() + defer sc.mux.RUnlock() + return sc.cache.GetPodCPUSet(podUID) +} + // SetCPUSet sets CPU set func (sc *stateCheckpoint) SetCPUSet(podUID string, containerName string, cset cpuset.CPUSet) { sc.mux.Lock() @@ -233,6 +408,17 @@ func (sc *stateCheckpoint) SetCPUAssignments(a ContainerCPUAssignments) { } } +// SetPodCPUSet sets pod-level CPU set +func (sc *stateCheckpoint) SetPodCPUSet(podUID string, cset cpuset.CPUSet) { + sc.mux.Lock() + defer sc.mux.Unlock() + sc.cache.SetPodCPUSet(podUID, cset) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint", "podUID", podUID) + } +} + // Delete deletes assignment for specified pod func (sc *stateCheckpoint) Delete(podUID string, containerName string) { sc.mux.Lock() @@ -244,6 +430,18 @@ func (sc *stateCheckpoint) Delete(podUID string, containerName string) { } } +// DeletePod deletes pod-level CPU assignments for specified pod. It does not +// affect container-level assignments. +func (sc *stateCheckpoint) DeletePod(podUID string) { + sc.mux.Lock() + defer sc.mux.Unlock() + sc.cache.DeletePod(podUID) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint", "podUID", podUID) + } +} + // ClearState clears the state and saves it in a checkpoint func (sc *stateCheckpoint) ClearState() { sc.mux.Lock() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go index 3da3c1a8d3..172bea6c67 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go @@ -17,18 +17,22 @@ limitations under the License. package state import ( + "maps" "sync" "github.com/go-logr/logr" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" "k8s.io/utils/cpuset" ) type stateMemory struct { sync.RWMutex - logger logr.Logger - assignments ContainerCPUAssignments - defaultCPUSet cpuset.CPUSet + logger logr.Logger + assignments ContainerCPUAssignments + podAssignments PodCPUAssignments + defaultCPUSet cpuset.CPUSet } var _ State = &stateMemory{} @@ -39,6 +43,16 @@ func NewMemoryState(logger logr.Logger) State { // since we store a checkpoint, we can use the relatively expensive "WithName". logger = klog.LoggerWithName(logger, "CPUManager state memory") logger.Info("Initialized") + + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + return &stateMemory{ + logger: logger, + assignments: ContainerCPUAssignments{}, + podAssignments: PodCPUAssignments{}, + defaultCPUSet: cpuset.New(), + } + } + return &stateMemory{ logger: logger, assignments: ContainerCPUAssignments{}, @@ -74,6 +88,21 @@ func (s *stateMemory) GetCPUAssignments() ContainerCPUAssignments { return s.assignments.Clone() } +func (s *stateMemory) GetPodCPUSet(podUID string) (cpuset.CPUSet, bool) { + s.RLock() + defer s.RUnlock() + res, ok := s.podAssignments[podUID] + return res.CPUSet.Clone(), ok +} + +func (s *stateMemory) GetPodCPUAssignments() PodCPUAssignments { + s.RLock() + defer s.RUnlock() + clone := make(PodCPUAssignments) + maps.Copy(clone, s.podAssignments) + return clone +} + func (s *stateMemory) SetCPUSet(podUID string, containerName string, cset cpuset.CPUSet) { s.Lock() defer s.Unlock() @@ -94,6 +123,16 @@ func (s *stateMemory) SetDefaultCPUSet(cset cpuset.CPUSet) { s.logger.Info("Updated default CPUSet", "cpuSet", cset) } +func (s *stateMemory) SetPodCPUSet(podUID string, cset cpuset.CPUSet) { + s.Lock() + defer s.Unlock() + + podEntry := s.podAssignments[podUID] + podEntry.CPUSet = cset + s.podAssignments[podUID] = podEntry + s.logger.Info("Updated pod CPUSet", "podUID", podUID, "cpuSet", cset) +} + func (s *stateMemory) SetCPUAssignments(a ContainerCPUAssignments) { s.Lock() defer s.Unlock() @@ -102,6 +141,15 @@ func (s *stateMemory) SetCPUAssignments(a ContainerCPUAssignments) { s.logger.Info("Updated CPUSet assignments", "assignments", a) } +func (s *stateMemory) SetPodCPUAssignments(a PodCPUAssignments) { + s.Lock() + defer s.Unlock() + + s.podAssignments = make(PodCPUAssignments) + maps.Copy(s.podAssignments, a) + s.logger.Info("Updated pod CPUSet assignments", "assignments", a) +} + func (s *stateMemory) Delete(podUID string, containerName string) { s.Lock() defer s.Unlock() @@ -113,11 +161,24 @@ func (s *stateMemory) Delete(podUID string, containerName string) { s.logger.V(2).Info("Deleted CPUSet assignment", "podUID", podUID, "containerName", containerName) } +// DeletePod deletes pod-level CPU assignments for specified pod. It does not +// affect container-level assignments. +func (s *stateMemory) DeletePod(podUID string) { + s.Lock() + defer s.Unlock() + + delete(s.podAssignments, podUID) + s.logger.V(2).Info("Deleted pod", "podUID", podUID) +} + func (s *stateMemory) ClearState() { s.Lock() defer s.Unlock() - s.defaultCPUSet = cpuset.CPUSet{} + s.defaultCPUSet = cpuset.New() s.assignments = make(ContainerCPUAssignments) + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + s.podAssignments = make(PodCPUAssignments) + } s.logger.V(2).Info("Cleared state") } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go index 166de0ccf7..cd796773a2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go @@ -250,7 +250,7 @@ func (m *ManagerImpl) PluginDisconnected(logger klog.Logger, resourceName string if ep, exists := m.endpoints[resourceName]; exists { m.markResourceUnhealthy(logger, resourceName) - logger.V(2).Info("Endpoint became unhealthy", "resourceName", resourceName, "endpoint", ep) + logger.V(2).Info("Endpoint became unhealthy", "resourceName", resourceName) ep.e.setStopTime(time.Now()) } @@ -1122,6 +1122,12 @@ func (m *ManagerImpl) GetAllocatableDevices() ResourceDeviceInstances { return resp } +// AllocatePod is called to trigger the allocation of resources to a pod. +func (m *ManagerImpl) AllocatePod(pod *v1.Pod) error { + // Device Manager does not support pod level resource allocation. + return nil +} + // GetDevices returns the devices used by the specified container func (m *ManagerImpl) GetDevices(podUID, containerName string) ResourceDeviceInstances { return m.podDevices.getContainerDevices(podUID, containerName) @@ -1203,21 +1209,36 @@ func (m *ManagerImpl) ShouldResetExtendedResourceCapacity() bool { } func (m *ManagerImpl) isContainerAlreadyRunning(logger klog.Logger, podUID, cntName string) bool { - cntID, err := m.containerMap.GetContainerID(podUID, cntName) - if err != nil { - logger.Error(err, "Container not found in the initial map, assumed NOT running", "podUID", podUID, "containerName", cntName) + // Check if ANY container for this pod/container name is running. + // This handles the case where a container restarted before kubelet restart, + // so the containerMap might have multiple entries (old exited + new running). + // We need to check all of them to see if any are running. + // + // Note: if container runtime is down when kubelet restarts, containerRunningSet will be empty, + // so containers will fail admission, hitting https://github.com/kubernetes/kubernetes/issues/118559. + // This scenario should however be rare enough. + foundAnyContainer := false + foundRunningContainer := false + + m.containerMap.Visit(func(visitPodUID, visitContainerName, visitContainerID string) { + if visitPodUID == podUID && visitContainerName == cntName { + foundAnyContainer = true + if m.containerRunningSet.Has(visitContainerID) { + foundRunningContainer = true + logger.V(4).Info("Container found in the initial running set", "podUID", podUID, "containerName", cntName, "containerID", visitContainerID) + } + } + }) + + if !foundAnyContainer { + logger.V(4).Info("Container not found in the initial map, assumed NOT running", "podUID", podUID, "containerName", cntName) return false } - // note that if container runtime is down when kubelet restarts, this set will be empty, - // so on kubelet restart containers will again fail admission, hitting https://github.com/kubernetes/kubernetes/issues/118559 again. - // This scenario should however be rare enough. - if !m.containerRunningSet.Has(cntID) { - logger.V(4).Info("Container not present in the initial running set", "podUID", podUID, "containerName", cntName, "containerID", cntID) + if !foundRunningContainer { + logger.V(4).Info("Container found in map but not in running set", "podUID", podUID, "containerName", cntName) return false } - // Once we make it here we know we have a running container. - logger.V(4).Info("Container found in the initial set, assumed running", "podUID", podUID, "containerName", cntName, "containerID", cntID) return true } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go index cdb6a50497..a6e0e79c10 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go @@ -104,7 +104,7 @@ func (c *client) Disconnect(logger klog.Logger) error { c.mutex.Lock() if c.grpc != nil { if err := c.grpc.Close(); err != nil { - logger.V(2).Info("Failed to close gRPC connection", "resource", c.Resource(), "err", err) + logger.V(2).Info("Failed to close grpc connection", "resource", c.Resource(), "err", err) } c.grpc = nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go index 8846122a3d..267aedf877 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go @@ -152,12 +152,27 @@ func (m *ManagerImpl) getAvailableDevices(resource string) sets.Set[string] { } func (m *ManagerImpl) generateDeviceTopologyHints(resource string, available sets.Set[string], reusable sets.Set[string], request int) []topologymanager.TopologyHint { - // Initialize minAffinitySize to include all NUMA Nodes - minAffinitySize := len(m.numaNodes) + // Narrow the bitmask iteration to NUMA nodes that actually host + // devices for this resource. On platforms where the OS exposes many + // NUMA nodes that carry no devices (e.g. NVIDIA GB200 with 36 NUMA + // nodes, most hosting only GPU HBM), iterating all machine NUMA + // nodes would enumerate O(2^n) subsets. Restricting to device- + // bearing nodes reduces n to the number of nodes that matter. + // Because device-less nodes never contribute to devicesInMask, + // excluding them does not change minAffinitySize or Preferred + // flag computation. + numaNodes := m.deviceNUMANodes(resource) + if len(numaNodes) == 0 { + numaNodes = m.numaNodes + } + + // Initialize minAffinitySize to the number of NUMA nodes under + // consideration; it will be narrowed as satisfying masks are found. + minAffinitySize := len(numaNodes) // Iterate through all combinations of NUMA Nodes and build hints from them. hints := []topologymanager.TopologyHint{} - bitmask.IterateBitMasks(m.numaNodes, func(mask bitmask.BitMask) { + bitmask.IterateBitMasks(numaNodes, func(mask bitmask.BitMask) { // First, update minAffinitySize for the current request size. devicesInMask := 0 for _, device := range m.allDevices[resource] { @@ -218,6 +233,28 @@ func (m *ManagerImpl) generateDeviceTopologyHints(resource string, available set return hints } +// deviceNUMANodes returns the sorted list of NUMA node IDs that host at least +// one device for the given resource. The returned set is guaranteed to be a +// subset of m.numaNodes: any NUMA IDs reported by device plugins that are not +// known to cadvisor are logged and dropped. +// The caller must hold m.mutex. +func (m *ManagerImpl) deviceNUMANodes(resource string) []int { + nodesWithDevices := sets.New[int]() + for _, device := range m.allDevices[resource] { + nodesWithDevices.Insert(m.getNUMANodeIds(device.Topology)...) + } + + knownNodes := sets.New[int](m.numaNodes...) + unknown := nodesWithDevices.Difference(knownNodes) + if unknown.Len() > 0 { + klog.TODO().Info("Ignoring NUMA node IDs reported by device plugin that are unknown to cadvisor", + "resource", resource, "unknownNodes", sets.List(unknown), "knownNodes", m.numaNodes) + nodesWithDevices = nodesWithDevices.Intersection(knownNodes) + } + + return sets.List(nodesWithDevices) +} + func (m *ManagerImpl) getNUMANodeIds(topology *pluginapi.TopologyInfo) []int { if topology == nil { return nil diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go index b377443c43..7ba66c463e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go @@ -89,6 +89,9 @@ type Manager interface { // and is consulted to make Topology aware resource alignments per Pod GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint + // AllocatePod is called to trigger the allocation of resources to a pod. + AllocatePod(pod *v1.Pod) error + // UpdateAllocatedDevices frees any Devices that are bound to terminated pods. UpdateAllocatedDevices() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS index 74bf9b65e6..d9e61e4cb9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS @@ -1,2 +1,5 @@ labels: - wg/device-management +approvers: + - pohly + - bart0sh diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go index f743258a14..c3dd650500 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go @@ -45,8 +45,6 @@ type ClaimInfo struct { // claimInfoCache is a cache of processed resource claims keyed by namespace/claimname. type claimInfoCache struct { - logger klog.Logger - sync.RWMutex checkpointer state.Checkpointer claimInfo map[string]*ClaimInfo @@ -137,7 +135,7 @@ func (info *ClaimInfo) cdiDevicesAsList(requestName string) []kubecontainer.CDID } // newClaimInfoCache creates a new claim info cache object, pre-populated from a checkpoint (if present). -func newClaimInfoCache(logger klog.Logger, stateDir, checkpointName string) (*claimInfoCache, error) { +func newClaimInfoCache(stateDir, checkpointName string) (*claimInfoCache, error) { checkpointer, err := state.NewCheckpointer(stateDir, checkpointName) if err != nil { return nil, fmt.Errorf("could not initialize checkpoint manager, please drain node and remove DRA state file, err: %w", err) @@ -149,7 +147,6 @@ func newClaimInfoCache(logger klog.Logger, stateDir, checkpointName string) (*cl } cache := &claimInfoCache{ - logger: logger, checkpointer: checkpointer, claimInfo: make(map[string]*ClaimInfo), } @@ -169,11 +166,12 @@ func newClaimInfoCache(logger klog.Logger, stateDir, checkpointName string) (*cl // withLock runs a function while holding the claimInfoCache lock. // It logs changes. -func (cache *claimInfoCache) withLock(f func() error) error { +func (cache *claimInfoCache) withLock(logger klog.Logger, f func() error) error { + logger = logger.WithName("dra-claiminfo") cache.Lock() defer cache.Unlock() - if loggerV := cache.logger.V(5); loggerV.Enabled() { + if loggerV := logger.V(5); loggerV.Enabled() { claimsInUseBefore := cache.claimsInUse() defer func() { claimsInUseAfter := cache.claimsInUse() @@ -188,7 +186,7 @@ func (cache *claimInfoCache) withLock(f func() error) error { } if changed { - cache.logger.V(5).Info("ResourceClaim usage changed", "claimsInUse", delta) + logger.V(5).Info("ResourceClaim usage changed", "claimsInUse", delta) } }() } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/healthinfo.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/healthinfo.go index 47f7ef12c7..68f138e88e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/healthinfo.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/healthinfo.go @@ -41,13 +41,14 @@ type healthInfoCache struct { } // newHealthInfoCache creates a new cache, loading from a checkpoint if present. -func newHealthInfoCache(stateFile string) (*healthInfoCache, error) { +func newHealthInfoCache(logger klog.Logger, stateFile string) (*healthInfoCache, error) { + logger = logger.WithName("dra-healthinfo") cache := &healthInfoCache{ HealthInfo: &state.DevicesHealthMap{}, stateFile: stateFile, } if err := cache.loadFromCheckpoint(); err != nil { - klog.Background().Error(err, "Failed to load health checkpoint, proceeding with empty cache") + logger.Error(err, "Failed to load health checkpoint, proceeding with empty cache") } return cache, nil } @@ -84,7 +85,8 @@ func (cache *healthInfoCache) withRLock(f func() error) error { // saveToCheckpointInternal does the actual saving without locking. // Assumes the caller holds the necessary lock. -func (cache *healthInfoCache) saveToCheckpointInternal() error { +func (cache *healthInfoCache) saveToCheckpointInternal(logger klog.Logger) error { + logger = logger.WithName("dra-healthinfo") if cache.stateFile == "" { return nil } @@ -100,7 +102,7 @@ func (cache *healthInfoCache) saveToCheckpointInternal() error { defer func() { if err := os.Remove(tempFile.Name()); err != nil && !os.IsNotExist(err) { - klog.Background().Error(err, "Failed to remove temporary checkpoint file", "path", tempFile.Name()) + logger.Error(err, "Failed to remove temporary checkpoint file", "path", tempFile.Name()) } }() @@ -121,8 +123,13 @@ func (cache *healthInfoCache) saveToCheckpointInternal() error { } // getHealthInfo returns the current health info, adjusting for timeouts. -func (cache *healthInfoCache) getHealthInfo(driverName, poolName, deviceName string) state.DeviceHealthStatus { - res := state.DeviceHealthStatusUnknown +func (cache *healthInfoCache) getHealthInfo(driverName, poolName, deviceName string) state.DeviceHealth { + res := state.DeviceHealth{ + PoolName: poolName, + DeviceName: deviceName, + Health: state.DeviceHealthStatusUnknown, + Message: "", + } _ = cache.withRLock(func() error { now := time.Now() @@ -137,9 +144,11 @@ func (cache *healthInfoCache) getHealthInfo(driverName, poolName, deviceName str // Check if device health has timed out if now.Sub(device.LastUpdated) > timeout { - res = state.DeviceHealthStatusUnknown + // Keep default Unknown status, clear message for stale device + res.Health = state.DeviceHealthStatusUnknown + res.Message = "" } else { - res = device.Health + res = device } } } @@ -151,7 +160,8 @@ func (cache *healthInfoCache) getHealthInfo(driverName, poolName, deviceName str // updateHealthInfo reconciles the cache with a fresh list of device health states // from a plugin. It identifies which devices have changed state and handles devices // that are no longer being reported by the plugin. -func (cache *healthInfoCache) updateHealthInfo(driverName string, devices []state.DeviceHealth) ([]state.DeviceHealth, error) { +func (cache *healthInfoCache) updateHealthInfo(logger klog.Logger, driverName string, devices []state.DeviceHealth) ([]state.DeviceHealth, error) { + logger = logger.WithName("dra-healthinfo") changedDevices := []state.DeviceHealth{} err := cache.withLock(func() error { now := time.Now() @@ -173,7 +183,8 @@ func (cache *healthInfoCache) updateHealthInfo(driverName string, devices []stat existingDevice, ok := currentDriver.Devices[key] - if !ok || existingDevice.Health != reportedDevice.Health || existingDevice.HealthCheckTimeout != reportedDevice.HealthCheckTimeout { + // Consider health status, message, and timeout changes as updates + if !ok || existingDevice.Health != reportedDevice.Health || existingDevice.Message != reportedDevice.Message || existingDevice.HealthCheckTimeout != reportedDevice.HealthCheckTimeout { changedDevices = append(changedDevices, reportedDevice) } @@ -194,6 +205,7 @@ func (cache *healthInfoCache) updateHealthInfo(driverName string, devices []stat // Mark as unknown if the device health has timed out if existingDevice.Health != state.DeviceHealthStatusUnknown && now.Sub(existingDevice.LastUpdated) > timeout { existingDevice.Health = state.DeviceHealthStatusUnknown + existingDevice.Message = "" existingDevice.LastUpdated = now currentDriver.Devices[key] = existingDevice @@ -204,8 +216,8 @@ func (cache *healthInfoCache) updateHealthInfo(driverName string, devices []stat // Phase 3: Persist changes to the checkpoint file if any state changed. if len(changedDevices) > 0 { - if err := cache.saveToCheckpointInternal(); err != nil { - klog.Background().Error(err, "Failed to save health checkpoint after update. Kubelet restart may lose the device health information.") + if err := cache.saveToCheckpointInternal(logger); err != nil { + logger.Error(err, "Failed to save health checkpoint after update. Kubelet restart may lose the device health information.") } } return nil @@ -218,9 +230,9 @@ func (cache *healthInfoCache) updateHealthInfo(driverName string, devices []stat } // clearDriver clears all health data for a specific driver. -func (cache *healthInfoCache) clearDriver(driverName string) error { +func (cache *healthInfoCache) clearDriver(logger klog.Logger, driverName string) error { return cache.withLock(func() error { delete(*cache.HealthInfo, driverName) - return cache.saveToCheckpointInternal() + return cache.saveToCheckpointInternal(logger) }) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go index d37747ec18..ea468f5787 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "path/filepath" + "slices" "strconv" "time" @@ -74,7 +75,7 @@ const defaultWipingDelay = 30 * time.Second type ActivePodsFunc func() []*v1.Pod // GetNodeFunc is a function that returns the node object using the kubelet's node lister. -type GetNodeFunc func() (*v1.Node, error) +type GetNodeFunc func(context.Context) (*v1.Node, error) // Manager is responsible for managing ResourceClaims. // It ensures that they are prepared before starting pods @@ -118,12 +119,12 @@ type Manager struct { // - Avoid repeated "failed to ...: failed to ..." when wrapping errors. // - Avoid wrapping when it does not provide relevant additional information to keep the user-visible error short. func NewManager(logger klog.Logger, kubeClient clientset.Interface, stateFileDirectory string) (*Manager, error) { - claimInfoCache, err := newClaimInfoCache(logger, stateFileDirectory, draManagerStateFileName) + claimInfoCache, err := newClaimInfoCache(stateFileDirectory, draManagerStateFileName) if err != nil { return nil, fmt.Errorf("create ResourceClaim cache: %w", err) } - healthInfoCache, err := newHealthInfoCache(filepath.Join(stateFileDirectory, "dra_health_state")) + healthInfoCache, err := newHealthInfoCache(logger, filepath.Join(stateFileDirectory, "dra_health_state")) if err != nil { return nil, fmt.Errorf("failed to create healthInfo cache: %w", err) } @@ -172,7 +173,7 @@ func (m *Manager) initDRAPluginManager(ctx context.Context, getNode GetNodeFunc, // reconcileLoop ensures that any stale state in the manager's claimInfoCache gets periodically reconciled. func (m *Manager) reconcileLoop(ctx context.Context) { - logger := klog.FromContext(ctx) + logger := klog.FromContext(ctx).WithName("dra-manager") // Only once all sources are ready do we attempt to reconcile. // This ensures that the call to m.activePods() below will succeed with // the actual active pods list. @@ -226,7 +227,8 @@ func (m *Manager) reconcileLoop(ctx context.Context) { func (m *Manager) PrepareResources(ctx context.Context, pod *v1.Pod) error { startTime := time.Now() err := m.prepareResources(ctx, pod) - kubeletmetrics.DRAOperationsDuration.WithLabelValues("PrepareResources", strconv.FormatBool(err == nil)).Observe(time.Since(startTime).Seconds()) + isError := (err != nil) + kubeletmetrics.DRAOperationsDuration.WithLabelValues("PrepareResources", strconv.FormatBool(isError)).Observe(time.Since(startTime).Seconds()) if err != nil { return fmt.Errorf("prepare dynamic resources: %w", err) } @@ -235,7 +237,8 @@ func (m *Manager) PrepareResources(ctx context.Context, pod *v1.Pod) error { func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { var err error - logger := klog.FromContext(ctx) + logger := klog.FromContext(ctx).WithName("dra-manager") + logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) batches := make(map[*draplugin.DRAPlugin][]*drapb.Claim) resourceClaims := make(map[types.UID]*resourceapi.ResourceClaim) @@ -268,7 +271,7 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { for i := range podResourceClaims { podClaim := &podResourceClaims[i] infos[i].podClaim = podClaim - logger.V(3).Info("Processing resource", "pod", klog.KObj(pod), "podClaim", podClaim.Name) + logger.V(3).Info("Processing resource", "podClaim", podClaim.Name) claimName, mustCheckOwner, err := resourceclaim.Name(pod, podClaim) if err != nil { return err @@ -288,14 +291,14 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { } if mustCheckOwner { - if err = resourceclaim.IsForPod(pod, resourceClaim); err != nil { + if err = resourceclaim.IsForPod(pod, resourceClaim, m.podGroupResourceClaimsEnabled()); err != nil { // No wrapping, error is already informative. return err } } // Check if pod is in the ReservedFor for the claim - if !resourceclaim.IsReservedForPod(pod, resourceClaim) { + if !resourceclaim.IsReservedForPod(pod, resourceClaim, m.podGroupResourceClaimsEnabled()) { return fmt.Errorf("pod %s (%s) is not allowed to use ResourceClaim %s (%s)", pod.Name, pod.UID, *claimName, resourceClaim.UID) } @@ -326,12 +329,12 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { // Now that we have everything that we need, we can update the claim info cache. // Almost nothing can go wrong anymore at this point. - err = m.cache.withLock(func() error { + err = m.cache.withLock(logger, func() error { for i := range podResourceClaims { resourceClaim := infos[i].resourceClaim podClaim := infos[i].podClaim if resourceClaim == nil { - logger.V(5).Info("No need to prepare resources, no claim generated", "pod", klog.KObj(pod), "podClaim", podClaim.Name) + logger.V(5).Info("No need to prepare resources, no claim generated", "podClaim", podClaim.Name) continue } // Get a reference to the claim info for this claim from the cache. @@ -340,12 +343,12 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { if !exists { claimInfo = infos[i].claimInfo m.cache.add(claimInfo) - logger.V(6).Info("Created new claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) + logger.V(6).Info("Created new claim info cache entry", "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) } else { if claimInfo.ClaimUID != resourceClaim.UID { return fmt.Errorf("old ResourceClaim with same name %s and different UID %s still exists (previous pod force-deleted?!)", resourceClaim.Name, claimInfo.ClaimUID) } - logger.V(6).Info("Found existing claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) + logger.V(6).Info("Found existing claim info cache entry", "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) } // Add a reference to the current pod in the claim info. @@ -361,7 +364,7 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { // If this claim is already prepared, continue preparing for any remaining claims. if claimInfo.isPrepared() { - logger.V(5).Info("Resources already prepared", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim)) + logger.V(5).Info("Resources already prepared", "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim)) continue } @@ -411,10 +414,10 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { claim := resourceClaims[types.UID(claimUID)] // Add the prepared CDI devices to the claim info - err := m.cache.withLock(func() error { + err := m.cache.withLock(logger, func() error { info, exists := m.cache.get(claim.Name, claim.Namespace) if !exists { - return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s", claim.Name) + return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s in namespace %s", claim.Name, claim.Namespace) } for _, device := range result.GetDevices() { info.addDevice(plugin.DriverName(), state.Device{PoolName: device.PoolName, @@ -436,12 +439,12 @@ func (m *Manager) prepareResources(ctx context.Context, pod *v1.Pod) error { } // Atomically perform some operations on the claimInfo cache. - err = m.cache.withLock(func() error { + err = m.cache.withLock(logger, func() error { // Mark all pod claims as prepared. for _, claim := range resourceClaims { info, exists := m.cache.get(claim.Name, claim.Namespace) if !exists { - return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s", claim.Name) + return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s in namespace %s", claim.Name, claim.Namespace) } info.setPrepared() } @@ -471,13 +474,40 @@ func lookupClaimRequest(claims []*drapb.Claim, claimUID string) *drapb.Claim { return nil } +// truncateHealthMessage truncates a health message to the maximum allowed length. +// If the message exceeds v1.ResourceHealthMessageMaxLength, it is truncated to +// (maxLength - 3) characters and "..." is appended. +func truncateHealthMessage(message string) string { + if len(message) <= v1.ResourceHealthMessageMaxLength { + return message + } + return message[:v1.ResourceHealthMessageMaxLength-3] + "..." +} + // GetResources gets a ContainerInfo object from the claimInfo cache. // This information is used by the caller to update a container config. func (m *Manager) GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) { cdiDevices := []kubecontainer.CDIDevice{} + // claimRequests maps claimName -> []requestNames for this container + claimRequests := make(map[string][]string) + + // Collect regular ResourceClaims + containerClaimsMap := make(map[string][]string, len(container.Resources.Claims)) + for _, claim := range container.Resources.Claims { + if _, ok := containerClaimsMap[claim.Name]; !ok { + containerClaimsMap[claim.Name] = []string{} + } + containerClaimsMap[claim.Name] = append(containerClaimsMap[claim.Name], claim.Request) + } + for i := range pod.Spec.ResourceClaims { podClaim := &pod.Spec.ResourceClaims[i] + requests, ok := containerClaimsMap[podClaim.Name] + if !ok { + continue + } + claimName, _, err := resourceclaim.Name(pod, podClaim) if err != nil { // No wrapping, error is already informative. @@ -489,61 +519,54 @@ func (m *Manager) GetResources(pod *v1.Pod, container *v1.Container) (*Container if claimName == nil { continue } - for _, claim := range container.Resources.Claims { - if podClaim.Name != claim.Name { - continue - } - err := m.cache.withRLock(func() error { - claimInfo, exists := m.cache.get(*claimName, pod.Namespace) - if !exists { - return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s", *claimName) - } - - // As of Kubernetes 1.31, CDI device IDs are not passed via annotations anymore. - cdiDevices = append(cdiDevices, claimInfo.cdiDevicesAsList(claim.Request)...) - - return nil - }) - if err != nil { - // No wrapping, this is the error above. - return nil, err - } - } + claimRequests[*claimName] = append(claimRequests[*claimName], requests...) } + // Collect extended resource claims if feature is enabled if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DRAExtendedResource) && pod.Status.ExtendedResourceClaimStatus != nil { claimName := pod.Status.ExtendedResourceClaimStatus.ResourceClaimName // if the container has requests for extended resources backed by DRA, // they must have been allocated via the extendedResourceClaim created // by the kube-scheduler. + + // Build map of this container's extended resource requests + extendedResourceRequests := make(map[string]bool) + for rName, rValue := range container.Resources.Requests { + if !rValue.IsZero() && schedutil.IsDRAExtendedResourceName(rName) { + extendedResourceRequests[rName.String()] = true + } + } + + // Collect request names matching this container's extended resources + for _, rm := range pod.Status.ExtendedResourceClaimStatus.RequestMappings { + // allow multiple device requests per container per resource. + if rm.ContainerName == container.Name && extendedResourceRequests[rm.ResourceName] { + claimRequests[claimName] = append(claimRequests[claimName], rm.RequestName) + } + } + } + + // Process all collected claims + for claimName, requestNames := range claimRequests { err := m.cache.withRLock(func() error { claimInfo, exists := m.cache.get(claimName, pod.Namespace) if !exists { - return fmt.Errorf("unable to get claim info for claim %s in namespace %s", claimName, pod.Namespace) + return fmt.Errorf("internal error: unable to get claim info for ResourceClaim %s in namespace %s", claimName, pod.Namespace) } - for rName, rValue := range container.Resources.Requests { - if rValue.IsZero() { - // We only care about the resources requested by the pod - continue - } - if schedutil.IsDRAExtendedResourceName(rName) { - for _, rm := range pod.Status.ExtendedResourceClaimStatus.RequestMappings { - // allow multiple device requests per container per resource. - if rm.ContainerName == container.Name && rm.ResourceName == rName.String() { - // As of Kubernetes 1.31, CDI device IDs are not passed via annotations anymore. - cdiDevices = append(cdiDevices, claimInfo.cdiDevicesAsList(rm.RequestName)...) - } - } - } + for _, requestName := range requestNames { + // As of Kubernetes 1.31, CDI device IDs are not passed via annotations anymore. + cdiDevices = append(cdiDevices, claimInfo.cdiDevicesAsList(requestName)...) } return nil }) if err != nil { + // No wrapping, this is the error above. return nil, err } } + return &ContainerInfo{CDIDevices: cdiDevices}, nil } @@ -554,7 +577,8 @@ func (m *Manager) GetResources(pod *v1.Pod, container *v1.Container) (*Container func (m *Manager) UnprepareResources(ctx context.Context, pod *v1.Pod) error { startTime := time.Now() err := m.unprepareResourcesForPod(ctx, pod) - kubeletmetrics.DRAOperationsDuration.WithLabelValues("UnprepareResources", strconv.FormatBool(err == nil)).Observe(time.Since(startTime).Seconds()) + isError := (err != nil) + kubeletmetrics.DRAOperationsDuration.WithLabelValues("UnprepareResources", strconv.FormatBool(isError)).Observe(time.Since(startTime).Seconds()) if err != nil { return fmt.Errorf("unprepare dynamic resources: %w", err) } @@ -587,12 +611,12 @@ func (m *Manager) unprepareResourcesForPod(ctx context.Context, pod *v1.Pod) err } func (m *Manager) unprepareResources(ctx context.Context, podUID types.UID, namespace string, claimNames []string) error { - logger := klog.FromContext(ctx) + logger := klog.FromContext(ctx).WithName("dra-manager") batches := make(map[string][]*drapb.Claim) claimNamesMap := make(map[types.UID]string) for _, claimName := range claimNames { // Atomically perform some operations on the claimInfo cache. - err := m.cache.withLock(func() error { + err := m.cache.withLock(logger, func() error { // Get the claim info from the cache claimInfo, exists := m.cache.get(claimName, namespace) @@ -668,7 +692,7 @@ func (m *Manager) unprepareResources(ctx context.Context, podUID types.UID, name } // Atomically perform some operations on the claimInfo cache. - err := m.cache.withLock(func() error { + err := m.cache.withLock(logger, func() error { // TODO(#132978): Re-evaluate this logic to support post-mortem health updates. // As of the initial implementation, we immediately delete the claim info upon // unprepare. This means a late-arriving health update for a terminated pod @@ -708,7 +732,18 @@ func (m *Manager) PodMightNeedToUnprepareResources(uid types.UID) bool { func (m *Manager) GetContainerClaimInfos(pod *v1.Pod, container *v1.Container) ([]*ClaimInfo, error) { claimInfos := make([]*ClaimInfo, 0, len(pod.Spec.ResourceClaims)) + // Build a map of container claims for O(1) lookup + containerClaimsMap := make(map[string]bool, len(container.Resources.Claims)) + for _, claim := range container.Resources.Claims { + containerClaimsMap[claim.Name] = true + } + for i, podResourceClaim := range pod.Spec.ResourceClaims { + // Only process claims that this container actually uses + if !containerClaimsMap[podResourceClaim.Name] { + continue + } + claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) if err != nil { // No wrapping, the error is already informative. @@ -722,23 +757,17 @@ func (m *Manager) GetContainerClaimInfos(pod *v1.Pod, container *v1.Container) ( // Ownership doesn't get checked here, this should have been done before. - for _, claim := range container.Resources.Claims { - if podResourceClaim.Name != claim.Name { - continue - } - - err := m.cache.withRLock(func() error { - claimInfo, exists := m.cache.get(*claimName, pod.Namespace) - if !exists { - return fmt.Errorf("unable to get information for ResourceClaim %s", *claimName) - } - claimInfos = append(claimInfos, claimInfo.DeepCopy()) - return nil - }) - if err != nil { - // No wrapping, this is the error above. - return nil, err + err = m.cache.withRLock(func() error { + claimInfo, exists := m.cache.get(*claimName, pod.Namespace) + if !exists { + return fmt.Errorf("unable to get information for ResourceClaim %s", *claimName) } + claimInfos = append(claimInfos, claimInfo.DeepCopy()) + return nil + }) + if err != nil { + // No wrapping, this is the error above. + return nil, err } } @@ -775,7 +804,9 @@ func (m *Manager) GetContainerClaimInfos(pod *v1.Pod, container *v1.Container) ( // UpdateAllocatedResourcesStatus updates the health status of allocated DRA resources in the pod's container statuses. func (m *Manager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStatus) { - logger := klog.FromContext(context.Background()) + logger := klog.FromContext(context.Background()).WithName("dra-manager") + logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) + enableHealthMessage := utilfeature.DefaultFeatureGate.Enabled(kubefeatures.ResourceHealthStatusMessage) for i := range status.ContainerStatuses { containerStatus := &status.ContainerStatuses[i] @@ -800,21 +831,37 @@ func (m *Manager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStat } } + // Build a map of pod claim statuses for O(1) lookup + podClaimStatusMap := make(map[string]string, len(pod.Status.ResourceClaimStatuses)) + for _, podClaimStatus := range pod.Status.ResourceClaimStatuses { + if podClaimStatus.ResourceClaimName != nil { + podClaimStatusMap[podClaimStatus.Name] = *podClaimStatus.ResourceClaimName + } + } + // Iterate through the claims requested by this specific container. for _, claim := range containerSpec.Resources.Claims { // Find the actual name of the ResourceClaim object. - var actualClaimName string - for _, podClaimStatus := range pod.Status.ResourceClaimStatuses { - if podClaimStatus.Name == claim.Name { - if podClaimStatus.ResourceClaimName != nil { - actualClaimName = *podClaimStatus.ResourceClaimName + // Try the O(1) map lookup first, then fall back to resolving + // from the pod spec. The fallback is needed because + // ResourceClaimStatuses may not be populated yet when a + // health update triggers an early status sync. + actualClaimName := podClaimStatusMap[claim.Name] + + if actualClaimName == "" { + for i := range pod.Spec.ResourceClaims { + if pod.Spec.ResourceClaims[i].Name == claim.Name { + claimNamePtr, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) + if err == nil && claimNamePtr != nil { + actualClaimName = *claimNamePtr + } + break } - break } } if actualClaimName == "" { - logger.V(4).Info("Could not find generated name for resource claim in pod status", "pod", klog.KObj(pod), "container", containerSpec.Name, "claimName", claim.Name) + logger.V(4).Info("Could not find generated name for resource claim", "container", containerSpec.Name, "claimName", claim.Name) continue } @@ -825,7 +872,7 @@ func (m *Manager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStat // Use the actual claim name to look up claim info. claimInfo, exists := m.cache.get(actualClaimName, pod.Namespace) if !exists { - logger.V(4).Info("Could not find claim info for resource claim", "pod", klog.KObj(pod), "container", containerSpec.Name, "claimName", actualClaimName) + logger.V(4).Info("Could not find claim info for resource claim", "container", containerSpec.Name, "claimName", actualClaimName) return } @@ -852,26 +899,34 @@ func (m *Manager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStat // Clear previous health entries before adding current ones. resStatus.Resources = []v1.ResourceHealth{} + // Use a map to track resourceIDs we've already added to avoid duplicates. + // Multiple devices in claimInfo.DriverState may have the same resourceID + // (e.g., when using the same CDI device ID), so we need to deduplicate. + seenResourceIDs := make(map[v1.ResourceID]bool) + for driverName, driverState := range claimInfo.DriverState { for _, device := range driverState.Devices { - healthStr := m.healthInfoCache.getHealthInfo(driverName, device.PoolName, device.DeviceName) - - var health v1.ResourceHealthStatus - switch healthStr { - case "Healthy": - health = v1.ResourceHealthStatusHealthy - case "Unhealthy": - health = v1.ResourceHealthStatusUnhealthy - default: - health = v1.ResourceHealthStatusUnknown + // Skip devices that don't match the request we're reporting for. + // Use BaseRequestRef to handle subrequests (e.g., "request/subrequest" -> "request") + // since device.RequestNames are stored with subrequest suffixes stripped. + if claim.Request != "" && len(device.RequestNames) > 0 && !slices.Contains(device.RequestNames, resourceclaim.BaseRequestRef(claim.Request)) { + continue } - resourceHealth := v1.ResourceHealth{Health: health} - if len(device.CDIDeviceIDs) > 0 { - resourceHealth.ResourceID = v1.ResourceID(device.CDIDeviceIDs[0]) - } else { - resourceHealth.ResourceID = v1.ResourceID(fmt.Sprintf("%s/%s/%s", driverName, device.PoolName, device.DeviceName)) + healthInfo := m.healthInfoCache.getHealthInfo(driverName, device.PoolName, device.DeviceName) + resourceHealth := buildResourceHealth( + driverName, + device, + healthInfo, + enableHealthMessage, + ) + + // Skip if we've already added this resourceID + if seenResourceIDs[resourceHealth.ResourceID] { + continue } + seenResourceIDs[resourceHealth.ResourceID] = true + resStatus.Resources = append(resStatus.Resources, resourceHealth) } } @@ -889,15 +944,80 @@ func (m *Manager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStat } } +func toResourceHealthStatus(health state.DeviceHealthStatus) v1.ResourceHealthStatus { + switch health { + case state.DeviceHealthStatusHealthy: + return v1.ResourceHealthStatusHealthy + case state.DeviceHealthStatusUnhealthy: + return v1.ResourceHealthStatusUnhealthy + default: + return v1.ResourceHealthStatusUnknown + } +} + +func buildResourceHealth(driverName string, device state.Device, healthInfo state.DeviceHealth, enableMessage bool) v1.ResourceHealth { + // Create the ResourceHealth entry + resourceHealth := v1.ResourceHealth{ + Health: toResourceHealthStatus(healthInfo.Health), + } + if enableMessage && len(healthInfo.Message) > 0 { + resourceHealth.Message = &healthInfo.Message + } + // Use first CDI device ID as ResourceID, with fallback + if len(device.CDIDeviceIDs) > 0 { + resourceHealth.ResourceID = v1.ResourceID(device.CDIDeviceIDs[0]) + } else { + resourceHealth.ResourceID = v1.ResourceID(fmt.Sprintf("%s/%s/%s", driverName, device.PoolName, device.DeviceName)) + } + return resourceHealth +} + +func toDeviceHealthStatus(health drahealthv1alpha1.HealthStatus) state.DeviceHealthStatus { + switch health { + case drahealthv1alpha1.HealthStatus_HEALTHY: + return state.DeviceHealthStatusHealthy + case drahealthv1alpha1.HealthStatus_UNHEALTHY: + return state.DeviceHealthStatusUnhealthy + default: + return state.DeviceHealthStatusUnknown + } +} + +func buildDeviceHealth(logger klog.Logger, device *drahealthv1alpha1.DeviceHealth) state.DeviceHealth { + // Extract the health check timeout from the gRPC response + // If not specified, zero, or negative, use the default timeout + timeout := DefaultHealthTimeout + timeoutSeconds := device.GetHealthCheckTimeoutSeconds() + if timeoutSeconds > 0 { + timeout = time.Duration(timeoutSeconds) * time.Second + } else if timeoutSeconds < 0 { + // Log warning for negative timeout values and use default + logger.V(4).Info("Ignoring negative health check timeout, using default", + "poolName", device.GetDevice().GetPoolName(), + "deviceName", device.GetDevice().GetDeviceName(), + "providedTimeout", timeoutSeconds, + "defaultTimeout", DefaultHealthTimeout) + } + return state.DeviceHealth{ + PoolName: device.GetDevice().GetPoolName(), + DeviceName: device.GetDevice().GetDeviceName(), + Health: toDeviceHealthStatus(device.GetHealth()), + LastUpdated: time.Unix(device.GetLastUpdatedTime(), 0), + HealthCheckTimeout: timeout, + Message: truncateHealthMessage(device.GetMessage()), + } +} + // HandleWatchResourcesStream processes health updates from the DRA plugin. func (m *Manager) HandleWatchResourcesStream(ctx context.Context, stream drahealthv1alpha1.DRAResourceHealth_NodeWatchResourcesClient, pluginName string) error { - logger := klog.FromContext(ctx) + logger := klog.FromContext(ctx).WithName("dra-manager") + logger = klog.LoggerWithValues(logger, "pluginName", pluginName) defer func() { - logger.V(4).Info("Clearing health cache for driver upon stream exit", "pluginName", pluginName) + logger.V(4).Info("Clearing health cache for driver upon stream exit") // Use a separate context for clearDriver if needed, though background should be fine. - if err := m.healthInfoCache.clearDriver(pluginName); err != nil { - logger.Error(err, "Failed to clear health info cache for driver", "pluginName", pluginName) + if err := m.healthInfoCache.clearDriver(logger, pluginName); err != nil { + logger.Error(err, "Failed to clear health info cache for driver") } }() @@ -906,63 +1026,31 @@ func (m *Manager) HandleWatchResourcesStream(ctx context.Context, stream draheal if err != nil { // Context canceled, normal shutdown. if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { - logger.V(4).Info("Stopping health monitoring due to context cancellation", "pluginName", pluginName, "reason", err) + logger.V(4).Info("Stopping health monitoring due to context cancellation", "reason", err) return err } // Stream closed cleanly by the server, get normal EOF. if errors.Is(err, io.EOF) { - logger.V(4).Info("Stream ended with EOF", "pluginName", pluginName) + logger.V(4).Info("Stream ended with EOF") return nil } // Other errors are unexpected, log & return. - logger.Error(err, "Error receiving from WatchResources stream", "pluginName", pluginName) + logger.Error(err, "Error receiving from WatchResources stream") return err } // Convert drahealthv1alpha1.DeviceHealth to state.DeviceHealth devices := make([]state.DeviceHealth, len(resp.GetDevices())) for i, d := range resp.GetDevices() { - var health state.DeviceHealthStatus - switch d.GetHealth() { - case drahealthv1alpha1.HealthStatus_HEALTHY: - health = state.DeviceHealthStatusHealthy - case drahealthv1alpha1.HealthStatus_UNHEALTHY: - health = state.DeviceHealthStatusUnhealthy - default: - health = state.DeviceHealthStatusUnknown - } - - // Extract the health check timeout from the gRPC response - // If not specified, zero, or negative, use the default timeout - timeout := DefaultHealthTimeout - timeoutSeconds := d.GetHealthCheckTimeoutSeconds() - if timeoutSeconds > 0 { - timeout = time.Duration(timeoutSeconds) * time.Second - } else if timeoutSeconds < 0 { - // Log warning for negative timeout values and use default - logger.V(4).Info("Ignoring negative health check timeout, using default", - "pluginName", pluginName, - "poolName", d.GetDevice().GetPoolName(), - "deviceName", d.GetDevice().GetDeviceName(), - "providedTimeout", timeoutSeconds, - "defaultTimeout", DefaultHealthTimeout) - } - - devices[i] = state.DeviceHealth{ - PoolName: d.GetDevice().GetPoolName(), - DeviceName: d.GetDevice().GetDeviceName(), - Health: health, - LastUpdated: time.Unix(d.GetLastUpdatedTime(), 0), - HealthCheckTimeout: timeout, - } - } - - changedDevices, updateErr := m.healthInfoCache.updateHealthInfo(pluginName, devices) + devices[i] = buildDeviceHealth(logger, d) + } + + changedDevices, updateErr := m.healthInfoCache.updateHealthInfo(logger, pluginName, devices) if updateErr != nil { - logger.Error(updateErr, "Failed to update health info cache", "pluginName", pluginName) + logger.Error(updateErr, "Failed to update health info cache") } if len(changedDevices) > 0 { - logger.V(4).Info("Health info changed, checking affected pods", "pluginName", pluginName, "changedDevicesCount", len(changedDevices)) + logger.V(4).Info("Health info changed, checking affected pods", "changedDevicesCount", len(changedDevices)) podsToUpdate := sets.New[string]() @@ -983,14 +1071,14 @@ func (m *Manager) HandleWatchResourcesStream(ctx context.Context, stream draheal if podsToUpdate.Len() > 0 { podUIDs := podsToUpdate.UnsortedList() - logger.Info("Sending health update notification for pods", "pluginName", pluginName, "pods", podUIDs) + logger.Info("Sending health update notification for pods", "pods", podUIDs) select { case m.update <- resourceupdates.Update{PodUIDs: podUIDs}: default: - logger.Error(nil, "DRA health update channel is full, discarding pod update notification", "pluginName", pluginName, "pods", podUIDs) + logger.Error(nil, "DRA health update channel is full, discarding pod update notification", "pods", podUIDs) } } else { - logger.V(4).Info("Health info changed, but no active pods found using the affected devices", "pluginName", pluginName) + logger.V(4).Info("Health info changed, but no active pods found using the affected devices") } } @@ -1002,3 +1090,7 @@ func (m *Manager) Updates() <-chan resourceupdates.Update { // Return the internal channel that HandleWatchResourcesStream writes to. return m.update } + +func (*Manager) podGroupResourceClaimsEnabled() bool { + return utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DRAWorkloadResourceClaims) +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin.go index 1529bdcc3a..a6598fec64 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin.go @@ -18,15 +18,11 @@ package plugin import ( "context" - "errors" "fmt" - "net" "sync" "time" "google.golang.org/grpc" - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/status" "k8s.io/klog/v2" @@ -65,70 +61,10 @@ type DRAPlugin struct { mutex sync.Mutex backgroundCtx context.Context - healthClient drahealthv1alpha1.DRAResourceHealthClient healthStreamCtx context.Context healthStreamCancel context.CancelFunc } -func (p *DRAPlugin) getOrCreateGRPCConn() (*grpc.ClientConn, error) { - p.mutex.Lock() - defer p.mutex.Unlock() - - // If connection exists and is ready, return it. - if p.conn != nil && p.conn.GetState() != connectivity.Shutdown { - // Initialize health client if connection exists but client is nil - // This allows lazy init if connection was established before health was added. - if p.healthClient == nil { - p.healthClient = drahealthv1alpha1.NewDRAResourceHealthClient(p.conn) - klog.FromContext(p.backgroundCtx).V(4).Info("Initialized DRAResourceHealthClient lazily") - } - return p.conn, nil - } - - // If the connection is dead, clean it up before creating a new one. - if p.conn != nil { - if err := p.conn.Close(); err != nil { - return nil, fmt.Errorf("failed to close stale gRPC connection to %s: %w", p.endpoint, err) - } - p.conn = nil - p.healthClient = nil - } - - ctx := p.backgroundCtx - logger := klog.FromContext(ctx) - - network := "unix" - logger.V(4).Info("Creating new gRPC connection", "protocol", network, "endpoint", p.endpoint) - // grpc.Dial is deprecated. grpc.NewClient should be used instead. - // For now this gets ignored because this function is meant to establish - // the connection, with the one second timeout below. Perhaps that - // approach should be reconsidered? - //nolint:staticcheck - conn, err := grpc.Dial( - p.endpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithContextDialer(func(ctx context.Context, target string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, target) - }), - grpc.WithChainUnaryInterceptor(newMetricsInterceptor(p.driverName)), - ) - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if ok := conn.WaitForStateChange(ctx, connectivity.Connecting); !ok { - return nil, errors.New("timed out waiting for gRPC connection to be ready") - } - - p.conn = conn - p.healthClient = drahealthv1alpha1.NewDRAResourceHealthClient(p.conn) - - return p.conn, nil -} - func (p *DRAPlugin) DriverName() string { return p.driverName } @@ -138,7 +74,7 @@ func (p *DRAPlugin) NodePrepareResources( req *drapbv1.NodePrepareResourcesRequest, opts ...grpc.CallOption, ) (*drapbv1.NodePrepareResourcesResponse, error) { - logger := klog.FromContext(ctx) + logger := klog.FromContext(ctx).WithName("dra-plugin") logger = klog.LoggerWithValues(logger, "driverName", p.driverName, "endpoint", p.endpoint) ctx = klog.NewContext(ctx, logger) logger.V(4).Info("Calling NodePrepareResources rpc", "request", req) @@ -169,11 +105,12 @@ func (p *DRAPlugin) NodeUnprepareResources( req *drapbv1.NodeUnprepareResourcesRequest, opts ...grpc.CallOption, ) (*drapbv1.NodeUnprepareResourcesResponse, error) { - logger := klog.FromContext(ctx) - logger.V(4).Info("Calling NodeUnprepareResource rpc", "request", req) + logger := klog.FromContext(ctx).WithName("dra-plugin") logger = klog.LoggerWithValues(logger, "driverName", p.driverName, "endpoint", p.endpoint) ctx = klog.NewContext(ctx, logger) + logger.V(4).Info("Calling NodeUnprepareResource rpc", "request", req) + ctx, cancel := context.WithTimeout(ctx, p.clientCallTimeout) defer cancel() @@ -221,17 +158,12 @@ func (p *DRAPlugin) HealthStreamCancel() context.CancelFunc { // NodeWatchResources establishes a stream to receive health updates from the DRA plugin. func (p *DRAPlugin) NodeWatchResources(ctx context.Context) (drahealthv1alpha1.DRAResourceHealth_NodeWatchResourcesClient, error) { - // Ensure a connection and the health client exist before proceeding. - // This call is idempotent and will create them if they don't exist. - _, err := p.getOrCreateGRPCConn() - if err != nil { - klog.FromContext(p.backgroundCtx).Error(err, "Failed to get gRPC connection for health client") - return nil, err - } + logger := klog.FromContext(ctx).WithName("dra-plugin") + logger = klog.LoggerWithValues(logger, "driverName", p.driverName, "endpoint", p.endpoint) + healthClient := drahealthv1alpha1.NewDRAResourceHealthClient(p.conn) - logger := klog.FromContext(ctx).WithValues("pluginName", p.driverName) logger.V(4).Info("Starting WatchResources stream") - stream, err := p.healthClient.NodeWatchResources(ctx, &drahealthv1alpha1.NodeWatchResourcesRequest{}) + stream, err := healthClient.NodeWatchResources(ctx, &drahealthv1alpha1.NodeWatchResourcesRequest{}) if err != nil { logger.Error(err, "NodeWatchResources RPC call failed") return nil, err diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin_manager.go index fd08372c93..367ad09751 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/dra_plugin_manager.go @@ -58,7 +58,7 @@ type DRAPluginManager struct { backgroundCtx context.Context cancel func(err error) kubeClient kubernetes.Interface - getNode func() (*v1.Node, error) + getNode func(context.Context) (*v1.Node, error) wipingDelay time.Duration streamHandler StreamHandler @@ -146,7 +146,7 @@ func (m *monitoredPlugin) HandleConn(_ context.Context, stats grpcstats.ConnStat // The context can be used to cancel all background activities. // If desired, Stop can be called in addition or instead of canceling // the context. It then also waits for background activities to stop. -func NewDRAPluginManager(ctx context.Context, kubeClient kubernetes.Interface, getNode func() (*v1.Node, error), streamHandler StreamHandler, wipingDelay time.Duration) *DRAPluginManager { +func NewDRAPluginManager(ctx context.Context, kubeClient kubernetes.Interface, getNode func(context.Context) (*v1.Node, error), streamHandler StreamHandler, wipingDelay time.Duration) *DRAPluginManager { ctx, cancel := context.WithCancelCause(ctx) pm := &DRAPluginManager{ backgroundCtx: klog.NewContext(ctx, klog.LoggerWithName(klog.FromContext(ctx), "DRA registration handler")), @@ -228,7 +228,7 @@ func (pm *DRAPluginManager) wipeResourceSlices(ctx context.Context, driver strin // Error logging is done inside the loop. Context cancellation doesn't get logged. _ = wait.ExponentialBackoffWithContext(ctx, backoff, func(ctx context.Context) (bool, error) { - node, err := pm.getNode() + node, err := pm.getNode(ctx) if apierrors.IsNotFound(err) { return false, nil } @@ -384,7 +384,7 @@ func (pm *DRAPluginManager) add(driverName string, endpoint string, chosenServic } p.conn = conn - if utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) { + if utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) && pm.streamHandler != nil { pm.wg.Add(1) go func() { defer pm.wg.Done() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go index d61a5b65f6..5861f6ff57 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go @@ -101,4 +101,8 @@ type DeviceHealth struct { // Zero value means use the default timeout (DefaultHealthTimeout). // This ensures backward compatibility with existing data. HealthCheckTimeout time.Duration + + // Message provides additional details about the device's health status. + // This field is optional and may be empty. + Message string } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go index 728cdf8d1c..96ca29bf3e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go @@ -55,9 +55,10 @@ var _ ContainerManager = &FakeContainerManager{} func NewFakeContainerManager() *FakeContainerManager { return &FakeContainerManager{ PodContainerManager: NewFakePodContainerManager(), - // Using klog.Background() for fake/test implementations where no real context is available - cpuManager: cpumanager.NewFakeManager(klog.Background()), - memoryManager: memorymanager.NewFakeManager(klog.Background()), + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + cpuManager: cpumanager.NewFakeManager(klog.TODO()), + memoryManager: memorymanager.NewFakeManager(klog.TODO()), } } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go index 1e7a5ca0c6..9efdfe8287 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go @@ -25,6 +25,7 @@ import ( internalapi "k8s.io/cri-api/pkg/apis" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" + kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api" ) @@ -32,7 +33,7 @@ import ( // for typecheck across platforms var _ func(int64, int64) int64 = MilliCPUToQuota var _ func(int64) uint64 = MilliCPUToShares -var _ func(*v1.Pod, bool, uint64, bool) *ResourceConfig = ResourceConfigForPod +var _ func(*v1.Pod, bool, uint64, bool, kubeletconfig.MemoryReservationPolicy) *ResourceConfig = ResourceConfigForPod var _ func() (*CgroupSubsystems, error) = GetCgroupSubsystems var _ func(string) ([]int, error) = getCgroupProcs var _ func(types.UID) string = GetPodCgroupNameSuffix diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go index b73ff774f8..ffd5db669e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go @@ -34,6 +34,7 @@ import ( v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" kubefeatures "k8s.io/kubernetes/pkg/features" + kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/cm/util" ) @@ -123,7 +124,7 @@ func HugePageLimits(resourceList v1.ResourceList) map[int64]int64 { } // ResourceConfigForPod takes the input pod and outputs the cgroup resource config. -func ResourceConfigForPod(allocatedPod *v1.Pod, enforceCPULimits bool, cpuPeriod uint64, enforceMemoryQoS bool) *ResourceConfig { +func ResourceConfigForPod(allocatedPod *v1.Pod, enforceCPULimits bool, cpuPeriod uint64, enforceMemoryQoS bool, memoryReservationPolicy kubeletconfig.MemoryReservationPolicy) *ResourceConfig { podLevelResourcesEnabled := utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResources) // sum requests and limits. reqs := resourcehelper.PodRequests(allocatedPod, resourcehelper.PodResourcesOptions{ @@ -207,14 +208,20 @@ func ResourceConfigForPod(allocatedPod *v1.Pod, enforceCPULimits bool, cpuPeriod } result.HugePageLimit = hugePageLimits - if enforceMemoryQoS { - memoryMin := int64(0) + if enforceMemoryQoS && memoryReservationPolicy == kubeletconfig.TieredReservationMemoryReservationPolicy { + memoryRequest := int64(0) if request, found := reqs[v1.ResourceMemory]; found { - memoryMin = request.Value() + memoryRequest = request.Value() } - if memoryMin > 0 { + if memoryRequest > 0 { + // Guaranteed pods get memory.min (hard protection, kernel never reclaims). + // Burstable pods get memory.low (soft protection, kernel prefers not to reclaim). + cgroupKey := Cgroup2MemoryLow + if qosClass == v1.PodQOSGuaranteed { + cgroupKey = Cgroup2MemoryMin + } result.Unified = map[string]string{ - Cgroup2MemoryMin: strconv.FormatInt(memoryMin, 10), + cgroupKey: strconv.FormatInt(memoryRequest, 10), } } } @@ -347,7 +354,7 @@ func GetKubeletContainer(logger klog.Logger, kubeletCgroups string) (string, err func CPURequestsFromConfig(podConfig *ResourceConfig) *resource.Quantity { var cpuRequest *resource.Quantity if podConfig != nil && *podConfig.CPUShares > 0 { - milliCPU := sharesToMilliCPU(int64(*podConfig.CPUShares)) + milliCPU := SharesToMilliCPU(int64(*podConfig.CPUShares)) if milliCPU > 0 { cpuRequest = resource.NewMilliQuantity(milliCPU, resource.DecimalSI) } @@ -360,7 +367,7 @@ func CPULimitsFromConfig(podConfig *ResourceConfig) *resource.Quantity { var cpuLimit *resource.Quantity if podConfig != nil && *podConfig.CPUPeriod > 0 { - milliCPU := quotaToMilliCPU(*podConfig.CPUQuota, int64(*podConfig.CPUPeriod)) + milliCPU := QuotaToMilliCPU(*podConfig.CPUQuota, int64(*podConfig.CPUPeriod)) if milliCPU > 0 { cpuLimit = resource.NewMilliQuantity(milliCPU, resource.DecimalSI) } @@ -378,9 +385,8 @@ func MemoryLimitsFromConfig(podConfig *ResourceConfig) *resource.Quantity { return memLimit } -// sharesToMilliCPU converts CpuShares (cpu.shares) to milli-CPU value -// TODO - dedup sharesToMilliCPU with sharesToMilliCPU in pkg/kubelet/kuberuntime/helpers_linux.go -func sharesToMilliCPU(shares int64) int64 { +// SharesToMilliCPU converts CpuShares (cpu.shares) to milli-CPU value +func SharesToMilliCPU(shares int64) int64 { milliCPU := int64(0) if shares >= int64(MinShares) { milliCPU = int64(math.Ceil(float64(shares*MilliCPUToCPU) / float64(SharesPerCPU))) @@ -388,10 +394,8 @@ func sharesToMilliCPU(shares int64) int64 { return milliCPU } -// quotaToMilliCPU converts cpu.cfs_quota_us and cpu.cfs_period_us to milli-CPU -// value -// TODO - dedup quotaToMilliCPU with sharesToMilliCPU in pkg/kubelet/kuberuntime/helpers_linux.go -func quotaToMilliCPU(quota int64, period int64) int64 { +// QuotaToMilliCPU converts cpu.cfs_quota_us and cpu.cfs_period_us to milli-CPU value +func QuotaToMilliCPU(quota int64, period int64) int64 { if quota == -1 { return int64(0) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go index 33df93ff8c..148e45bc02 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. @@ -24,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" + kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" ) const ( @@ -49,7 +49,7 @@ func MilliCPUToShares(milliCPU int64) uint64 { } // ResourceConfigForPod takes the input pod and outputs the cgroup resource config. -func ResourceConfigForPod(pod *v1.Pod, enforceCPULimit bool, cpuPeriod uint64, enforceMemoryQoS bool) *ResourceConfig { +func ResourceConfigForPod(pod *v1.Pod, enforceCPULimit bool, cpuPeriod uint64, enforceMemoryQoS bool, memoryReservationPolicy kubeletconfig.MemoryReservationPolicy) *ResourceConfig { return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go index 91561cf713..39bb1e76d9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go index 4f6aa89a8e..c8cde975be 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go index ec960f8ead..ee638c6868 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go index e589c78f57..bbe3c4a885 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go @@ -76,6 +76,12 @@ func (m *fakeManager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymana return map[string][]topologymanager.TopologyHint{} } +func (m *fakeManager) AllocatePod(pod *v1.Pod) error { + logger := klog.TODO() + logger.Info("AllocatePod", "pod", klog.KObj(pod)) + return nil +} + func (m *fakeManager) State() state.Reader { return m.state } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go index 585ebff101..9e11d24627 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go @@ -84,6 +84,9 @@ type Manager interface { // and other resource controllers. GetPodTopologyHints(*v1.Pod) map[string][]topologymanager.TopologyHint + // AllocatePod is called to trigger the allocation of memory to a pod. + AllocatePod(pod *v1.Pod) error + // GetMemoryNUMANodes provides NUMA nodes that are used to allocate the container memory GetMemoryNUMANodes(logger klog.Logger, pod *v1.Pod, container *v1.Container) sets.Set[int] @@ -276,6 +279,22 @@ func (m *manager) Allocate(pod *v1.Pod, container *v1.Container) error { return nil } +func (m *manager) AllocatePod(pod *v1.Pod) error { + logger := klog.TODO() // until we move topology manager to contextual logging + + m.removeStaleState(logger) + + m.Lock() + defer m.Unlock() + + // Call down into the policy to assign this container memory if required. + if err := m.policy.AllocatePod(logger, m.state, pod); err != nil { + logger.Error(err, "AllocatePod error", "pod", klog.KObj(pod)) + return err + } + return nil +} + // RemoveContainer removes the container from the state func (m *manager) RemoveContainer(logger klog.Logger, containerID string) error { logger = klog.LoggerWithValues(logger, "containerID", containerID) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go index 3c17ec93c2..c4dfe376b8 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go @@ -42,6 +42,8 @@ type Policy interface { // and is consulted to achieve NUMA aware resource alignment among this // and other resource controllers. GetPodTopologyHints(logger klog.Logger, s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint + // AllocatePod is called to trigger the allocation of memory to a pod-level resources pod. + AllocatePod(logger klog.Logger, s state.State, pod *v1.Pod) error // GetAllocatableMemory returns the amount of allocatable memory for each NUMA node GetAllocatableMemory(s state.State) []state.Block } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go index 53f5746d48..59fcdba7a9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go @@ -69,7 +69,8 @@ func (p *bestEffortPolicy) RemoveContainer(logger logr.Logger, s state.State, po } func (p *bestEffortPolicy) GetPodTopologyHints(logger logr.Logger, s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - return p.static.GetPodTopologyHints(logger, s, pod) + // Pod-level resources are not supported on Windows. + return nil } func (p *bestEffortPolicy) GetTopologyHints(logger logr.Logger, s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { @@ -79,3 +80,8 @@ func (p *bestEffortPolicy) GetTopologyHints(logger logr.Logger, s state.State, p func (p *bestEffortPolicy) GetAllocatableMemory(s state.State) []state.Block { return p.static.GetAllocatableMemory(s) } + +func (p *bestEffortPolicy) AllocatePod(logger logr.Logger, s state.State, pod *v1.Pod) error { + // Pod-level resources are not supported on Windows. + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go index ceb2d236d1..7499913cec 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go @@ -68,6 +68,10 @@ func (p *none) GetPodTopologyHints(_ klog.Logger, s state.State, pod *v1.Pod) ma return nil } +func (p *none) AllocatePod(_ klog.Logger, s state.State, pod *v1.Pod) error { + return nil +} + // GetAllocatableMemory returns the amount of allocatable memory for each NUMA node func (p *none) GetAllocatableMemory(s state.State) []state.Block { return []state.Block{} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go index eb5c3b5f67..16b3b4a637 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go @@ -19,7 +19,9 @@ package memorymanager import ( "fmt" "sort" + "strings" + "github.com/go-logr/logr" cadvisorapi "github.com/google/cadvisor/info/v1" v1 "k8s.io/api/core/v1" @@ -31,7 +33,9 @@ import ( corehelper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/pkg/kubelet/cm/admission" "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" + cmqos "k8s.io/kubernetes/pkg/kubelet/cm/qos" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" "k8s.io/kubernetes/pkg/kubelet/metrics" @@ -94,28 +98,353 @@ func (p *staticPolicy) Start(logger klog.Logger, s state.State) error { return nil } +// validatePodScopeResources checks for the "empty shared pool" scenario. This +// occurs when the sum of exclusive container memory requests consumes the +// entire pod-level budget, leaving no memory for containers that require a +// shared pool. Such a configuration is invalid because it would lead to +// containers in the shared pool having no memory allocated, causing them to +// fail. +func (p *staticPolicy) validatePodScopeResources(logger logr.Logger, pod *v1.Pod) error { + podTotalMemory, err := getPodRequestedResources(logger, pod) + if err != nil { + return err + } + + hasSharedLongRunningContainers := false + // Sum memory requests for all containers that run for the full pod lifetime + // (main containers and restartable init containers) to determine the + // total exclusive memory usage that might impact the shared pool. + sumOfLongRunningExclusiveMemory := make(map[v1.ResourceName]uint64) + + // Check for empty shared pool for standard init containers. + for _, container := range pod.Spec.InitContainers { + containerReqs, err := getContainerRequestedResources(logger, pod, &container) + if err != nil { + return err + } + + if !podutil.IsRestartableInitContainer(&container) { + if len(containerReqs) == 0 { + // This check ensures that if there are any standard init containers that need a + // shared pool, that pool is not empty. An empty pool would occur if the pod + // budget is fully consumed by sidecars. + for resourceName, poolSize := range podTotalMemory { + if sumOfLongRunningExclusiveMemory[resourceName] >= poolSize { + return fmt.Errorf("pod rejected, pod has shared init containers but no %s available for them", resourceName) + } + } + } + } else { + // If there are restartable init containers, keep track for the empty shared pool check. + if len(containerReqs) == 0 { + hasSharedLongRunningContainers = true + } else { + for resourceName, reqAmount := range containerReqs { + sumOfLongRunningExclusiveMemory[resourceName] += reqAmount + } + } + } + } + + // Check for empty shared pool for concurrently running containers (app and restartable init containers). + for _, container := range pod.Spec.Containers { + containerReqs, err := getContainerRequestedResources(logger, pod, &container) + if err != nil { + return err + } + + if len(containerReqs) == 0 { + hasSharedLongRunningContainers = true + } else { + for resourceName, val := range containerReqs { + sumOfLongRunningExclusiveMemory[resourceName] += val + } + } + } + + // This check ensures that if there are any standard containers that need a shared + // pool, that pool is not empty. An empty pool would occur if the pod budget is + // fully consumed by sidecars and main containers with exclusive resources. + if hasSharedLongRunningContainers { + for resourceName, totalPodResource := range podTotalMemory { + if sumOfLongRunningExclusiveMemory[resourceName] >= totalPodResource { + return fmt.Errorf("pod rejected, sum of exclusive container %s requests equals pod budget, leaving no memory for shared containers", resourceName) + } + } + } + + return nil +} + +// AllocatePod is the entry point for pod-level resource allocation. +// It's called once per pod by the Topology Manager's pod-scope admit handler. +// The logic here allocates a single NUMA-aligned "bubble" of memory for the +// entire pod. All containers within the pod will share this NUMA binding. +func (p *staticPolicy) AllocatePod(logger klog.Logger, s state.State, pod *v1.Pod) (rerr error) { + podUID := string(pod.UID) + logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) + logger.V(4).Info("AllocatePod called for pod-level managed pod") + + qos := v1qos.GetPodQOS(pod) + if qos != v1.PodQOSGuaranteed { + return nil + } + + // 1. Calculate memory resources. + podTotalMemory, err := getPodRequestedResources(logger, pod) + if err != nil { + logger.Error(err, "Failed to get pod requested resources", "podUID", podUID) + return nil + } + logger.V(4).Info("Calculated total pod memory", "podTotalMemory", podTotalMemory) + + metrics.MemoryManagerPinningRequestTotal.Inc() + defer func() { + if rerr != nil { + metrics.MemoryManagerPinningErrorsTotal.Inc() + metrics.ResourceManagerAllocationErrorsTotal.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerPod).Inc() + } + }() + + // 2. Validate for the "empty shared pool" case. + // Even though this is checked during hint generation, we must re-evaluate it here. + // If the Topology Manager is running with the "best-effort" or "none" policies, + // it will still admit the pod even if GetPodTopologyHints returns an empty hint list. + // This ensures we explicitly reject the pod during allocation to prevent Kubelet + // from attempting to create invalid cgroups (e.g., an empty cpuset.mems) for shared containers. + if err := p.validatePodScopeResources(logger, pod); err != nil { + return admission.NewEmptyPodSharedPoolError(err) + } + + // 3. Handle hints and NUMA alignment. + machineState := s.GetMachineState() + bestHint := p.affinity.GetAffinity(podUID, append(pod.Spec.InitContainers, pod.Spec.Containers...)[0].Name) + if bestHint.NUMANodeAffinity == nil { + defaultHint, err := p.getDefaultHint(machineState, pod, podTotalMemory) + if err != nil { + return err + } + if !defaultHint.Preferred && bestHint.Preferred { + return fmt.Errorf("[memorymanager] failed to find the default preferred hint") + } + bestHint = *defaultHint + } + + if !isAffinitySatisfyRequest(machineState, bestHint.NUMANodeAffinity, podTotalMemory) { + extendedHint, err := p.extendTopologyManagerHint(machineState, pod, podTotalMemory, bestHint.NUMANodeAffinity) + if err != nil { + return err + } + if !extendedHint.Preferred && bestHint.Preferred { + return fmt.Errorf("[memorymanager] failed to find the extended preferred hint") + } + bestHint = *extendedHint + } + + if isAffinityViolatingNUMAAllocations(machineState, bestHint.NUMANodeAffinity) { + return fmt.Errorf("[memorymanager] preferred hint violates NUMA node allocation") + } + + maskBits := bestHint.NUMANodeAffinity.GetBits() + + // 4. Partition the pod's memory allocation, handling init container reuse correctly. + exclusiveMemory := make(map[string][]state.Block) + sidecarMemory := make(map[v1.ResourceName]uint64) + + // First, iterate through all init containers and allocate their memory. + for _, c := range pod.Spec.InitContainers { + reqs, err := getContainerRequestedResources(logger, pod, &c) + if err != nil { + return err + } + + metrics.MemoryManagerPinningRequestTotal.Inc() + + // The pool available for this init container is the entire pod allocation + // minus what's already taken by sidecars. + runnablePool := make(map[v1.ResourceName]uint64) + for resourceName, total := range podTotalMemory { + runnablePool[resourceName] = total - sidecarMemory[resourceName] + } + + if len(reqs) == 0 { + // Restartable init containers will access the main pod shared pool. + if podutil.IsRestartableInitContainer(&c) { + continue + } + + // Non restartable init containers will have access to the whole pod pool + // amount minus the sidecar exclusive memory up to that point. + blocks := []state.Block{} + for resourceName, req := range runnablePool { + if req > 0 { + blocks = append(blocks, state.Block{ + NUMAAffinity: maskBits, + Size: req, + Type: resourceName, + }) + } + } + exclusiveMemory[c.Name] = blocks + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerSharedPod).Inc() + continue + } + + // Allocate blocks + blocks := []state.Block{} + for resourceName, req := range reqs { + if req > 0 { + blocks = append(blocks, state.Block{ + NUMAAffinity: maskBits, + Size: req, + Type: resourceName, + }) + } + } + exclusiveMemory[c.Name] = blocks + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerExclusivePod).Inc() + + // If it's a restartable sidecar, its memory is permanently consumed from the pod's budget. + if podutil.IsRestartableInitContainer(&c) { + for resourceName, req := range reqs { + sidecarMemory[resourceName] += req + } + } + } + + // Recalculate the pool available for app containers. + // This is the total pod budget minus what all sidecars are using. + appContainerPool := make(map[v1.ResourceName]uint64) + for resourceName, total := range podTotalMemory { + appContainerPool[resourceName] = total - sidecarMemory[resourceName] + } + + // Second, iterate through regular containers, allocating from the remaining pool. + for _, c := range pod.Spec.Containers { + reqs, err := getContainerRequestedResources(logger, pod, &c) + if err != nil { + // This should not happen, as we have already validated the pod's resources. + return err + } + + // A container with no memory requests will be part of the shared pool. + if len(reqs) == 0 { + continue + } + metrics.MemoryManagerPinningRequestTotal.Inc() + + // Allocate blocks and consume from the pool + blocks := []state.Block{} + for resourceName, req := range reqs { + if req > 0 { + blocks = append(blocks, state.Block{ + NUMAAffinity: maskBits, + Size: req, + Type: resourceName, + }) + appContainerPool[resourceName] -= req + } + } + exclusiveMemory[c.Name] = blocks + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerExclusivePod).Inc() + } + + // The final shared pool is what remains after all exclusive allocations. + podSharedPoolBlocks := []state.Block{} + for resourceName, val := range appContainerPool { + if val > 0 { + podSharedPoolBlocks = append(podSharedPoolBlocks, state.Block{ + NUMAAffinity: maskBits, + Size: val, + Type: resourceName, + }) + } + } + + podAllocation := []state.Block{} + for resourceName, requestedSize := range podTotalMemory { + podAllocation = append(podAllocation, state.Block{ + NUMAAffinity: maskBits, + Size: requestedSize, + Type: resourceName, + }) + } + s.SetPodMemoryBlocks(podUID, podAllocation) + + // 5. Now that partitioning is successful, update the global machine state. + for resourceName, requestedSize := range podTotalMemory { + p.updateMachineState(machineState, maskBits, resourceName, requestedSize) + } + logger.V(4).Info("Partitioned pod-level memory allocation", "exclusiveMemory", podMemoryAllocationToString(exclusiveMemory), "podSharedPool", memoryBlocksToString(podSharedPoolBlocks)) + + // 6. Save all container assignments to the state. + for _, c := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { + if blocks, isExclusive := exclusiveMemory[c.Name]; isExclusive { + s.SetMemoryBlocks(podUID, c.Name, blocks) + } else { + s.SetMemoryBlocks(podUID, c.Name, podSharedPoolBlocks) + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerSharedPod).Inc() + } + + metrics.ResourceManagerAllocationsTotal.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerPod).Inc() + } + + s.SetMachineState(machineState) + return nil +} + +func podMemoryAllocationToString(alloc map[string][]state.Block) string { + if len(alloc) == 0 { + return "" + } + var sb strings.Builder + for name, blocks := range alloc { + fmt.Fprintf(&sb, ",%s=%s", name, memoryBlocksToString(blocks)) + } + // if we have gone so far, it means we have at least 1 alloc, so the cut is safe + repr := sb.String()[1:] + return "<" + repr + ">" +} + +func memoryBlocksToString(blocks []state.Block) string { + if len(blocks) == 0 { + return "[]" + } + var sb strings.Builder + for _, block := range blocks { + // Format: {Type:SizeMi @ [NUMA_Nodes]} + fmt.Fprintf(&sb, ",{%s:%dMi @ %v}", block.Type, block.Size/(1024*1024), block.NUMAAffinity) + } + // Cut the leading comma + repr := sb.String()[1:] + return "[" + repr + "]" +} + // Allocate call is idempotent func (p *staticPolicy) Allocate(logger klog.Logger, s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { // allocate the memory only for guaranteed pods logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod), "containerName", container.Name) + + podUID := string(pod.UID) + // Allocate the memory only for guaranteed pods qos := v1qos.GetPodQOS(pod) if qos != v1.PodQOSGuaranteed { logger.V(5).Info("Exclusive memory allocation skipped, pod QoS is not guaranteed", "qos", qos) return nil } - podUID := string(pod.UID) - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { logger.V(2).Info("Allocation skipped, pod is using pod-level resources which are not supported by the static Memory manager policy", "podUID", podUID) return nil } logger.Info("Allocate") - // container belongs in an exclusively allocated pool + // Container belongs in an exclusively allocated pool metrics.MemoryManagerPinningRequestTotal.Inc() defer func() { if rerr != nil { metrics.MemoryManagerPinningErrorsTotal.Inc() + metrics.ResourceManagerAllocationErrorsTotal.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerNode).Inc() } }() if blocks := s.GetMemoryBlocks(podUID, container.Name); blocks != nil { @@ -129,7 +458,7 @@ func (p *staticPolicy) Allocate(logger klog.Logger, s state.State, pod *v1.Pod, hint := p.affinity.GetAffinity(podUID, container.Name) logger.Info("Got topology affinity", "hint", hint) - requestedResources, err := getRequestedResources(pod, container) + requestedResources, err := getContainerRequestedResources(logger, pod, container) if err != nil { return err } @@ -190,6 +519,7 @@ func (p *staticPolicy) Allocate(logger klog.Logger, s state.State, pod *v1.Pod, // Update nodes memory state p.updateMachineState(machineState, maskBits, resourceName, requestedSize) + metrics.ResourceManagerAllocationsTotal.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerNode).Inc() } p.updatePodReusableMemory(pod, container, containerBlocks) @@ -204,6 +534,7 @@ func (p *staticPolicy) Allocate(logger klog.Logger, s state.State, pod *v1.Pod, // though the final state here doesn't accurately reflect what was (in reality) allocated to each container // TODO: we should refactor our state structs to reflect the amount of the re-used memory p.updateInitContainersMemoryBlocks(logger, s, pod, container, containerBlocks) + metrics.ResourceManagerContainerAssignments.WithLabelValues(metrics.ResourceManagerMemory, metrics.ResourceManagerExclusiveNode).Inc() logger.V(4).Info("Allocated exclusive memory") return nil @@ -257,15 +588,35 @@ func (p *staticPolicy) getPodReusableMemory(pod *v1.Pod, numaAffinity bitmask.Bi // RemoveContainer call is idempotent func (p *staticPolicy) RemoveContainer(logger klog.Logger, s state.State, podUID string, containerName string) { logger = klog.LoggerWithValues(logger, "podUID", podUID, "containerName", containerName) + logger.Info("RemoveContainer", "podUID", podUID, "containerName", containerName) + + // Check if this pod is managed with pod-level memory. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + if podMemory := s.GetPodMemoryBlocks(podUID); podMemory != nil { + s.Delete(podUID, containerName) + // If this was the last container for the pod, then release the entire pod-level memory. + if len(s.GetMemoryAssignments()[podUID]) == 0 { + p.releaseMemory(s, podMemory) + s.DeletePod(podUID) // Clean up all state for the pod. + logger.Info("Released pod-level memory") + } + // If other containers still exist, do not release any memory yet. + // The pod-level memory will be released when the last container is removed. + return + } + } blocks := s.GetMemoryBlocks(podUID, containerName) if blocks == nil { return } - - logger.Info("RemoveContainer", "podUID", podUID, "containerName", containerName) s.Delete(podUID, containerName) + p.releaseMemory(s, blocks) + logger.Info("Released container-level memory") +} + +func (p *staticPolicy) releaseMemory(s state.State, blocks []state.Block) { // Mutate machine memory state to update free and reserved memory machineState := s.GetMachineState() for _, b := range blocks { @@ -346,13 +697,32 @@ func regenerateHints(logger klog.Logger, pod *v1.Pod, ctn *v1.Container, ctnBloc return hints } -func getPodRequestedResources(pod *v1.Pod) (map[v1.ResourceName]uint64, error) { +func getPodRequestedResources(logger logr.Logger, pod *v1.Pod) (map[v1.ResourceName]uint64, error) { + // If pod-level resources are set, use them directly. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + requestedResources := make(map[v1.ResourceName]uint64) + for resourceName, quantity := range pod.Spec.Resources.Requests { + if resourceName != v1.ResourceMemory && !corehelper.IsHugePageResourceName(resourceName) { + continue + } + requestedSize, succeed := quantity.AsInt64() + if !succeed { + return nil, fmt.Errorf("[memorymanager] failed to represent quantity as int64") + } + if requestedSize <= 0 { + continue + } + requestedResources[resourceName] = uint64(requestedSize) + } + return requestedResources, nil + } + // Maximun resources requested by init containers at any given time. reqRsrcsByInitCtrs := make(map[v1.ResourceName]uint64) // Total resources requested by restartable init containers. reqRsrcsByRestartableInitCtrs := make(map[v1.ResourceName]uint64) for _, ctr := range pod.Spec.InitContainers { - reqRsrcs, err := getRequestedResources(pod, &ctr) + reqRsrcs, err := getContainerRequestedResources(logger, pod, &ctr) if err != nil { return nil, err @@ -374,7 +744,7 @@ func getPodRequestedResources(pod *v1.Pod) (map[v1.ResourceName]uint64, error) { reqRsrcsByAppCtrs := make(map[v1.ResourceName]uint64) for _, ctr := range pod.Spec.Containers { - reqRsrcs, err := getRequestedResources(pod, &ctr) + reqRsrcs, err := getContainerRequestedResources(logger, pod, &ctr) if err != nil { return nil, err @@ -408,14 +778,37 @@ func (p *staticPolicy) GetPodTopologyHints(logger klog.Logger, s state.State, po return nil } - reqRsrcs, err := getPodRequestedResources(pod) + // Get a count of how much memory has been requested by Pod. + reqRsrcs, err := getPodRequestedResources(logger, pod) if err != nil { logger.Error(err, "Failed to get pod requested resources", "podUID", pod.UID) return nil } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { - logger.V(3).Info("Topology hints generation skipped, pod is using pod-level resources which are not supported by the static Memory manager policy", "podUID", pod.UID) + // If the pod has pod-level resources but the feature gate is disabled, + // log it and return nil hints to admit the pod without alignment. + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { + logger.V(3).Info("Memory Manager pod hint generation skipped, pod is using pod-level resources but the PodLevelResourceManagers feature gate is not enabled", "podUID", pod.UID) + return nil + } + + // Validate that if a pod has containers that will be placed in a shared pool, + // there are actually memory left over for that pool after accounting for all + // exclusive allocations. If the sum of exclusive memory requests consumes the + // entire pod-level memory budget, no hints will be generated, causing the pod + // to be rejected by the Topology Manager. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + if err := p.validatePodScopeResources(logger, pod); err != nil { + logger.V(2).Info("Pod admission will fail", "error", err) + hints := make(map[string][]topologymanager.TopologyHint) + for resourceName := range reqRsrcs { + hints[string(resourceName)] = []topologymanager.TopologyHint{} + } + return hints + } + } + + if len(reqRsrcs) == 0 { return nil } @@ -443,14 +836,16 @@ func (p *staticPolicy) GetTopologyHints(logger klog.Logger, s state.State, pod * return nil } - requestedResources, err := getRequestedResources(pod, container) + requestedResources, err := getContainerRequestedResources(logger, pod, container) if err != nil { logger.Error(err, "Failed to get container requested resources", "podUID", pod.UID, "containerName", container.Name) return nil } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && resourcehelper.IsPodLevelResourcesSet(pod) { - logger.V(3).Info("Topology hints generation skipped, pod is using pod-level resources which are not supported by the static Memory manager policy", "podUID", pod.UID) + // If the pod has pod-level resources but the feature gate is disabled, + // log it and return nil hints to admit the pod without alignment. + if (!utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) || !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources)) && resourcehelper.IsPodLevelResourcesSet(pod) { + logger.V(3).Info("Memory Manager pod hint generation skipped, pod is using pod-level resources but the PodLevelResourceManagers feature gate is not enabled", "podUID", pod.UID) return nil } @@ -465,12 +860,21 @@ func (p *staticPolicy) GetTopologyHints(logger klog.Logger, s state.State, pod * return p.calculateHints(s.GetMachineState(), pod, requestedResources) } -func getRequestedResources(pod *v1.Pod, container *v1.Container) (map[v1.ResourceName]uint64, error) { +func getContainerRequestedResources(logger logr.Logger, pod *v1.Pod, container *v1.Container) (map[v1.ResourceName]uint64, error) { requestedResources := map[v1.ResourceName]uint64{} + // For pod-level resource management, a container is only considered for exclusive + // memory if its request equals its limit for both the CPU and Memory. This + // aligns with the Guaranteed QoS requirement for container-level resources. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) && !cmqos.IsContainerEquivalentQOSGuaranteed(container) { + logger.V(5).Info("Exclusive Memory allocation skipped, container is not eligible, request and limit are not equal", "pod", klog.KObj(pod), "containerName", container.Name) + return requestedResources, nil + } + for resourceName, quantity := range container.Resources.Requests { if resourceName != v1.ResourceMemory && !corehelper.IsHugePageResourceName(resourceName) { continue } + requestedSize, succeed := quantity.AsInt64() if !succeed { return nil, fmt.Errorf("[memorymanager] failed to represent quantity as int64") @@ -614,45 +1018,18 @@ func (p *staticPolicy) validateState(logger klog.Logger, s state.State) error { // calculate all memory assigned to containers expectedMachineState := p.getDefaultMachineState() for pod, container := range memoryAssignments { - for containerName, blocks := range container { - for _, b := range blocks { - requestedSize := b.Size - for _, nodeID := range b.NUMAAffinity { - nodeState, ok := expectedMachineState[nodeID] - if !ok { - return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses the NUMA that does not exist", pod, containerName) - } - - nodeState.NumberOfAssignments++ - nodeState.Cells = b.NUMAAffinity - - memoryState, ok := nodeState.MemoryMap[b.Type] - if !ok { - return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses memory resource that does not exist", pod, containerName) - } - - if requestedSize == 0 { - continue - } - - // this node does not have enough memory continue to the next one - if memoryState.Free <= 0 { - continue - } - - // the node has enough memory to satisfy the request - if memoryState.Free >= requestedSize { - memoryState.Reserved += requestedSize - memoryState.Free -= requestedSize - requestedSize = 0 - continue - } - - // the node does not have enough memory, use the node remaining memory and move to the next node - requestedSize -= memoryState.Free - memoryState.Reserved += memoryState.Free - memoryState.Free = 0 + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + if podBlocks := s.GetPodMemoryBlocks(pod); len(podBlocks) > 0 { + if err := p.updateExpectedMachineState(expectedMachineState, podBlocks, pod, ""); err != nil { + return err } + continue + } + } + + for containerName, blocks := range container { + if err := p.updateExpectedMachineState(expectedMachineState, blocks, pod, containerName); err != nil { + return err } } } @@ -668,6 +1045,49 @@ func (p *staticPolicy) validateState(logger klog.Logger, s state.State) error { return nil } +func (p *staticPolicy) updateExpectedMachineState(expectedMachineState state.NUMANodeMap, blocks []state.Block, podUID, containerName string) error { + for _, b := range blocks { + requestedSize := b.Size + for _, nodeID := range b.NUMAAffinity { + nodeState, ok := expectedMachineState[nodeID] + if !ok { + return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses the NUMA that does not exist", podUID, containerName) + } + + nodeState.NumberOfAssignments++ + nodeState.Cells = b.NUMAAffinity + + memoryState, ok := nodeState.MemoryMap[b.Type] + if !ok { + return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses memory resource that does not exist", podUID, containerName) + } + + if requestedSize == 0 { + continue + } + + // this node does not have enough memory continue to the next one + if memoryState.Free <= 0 { + continue + } + + // the node has enough memory to satisfy the request + if memoryState.Free >= requestedSize { + memoryState.Reserved += requestedSize + memoryState.Free -= requestedSize + requestedSize = 0 + continue + } + + // the node does not have enough memory, use the node remaining memory and move to the next node + requestedSize -= memoryState.Free + memoryState.Reserved += memoryState.Free + memoryState.Free = 0 + } + } + return nil +} + func areMachineStatesEqual(logger klog.Logger, ms1, ms2 state.NUMANodeMap) bool { if len(ms1) != len(ms2) { logger.Info("Node states were different", "lengthNode1", len(ms1), "lengthNode2", len(ms2)) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go index 93b1302baa..445d0cf57b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go @@ -18,15 +18,36 @@ package state import ( "encoding/json" + "fmt" + "hash/fnv" + "strings" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" + "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" + "k8s.io/utils/dump" ) +var _ checkpointmanager.Checkpoint = &MemoryManagerCheckpointV1{} +var _ checkpointmanager.Checkpoint = &MemoryManagerCheckpointV2{} var _ checkpointmanager.Checkpoint = &MemoryManagerCheckpoint{} -// MemoryManagerCheckpoint struct is used to store memory/pod assignments in a checkpoint +// MemoryManagerCheckpoint struct is used to store memory/pod assignments in a checkpoint in v2 format type MemoryManagerCheckpoint struct { + PolicyName string `json:"policyName"` + MachineState NUMANodeMap `json:"machineState"` + Entries ContainerMemoryAssignments `json:"entries,omitempty"` + PodEntries PodMemoryAssignments `json:"podEntries,omitempty"` + Checksum checksum.Checksum `json:"checksum"` +} + +// MemoryManagerCheckpointV2 struct is used to store memory/pod assignments in a checkpoint in v2 format +type MemoryManagerCheckpointV2 = MemoryManagerCheckpoint + +// MemoryManagerCheckpointV1 struct is used to store memory/pod assignments in a checkpoint in v1 format +type MemoryManagerCheckpointV1 struct { PolicyName string `json:"policyName"` MachineState NUMANodeMap `json:"machineState"` Entries ContainerMemoryAssignments `json:"entries,omitempty"` @@ -34,28 +55,100 @@ type MemoryManagerCheckpoint struct { } // NewMemoryManagerCheckpoint returns an instance of Checkpoint -func NewMemoryManagerCheckpoint() *MemoryManagerCheckpoint { +func newMemoryManagerCheckpoint() *MemoryManagerCheckpoint { //nolint:staticcheck // unexported-type-in-api user-facing error message - return &MemoryManagerCheckpoint{ + return newMemoryManagerCheckpointV2() +} + +func newMemoryManagerCheckpointV1() *MemoryManagerCheckpointV1 { + return &MemoryManagerCheckpointV1{ Entries: ContainerMemoryAssignments{}, MachineState: NUMANodeMap{}, } } -// MarshalCheckpoint returns marshalled checkpoint -func (mp *MemoryManagerCheckpoint) MarshalCheckpoint() ([]byte, error) { +func newMemoryManagerCheckpointV2() *MemoryManagerCheckpointV2 { + return &MemoryManagerCheckpointV2{ + Entries: ContainerMemoryAssignments{}, + PodEntries: PodMemoryAssignments{}, + MachineState: NUMANodeMap{}, + } +} + +// MarshalCheckpoint returns marshalled checkpoint in v1 format +func (mp *MemoryManagerCheckpointV1) MarshalCheckpoint() ([]byte, error) { + // make sure checksum wasn't set before so it doesn't affect output checksum + mp.Checksum = 0 + + // In order to preserve rollback compatibility when the feature gate is disabled, + // we must generate a checksum using the legacy struct name "MemoryManagerCheckpoint" + // instead of "MemoryManagerCheckpointV1". Older Kubelets do not have the string + // replacement logic and expect the original struct name. + object := dump.ForHash(mp) + object = strings.Replace(object, "MemoryManagerCheckpointV1", "MemoryManagerCheckpoint", 1) + hash := fnv.New32a() + _, _ = fmt.Fprintf(hash, "%v", object) + mp.Checksum = checksum.Checksum(hash.Sum32()) + + return json.Marshal(*mp) +} + +// MarshalCheckpoint returns marshalled checkpoint in v2 format +func (mp *MemoryManagerCheckpointV2) MarshalCheckpoint() ([]byte, error) { // make sure checksum wasn't set before so it doesn't affect output checksum mp.Checksum = 0 mp.Checksum = checksum.New(mp) return json.Marshal(*mp) } -// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint -func (mp *MemoryManagerCheckpoint) UnmarshalCheckpoint(blob []byte) error { +// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint in v1 format +func (mp *MemoryManagerCheckpointV1) UnmarshalCheckpoint(blob []byte) error { + return json.Unmarshal(blob, mp) +} + +// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint in v2 format +func (mp *MemoryManagerCheckpointV2) UnmarshalCheckpoint(blob []byte) error { return json.Unmarshal(blob, mp) } -// VerifyChecksum verifies that current checksum of checkpoint is valid +// VerifyChecksum verifies that current checksum of checkpoint is valid in v1 format +func (mp *MemoryManagerCheckpointV1) VerifyChecksum() error { + if mp.Checksum == 0 { + // accept empty checksum for compatibility with old file backend + return nil + } + + ck := mp.Checksum + mp.Checksum = 0 + + if !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + err := ck.Verify(mp) + if err == nil { + mp.Checksum = ck + return nil + } + // If the standard verification failed, it could be a legacy checkpoint. + // Fallback to the legacy verification method, when V2 is latest. + } + + object := dump.ForHash(mp) + object = strings.Replace(object, "MemoryManagerCheckpointV1", "MemoryManagerCheckpoint", 1) + mp.Checksum = ck + + hash := fnv.New32a() + _, _ = fmt.Fprintf(hash, "%v", object) + actualCS := checksum.Checksum(hash.Sum32()) + if mp.Checksum != actualCS { + return &errors.CorruptCheckpointError{ + ActualCS: uint64(actualCS), + ExpectedCS: uint64(mp.Checksum), + } + } + + return nil +} + +// VerifyChecksum verifies that current checksum of checkpoint is valid in v2 format func (mp *MemoryManagerCheckpoint) VerifyChecksum() error { ck := mp.Checksum mp.Checksum = 0 diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go index 322ca608e4..03c68fa336 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go @@ -100,14 +100,26 @@ func (as ContainerMemoryAssignments) Clone() ContainerMemoryAssignments { return clone } +// PodMemoryAssignments stores memory assignments of pods +type PodMemoryAssignments map[string]PodEntry + +// PodEntry represents pod-level memory assignments for a pod +type PodEntry struct { + MemoryBlocks []Block `json:"memoryBlocks,omitempty"` +} + // Reader interface used to read current memory/pod assignment state type Reader interface { // GetMachineState returns Memory Map stored in the State GetMachineState() NUMANodeMap // GetMemoryBlocks returns memory assignments of a container GetMemoryBlocks(podUID string, containerName string) []Block + // GetPodMemoryBlocks returns pod-level memory assignments of a pod + GetPodMemoryBlocks(podUID string) []Block // GetMemoryAssignments returns ContainerMemoryAssignments GetMemoryAssignments() ContainerMemoryAssignments + // GetPodMemoryAssignments returns all pod-level memory assignments + GetPodMemoryAssignments() PodMemoryAssignments } type writer interface { @@ -115,10 +127,16 @@ type writer interface { SetMachineState(memoryMap NUMANodeMap) // SetMemoryBlocks stores memory assignments of a container SetMemoryBlocks(podUID string, containerName string, blocks []Block) + // SetPodMemoryBlocks stores pod-level memory assignments of a pod + SetPodMemoryBlocks(podUID string, blocks []Block) // SetMemoryAssignments sets ContainerMemoryAssignments by using the passed parameter SetMemoryAssignments(assignments ContainerMemoryAssignments) + // SetPodMemoryAssignments sets PodMemoryAssignments by using the passed parameter + SetPodMemoryAssignments(assignments PodMemoryAssignments) // Delete deletes corresponding Blocks from ContainerMemoryAssignments Delete(podUID string, containerName string) + // DeletePod deletes all pod-level memory assignments for specified pod + DeletePod(podUID string) // ClearState clears machineState and ContainerMemoryAssignments ClearState() } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go index a23833f26c..ae55415c77 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go @@ -17,13 +17,17 @@ limitations under the License. package state import ( + "errors" "fmt" + "maps" "path/filepath" "sync" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" + cperrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" ) var _ State = &stateCheckpoint{} @@ -61,35 +65,132 @@ func NewCheckpointState(logger klog.Logger, stateDir, checkpointName, policyName return stateCheckpoint, nil } +// migrateV1CheckpointToV2Checkpoint converts checkpoints from the v1 format to the v2 format +func (sc *stateCheckpoint) migrateV1CheckpointToV2Checkpoint(src *MemoryManagerCheckpointV1, dst *MemoryManagerCheckpointV2) { + if src.PolicyName != "" { + dst.PolicyName = src.PolicyName + } + if src.MachineState != nil { + dst.MachineState = src.MachineState.Clone() + } + if len(src.Entries) > 0 { + dst.Entries = src.Entries.Clone() + } +} + // restores state from a checkpoint and creates it if it doesn't exist func (sc *stateCheckpoint) restoreState() error { sc.Lock() defer sc.Unlock() + + var checkpoint any var err error - checkpoint := NewMemoryManagerCheckpoint() - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpoint); err != nil { - if err == errors.ErrCheckpointNotFound { + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + checkpoint, err = sc.loadAndMigrateCheckpointV2() + } else { + checkpoint, err = sc.loadCheckpointV1() + } + + if err != nil { + if errors.Is(err, cperrors.ErrCheckpointNotFound) { return sc.storeState() } return err } - if sc.policyName != checkpoint.PolicyName { - return fmt.Errorf("[memorymanager] configured policy %q differs from state checkpoint policy %q", sc.policyName, checkpoint.PolicyName) + switch cp := checkpoint.(type) { + case *MemoryManagerCheckpointV2: + if sc.policyName != cp.PolicyName { + return fmt.Errorf("[memorymanager] configured policy %q differs from state checkpoint policy %q", sc.policyName, cp.PolicyName) + } + sc.cache.SetMachineState(cp.MachineState) + sc.cache.SetMemoryAssignments(cp.Entries) + sc.cache.SetPodMemoryAssignments(cp.PodEntries) + case *MemoryManagerCheckpointV1: + if sc.policyName != cp.PolicyName { + return fmt.Errorf("[memorymanager] configured policy %q differs from state checkpoint policy %q", sc.policyName, cp.PolicyName) + } + sc.cache.SetMachineState(cp.MachineState) + sc.cache.SetMemoryAssignments(cp.Entries) + default: + return fmt.Errorf("unknown checkpoint type: %T", cp) } - sc.cache.SetMachineState(checkpoint.MachineState) - sc.cache.SetMemoryAssignments(checkpoint.Entries) - sc.logger.V(2).Info("State checkpoint: restored state from checkpoint") return nil } +// loadAndMigrateCheckpointV2 loads the latest checkpoint and migrates it from older versions if needed. +func (sc *stateCheckpoint) loadAndMigrateCheckpointV2() (*MemoryManagerCheckpointV2, error) { + // Try to load as V2. + checkpointV2 := newMemoryManagerCheckpointV2() + err := sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV2) + if err == nil { + return checkpointV2, nil + } + if errors.Is(err, cperrors.ErrCheckpointNotFound) { + return nil, err + } + + // Log the V2 load error and fall back to V1. + if errors.Is(err, cperrors.CorruptCheckpointError{}) { + sc.logger.Error(err, "V2 checkpoint for memory manager is corrupt, falling back to V1") + } else { + sc.logger.Info("could not load V2 checkpoint for memory manager, falling back to V1", "err", err) + } + + // Try to load as V1. + checkpointV1, err := sc.loadCheckpointV1() + if err != nil { + // This will return ErrCheckpointNotFound if it's not found, or a corruption error. + return nil, err + } + + // Loaded V1, now migrate to V2. + sc.logger.Info("migrating memory manager checkpoint from v1 to v2") + sc.migrateV1CheckpointToV2Checkpoint(checkpointV1, checkpointV2) + + return checkpointV2, nil +} + +func (sc *stateCheckpoint) loadCheckpointV1() (*MemoryManagerCheckpointV1, error) { + checkpointV1 := newMemoryManagerCheckpointV1() + err := sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV1) + if err != nil { + return nil, err + } + return checkpointV1, nil +} + // saves state to a checkpoint, caller is responsible for locking func (sc *stateCheckpoint) storeState() error { - checkpoint := NewMemoryManagerCheckpoint() + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + return sc.storeStateV2() + } + return sc.storeStateV1() +} + +func (sc *stateCheckpoint) storeStateV2() error { + checkpoint := newMemoryManagerCheckpoint() + checkpoint.PolicyName = sc.policyName + checkpoint.MachineState = sc.cache.GetMachineState() + checkpoint.Entries = sc.cache.GetMemoryAssignments() + + podAssignments := sc.cache.GetPodMemoryAssignments() + maps.Copy(checkpoint.PodEntries, podAssignments) + + err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint) + if err != nil { + sc.logger.Error(err, "Could not save checkpoint") + return err + } + return nil +} + +func (sc *stateCheckpoint) storeStateV1() error { + checkpoint := newMemoryManagerCheckpointV1() checkpoint.PolicyName = sc.policyName checkpoint.MachineState = sc.cache.GetMachineState() checkpoint.Entries = sc.cache.GetMemoryAssignments() @@ -126,6 +227,22 @@ func (sc *stateCheckpoint) GetMemoryAssignments() ContainerMemoryAssignments { return sc.cache.GetMemoryAssignments() } +// GetPodMemoryBlocks returns memory assignments of a pod +func (sc *stateCheckpoint) GetPodMemoryBlocks(podUID string) []Block { + sc.RLock() + defer sc.RUnlock() + + return sc.cache.GetPodMemoryBlocks(podUID) +} + +// GetPodMemoryAssignments returns all pod-level memory assignments +func (sc *stateCheckpoint) GetPodMemoryAssignments() PodMemoryAssignments { + sc.RLock() + defer sc.RUnlock() + + return sc.cache.GetPodMemoryAssignments() +} + // SetMachineState stores NUMANodeMap in State func (sc *stateCheckpoint) SetMachineState(memoryMap NUMANodeMap) { sc.Lock() @@ -162,6 +279,29 @@ func (sc *stateCheckpoint) SetMemoryAssignments(assignments ContainerMemoryAssig } } +func (sc *stateCheckpoint) SetPodMemoryAssignments(assignments PodMemoryAssignments) { + sc.Lock() + defer sc.Unlock() + + sc.cache.SetPodMemoryAssignments(assignments) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint") + } +} + +// SetPodMemoryBlocks stores memory assignments of a pod +func (sc *stateCheckpoint) SetPodMemoryBlocks(podUID string, blocks []Block) { + sc.Lock() + defer sc.Unlock() + + sc.cache.SetPodMemoryBlocks(podUID, blocks) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint", "podUID", podUID) + } +} + // Delete deletes corresponding Blocks from ContainerMemoryAssignments func (sc *stateCheckpoint) Delete(podUID string, containerName string) { sc.Lock() @@ -174,6 +314,19 @@ func (sc *stateCheckpoint) Delete(podUID string, containerName string) { } } +// DeletePod deletes pod-level CPU assignments for specified pod. It does not +// affect container-level assignments. +func (sc *stateCheckpoint) DeletePod(podUID string) { + sc.Lock() + defer sc.Unlock() + + sc.cache.DeletePod(podUID) + err := sc.storeState() + if err != nil { + sc.logger.Error(err, "Failed to store state to checkpoint", "podUID", podUID) + } +} + // ClearState clears machineState and ContainerMemoryAssignments func (sc *stateCheckpoint) ClearState() { sc.Lock() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go index 59aec92560..87b848517b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go @@ -17,16 +17,20 @@ limitations under the License. package state import ( + "maps" "sync" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" ) type stateMemory struct { sync.RWMutex - logger klog.Logger - assignments ContainerMemoryAssignments - machineState NUMANodeMap + logger klog.Logger + assignments ContainerMemoryAssignments + podAssignments PodMemoryAssignments + machineState NUMANodeMap } var _ State = &stateMemory{} @@ -34,6 +38,16 @@ var _ State = &stateMemory{} // NewMemoryState creates new State for keeping track of cpu/pod assignment func NewMemoryState(logger klog.Logger) State { logger.Info("Initializing new in-memory state store") + + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + return &stateMemory{ + logger: logger, + assignments: ContainerMemoryAssignments{}, + podAssignments: PodMemoryAssignments{}, + machineState: NUMANodeMap{}, + } + } + return &stateMemory{ logger: logger, assignments: ContainerMemoryAssignments{}, @@ -68,6 +82,27 @@ func (s *stateMemory) GetMemoryAssignments() ContainerMemoryAssignments { return s.assignments.Clone() } +// GetPodMemoryBlocks returns memory assignments of a pod +func (s *stateMemory) GetPodMemoryBlocks(podUID string) []Block { + s.RLock() + defer s.RUnlock() + + if res, ok := s.podAssignments[podUID]; ok { + return append([]Block{}, res.MemoryBlocks...) + } + return nil +} + +// GetPodMemoryAssignments returns all pod-level memory assignments +func (s *stateMemory) GetPodMemoryAssignments() PodMemoryAssignments { + s.RLock() + defer s.RUnlock() + + clone := make(PodMemoryAssignments) + maps.Copy(clone, s.podAssignments) + return clone +} + // SetMachineState stores NUMANodeMap in State func (s *stateMemory) SetMachineState(nodeMap NUMANodeMap) { s.Lock() @@ -99,6 +134,27 @@ func (s *stateMemory) SetMemoryAssignments(assignments ContainerMemoryAssignment s.logger.V(5).Info("Updated Memory assignments", "assignments", assignments) } +// SetPodMemoryAssignments sets PodMemoryAssignments by using the passed parameter +func (s *stateMemory) SetPodMemoryAssignments(assignments PodMemoryAssignments) { + s.Lock() + defer s.Unlock() + + s.podAssignments = make(PodMemoryAssignments) + maps.Copy(s.podAssignments, assignments) + s.logger.V(5).Info("Updated Pod Memory assignments", "assignments", assignments) +} + +// SetPodMemoryBlocks stores memory assignments of a pod +func (s *stateMemory) SetPodMemoryBlocks(podUID string, blocks []Block) { + s.Lock() + defer s.Unlock() + + podAssigments := s.podAssignments[podUID] + podAssigments.MemoryBlocks = append([]Block{}, blocks...) + s.podAssignments[podUID] = podAssigments + s.logger.Info("Updated pod memory state", "podUID", podUID) +} + // Delete deletes corresponding Blocks from ContainerMemoryAssignments func (s *stateMemory) Delete(podUID string, containerName string) { s.Lock() @@ -115,6 +171,16 @@ func (s *stateMemory) Delete(podUID string, containerName string) { s.logger.V(2).Info("Deleted memory assignment", "podUID", podUID, "containerName", containerName) } +// DeletePod deletes pod-level CPU assignments for specified pod. It does not +// affect container-level assignments. +func (s *stateMemory) DeletePod(podUID string) { + s.Lock() + defer s.Unlock() + + delete(s.podAssignments, podUID) + s.logger.V(2).Info("Deleted pod memory assignment", "podUID", podUID) +} + // ClearState clears machineState and ContainerMemoryAssignments func (s *stateMemory) ClearState() { s.Lock() @@ -122,5 +188,8 @@ func (s *stateMemory) ClearState() { s.machineState = NUMANodeMap{} s.assignments = make(ContainerMemoryAssignments) + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + s.podAssignments = make(PodMemoryAssignments) + } s.logger.V(2).Info("Cleared state") } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go index 2981c4ebd4..39a7a880c4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. @@ -245,6 +244,8 @@ func getCgroupConfigInternal(rl v1.ResourceList, compressibleResourcesOnly bool) // Note that not all resources that are available on the node are included in the returned list of resources. // Returns a ResourceList. func (cm *containerManagerImpl) GetNodeAllocatableAbsolute() v1.ResourceList { + cm.RLock() + defer cm.RUnlock() return cm.getNodeAllocatableAbsoluteImpl(cm.capacity) } @@ -276,6 +277,8 @@ func (cm *containerManagerImpl) getNodeAllocatableInternalAbsolute() v1.Resource // GetNodeAllocatableReservation returns amount of compute or storage resource that have to be reserved on this node from scheduling. func (cm *containerManagerImpl) GetNodeAllocatableReservation() v1.ResourceList { + cm.RLock() + defer cm.RUnlock() evictionReservation := hardEvictionReservation(cm.HardEvictionThresholds, cm.capacity) result := make(v1.ResourceList) for k := range cm.capacity { @@ -299,6 +302,8 @@ func (cm *containerManagerImpl) GetNodeAllocatableReservation() v1.ResourceList // validateNodeAllocatable ensures that the user specified Node Allocatable Configuration doesn't reserve more than the node capacity. // Returns error if the configuration is invalid, nil otherwise. func (cm *containerManagerImpl) validateNodeAllocatable() error { + cm.RLock() + defer cm.RUnlock() var errors []string nar := cm.GetNodeAllocatableReservation() for k, v := range nar { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go index 14a77a741b..327e612c42 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go @@ -31,6 +31,7 @@ import ( "k8s.io/klog/v2" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" kubefeatures "k8s.io/kubernetes/pkg/features" + kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" ) const ( @@ -57,6 +58,8 @@ type podContainerManagerImpl struct { cpuCFSQuotaPeriod uint64 // podContainerManager is the ContainerManager running on the machine podContainerManager ContainerManager + // memoryReservationPolicy controls memory reservation protection behavior + memoryReservationPolicy kubeletconfig.MemoryReservationPolicy } // Make sure that podContainerManagerImpl implements the PodContainerManager interface @@ -77,7 +80,7 @@ func (m *podContainerManagerImpl) EnsureExists(logger klog.Logger, pod *v1.Pod) if !alreadyExists { enforceCPULimits := m.enforceCPULimits if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DisableCPUQuotaWithExclusiveCPUs) && m.podContainerManager.PodHasExclusiveCPUs(pod) { - klog.V(2).InfoS("Disabled CFS quota", "pod", klog.KObj(pod)) + logger.V(2).Info("Disabled CFS quota", "pod", klog.KObj(pod)) enforceCPULimits = false } enforceMemoryQoS := false @@ -89,13 +92,13 @@ func (m *podContainerManagerImpl) EnsureExists(logger klog.Logger, pod *v1.Pod) podContainerName, _ := m.GetPodContainerName(pod) containerConfig := &CgroupConfig{ Name: podContainerName, - ResourceParameters: ResourceConfigForPod(pod, enforceCPULimits, m.cpuCFSQuotaPeriod, enforceMemoryQoS), + ResourceParameters: ResourceConfigForPod(pod, enforceCPULimits, m.cpuCFSQuotaPeriod, enforceMemoryQoS, m.memoryReservationPolicy), } if m.podPidsLimit > 0 { containerConfig.ResourceParameters.PidsLimit = &m.podPidsLimit } if enforceMemoryQoS { - klog.V(4).InfoS("MemoryQoS config for pod", "pod", klog.KObj(pod), "unified", containerConfig.ResourceParameters.Unified) + logger.V(4).Info("MemoryQoS config for pod", "pod", klog.KObj(pod), "unified", containerConfig.ResourceParameters.Unified) } if err := m.cgroupManager.Create(logger, containerConfig); err != nil { return fmt.Errorf("failed to create container for %v : %v", podContainerName, err) @@ -148,14 +151,14 @@ func (m *podContainerManagerImpl) SetPodCgroupConfig(logger klog.Logger, pod *v1 } // Kill one process ID -func (m *podContainerManagerImpl) killOnePid(pid int) error { +func (m *podContainerManagerImpl) killOnePid(logger klog.Logger, pid int) error { // os.FindProcess never returns an error on POSIX // https://go-review.googlesource.com/c/go/+/19093 p, _ := os.FindProcess(pid) if err := p.Kill(); err != nil { // If the process already exited, that's fine. if errors.Is(err, os.ErrProcessDone) { - klog.V(3).InfoS("Process no longer exists", "pid", pid) + logger.V(3).Info("Process no longer exists", "pid", pid) return nil } return err @@ -178,23 +181,23 @@ func (m *podContainerManagerImpl) tryKillingCgroupProcesses(logger klog.Logger, removed := map[int]bool{} for i := 0; i < 5; i++ { if i != 0 { - klog.V(3).InfoS("Attempt failed to kill all unwanted process from cgroup, retrying", "attempt", i, "cgroupName", podCgroup) + logger.V(3).Info("Attempt failed to kill all unwanted process from cgroup, retrying", "attempt", i, "cgroupName", podCgroup) } errlist = []error{} for _, pid := range pidsToKill { if _, ok := removed[pid]; ok { continue } - klog.V(3).InfoS("Attempting to kill process from cgroup", "pid", pid, "cgroupName", podCgroup) - if err := m.killOnePid(pid); err != nil { - klog.V(3).InfoS("Failed to kill process from cgroup", "pid", pid, "cgroupName", podCgroup, "err", err) + logger.V(3).Info("Attempting to kill process from cgroup", "pid", pid, "cgroupName", podCgroup) + if err := m.killOnePid(logger, pid); err != nil { + logger.V(3).Info("Failed to kill process from cgroup", "pid", pid, "cgroupName", podCgroup, "err", err) errlist = append(errlist, err) } else { removed[pid] = true } } if len(errlist) == 0 { - klog.V(3).InfoS("Successfully killed all unwanted processes from cgroup", "cgroupName", podCgroup) + logger.V(3).Info("Successfully killed all unwanted processes from cgroup", "cgroupName", podCgroup) return nil } } @@ -254,6 +257,9 @@ func (m *podContainerManagerImpl) IsPodCgroup(cgroupfs string) (bool, types.UID) // GetAllPodsFromCgroups scans through all the subsystems of pod cgroups // Get list of pods whose cgroup still exist on the cgroup mounts func (m *podContainerManagerImpl) GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) { + // Use klog.TODO() because we currently do not have a proper logger to pass in. + // Replace this with an appropriate logger when refactoring this function to accept a logger parameter. + logger := klog.TODO() // Map for storing all the found pods on the disk foundPods := make(map[types.UID]CgroupName) qosContainersList := [3]CgroupName{m.qosContainersInfo.BestEffort, m.qosContainersInfo.Burstable, m.qosContainersInfo.Guaranteed} @@ -294,7 +300,7 @@ func (m *podContainerManagerImpl) GetAllPodsFromCgroups() (map[types.UID]CgroupN parts := strings.Split(basePath, podCgroupNamePrefix) // the uid is missing, so we log the unexpected cgroup not of form pod if len(parts) != 2 { - klog.InfoS("Pod cgroup manager ignored unexpected cgroup because it is not a pod", "path", cgroupfsPath) + logger.Info("Pod cgroup manager ignored unexpected cgroup because it is not a pod", "path", cgroupfsPath) continue } podUID := parts[1] diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/doc.go new file mode 100644 index 0000000000..e5fd17f7fc --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2025 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 cm/qos includes the internal helper the Container Manager (cm) uses to perform +// resource allocation based on Quality of Service. +// The recommended import alias is `cmqos`. + +package qos diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/helpers.go new file mode 100644 index 0000000000..30b14cc6aa --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/helpers.go @@ -0,0 +1,43 @@ +/* +Copyright 2025 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 qos + +import ( + v1 "k8s.io/api/core/v1" +) + +// IsContainerEquivalentQOSGuaranteed checks if a container is considered Guaranteed +// from the perspective of resource managers that allocate exclusive resources. +// This requires the container to have both requests and limits set and equal +// for both CPU and Memory. +func IsContainerEquivalentQOSGuaranteed(container *v1.Container) bool { + // Check container-level CPU requests and limits are equal. + cpuRequest := container.Resources.Requests[v1.ResourceCPU] + cpuLimit := container.Resources.Limits[v1.ResourceCPU] + if cpuRequest.IsZero() || !cpuRequest.Equal(cpuLimit) { + return false + } + + // Check container-level Memory requests and limits are equal. + memRequest := container.Resources.Requests[v1.ResourceMemory] + memLimit := container.Resources.Limits[v1.ResourceMemory] + if memRequest.IsZero() || !memRequest.Equal(memLimit) { + return false + } + + return true +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/diff/cmp.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/types.go similarity index 50% rename from vendor/k8s.io/apimachinery/pkg/util/diff/cmp.go rename to vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/types.go index 0a8100d063..931bbdbb39 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/diff/cmp.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos/types.go @@ -1,6 +1,3 @@ -//go:build usegocmp -// +build usegocmp - /* Copyright 2025 The Kubernetes Authors. @@ -17,15 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -package diff +package qos -import ( - "github.com/google/go-cmp/cmp" //nolint:depguard -) +// ResourceIsolationLevel defines the level of isolation for a resource. +type ResourceIsolationLevel string -// Diff returns a string representation of the difference between two objects. -// When built with the usegocmp tag, it uses go-cmp/cmp to generate a diff -// between the objects. -func Diff(a, b any) string { - return cmp.Diff(a, b) -} +const ( + // ResourceIsolationHost implies the resource is shared with other containers on the host. + ResourceIsolationHost ResourceIsolationLevel = "host" + // ResourceIsolationPod implies the resource is isolated from other pods but shared within the pod. + ResourceIsolationPod ResourceIsolationLevel = "pod" + // ResourceIsolationContainer implies the resource is exclusive to the container. + ResourceIsolationContainer ResourceIsolationLevel = "container" +) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go index d30283afbc..34e5209d18 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go @@ -37,7 +37,9 @@ import ( "k8s.io/component-helpers/resource" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" kubefeatures "k8s.io/kubernetes/pkg/features" + kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/managed" + kubeletmetrics "k8s.io/kubernetes/pkg/kubelet/metrics" ) const ( @@ -54,13 +56,14 @@ type QOSContainerManager interface { type qosContainerManagerImpl struct { sync.Mutex - qosContainersInfo QOSContainersInfo - subsystems *CgroupSubsystems - cgroupManager CgroupManager - activePods ActivePodsFunc - getNodeAllocatable func() v1.ResourceList - cgroupRoot CgroupName - qosReserved map[v1.ResourceName]int64 + qosContainersInfo QOSContainersInfo + subsystems *CgroupSubsystems + cgroupManager CgroupManager + activePods ActivePodsFunc + getNodeAllocatable func() v1.ResourceList + cgroupRoot CgroupName + qosReserved map[v1.ResourceName]int64 + memoryReservationPolicy kubeletconfig.MemoryReservationPolicy } func NewQOSContainerManager(subsystems *CgroupSubsystems, cgroupRoot CgroupName, nodeConfig NodeConfig, cgroupManager CgroupManager) (QOSContainerManager, error) { @@ -71,10 +74,11 @@ func NewQOSContainerManager(subsystems *CgroupSubsystems, cgroupRoot CgroupName, } return &qosContainerManagerImpl{ - subsystems: subsystems, - cgroupManager: cgroupManager, - cgroupRoot: cgroupRoot, - qosReserved: nodeConfig.QOSReserved, + subsystems: subsystems, + cgroupManager: cgroupManager, + cgroupRoot: cgroupRoot, + qosReserved: nodeConfig.QOSReserved, + memoryReservationPolicy: nodeConfig.MemoryReservationPolicy, }, nil } @@ -142,7 +146,7 @@ func (m *qosContainerManagerImpl) Start(ctx context.Context, getNodeAllocatable go wait.Until(func() { err := m.UpdateCgroups(logger) if err != nil { - klog.InfoS("Failed to reserve QoS requests", "err", err) + logger.Info("Failed to reserve QoS requests", "err", err) } }, periodicQOSCgroupUpdateInterval, wait.NeverStop) @@ -237,23 +241,23 @@ func (m *qosContainerManagerImpl) getQoSMemoryRequests() map[v1.PodQOSClass]int6 // setMemoryReserve sums the memory limits of all pods in a QOS class, // calculates QOS class memory limits, and set those limits in the // CgroupConfig for each QOS class. -func (m *qosContainerManagerImpl) setMemoryReserve(configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { +func (m *qosContainerManagerImpl) setMemoryReserve(logger klog.Logger, configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { qosMemoryRequests := m.getQoSMemoryRequests() resources := m.getNodeAllocatable() allocatableResource, ok := resources[v1.ResourceMemory] if !ok { - klog.V(2).InfoS("Allocatable memory value could not be determined, not setting QoS memory limits") + logger.V(2).Info("Allocatable memory value could not be determined, not setting QoS memory limits") return } allocatable := allocatableResource.Value() if allocatable == 0 { - klog.V(2).InfoS("Allocatable memory reported as 0, might be in standalone mode, not setting QoS memory limits") + logger.V(2).Info("Allocatable memory reported as 0, might be in standalone mode, not setting QoS memory limits") return } for qos, limits := range qosMemoryRequests { - klog.V(2).InfoS("QoS pod memory limit", "qos", qos, "limits", limits, "percentReserve", percentReserve) + logger.V(2).Info("QoS pod memory limit", "qos", qos, "limits", limits, "percentReserve", percentReserve) } // Calculate QOS memory limits @@ -266,14 +270,14 @@ func (m *qosContainerManagerImpl) setMemoryReserve(configs map[v1.PodQOSClass]*C // retrySetMemoryReserve checks for any QoS cgroups over the limit // that was attempted to be set in the first Update() and adjusts // their memory limit to the usage to prevent further growth. -func (m *qosContainerManagerImpl) retrySetMemoryReserve(configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { +func (m *qosContainerManagerImpl) retrySetMemoryReserve(logger klog.Logger, configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { // Unreclaimable memory usage may already exceeded the desired limit // Attempt to set the limit near the current usage to put pressure // on the cgroup and prevent further growth. for qos, config := range configs { usage, err := m.cgroupManager.MemoryUsage(config.Name) if err != nil { - klog.V(2).InfoS("Failed to get resource stats", "err", err) + logger.V(2).Info("Failed to get resource stats", "err", err) return } @@ -289,32 +293,39 @@ func (m *qosContainerManagerImpl) retrySetMemoryReserve(configs map[v1.PodQOSCla } } -// setMemoryQoS sums the memory requests of all pods in the Burstable class, -// and set the sum memory as the memory.min in the Unified field of CgroupConfig. -func (m *qosContainerManagerImpl) setMemoryQoS(configs map[v1.PodQOSClass]*CgroupConfig) { - qosMemoryRequests := m.getQoSMemoryRequests() - - // Calculate the memory.min: - // for burstable(/kubepods/burstable): sum of all burstable pods - // for guaranteed(/kubepods): sum of all guaranteed and burstable pods - burstableMin := qosMemoryRequests[v1.PodQOSBurstable] - guaranteedMin := qosMemoryRequests[v1.PodQOSGuaranteed] + burstableMin - - if burstableMin > 0 { - if configs[v1.PodQOSBurstable].ResourceParameters.Unified == nil { - configs[v1.PodQOSBurstable].ResourceParameters.Unified = make(map[string]string) +// setMemoryQoS sets cgroup v2 memory protection for QoS-class cgroups. +// Guaranteed pods get memory.min (hard protection), Burstable pods get memory.low (soft protection). +func (m *qosContainerManagerImpl) setMemoryQoS(logger klog.Logger, configs map[v1.PodQOSClass]*CgroupConfig) { + setUnified := func(qos v1.PodQOSClass, key string, value int64) { + if configs[qos].ResourceParameters.Unified == nil { + configs[qos].ResourceParameters.Unified = make(map[string]string) } - configs[v1.PodQOSBurstable].ResourceParameters.Unified[Cgroup2MemoryMin] = strconv.FormatInt(burstableMin, 10) - klog.V(4).InfoS("MemoryQoS config for qos", "qos", v1.PodQOSBurstable, "memoryMin", burstableMin) + configs[qos].ResourceParameters.Unified[key] = strconv.FormatInt(value, 10) + logger.V(4).Info("MemoryQoS config for qos", "qos", qos, "key", key, "value", value) } - if guaranteedMin > 0 { - if configs[v1.PodQOSGuaranteed].ResourceParameters.Unified == nil { - configs[v1.PodQOSGuaranteed].ResourceParameters.Unified = make(map[string]string) - } - configs[v1.PodQOSGuaranteed].ResourceParameters.Unified[Cgroup2MemoryMin] = strconv.FormatInt(guaranteedMin, 10) - klog.V(4).InfoS("MemoryQoS config for qos", "qos", v1.PodQOSGuaranteed, "memoryMin", guaranteedMin) + if m.memoryReservationPolicy != kubeletconfig.TieredReservationMemoryReservationPolicy { + setUnified(v1.PodQOSGuaranteed, Cgroup2MemoryMin, 0) + setUnified(v1.PodQOSBurstable, Cgroup2MemoryLow, 0) + kubeletmetrics.MemoryQoSNodeMemoryMinBytes.Set(0) + kubeletmetrics.MemoryQoSNodeMemoryLowBytes.Set(0) + return } + + qosMemoryRequests := m.getQoSMemoryRequests() + + burstableRequests := qosMemoryRequests[v1.PodQOSBurstable] + guaranteedRequests := qosMemoryRequests[v1.PodQOSGuaranteed] + + kubeletmetrics.MemoryQoSNodeMemoryMinBytes.Set(float64(guaranteedRequests)) + kubeletmetrics.MemoryQoSNodeMemoryLowBytes.Set(float64(burstableRequests)) + + // Guaranteed QoS class: memory.min = sum of guaranteed + burstable requests + // (parent must cover children's protection for it to be effective) + setUnified(v1.PodQOSGuaranteed, Cgroup2MemoryMin, guaranteedRequests+burstableRequests) + + // Burstable QoS class: memory.low = sum of burstable pod requests + setUnified(v1.PodQOSBurstable, Cgroup2MemoryLow, burstableRequests) } func (m *qosContainerManagerImpl) UpdateCgroups(logger logr.Logger) error { @@ -346,17 +357,17 @@ func (m *qosContainerManagerImpl) UpdateCgroups(logger logr.Logger) error { return err } - // update the qos level cgrougs v2 settings of memory qos if feature enabled - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.MemoryQoS) && - libcontainercgroups.IsCgroup2UnifiedMode() { - m.setMemoryQoS(qosConfigs) + // Update cgroup v2 memory.min settings. Called only when MemoryQoS is + // enabled and cgroups v2 is the unified mode. + if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.MemoryQoS) && libcontainercgroups.IsCgroup2UnifiedMode() { + m.setMemoryQoS(logger, qosConfigs) } if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.QOSReserved) { for resource, percentReserve := range m.qosReserved { switch resource { case v1.ResourceMemory: - m.setMemoryReserve(qosConfigs, percentReserve) + m.setMemoryReserve(logger, qosConfigs, percentReserve) } } @@ -368,7 +379,7 @@ func (m *qosContainerManagerImpl) UpdateCgroups(logger logr.Logger) error { } } if updateSuccess { - klog.V(4).InfoS("Updated QoS cgroup configuration") + logger.V(4).Info("Updated QoS cgroup configuration") return nil } @@ -378,7 +389,7 @@ func (m *qosContainerManagerImpl) UpdateCgroups(logger logr.Logger) error { for resource, percentReserve := range m.qosReserved { switch resource { case v1.ResourceMemory: - m.retrySetMemoryReserve(qosConfigs, percentReserve) + m.retrySetMemoryReserve(logger, qosConfigs, percentReserve) } } } @@ -386,12 +397,12 @@ func (m *qosContainerManagerImpl) UpdateCgroups(logger logr.Logger) error { for _, config := range qosConfigs { err := m.cgroupManager.Update(logger, config) if err != nil { - klog.ErrorS(err, "Failed to update QoS cgroup configuration") + logger.Error(err, "Failed to update QoS cgroup configuration") return err } } - klog.V(4).InfoS("Updated QoS cgroup configuration") + logger.V(4).Info("Updated QoS cgroup configuration") return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go index a79a0a3887..d6ef911e24 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go @@ -19,7 +19,7 @@ package topologymanager import ( "context" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/kubelet/cm/admission" "k8s.io/kubernetes/pkg/kubelet/lifecycle" @@ -28,6 +28,7 @@ import ( type fakeManager struct { hint *TopologyHint policy Policy + scope string } // NewFakeManager returns an instance of FakeManager @@ -38,6 +39,13 @@ func NewFakeManager() Manager { return &fakeManager{} } +// NewFakeManagerWithScope returns an instance of fake topology manager with specified scope +func NewFakeManagerWithScope(scope string) Manager { + return &fakeManager{ + scope: scope, + } +} + // NewFakeManagerWithHint returns an instance of fake topology manager with specified topology hints func NewFakeManagerWithHint(hint *TopologyHint) Manager { // Use klog.TODO() because changing NewManager requires changes in too many other components @@ -76,6 +84,10 @@ func (m *fakeManager) GetPolicy() Policy { return m.policy } +func (m *fakeManager) Name() string { + return m.scope +} + func (m *fakeManager) AddHintProvider(logger klog.Logger, h HintProvider) { logger.Info("AddHintProvider", "hintProvider", h) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go index ff34253df9..21103a6a11 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go @@ -28,12 +28,12 @@ import ( ) const ( - // containerTopologyScope specifies the TopologyManagerScope per container. - containerTopologyScope = "container" - // podTopologyScope specifies the TopologyManagerScope per pod. - podTopologyScope = "pod" + // ContainerTopologyScope specifies the TopologyManagerScope per container. + ContainerTopologyScope = "container" + // PodTopologyScope specifies the TopologyManagerScope per pod. + PodTopologyScope = "pod" // noneTopologyScope specifies the TopologyManagerScope when topologyPolicyName is none. - noneTopologyScope = "none" + NoneTopologyScope = "none" ) type podTopologyHints map[string]map[string]TopologyHint @@ -151,7 +151,7 @@ func (s *scope) admitPolicyNone(pod *v1.Pod) lifecycle.PodAdmitResult { } // It would be better to implement this function in topologymanager instead of scope -// but topologymanager do not track providers anymore +// but topologymanager does not track providers anymore func (s *scope) allocateAlignedResources(pod *v1.Pod, container *v1.Container) error { for _, provider := range s.hintProviders { err := provider.Allocate(pod, container) @@ -161,3 +161,13 @@ func (s *scope) allocateAlignedResources(pod *v1.Pod, container *v1.Container) e } return nil } + +func (s *scope) allocatePodAlignedResources(pod *v1.Pod) error { + for _, provider := range s.hintProviders { + err := provider.AllocatePod(pod) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go index d8a68ec451..7c7551f1fc 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go @@ -20,7 +20,10 @@ import ( "context" "k8s.io/api/core/v1" + utilfeature "k8s.io/apiserver/pkg/util/feature" + resourcehelper "k8s.io/component-helpers/resource" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/cm/admission" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/lifecycle" @@ -38,7 +41,7 @@ var _ Scope = &containerScope{} func NewContainerScope(policy Policy) Scope { return &containerScope{ scope{ - name: containerTopologyScope, + name: ContainerTopologyScope, podTopologyHints: podTopologyHints{}, policy: policy, podMap: containermap.NewContainerMap(), @@ -58,6 +61,9 @@ func (s *containerScope) Admit(ctx context.Context, pod *v1.Pod) lifecycle.PodAd metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedNUMANode).Inc() } metrics.TopologyManagerAdmissionErrorsTotal.Inc() + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + return admission.GetPodAdmitResult(NewPodLevelTopologyAffinityError("pod with pod-level resources failed admission with a container-level topology manager")) + } return admission.GetPodAdmitResult(&TopologyAffinityError{}) } logger.Info("Topology Affinity", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go index 44f6c32158..dc054ba3c4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go @@ -35,7 +35,7 @@ var _ Scope = &noneScope{} func NewNoneScope() Scope { return &noneScope{ scope{ - name: noneTopologyScope, + name: NoneTopologyScope, podTopologyHints: podTopologyHints{}, policy: NewNonePolicy(), podMap: containermap.NewContainerMap(), diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go index 8498ccbd89..21df862ef1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go @@ -19,8 +19,11 @@ package topologymanager import ( "context" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + utilfeature "k8s.io/apiserver/pkg/util/feature" + resourcehelper "k8s.io/component-helpers/resource" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/cm/admission" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/lifecycle" @@ -38,7 +41,7 @@ var _ Scope = &podScope{} func NewPodScope(policy Policy) Scope { return &podScope{ scope{ - name: podTopologyScope, + name: PodTopologyScope, podTopologyHints: podTopologyHints{}, policy: policy, podMap: containermap.NewContainerMap(), @@ -47,17 +50,21 @@ func NewPodScope(policy Policy) Scope { } func (s *podScope) Admit(ctx context.Context, pod *v1.Pod) lifecycle.PodAdmitResult { + // If the PodLevelResourceManagers feature is enabled, delegate the resource + // allocation to the hint providers (CPU and Memory managers) via the AllocatePod call. + // This is a one-time allocation for the entire pod. + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) && resourcehelper.IsPodLevelResourcesSet(pod) { + return s.admitUsingPodResources(ctx, pod) + } + return s.admitUsingContainerResources(ctx, pod) +} + +func (s *podScope) admitUsingContainerResources(ctx context.Context, pod *v1.Pod) lifecycle.PodAdmitResult { logger := klog.FromContext(ctx) - bestHint, admit := s.calculateAffinity(logger, pod) - logger.Info("Best TopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod)) + bestHint, admit := s.checkAffinity(logger, pod) if !admit { - if IsAlignmentGuaranteed(s.policy) { - // increment only if we know we allocate aligned resources. - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Inc() - } - metrics.TopologyManagerAdmissionErrorsTotal.Inc() - return admission.GetPodAdmitResult(&TopologyAffinityError{}) + return admission.GetPodAdmitResult(NewTopologyAffinityError()) } for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { @@ -70,12 +77,63 @@ func (s *podScope) Admit(ctx context.Context, pod *v1.Pod) lifecycle.PodAdmitRes return admission.GetPodAdmitResult(err) } } + + s.updateSuccessMetrics(logger, pod) + return admission.GetPodAdmitResult(nil) +} + +func (s *podScope) admitUsingPodResources(ctx context.Context, pod *v1.Pod) lifecycle.PodAdmitResult { + logger := klog.FromContext(ctx) + + bestHint, admit := s.checkAffinity(logger, pod) + if !admit { + return admission.GetPodAdmitResult(NewPodLevelTopologyAffinityError("pod with pod-level resources failed admission under pod-scope topology manager")) + } + + // If the PodLevelResourceManagers feature is enabled, delegate the resource + // allocation to the hint providers (CPU and Memory managers) via the AllocatePod call. + // This is a one-time allocation for the entire pod. + logger.V(4).Info("Calling AllocatePod on hint providers", "pod", klog.KObj(pod)) + + // Store the best hint for all containers. + for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { + logger.Info("Topology Affinity", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) + s.setTopologyHints(string(pod.UID), container.Name, bestHint) + } + + err := s.allocatePodAlignedResources(pod) + if err != nil { + logger.Error(err, "Pod-level allocation failed", "pod", klog.KObj(pod)) + metrics.TopologyManagerAdmissionErrorsTotal.Inc() + return admission.GetPodAdmitResult(err) + } + + s.updateSuccessMetrics(logger, pod) + return admission.GetPodAdmitResult(nil) +} + +func (s *podScope) checkAffinity(logger klog.Logger, pod *v1.Pod) (TopologyHint, bool) { + // Calculate the best NUMA affinity for the pod as a whole. + bestHint, admit := s.calculateAffinity(logger, pod) + logger.Info("Best TopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod)) + if !admit { + if IsAlignmentGuaranteed(s.policy) { + // Increment failure metric only if alignment was guaranteed. + metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Inc() + } + metrics.TopologyManagerAdmissionErrorsTotal.Inc() + + return TopologyHint{}, false + } + return bestHint, true +} + +func (s *podScope) updateSuccessMetrics(logger klog.Logger, pod *v1.Pod) { if IsAlignmentGuaranteed(s.policy) { - // increment only if we know we allocate aligned resources. + // Increment success metric only if alignment was guaranteed. logger.V(4).Info("Resource alignment at pod scope guaranteed", "pod", klog.KObj(pod)) metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Inc() } - return admission.GetPodAdmitResult(nil) } func (s *podScope) accumulateProvidersHints(logger klog.Logger, pod *v1.Pod) []map[string][]TopologyHint { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go index 458efe178d..50a4b33a1e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go @@ -46,6 +46,11 @@ const ( // TopologyAffinityError represents an resource alignment error type TopologyAffinityError struct{} +// NewTopologyAffinityError returns a new TopologyAffinityError. +func NewTopologyAffinityError() *TopologyAffinityError { + return &TopologyAffinityError{} +} + func (e TopologyAffinityError) Error() string { return "Resources cannot be allocated with Topology locality" } @@ -54,6 +59,27 @@ func (e TopologyAffinityError) Type() string { return ErrorTopologyAffinity } +// PodLevelTopologyAffinityError represents a pod-level resource alignment error. +type PodLevelTopologyAffinityError struct { + message string +} + +// NewPodLevelTopologyAffinityError returns a new PodLevelTopologyAffinityError. +func NewPodLevelTopologyAffinityError(message string) *PodLevelTopologyAffinityError { + return &PodLevelTopologyAffinityError{message: message} +} + +func (e *PodLevelTopologyAffinityError) Error() string { + if e.message != "" { + return "Pod Scope " + e.message + } + return "Pod Scope Resources cannot be allocated with Topology locality" +} + +func (e *PodLevelTopologyAffinityError) Type() string { + return ErrorTopologyAffinity +} + // Manager interface provides methods for Kubelet to manage pod topology hints type Manager interface { // PodAdmitHandler is implemented by Manager @@ -89,6 +115,8 @@ type HintProvider interface { // GetPodTopologyHints returns a map of resource names to a list of possible // concrete resource allocations per Pod in terms of NUMA locality hints. GetPodTopologyHints(pod *v1.Pod) map[string][]TopologyHint + // AllocatePod is called to trigger the allocation of resources to a pod. + AllocatePod(pod *v1.Pod) error // Allocate triggers resource allocation to occur on the HintProvider after // all hints have been gathered and the aggregated Hint is available via a // call to Store.GetAffinity(). @@ -99,6 +127,7 @@ type HintProvider interface { type Store interface { GetAffinity(podUID string, containerName string) TopologyHint GetPolicy() Policy + Name() string } // TopologyHint is a struct containing the NUMANodeAffinity for a Container @@ -179,10 +208,10 @@ func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topology var scope Scope switch topologyScopeName { - case containerTopologyScope: + case ContainerTopologyScope: scope = NewContainerScope(policy) - case podTopologyScope: + case PodTopologyScope: scope = NewPodScope(policy) default: @@ -214,6 +243,10 @@ func (m *manager) GetPolicy() Policy { return m.scope.GetPolicy() } +func (m *manager) Name() string { + return m.scope.Name() +} + func (m *manager) AddHintProvider(_ klog.Logger, h HintProvider) { m.scope.AddHintProvider(h) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go index b655f41388..ccf2009280 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go index 60c040299c..c02cc9c8ff 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go @@ -27,14 +27,13 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) // WaitForAPIServerSyncPeriod is the period between checks for the node list/watch initial sync const WaitForAPIServerSyncPeriod = 1 * time.Second // NewSourceApiserver creates a config source that watches and pulls from the apiserver. -func NewSourceApiserver(logger klog.Logger, c clientset.Interface, nodeName types.NodeName, nodeHasSynced func() bool, updates chan<- interface{}) { +func NewSourceApiserver(logger klog.Logger, c clientset.Interface, nodeName types.NodeName, nodeHasSynced func() bool, updates chan<- sourceUpdate) { lw := cache.NewListWatchFromClient(c.CoreV1().RESTClient(), "pods", metav1.NamespaceAll, fields.OneTermEqualSelector("spec.nodeName", string(nodeName))) // The Reflector responsible for watching pods at the apiserver should be run only after @@ -55,13 +54,13 @@ func NewSourceApiserver(logger klog.Logger, c clientset.Interface, nodeName type } // newSourceApiserverFromLW holds creates a config source that watches and pulls from the apiserver. -func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- interface{}) { +func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- sourceUpdate) { send := func(objs []interface{}) { var pods []*v1.Pod for _, o := range objs { pods = append(pods, o.(*v1.Pod)) } - updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.ApiserverSource} + updates <- sourceUpdate{Pods: pods} } r := cache.NewReflector(lw, &v1.Pod{}, cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc), 0) go r.Run(wait.NeverStop) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go index dc0728c8f3..299fdd5497 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go @@ -18,7 +18,6 @@ package config import ( "context" - "fmt" "reflect" "sync" "time" @@ -34,23 +33,6 @@ import ( "k8s.io/kubernetes/pkg/kubelet/util/format" ) -// PodConfigNotificationMode describes how changes are sent to the update channel. -type PodConfigNotificationMode int - -const ( - // PodConfigNotificationUnknown is the default value for - // PodConfigNotificationMode when uninitialized. - PodConfigNotificationUnknown PodConfigNotificationMode = iota - // PodConfigNotificationSnapshot delivers the full configuration as a SET whenever - // any change occurs. - PodConfigNotificationSnapshot - // PodConfigNotificationSnapshotAndUpdates delivers an UPDATE and DELETE message whenever pods are - // changed, and a SET message if there are any additions or removals. - PodConfigNotificationSnapshotAndUpdates - // PodConfigNotificationIncremental delivers ADD, UPDATE, DELETE, REMOVE, RECONCILE to the update channel. - PodConfigNotificationIncremental -) - type podStartupSLIObserver interface { ObservedPodOnWatch(pod *v1.Pod, when time.Time) } @@ -70,11 +52,15 @@ type PodConfig struct { sources sets.Set[string] } +type sourceUpdate struct { + Pods []*v1.Pod +} + // NewPodConfig creates an object that can merge many configuration sources into a stream // of normalized updates to a pod configuration. -func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder, startupSLIObserver podStartupSLIObserver) *PodConfig { +func NewPodConfig(recorder record.EventRecorderLogger, startupSLIObserver podStartupSLIObserver) *PodConfig { updates := make(chan kubetypes.PodUpdate, 50) - storage := newPodStorage(updates, mode, recorder, startupSLIObserver) + storage := newPodStorage(updates, recorder, startupSLIObserver) podConfig := &PodConfig{ pods: storage, mux: newMux(storage), @@ -86,7 +72,7 @@ func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder, // Channel creates or returns a config source channel. The channel // only accepts PodUpdates -func (c *PodConfig) Channel(ctx context.Context, source string) chan<- interface{} { +func (c *PodConfig) Channel(ctx context.Context, source string) chan<- sourceUpdate { c.sourcesLock.Lock() defer c.sourcesLock.Unlock() c.sources.Insert(source) @@ -113,11 +99,6 @@ func (c *PodConfig) Updates() <-chan kubetypes.PodUpdate { return c.updates } -// Sync requests the full configuration be delivered to the update channel. -func (c *PodConfig) Sync() { - c.pods.sync() -} - // podStorage manages the current pod state at any point in time and ensures updates // to the channel are delivered in order. Note that this object is an in-memory source of // "truth" and on creation contains zero entries. Once all previously read sources are @@ -126,7 +107,6 @@ type podStorage struct { podLock sync.RWMutex // map of source name to pod uid to pod reference pods map[string]map[types.UID]*v1.Pod - mode PodConfigNotificationMode // ensures that updates are delivered in strict order // on the updates channel @@ -138,7 +118,7 @@ type podStorage struct { sourcesSeen sets.Set[string] // the EventRecorder to use - recorder record.EventRecorder + recorder record.EventRecorderLogger startupSLIObserver podStartupSLIObserver } @@ -146,10 +126,9 @@ type podStorage struct { // TODO: PodConfigNotificationMode could be handled by a listener to the updates channel // in the future, especially with multiple listeners. // TODO: allow initialization of the current state of the store with snapshotted version. -func newPodStorage(updates chan<- kubetypes.PodUpdate, mode PodConfigNotificationMode, recorder record.EventRecorder, startupSLIObserver podStartupSLIObserver) *podStorage { +func newPodStorage(updates chan<- kubetypes.PodUpdate, recorder record.EventRecorderLogger, startupSLIObserver podStartupSLIObserver) *podStorage { return &podStorage{ pods: make(map[string]map[types.UID]*v1.Pod), - mode: mode, updates: updates, sourcesSeen: sets.Set[string]{}, recorder: recorder, @@ -157,69 +136,45 @@ func newPodStorage(updates chan<- kubetypes.PodUpdate, mode PodConfigNotificatio } } -// Merge normalizes a set of incoming changes from different sources into a map of all Pods -// and ensures that redundant changes are filtered out, and then pushes zero or more minimal +// Merge normalizes a set of incoming updates from different sources into a map of all Pods +// and ensures that redundant updates are filtered out, and then pushes zero or more minimal // updates onto the update channel. Ensures that updates are delivered in order. -func (s *podStorage) Merge(ctx context.Context, source string, change interface{}) error { +func (s *podStorage) Merge(ctx context.Context, source string, update sourceUpdate) error { s.updateLock.Lock() defer s.updateLock.Unlock() seenBefore := s.sourcesSeen.Has(source) - adds, updates, deletes, removes, reconciles := s.merge(ctx, source, change) + adds, updates, deletes, removes, reconciles := s.merge(ctx, source, update) firstSet := !seenBefore && s.sourcesSeen.Has(source) // deliver update notifications - switch s.mode { - case PodConfigNotificationIncremental: - if len(removes.Pods) > 0 { - s.updates <- *removes - } - if len(adds.Pods) > 0 { - s.updates <- *adds - } - if len(updates.Pods) > 0 { - s.updates <- *updates - } - if len(deletes.Pods) > 0 { - s.updates <- *deletes - } - if firstSet && len(adds.Pods) == 0 && len(updates.Pods) == 0 && len(deletes.Pods) == 0 { - // Send an empty update when first seeing the source and there are - // no ADD or UPDATE or DELETE pods from the source. This signals kubelet that - // the source is ready. - s.updates <- *adds - } - // Only add reconcile support here, because kubelet doesn't support Snapshot update now. - if len(reconciles.Pods) > 0 { - s.updates <- *reconciles - } - - case PodConfigNotificationSnapshotAndUpdates: - if len(removes.Pods) > 0 || len(adds.Pods) > 0 || firstSet { - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: source} - } - if len(updates.Pods) > 0 { - s.updates <- *updates - } - if len(deletes.Pods) > 0 { - s.updates <- *deletes - } - - case PodConfigNotificationSnapshot: - if len(updates.Pods) > 0 || len(deletes.Pods) > 0 || len(adds.Pods) > 0 || len(removes.Pods) > 0 || firstSet { - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: source} - } - - case PodConfigNotificationUnknown: - fallthrough - default: - panic(fmt.Sprintf("unsupported PodConfigNotificationMode: %#v", s.mode)) + if len(removes.Pods) > 0 { + s.updates <- *removes + } + if len(adds.Pods) > 0 { + s.updates <- *adds + } + if len(updates.Pods) > 0 { + s.updates <- *updates + } + if len(deletes.Pods) > 0 { + s.updates <- *deletes + } + if firstSet && len(adds.Pods) == 0 && len(updates.Pods) == 0 && len(deletes.Pods) == 0 { + // Send an empty update when first seeing the source and there are + // no ADD or UPDATE or DELETE pods from the source. This signals kubelet that + // the source is ready. + s.updates <- *adds + } + // Only add reconcile support here, because kubelet doesn't support Snapshot update now. + if len(reconciles.Pods) > 0 { + s.updates <- *reconciles } return nil } -func (s *podStorage) merge(ctx context.Context, source string, change interface{}) (adds, updates, deletes, removes, reconciles *kubetypes.PodUpdate) { +func (s *podStorage) merge(ctx context.Context, source string, update sourceUpdate) (adds, updates, deletes, removes, reconciles *kubetypes.PodUpdate) { s.podLock.Lock() defer s.podLock.Unlock() logger := klog.FromContext(ctx) @@ -268,47 +223,17 @@ func (s *podStorage) merge(ctx context.Context, source string, change interface{ } } - update := change.(kubetypes.PodUpdate) - switch update.Op { - case kubetypes.ADD, kubetypes.UPDATE, kubetypes.DELETE: - if update.Op == kubetypes.ADD { - logger.V(4).Info("Adding new pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } else if update.Op == kubetypes.DELETE { - logger.V(4).Info("Gracefully deleting pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } else { - logger.V(4).Info("Updating pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } - updatePodsFunc(update.Pods, pods, pods) - - case kubetypes.REMOVE: - logger.V(4).Info("Removing pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - for _, value := range update.Pods { - if existing, found := pods[value.UID]; found { - // this is a delete - delete(pods, value.UID) - removePods = append(removePods, existing) - continue - } - // this is a no-op + logger.V(4).Info("Setting pods for source", "source", source) + s.markSourceSet(source) + // Clear the old map entries by just creating a new map + oldPods := pods + pods = make(map[types.UID]*v1.Pod) + updatePodsFunc(update.Pods, oldPods, pods) + for uid, existing := range oldPods { + if _, found := pods[uid]; !found { + // this is a delete + removePods = append(removePods, existing) } - - case kubetypes.SET: - logger.V(4).Info("Setting pods for source", "source", source) - s.markSourceSet(source) - // Clear the old map entries by just creating a new map - oldPods := pods - pods = make(map[types.UID]*v1.Pod) - updatePodsFunc(update.Pods, oldPods, pods) - for uid, existing := range oldPods { - if _, found := pods[uid]; !found { - // this is a delete - removePods = append(removePods, existing) - } - } - - default: - logger.Info("Received invalid update type", "type", update) - } s.pods[source] = pods @@ -334,7 +259,7 @@ func (s *podStorage) seenSources(sources ...string) bool { return s.sourcesSeen.HasAll(sources...) } -func filterInvalidPods(logger klog.Logger, pods []*v1.Pod, source string, recorder record.EventRecorder) (filtered []*v1.Pod) { +func filterInvalidPods(logger klog.Logger, pods []*v1.Pod, source string, recorder record.EventRecorderLogger) (filtered []*v1.Pod) { names := sets.Set[string]{} for i, pod := range pods { // Pods from each source are assumed to have passed validation individually. @@ -342,7 +267,7 @@ func filterInvalidPods(logger klog.Logger, pods []*v1.Pod, source string, record name := kubecontainer.GetPodFullName(pod) if names.Has(name) { logger.Info("Pod failed validation due to duplicate pod name, ignoring", "index", i, "pod", klog.KObj(pod), "source", source) - recorder.Eventf(pod, v1.EventTypeWarning, events.FailedValidation, "Error validating pod %s from %s due to duplicate pod name %q, ignoring", format.Pod(pod), source, pod.Name) + recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedValidation, "Error validating pod %s from %s due to duplicate pod name %q, ignoring", format.Pod(pod), source, pod.Name) continue } else { names.Insert(name) @@ -475,25 +400,6 @@ func checkAndUpdatePod(existing, ref *v1.Pod) (needUpdate, needReconcile, needGr return } -// sync sends a copy of the current state through the update channel. -func (s *podStorage) sync() { - s.updateLock.Lock() - defer s.updateLock.Unlock() - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: kubetypes.AllSource} -} - -func (s *podStorage) mergedState() interface{} { - s.podLock.RLock() - defer s.podLock.RUnlock() - pods := make([]*v1.Pod, 0) - for _, sourcePods := range s.pods { - for _, podRef := range sourcePods { - pods = append(pods, podRef.DeepCopy()) - } - } - return pods -} - func copyPods(sourcePods []*v1.Pod) []*v1.Pod { pods := []*v1.Pod{} for _, source := range sourcePods { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go index 541f41318b..dc938b6ec9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go @@ -31,7 +31,6 @@ import ( "k8s.io/client-go/tools/cache" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/kubelet/managed" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" utilio "k8s.io/utils/io" ) @@ -56,12 +55,12 @@ type sourceFile struct { period time.Duration store cache.Store fileKeyMapping map[string]string - updates chan<- interface{} + updates chan<- sourceUpdate watchEvents chan *watchEvent } // NewSourceFile watches a config file for changes. -func NewSourceFile(logger klog.Logger, path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) { +func NewSourceFile(logger klog.Logger, path string, nodeName types.NodeName, period time.Duration, updates chan<- sourceUpdate) { // "github.com/sigma/go-inotify" requires a path without trailing "/" path = strings.TrimRight(path, string(os.PathSeparator)) @@ -70,13 +69,13 @@ func NewSourceFile(logger klog.Logger, path string, nodeName types.NodeName, per config.run(logger) } -func newSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) *sourceFile { +func newSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- sourceUpdate) *sourceFile { send := func(objs []interface{}) { var pods []*v1.Pod for _, o := range objs { pods = append(pods, o.(*v1.Pod)) } - updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.FileSource} + updates <- sourceUpdate{Pods: pods} } store := cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc) return &sourceFile{ @@ -127,7 +126,7 @@ func (s *sourceFile) listConfig(logger klog.Logger) error { return err } // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.FileSource} + s.updates <- sourceUpdate{Pods: []*v1.Pod{}} return fmt.Errorf("path does not exist, ignoring") } @@ -139,7 +138,7 @@ func (s *sourceFile) listConfig(logger klog.Logger) error { } if len(pods) == 0 { // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.FileSource} + s.updates <- sourceUpdate{Pods: pods} return nil } return s.replaceStore(pods...) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go index f05010f8ec..84ff81c9cd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2016 The Kubernetes Authors. @@ -27,12 +26,11 @@ import ( "time" "github.com/fsnotify/fsnotify" + v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" - "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/util/flowcontrol" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) const ( @@ -73,7 +71,7 @@ func (s *sourceFile) doWatch(logger klog.Logger) error { return err } // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.FileSource} + s.updates <- sourceUpdate{Pods: []*v1.Pod{}} return &retryableError{"path does not exist, ignoring"} } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go index 1b2c56a666..3ea4bccd74 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go index 123f5edf01..13ed0d6b82 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go @@ -25,7 +25,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" api "k8s.io/kubernetes/pkg/apis/core" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" @@ -36,14 +35,14 @@ type sourceURL struct { url string header http.Header nodeName types.NodeName - updates chan<- interface{} + updates chan<- sourceUpdate data []byte failureLogs int client *http.Client } // NewSourceURL specifies the URL where to read the Pod configuration from, then watches it for changes. -func NewSourceURL(logger klog.Logger, url string, header http.Header, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) { +func NewSourceURL(logger klog.Logger, url string, header http.Header, nodeName types.NodeName, period time.Duration, updates chan<- sourceUpdate) { config := &sourceURL{ url: url, header: header, @@ -102,7 +101,7 @@ func (s *sourceURL) extractFromURL(logger klog.Logger) error { } if len(data) == 0 { // Emit an update with an empty PodList to allow HTTPSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} + s.updates <- sourceUpdate{Pods: []*v1.Pod{}} return fmt.Errorf("zero-length data received from %v", s.url) } // Short circuit if the data has not changed since the last time it was read. @@ -118,7 +117,7 @@ func (s *sourceURL) extractFromURL(logger klog.Logger) error { // It parsed but could not be used. return singlePodErr } - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{pod}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} + s.updates <- sourceUpdate{Pods: []*v1.Pod{pod}} return nil } @@ -133,7 +132,7 @@ func (s *sourceURL) extractFromURL(logger klog.Logger) error { for i := range podList.Items { pods = append(pods, &podList.Items[i]) } - s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.HTTPSource} + s.updates <- sourceUpdate{Pods: pods} return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go index 091148f950..6482562055 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go @@ -28,7 +28,7 @@ type merger interface { // Invoked when a change from a source is received. May also function as an incremental // merger if you wish to consume changes incrementally. Must be reentrant when more than // one source is defined. - Merge(ctx context.Context, source string, update interface{}) error + Merge(ctx context.Context, source string, update sourceUpdate) error } // mux is a class for merging configuration from multiple sources. Changes are @@ -40,13 +40,13 @@ type mux struct { // Sources and their lock. sourceLock sync.RWMutex // Maps source names to channels - sources map[string]chan interface{} + sources map[string]chan sourceUpdate } // newMux creates a new mux that can merge changes from multiple sources. func newMux(merger merger) *mux { mux := &mux{ - sources: make(map[string]chan interface{}), + sources: make(map[string]chan sourceUpdate), merger: merger, } return mux @@ -57,7 +57,7 @@ func newMux(merger merger) *mux { // source will return the same channel. This allows change and state based sources // to use the same channel. Different source names however will be treated as a // union. -func (m *mux) ChannelWithContext(ctx context.Context, source string) chan interface{} { +func (m *mux) ChannelWithContext(ctx context.Context, source string) chan sourceUpdate { if len(source) == 0 { panic("Channel given an empty name") } @@ -67,14 +67,14 @@ func (m *mux) ChannelWithContext(ctx context.Context, source string) chan interf if exists { return channel } - newChannel := make(chan interface{}) + newChannel := make(chan sourceUpdate) m.sources[source] = newChannel go wait.Until(func() { m.listen(ctx, source, newChannel) }, 0, ctx.Done()) return newChannel } -func (m *mux) listen(ctx context.Context, source string, listenChannel <-chan interface{}) { +func (m *mux) listen(ctx context.Context, source string, listenChannel <-chan sourceUpdate) { logger := klog.FromContext(ctx) for update := range listenChannel { if err := m.merger.Merge(ctx, source, update); err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go index 9b4138634d..5067c9ddc9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go @@ -32,21 +32,30 @@ import ( // has no states known by the runtime, Cache returns an empty PodStatus object // with ID populated. // -// Cache provides two methods to retrieve the PodStatus: the non-blocking Get() -// and the blocking GetNewerThan() method. The component responsible for -// populating the cache is expected to call Delete() to explicitly free the -// cache entries. +// The component responsible for populating the cache is expected to call +// Delete() to explicitly free the cache entries. type Cache interface { - Get(types.UID) (*PodStatus, error) + ROCache // Set updates the cache by setting the PodStatus for the pod only // if the data is newer than the cache based on the provided // time stamp. Returns if the cache was updated. Set(types.UID, *PodStatus, error, time.Time) (updated bool) + // SetObservedTime modifies the observed timestamp of a pod in the cache. + // This indicates that the pod's state was recently confirmed to be accurate + // by the runtime, even if its status wasn't modified. + SetObservedTime(types.UID, time.Time) + Delete(types.UID) + UpdateTime(time.Time) +} + +// ROCache is a read-only interface to the pod status cache. It provides two +// methods to retrieve the PodStatus: the non-blocking Get() and the blocking +// GetNewerThan() method. +type ROCache interface { + Get(types.UID) (*PodStatus, error) // GetNewerThan is a blocking call that only returns the status // when it is newer than the given time. GetNewerThan(types.UID, time.Time) (*PodStatus, error) - Delete(types.UID) - UpdateTime(time.Time) } type data struct { @@ -56,6 +65,10 @@ type data struct { err error // Time when the data was last modified. modified time.Time + // Time when the data was last individually observed/verified by the runtime. + // The actual observed time should be the more recent of observedTime and the global cache timestamp. + // This is updated when the pod is relisted but its status hasn't changed. + observedTime time.Time } type subRecord struct { @@ -111,11 +124,23 @@ func (c *cache) Set(id types.UID, status *PodStatus, err error, timestamp time.T } } - c.pods[id] = &data{status: status, err: err, modified: timestamp} + c.pods[id] = &data{status: status, err: err, modified: timestamp, observedTime: timestamp} c.notify(id, timestamp) return true } +// SetObservedTime modifies the observed timestamp of a pod in the cache and +// notify subscribers if needed. +func (c *cache) SetObservedTime(id types.UID, timestamp time.Time) { + c.lock.Lock() + defer c.lock.Unlock() + if d, ok := c.pods[id]; ok { + d.observedTime = timestamp + } + // Notify all the subscribers if the condition is met. + c.notify(id, timestamp) +} + // Delete removes the entry of the pod. func (c *cache) Delete(id types.UID) { c.lock.Lock() @@ -163,9 +188,10 @@ func (c *cache) getIfNewerThan(id types.UID, minTime time.Time) *data { // minTime, return the default status. return makeDefaultData(id) } - if ok && (d.modified.After(minTime) || globalTimestampIsNewer) { + if ok && (globalTimestampIsNewer || d.modified.After(minTime) || d.observedTime.After(minTime)) { // Status is cached, return status if either of the following is true. // * status was modified after minTime + // * status was observed after minTime // * the global timestamp of the cache is newer than minTime. return d } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go index ddafc82434..2608d4dcba 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go @@ -50,19 +50,19 @@ type HandlerRunner interface { // able to get necessary informations like the RunContainerOptions, DNS settings, Host IP. type RuntimeHelper interface { GenerateRunContainerOptions(ctx context.Context, pod *v1.Pod, container *v1.Container, podIP string, podIPs []string, imageVolumes ImageVolumes) (contOpts *RunContainerOptions, cleanupAction func(), err error) - GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error) + GetPodDNS(ctx context.Context, pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error) // GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host // of a pod. GetPodCgroupParent(pod *v1.Pod) string GetPodDir(podUID types.UID) string - GeneratePodHostNameAndDomain(pod *v1.Pod) (hostname string, hostDomain string, err error) + GeneratePodHostNameAndDomain(logger klog.Logger, pod *v1.Pod) (hostname string, hostDomain string, err error) // GetExtraSupplementalGroupsForPod returns a list of the extra // supplemental groups for the Pod. These extra supplemental groups come // from annotations on persistent volumes that the pod depends on. GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 // GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace - GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) + GetOrCreateUserNamespaceMappings(logger klog.Logger, pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) // PrepareDynamicResources prepares resources for a pod. PrepareDynamicResources(ctx context.Context, pod *v1.Pod) error @@ -70,11 +70,15 @@ type RuntimeHelper interface { // UnprepareDynamicResources unprepares resources for a a pod. UnprepareDynamicResources(ctx context.Context, pod *v1.Pod) error - // SetPodWatchCondition flags a pod to be inspected until the condition is met. - SetPodWatchCondition(types.UID, string, func(*PodStatus) bool) + // RequestPodReinspect flags a pod to be inspected on the next relist. + RequestPodReinspect(types.UID) // PodCPUAndMemoryStats reads the latest CPU & memory usage stats. PodCPUAndMemoryStats(context.Context, *v1.Pod, *PodStatus) (*statsapi.PodStats, error) + + // OnPodSandboxReady callback is invoked after pod sandbox, networking, volume are ready. + // This is used to update the PodReadyToStartContainers condition. + OnPodSandboxReady(ctx context.Context, pod *v1.Pod) error } // ShouldContainerBeRestarted checks whether a container needs to be restarted. @@ -277,14 +281,20 @@ func ExpandContainerCommandAndArgs(container *v1.Container, envs []EnvVar) (comm } // FilterEventRecorder creates an event recorder to record object's event except implicitly required container's, like infra container. -func FilterEventRecorder(recorder record.EventRecorder) record.EventRecorder { +func FilterEventRecorder(recorder record.EventRecorderLogger) record.EventRecorderLogger { return &innerEventRecorder{ recorder: recorder, } } type innerEventRecorder struct { - recorder record.EventRecorder + recorder record.EventRecorderLogger +} + +func (irecorder *innerEventRecorder) WithLogger(logger klog.Logger) record.EventRecorderLogger { + return &innerEventRecorder{ + recorder: irecorder.recorder.WithLogger(logger), + } } func (irecorder *innerEventRecorder) shouldRecordEvent(object runtime.Object) (*v1.ObjectReference, bool) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go index 46deb9da07..95f7954fe4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go @@ -19,6 +19,7 @@ package container import ( "context" + "errors" "fmt" "io" "net/url" @@ -89,6 +90,9 @@ type Runtime interface { // specifies whether the runtime returns all containers including those already // exited and dead containers (used for garbage collection). GetPods(ctx context.Context, all bool) ([]*Pod, error) + // GetPod fetches the current sandboxes & containers for a pod. + // Returns ErrPodNotFound when no sandboxes are found for the requested pod. + GetPod(ctx context.Context, podUID types.UID) (*Pod, error) // GarbageCollect removes dead containers using the specified container gc policy // If allSourcesReady is not true, it means that kubelet doesn't have the // complete list of pods from all available sources (e.g., apiserver, http, @@ -109,7 +113,7 @@ type Runtime interface { KillPod(ctx context.Context, pod *v1.Pod, runningPod Pod, gracePeriodOverride *int64) error // GetPodStatus retrieves the status of the pod, including the // information of all containers in the pod that are visible in Runtime. - GetPodStatus(ctx context.Context, uid types.UID, name, namespace string) (*PodStatus, error) + GetPodStatus(ctx context.Context, pod *Pod) (*PodStatus, error) // TODO(vmarmol): Unify pod and containerID args. // GetContainerLogs returns logs of a specific container. By // default, it returns a snapshot of the container log. Set 'follow' to true to @@ -149,6 +153,11 @@ type Runtime interface { UpdateActuatedPodLevelResources(actuatedPod *v1.Pod) error } +var ( + // ErrPodNotFound is returned by GetPod when no sandboxes are found for the requested pod. + ErrPodNotFound = errors.New("pod sandboxes not found") +) + // StreamingRuntime is the interface implemented by runtimes that handle the serving of the // streaming calls (exec/attach/port-forward) themselves. In this case, Kubelet should redirect to // the runtime server. @@ -209,8 +218,11 @@ type Pod struct { // List of sandboxes associated with this pod. The sandboxes are converted // to Container temporarily to avoid substantial changes to other // components. This is only populated by kuberuntime. + // Sandboxes are sorted by creation time, newest -> oldest. // TODO: use the runtimeApi.PodSandbox type directly. Sandboxes []*Container + // Timestamp is the time that this Pod object was read from the runtime. + Timestamp time.Time } // PodPair contains both runtime#Pod and api#Pod @@ -318,6 +330,10 @@ type Container struct { Hash uint64 // State is the state of the container. State State + // ID of the sandbox to which this container belongs. + PodSandboxID string + // Creation time of the container in nanoseconds. + CreatedAt int64 } // PodStatus represents the status of the pod and its containers. @@ -462,7 +478,7 @@ type Image struct { // EnvVar represents the environment variable. type EnvVar struct { Name string - Value string + Value string // TODO: switch to []byte } // Annotation represents an annotation. @@ -652,7 +668,8 @@ func (c *RuntimeCondition) String() string { // RuntimeFeatures contains the set of features implemented by the runtime type RuntimeFeatures struct { - SupplementalGroupsPolicy bool + SupplementalGroupsPolicy bool + UserNamespacesHostNetwork bool } // String formats the runtime condition into a human readable string. @@ -660,7 +677,7 @@ func (f *RuntimeFeatures) String() string { if f == nil { return "nil" } - return fmt.Sprintf("SupplementalGroupsPolicy: %v", f.SupplementalGroupsPolicy) + return fmt.Sprintf("SupplementalGroupsPolicy: %v UserNamespacesHostNetwork: %v", f.SupplementalGroupsPolicy, f.UserNamespacesHostNetwork) } // Pods represents the list of pods diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go index af5c67a42c..bb2488ab67 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go @@ -108,10 +108,6 @@ const ( StartContainer SyncAction = "StartContainer" // KillContainer action KillContainer SyncAction = "KillContainer" - // SetupNetwork action - SetupNetwork SyncAction = "SetupNetwork" - // TeardownNetwork action - TeardownNetwork SyncAction = "TeardownNetwork" // InitContainer action InitContainer SyncAction = "InitContainer" // CreatePodSandbox action diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_cache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_cache.go index ad20e7efca..9c8c76f48a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_cache.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_cache.go @@ -33,7 +33,11 @@ func NewFakeCache(runtime container.Runtime) container.Cache { } func (c *fakeCache) Get(id types.UID) (*container.PodStatus, error) { - return c.runtime.GetPodStatus(context.TODO(), id, "", "") + pod, err := c.runtime.GetPod(context.TODO(), id) + if err != nil { + pod = &container.Pod{ID: id} + } + return c.runtime.GetPodStatus(context.TODO(), pod) } func (c *fakeCache) GetNewerThan(id types.UID, minTime time.Time) (*container.PodStatus, error) { @@ -49,3 +53,6 @@ func (c *fakeCache) Delete(id types.UID) { func (c *fakeCache) UpdateTime(_ time.Time) { } + +func (c *fakeCache) SetObservedTime(id types.UID, timestamp time.Time) { +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime.go index 710c7f4d2b..4825f1c3ff 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime.go @@ -237,6 +237,27 @@ func (f *FakeRuntime) GetPods(_ context.Context, all bool) ([]*kubecontainer.Pod return pods, f.Err } +func (f *FakeRuntime) GetPod(_ context.Context, podUID types.UID) (*kubecontainer.Pod, error) { + f.Lock() + defer f.Unlock() + + if f.Err != nil { + return nil, f.Err + } + + for _, fakePod := range f.PodList { + if fakePod.Pod.ID == podUID { + return fakePod.Pod, nil + } + } + for _, fakePod := range f.AllPodList { + if fakePod.Pod.ID == podUID { + return fakePod.Pod, nil + } + } + return nil, kubecontainer.ErrPodNotFound +} + func (f *FakeRuntime) SyncPod(_ context.Context, pod *v1.Pod, _ *kubecontainer.PodStatus, _ []v1.Secret, backOff *flowcontrol.Backoff, _ bool) (result kubecontainer.PodSyncResult) { f.Lock() defer f.Unlock() @@ -303,7 +324,7 @@ func (f *FakeRuntime) GeneratePodStatus(event *runtimeapi.ContainerEventResponse return &status } -func (f *FakeRuntime) GetPodStatus(_ context.Context, uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) { +func (f *FakeRuntime) GetPodStatus(_ context.Context, pod *kubecontainer.Pod) (*kubecontainer.PodStatus, error) { f.Lock() defer f.Unlock() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go index 36031528d1..aa28712096 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go @@ -24,6 +24,7 @@ import ( kubetypes "k8s.io/apimachinery/pkg/types" utilfeature "k8s.io/apiserver/pkg/util/feature" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" + "k8s.io/klog/v2" statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1" "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -54,7 +55,7 @@ func (f *FakeRuntimeHelper) GetPodCgroupParent(pod *v1.Pod) string { return "" } -func (f *FakeRuntimeHelper) GetPodDNS(pod *v1.Pod) (*runtimeapi.DNSConfig, error) { +func (f *FakeRuntimeHelper) GetPodDNS(_ context.Context, pod *v1.Pod) (*runtimeapi.DNSConfig, error) { return &runtimeapi.DNSConfig{ Servers: f.DNSServers, Searches: f.DNSSearches, @@ -62,7 +63,7 @@ func (f *FakeRuntimeHelper) GetPodDNS(pod *v1.Pod) (*runtimeapi.DNSConfig, error } // This is not used by docker runtime. -func (f *FakeRuntimeHelper) GeneratePodHostNameAndDomain(pod *v1.Pod) (string, string, error) { +func (f *FakeRuntimeHelper) GeneratePodHostNameAndDomain(logger klog.Logger, _ *v1.Pod) (string, string, error) { return f.HostName, f.HostDomain, f.Err } @@ -74,7 +75,7 @@ func (f *FakeRuntimeHelper) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int6 return nil } -func (f *FakeRuntimeHelper) GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { +func (f *FakeRuntimeHelper) GetOrCreateUserNamespaceMappings(logger klog.Logger, pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { featureEnabled := utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesSupport) if pod == nil || pod.Spec.HostUsers == nil { return nil, nil @@ -117,7 +118,11 @@ func (f *FakeRuntimeHelper) UnprepareDynamicResources(ctx context.Context, pod * return nil } -func (f *FakeRuntimeHelper) SetPodWatchCondition(_ kubetypes.UID, _ string, _ func(*kubecontainer.PodStatus) bool) { +func (f *FakeRuntimeHelper) RequestPodReinspect(_ kubetypes.UID) { + // Not implemented. +} + +func (f *FakeRuntimeHelper) RequestPodRelist(_ kubetypes.UID) { // Not implemented. } @@ -127,3 +132,8 @@ func (f *FakeRuntimeHelper) PodCPUAndMemoryStats(_ context.Context, pod *v1.Pod, } return nil, fmt.Errorf("stats for pod %q not found", pod.UID) } + +func (f *FakeRuntimeHelper) OnPodSandboxReady(_ context.Context, _ *v1.Pod) error { + // Not implemented + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/mocks.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/mocks.go index 0730274372..e2a07c3cff 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/mocks.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/mocks.go @@ -697,9 +697,77 @@ func (_c *MockRuntime_GetImageSize_Call) RunAndReturn(run func(ctx context.Conte return _c } +// GetPod provides a mock function for the type MockRuntime +func (_mock *MockRuntime) GetPod(ctx context.Context, podUID types.UID) (*container.Pod, error) { + ret := _mock.Called(ctx, podUID) + + if len(ret) == 0 { + panic("no return value specified for GetPod") + } + + var r0 *container.Pod + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, types.UID) (*container.Pod, error)); ok { + return returnFunc(ctx, podUID) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, types.UID) *container.Pod); ok { + r0 = returnFunc(ctx, podUID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*container.Pod) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, types.UID) error); ok { + r1 = returnFunc(ctx, podUID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockRuntime_GetPod_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPod' +type MockRuntime_GetPod_Call struct { + *mock.Call +} + +// GetPod is a helper method to define mock.On call +// - ctx context.Context +// - podUID types.UID +func (_e *MockRuntime_Expecter) GetPod(ctx interface{}, podUID interface{}) *MockRuntime_GetPod_Call { + return &MockRuntime_GetPod_Call{Call: _e.mock.On("GetPod", ctx, podUID)} +} + +func (_c *MockRuntime_GetPod_Call) Run(run func(ctx context.Context, podUID types.UID)) *MockRuntime_GetPod_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.UID + if args[1] != nil { + arg1 = args[1].(types.UID) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockRuntime_GetPod_Call) Return(pod *container.Pod, err error) *MockRuntime_GetPod_Call { + _c.Call.Return(pod, err) + return _c +} + +func (_c *MockRuntime_GetPod_Call) RunAndReturn(run func(ctx context.Context, podUID types.UID) (*container.Pod, error)) *MockRuntime_GetPod_Call { + _c.Call.Return(run) + return _c +} + // GetPodStatus provides a mock function for the type MockRuntime -func (_mock *MockRuntime) GetPodStatus(ctx context.Context, uid types.UID, name string, namespace string) (*container.PodStatus, error) { - ret := _mock.Called(ctx, uid, name, namespace) +func (_mock *MockRuntime) GetPodStatus(ctx context.Context, pod *container.Pod) (*container.PodStatus, error) { + ret := _mock.Called(ctx, pod) if len(ret) == 0 { panic("no return value specified for GetPodStatus") @@ -707,18 +775,18 @@ func (_mock *MockRuntime) GetPodStatus(ctx context.Context, uid types.UID, name var r0 *container.PodStatus var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, types.UID, string, string) (*container.PodStatus, error)); ok { - return returnFunc(ctx, uid, name, namespace) + if returnFunc, ok := ret.Get(0).(func(context.Context, *container.Pod) (*container.PodStatus, error)); ok { + return returnFunc(ctx, pod) } - if returnFunc, ok := ret.Get(0).(func(context.Context, types.UID, string, string) *container.PodStatus); ok { - r0 = returnFunc(ctx, uid, name, namespace) + if returnFunc, ok := ret.Get(0).(func(context.Context, *container.Pod) *container.PodStatus); ok { + r0 = returnFunc(ctx, pod) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*container.PodStatus) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, types.UID, string, string) error); ok { - r1 = returnFunc(ctx, uid, name, namespace) + if returnFunc, ok := ret.Get(1).(func(context.Context, *container.Pod) error); ok { + r1 = returnFunc(ctx, pod) } else { r1 = ret.Error(1) } @@ -732,36 +800,24 @@ type MockRuntime_GetPodStatus_Call struct { // GetPodStatus is a helper method to define mock.On call // - ctx context.Context -// - uid types.UID -// - name string -// - namespace string -func (_e *MockRuntime_Expecter) GetPodStatus(ctx interface{}, uid interface{}, name interface{}, namespace interface{}) *MockRuntime_GetPodStatus_Call { - return &MockRuntime_GetPodStatus_Call{Call: _e.mock.On("GetPodStatus", ctx, uid, name, namespace)} +// - pod *container.Pod +func (_e *MockRuntime_Expecter) GetPodStatus(ctx interface{}, pod interface{}) *MockRuntime_GetPodStatus_Call { + return &MockRuntime_GetPodStatus_Call{Call: _e.mock.On("GetPodStatus", ctx, pod)} } -func (_c *MockRuntime_GetPodStatus_Call) Run(run func(ctx context.Context, uid types.UID, name string, namespace string)) *MockRuntime_GetPodStatus_Call { +func (_c *MockRuntime_GetPodStatus_Call) Run(run func(ctx context.Context, pod *container.Pod)) *MockRuntime_GetPodStatus_Call { _c.Call.Run(func(args mock.Arguments) { var arg0 context.Context if args[0] != nil { arg0 = args[0].(context.Context) } - var arg1 types.UID + var arg1 *container.Pod if args[1] != nil { - arg1 = args[1].(types.UID) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 string - if args[3] != nil { - arg3 = args[3].(string) + arg1 = args[1].(*container.Pod) } run( arg0, arg1, - arg2, - arg3, ) }) return _c @@ -772,7 +828,7 @@ func (_c *MockRuntime_GetPodStatus_Call) Return(podStatus *container.PodStatus, return _c } -func (_c *MockRuntime_GetPodStatus_Call) RunAndReturn(run func(ctx context.Context, uid types.UID, name string, namespace string) (*container.PodStatus, error)) *MockRuntime_GetPodStatus_Call { +func (_c *MockRuntime_GetPodStatus_Call) RunAndReturn(run func(ctx context.Context, pod *container.Pod) (*container.PodStatus, error)) *MockRuntime_GetPodStatus_Call { _c.Call.Return(run) return _c } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go b/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go index 209cb07639..817b478781 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go @@ -88,6 +88,7 @@ const ( // Image manager event reason list const ( + InvalidImageID = "InvalidImageID" InvalidDiskCapacity = "InvalidDiskCapacity" FreeDiskSpaceFailed = "FreeDiskSpaceFailed" ) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/events/resize.go b/vendor/k8s.io/kubernetes/pkg/kubelet/events/resize.go index 1d3ea45caf..7c1310ae6e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/events/resize.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/events/resize.go @@ -40,27 +40,27 @@ type podResourceSummary struct { } // PodResizeCompletedMsg generates the pod resize completed event message. -func PodResizeCompletedMsg(allocatedPod *v1.Pod, generation int64) string { - return podResizeMessage(allocatedPod, generation, "", "Pod resize completed") +func PodResizeCompletedMsg(logger klog.Logger, allocatedPod *v1.Pod, generation int64) string { + return podResizeMessage(logger, allocatedPod, generation, "", "Pod resize completed") } // PodResizeStartedMsg generates the pod resize in progress event message. -func PodResizeStartedMsg(allocatedPod *v1.Pod, generation int64) string { - return podResizeMessage(allocatedPod, generation, "", "Pod resize started") +func PodResizeStartedMsg(logger klog.Logger, allocatedPod *v1.Pod, generation int64) string { + return podResizeMessage(logger, allocatedPod, generation, "", "Pod resize started") } // PodResizeErrorMsg generates the pod resize in progress error event message. -func PodResizeErrorMsg(allocatedPod *v1.Pod, generation int64, errorMsg string) string { - return podResizeMessage(allocatedPod, generation, errorMsg, "Pod resize error") +func PodResizeErrorMsg(logger klog.Logger, allocatedPod *v1.Pod, generation int64, errorMsg string) string { + return podResizeMessage(logger, allocatedPod, generation, errorMsg, "Pod resize error") } // PodResizePendingMsg generates the pod resize pending event message. -func PodResizePendingMsg(pod *v1.Pod, reason, message string, generation int64) string { - return podResizeMessage(pod, generation, message, fmt.Sprintf("Pod resize %s", reason)) +func PodResizePendingMsg(logger klog.Logger, pod *v1.Pod, reason, message string, generation int64) string { + return podResizeMessage(logger, pod, generation, message, fmt.Sprintf("Pod resize %s", reason)) } -func podResizeMessage(pod *v1.Pod, generation int64, errorMsg, messagePrefix string) string { - resources, err := makeResourceSummaryFromSpec(pod, generation, errorMsg) +func podResizeMessage(logger klog.Logger, pod *v1.Pod, generation int64, errorMsg, messagePrefix string) string { + resources, err := makeResourceSummaryFromSpec(logger, pod, generation, errorMsg) if err != nil { return messagePrefix } @@ -69,7 +69,7 @@ func podResizeMessage(pod *v1.Pod, generation int64, errorMsg, messagePrefix str } // Returns the desired resources from the podspec. -func makeResourceSummaryFromSpec(pod *v1.Pod, generation int64, errorMessage string) (string, error) { +func makeResourceSummaryFromSpec(logger klog.Logger, pod *v1.Pod, generation int64, errorMessage string) (string, error) { specResources := &podResourceSummary{Generation: generation, Error: errorMessage} for container, containerType := range podutil.ContainerIter(&pod.Spec, podutil.InitContainers|podutil.Containers) { allocation := containerAllocation{ @@ -86,7 +86,7 @@ func makeResourceSummaryFromSpec(pod *v1.Pod, generation int64, errorMessage str message, err := json.Marshal(specResources) if err != nil { - klog.ErrorS(err, "Failed to serialize resource summary", "pod", format.Pod(pod)) + logger.Error(err, "Failed to serialize resource summary", "pod", format.Pod(pod)) return "", err } return string(message), nil diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_linux.go index 172531427c..01e5b08042 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_others.go index 912acf178d..082f509d5b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_others.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_windows.go index de6517f654..c00a8d6916 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/defaults_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/eviction_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/eviction_manager.go index 556c0d2a7c..4019d6aa3f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/eviction_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/eviction_manager.go @@ -617,7 +617,7 @@ func (m *managerImpl) evictPod(logger klog.Logger, pod *v1.Pod, gracePeriodOverr return false } // record that we are evicting the pod - m.recorder.AnnotatedEventf(pod, annotations, v1.EventTypeWarning, Reason, evictMsg) + m.recorder.AnnotatedEventf(pod, annotations, v1.EventTypeWarning, Reason, "%s", evictMsg) // this is a blocking call and should only return when the pod and its containers are killed. logger.V(3).Info("Evicting pod", "pod", klog.KObj(pod), "podUID", pod.UID, "message", evictMsg) err := m.killPodFunc(pod, true, &gracePeriodOverride, func(status *v1.PodStatus) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_others.go index b3e9324b51..902b07d549 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_windows.go index f37d4f82b3..978c17367d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_others.go index 140d6be17c..d4050da163 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_windows.go index 96e9b4f071..0984c693e1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/memory_threshold_notifier_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/threshold_notifier_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/threshold_notifier_unsupported.go index b06a2839e6..d692e71270 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/threshold_notifier_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/threshold_notifier_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_gc_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_gc_manager.go index 8075c1a4d0..e42d35cb97 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_gc_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_gc_manager.go @@ -27,6 +27,7 @@ import ( "time" "go.opentelemetry.io/otel/trace" + v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" @@ -383,7 +384,7 @@ func (im *realImageGCManager) GarbageCollect(ctx context.Context, beganGC time.T // Check valid capacity. if capacity == 0 { err := goerrors.New("invalid capacity 0 on image filesystem") - im.recorder.Eventf(im.nodeRef, v1.EventTypeWarning, events.InvalidDiskCapacity, err.Error()) + im.recorder.Eventf(im.nodeRef, v1.EventTypeWarning, events.InvalidDiskCapacity, "%s", err.Error()) return err } @@ -578,7 +579,7 @@ func (im *realImageGCManager) imagesInEvictionOrder(ctx context.Context, freeTim imageID := getImageIDFromTuple(image) // Ensure imageID is valid or else continue if imageID == "" { - im.recorder.Eventf(im.nodeRef, v1.EventTypeWarning, "ImageID is not valid, skipping, ImageID: %v", imageID) + im.recorder.Eventf(im.nodeRef, v1.EventTypeWarning, events.InvalidImageID, "ImageID is not valid, skipping, image: %v", image) continue } images = append(images, evictionInfo{ diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_manager.go index 1093359ecc..779dd00ae4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/image_manager.go @@ -315,11 +315,12 @@ func (m *imageManager) makeLookupPullCredentialsFunc(image string, pod *v1.Pod, } func (m *imageManager) pullImage(ctx context.Context, logPrefix string, objRef *v1.ObjectReference, podUID types.UID, image string, imgSpec kubecontainer.ImageSpec, pullCredentials []credentialprovider.TrackedAuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (imageRef, message string, err error) { + logger := klog.FromContext(ctx) var pullSucceeded bool var finalPullCredentials *credentialprovider.TrackedAuthConfig if utilfeature.DefaultFeatureGate.Enabled(features.KubeletEnsureSecretPulledImages) { - if err := m.imagePullManager.RecordPullIntent(image); err != nil { + if err := m.imagePullManager.RecordPullIntent(logger, image); err != nil { return "", fmt.Sprintf("Failed to record image pull intent for container image %q: %v", image, err), err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/metrics.go index 0a93f12bab..b7e3e766ed 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/metrics.go @@ -30,8 +30,8 @@ import ( var ( ensureImageRequestsCounter = metrics.NewCounterVec( &metrics.CounterOpts{ - Subsystem: kubeletmetrics.KubeletSubsystem + "_" + "image_manager", - Name: "ensure_image_requests_total", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "image_manager_ensure_image_requests_total", Help: "Number of ensure-image requests processed by the kubelet.", StabilityLevel: metrics.ALPHA, }, diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/fs_pullrecords.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/fs_pullrecords.go index 3e1a249430..c1da5fb304 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/fs_pullrecords.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/fs_pullrecords.go @@ -58,7 +58,7 @@ type fsPullRecordsAccessor struct { // NewFSPullRecordsAccessor returns an accessor for the ImagePullIntent/ImagePulledRecord // records with a filesystem as the backing database. -func NewFSPullRecordsAccessor(kubeletDir string) (PullRecordsAccessor, error) { +func NewFSPullRecordsAccessor(logger klog.Logger, kubeletDir string) (PullRecordsAccessor, error) { kubeletConfigEncoder, kubeletConfigDecoder, err := createKubeletConfigSchemeEncoderDecoder() if err != nil { return nil, err @@ -80,11 +80,11 @@ func NewFSPullRecordsAccessor(kubeletDir string) (PullRecordsAccessor, error) { return nil, err } - accessor.recordsVersionMigration() + accessor.recordsVersionMigration(logger) return NewMeteringRecordsAccessor(accessor, fsPullIntentsSize, fsPulledRecordsSize), nil } -func (f *fsPullRecordsAccessor) recordsVersionMigration() { +func (f *fsPullRecordsAccessor) recordsVersionMigration(logger klog.Logger) { err := processDirFiles(f.pullingDir, func(filePath string, fileContent []byte) error { intent, isCurrentVersion, err := decodeIntent(f.decoder, fileContent) @@ -92,14 +92,14 @@ func (f *fsPullRecordsAccessor) recordsVersionMigration() { return fmt.Errorf("failed to decode ImagePullIntent from file %q: %w", filePath, err) } if !isCurrentVersion { - if err := f.WriteImagePullIntent(intent.Image); err != nil { + if err := f.WriteImagePullIntent(logger, intent.Image); err != nil { return fmt.Errorf("failed to migrate ImagePullIntent for image %q to the current version: %w", intent.Image, err) } } return nil }) if err != nil { - klog.ErrorS(err, "Error migrating image pull intents") + logger.Error(err, "Error migrating image pull intents") } err = processDirFiles(f.pulledDir, func(filePath string, fileContent []byte) error { @@ -108,7 +108,7 @@ func (f *fsPullRecordsAccessor) recordsVersionMigration() { return fmt.Errorf("failed to decode ImagePulledRecord from file %q: %w", filePath, err) } if !isCurrentVersion { - if err := f.WriteImagePulledRecord(pullRecord); err != nil { + if err := f.WriteImagePulledRecord(logger, pullRecord); err != nil { return fmt.Errorf("failed to migrate ImagePulledRecord for image ref %q to the current version: %w", pullRecord.ImageRef, err) } } @@ -116,11 +116,11 @@ func (f *fsPullRecordsAccessor) recordsVersionMigration() { }) if err != nil { - klog.ErrorS(err, "Error migrating image pulled records") + logger.Error(err, "Error migrating image pulled records") } } -func (f *fsPullRecordsAccessor) WriteImagePullIntent(image string) error { +func (f *fsPullRecordsAccessor) WriteImagePullIntent(logger klog.Logger, image string) error { intent := kubeletconfiginternal.ImagePullIntent{ Image: image, } @@ -166,7 +166,7 @@ func (f *fsPullRecordsAccessor) ImagePullIntentExists(image string) (bool, error return intent.Image == image, nil } -func (f *fsPullRecordsAccessor) DeleteImagePullIntent(image string) error { +func (f *fsPullRecordsAccessor) DeleteImagePullIntent(logger klog.Logger, image string) error { err := os.Remove(filepath.Join(f.pullingDir, cacheFilename(image))) if os.IsNotExist(err) { return nil @@ -207,7 +207,7 @@ func (f *fsPullRecordsAccessor) ListImagePulledRecords() ([]*kubeletconfigintern return pullRecords, err } -func (f *fsPullRecordsAccessor) WriteImagePulledRecord(pulledRecord *kubeletconfiginternal.ImagePulledRecord) error { +func (f *fsPullRecordsAccessor) WriteImagePulledRecord(logger klog.Logger, pulledRecord *kubeletconfiginternal.ImagePulledRecord) error { recordBytes := bytes.NewBuffer([]byte{}) if err := f.encoder.Encode(pulledRecord, recordBytes); err != nil { return fmt.Errorf("failed to serialize ImagePulledRecord: %w", err) @@ -216,7 +216,7 @@ func (f *fsPullRecordsAccessor) WriteImagePulledRecord(pulledRecord *kubeletconf return writeFile(f.pulledDir, cacheFilename(pulledRecord.ImageRef), recordBytes.Bytes()) } -func (f *fsPullRecordsAccessor) DeleteImagePulledRecord(imageRef string) error { +func (f *fsPullRecordsAccessor) DeleteImagePulledRecord(logger klog.Logger, imageRef string) error { err := os.Remove(filepath.Join(f.pulledDir, cacheFilename(imageRef))) if os.IsNotExist(err) { return nil diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_manager.go index 98fe1b0338..27e97381d8 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_manager.go @@ -29,7 +29,6 @@ import ( "k8s.io/klog/v2" kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/util/parsers" ) var _ ImagePullManager = &PullManager{} @@ -77,11 +76,11 @@ func NewImagePullManager(ctx context.Context, recordsAccessor PullRecordsAccesso return m, nil } -func (f *PullManager) RecordPullIntent(image string) error { +func (f *PullManager) RecordPullIntent(logger klog.Logger, image string) error { f.intentAccessors.Lock(image) defer f.intentAccessors.Unlock(image) - if err := f.recordsAccessor.WriteImagePullIntent(image); err != nil { + if err := f.recordsAccessor.WriteImagePullIntent(logger, image); err != nil { return fmt.Errorf("failed to record image pull intent: %w", err) } @@ -153,7 +152,7 @@ func (f *PullManager) writePulledRecordIfChanged(ctx context.Context, image, ima return nil } - return f.recordsAccessor.WriteImagePulledRecord(pulledRecord) + return f.recordsAccessor.WriteImagePulledRecord(logger, pulledRecord) } func (f *PullManager) RecordImagePullFailed(ctx context.Context, image string) { @@ -169,7 +168,7 @@ func (f *PullManager) decrementImagePullIntent(ctx context.Context, image string defer f.intentAccessors.Unlock(image) if f.getIntentCounterForImage(image) <= 1 { - if err := f.recordsAccessor.DeleteImagePullIntent(image); err != nil { + if err := f.recordsAccessor.DeleteImagePullIntent(logger, image); err != nil { logger.Error(err, "failed to remove image pull intent", "image", image) return } @@ -350,7 +349,7 @@ func (f *PullManager) PruneUnknownRecords(ctx context.Context, imageList []strin continue } - if err := f.recordsAccessor.DeleteImagePulledRecord(imageRecord.ImageRef); err != nil { + if err := f.recordsAccessor.DeleteImagePulledRecord(logger, imageRecord.ImageRef); err != nil { logger.Error(err, "failed to remove an ImagePulledRecord", "imageRef", imageRecord.ImageRef) } } @@ -398,7 +397,7 @@ func (f *PullManager) initialize(ctx context.Context) { continue } - if err := f.recordsAccessor.DeleteImagePullIntent(image); err != nil { + if err := f.recordsAccessor.DeleteImagePullIntent(logger, image); err != nil { logger.V(2).Info("failed to remove image pull intent file", "imageName", image, "error", err) } } @@ -576,12 +575,6 @@ func imagePullSecretLess(a, b kubeletconfiginternal.ImagePullSecret) int { return strings.Compare(a.UID, b.UID) } -// trimImageTagDigest removes the tag and digest from an image name -func trimImageTagDigest(containerImage string) (string, error) { - imageName, _, _, err := parsers.ParseImageName(containerImage) - return imageName, err -} - // mergePullServiceAccounts merges two slices of ImagePullServiceAccount object into one while // keeping the objects unique per `Namespace, Name, UID` key. // The returned slice is sorted by Namespace, Name and UID (in this order). diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_policies.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_policies.go index 2642275a3d..be6cf14dfe 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_policies.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/image_pull_policies.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - dockerref "github.com/distribution/reference" + imageref "github.com/distribution/reference" "k8s.io/apimachinery/pkg/util/sets" kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" @@ -110,11 +110,19 @@ func (p *NeverVerifyAllowlistedImages) RequireCredentialVerificationForImage(ima } func (p *NeverVerifyAllowlistedImages) imageMatches(image string) bool { - if p.absoluteURLs.Has(image) { + noTagsName, err := trimImageTagDigest(image) + if err != nil { + // in a best-effort manner, we should still attempt to match with what + // we've got from the user + noTagsName = image + } + + if p.absoluteURLs.Has(noTagsName) { return true } + for _, prefix := range p.prefixes { - if strings.HasPrefix(image, prefix) { + if strings.HasPrefix(noTagsName, prefix) { return true } } @@ -155,12 +163,12 @@ func getAllowlistImagePattern(pattern string) (string, bool, error) { return "", false, fmt.Errorf("at least registry hostname is required") } } else { // not a wildcard - image, err := dockerref.ParseNormalizedNamed(trimmedPattern) + image, err := trimImageTagDigest(trimmedPattern) if err != nil { return "", false, fmt.Errorf("failed to parse as an image name: %w", err) } - if trimmedPattern != image.Name() { // image.Name() returns the image name without tag/digest + if trimmedPattern != image { return "", false, fmt.Errorf("neither tag nor digest is accepted in an image reference: %s", pattern) } @@ -169,3 +177,36 @@ func getAllowlistImagePattern(pattern string) (string, bool, error) { return trimmedPattern, true, nil } + +// trimImageTagDigest trims digest and tag from an image name +func trimImageTagDigest(image string) (string, error) { + imageParsed, err := imageref.Parse(image) + if err != nil { + return "", err + } + var tag, digest string + if tagged, ok := imageParsed.(imageref.Tagged); ok { + tag = tagged.Tag() + } + if digested, ok := imageParsed.(imageref.Digested); ok { + digest = digested.Digest().String() + } + + if len(digest) > 0 { + var foundDigest bool + image, foundDigest = strings.CutSuffix(image, "@"+digest) + if !foundDigest { + return "", fmt.Errorf("digest was not specified last, this does not appear to be a valid image spec: %q", image) + } + } + + if len(tag) > 0 { + var tagFound bool + image, tagFound = strings.CutSuffix(image, ":"+tag) + if !tagFound { + return "", fmt.Errorf("tag %q was not specified last (or before the digest), this does not appear to be a valid image spec: %q", tag, image) + } + } + + return image, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/interfaces.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/interfaces.go index 7d8812bc73..9ec680a1e3 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/interfaces.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/interfaces.go @@ -20,6 +20,7 @@ import ( "context" "time" + "k8s.io/klog/v2" kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" ) @@ -39,7 +40,7 @@ type ImagePullManager interface { // RecordPullIntent() must match exactly one call of RecordImagePulled()/RecordImagePullFailed(). // // `image` is the content of the pod's container `image` field. - RecordPullIntent(image string) error + RecordPullIntent(logger klog.Logger, image string) error // RecordImagePulled writes a record of an image being successfully pulled // with ImagePullCredentials. // @@ -96,9 +97,9 @@ type PullRecordsAccessor interface { // for the given image. ImagePullIntentExists(image string) (bool, error) // WriteImagePullIntent writes a an intent record for the image into the database - WriteImagePullIntent(image string) error + WriteImagePullIntent(logger klog.Logger, image string) error // DeleteImagePullIntent removes an `image` intent record from the database - DeleteImagePullIntent(image string) error + DeleteImagePullIntent(logger klog.Logger, image string) error // ListImagePulledRecords lists the database ImagePulledRecords. // Records that cannot be decoded will be ignored. @@ -113,8 +114,8 @@ type PullRecordsAccessor interface { // it returns a exists=true with err equal to the decoding error. GetImagePulledRecord(imageRef string) (record *kubeletconfiginternal.ImagePulledRecord, exists bool, err error) // WriteImagePulledRecord writes an ImagePulledRecord into the database. - WriteImagePulledRecord(record *kubeletconfiginternal.ImagePulledRecord) error + WriteImagePulledRecord(logger klog.Logger, record *kubeletconfiginternal.ImagePulledRecord) error // DeleteImagePulledRecord removes an ImagePulledRecord for `imageRef` from the // database. - DeleteImagePulledRecord(imageRef string) error + DeleteImagePulledRecord(logger klog.Logger, imageRef string) error } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/mem_pullrecords.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/mem_pullrecords.go index 3ed9f7fb12..496623036b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/mem_pullrecords.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/mem_pullrecords.go @@ -98,7 +98,7 @@ type cachedPullRecordsAccessor struct { pulledRecords *lruCache[string, kubeletconfiginternal.ImagePulledRecord] } -func NewCachedPullRecordsAccessor(delegate PullRecordsAccessor, intentsCacheSize, pulledRecordsCacheSize, stripedLocksSize int32) PullRecordsAccessor { +func NewCachedPullRecordsAccessor(logger klog.Logger, delegate PullRecordsAccessor, intentsCacheSize, pulledRecordsCacheSize, stripedLocksSize int32) PullRecordsAccessor { intentsCacheSize = min(intentsCacheSize, 1024) pulledRecordsCacheSize = min(pulledRecordsCacheSize, 2000) @@ -113,11 +113,11 @@ func NewCachedPullRecordsAccessor(delegate PullRecordsAccessor, intentsCacheSize // warm our caches and set authoritative _, err := c.ListImagePullIntents() if err != nil { - klog.InfoS("there was an error initializing the image pull intents cache, the cache will work in a non-authoritative mode until the intents are listed successfully", "error", err) + logger.Info("there was an error initializing the image pull intents cache, the cache will work in a non-authoritative mode until the intents are listed successfully", "error", err) } _, err = c.ListImagePulledRecords() if err != nil { - klog.InfoS("there was an error initializing the image pulled records cache, the cache will work in a non-authoritative mode until the pulled records are listed successfully", "error", err) + logger.Info("there was an error initializing the image pulled records cache, the cache will work in a non-authoritative mode until the pulled records are listed successfully", "error", err) } return NewMeteringRecordsAccessor(c, inMemIntentsPercent, inMemPulledRecordsPercent) } @@ -160,11 +160,11 @@ func (c *cachedPullRecordsAccessor) ImagePullIntentExists(image string) (bool, e return exists, err } -func (c *cachedPullRecordsAccessor) WriteImagePullIntent(image string) error { +func (c *cachedPullRecordsAccessor) WriteImagePullIntent(logger klog.Logger, image string) error { c.intentsLocks.Lock(image) defer c.intentsLocks.Unlock(image) - if err := c.delegate.WriteImagePullIntent(image); err != nil { + if err := c.delegate.WriteImagePullIntent(logger, image); err != nil { return err } c.intents.Set(image, &kubeletconfiginternal.ImagePullIntent{ @@ -174,11 +174,11 @@ func (c *cachedPullRecordsAccessor) WriteImagePullIntent(image string) error { return nil } -func (c *cachedPullRecordsAccessor) DeleteImagePullIntent(image string) error { +func (c *cachedPullRecordsAccessor) DeleteImagePullIntent(logger klog.Logger, image string) error { c.intentsLocks.Lock(image) defer c.intentsLocks.Unlock(image) - if err := c.delegate.DeleteImagePullIntent(image); err != nil { + if err := c.delegate.DeleteImagePullIntent(logger, image); err != nil { return err } c.intents.Delete(image) @@ -223,35 +223,35 @@ func (c *cachedPullRecordsAccessor) GetImagePulledRecord(imageRef string) (*kube return pulledRecord, exists, err } -func (c *cachedPullRecordsAccessor) WriteImagePulledRecord(record *kubeletconfiginternal.ImagePulledRecord) error { +func (c *cachedPullRecordsAccessor) WriteImagePulledRecord(logger klog.Logger, record *kubeletconfiginternal.ImagePulledRecord) error { c.pulledRecordsLocks.Lock(record.ImageRef) defer c.pulledRecordsLocks.Unlock(record.ImageRef) - if err := c.delegate.WriteImagePulledRecord(record); err != nil { + if err := c.delegate.WriteImagePulledRecord(logger, record); err != nil { return err } c.pulledRecords.Set(record.ImageRef, record) return nil } -func (c *cachedPullRecordsAccessor) DeleteImagePulledRecord(imageRef string) error { +func (c *cachedPullRecordsAccessor) DeleteImagePulledRecord(logger klog.Logger, imageRef string) error { c.pulledRecordsLocks.Lock(imageRef) defer c.pulledRecordsLocks.Unlock(imageRef) - if err := c.delegate.DeleteImagePulledRecord(imageRef); err != nil { + if err := c.delegate.DeleteImagePulledRecord(logger, imageRef); err != nil { return err } c.pulledRecords.Delete(imageRef) return nil } -func (f *cachedPullRecordsAccessor) intentsSize() (uint, error) { - intentsUsage := f.intents.Len() * 100 / f.intents.maxSize +func (c *cachedPullRecordsAccessor) intentsSize() (uint, error) { + intentsUsage := c.intents.Len() * 100 / c.intents.maxSize return uint(intentsUsage), nil } -func (f *cachedPullRecordsAccessor) pulledRecordsSize() (uint, error) { - pulledRecordsUsage := f.pulledRecords.Len() * 100 / f.pulledRecords.maxSize +func (c *cachedPullRecordsAccessor) pulledRecordsSize() (uint, error) { + pulledRecordsUsage := c.pulledRecords.Len() * 100 / c.pulledRecords.maxSize return uint(pulledRecordsUsage), nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/metrics.go index 7be9812210..adf16a44e9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/metrics.go @@ -24,8 +24,6 @@ import ( kubeletmetrics "k8s.io/kubernetes/pkg/kubelet/metrics" ) -const imageManagerSubsystem = kubeletmetrics.KubeletSubsystem + "_imagemanager" - type mustAttemptImagePullResult string const ( @@ -38,40 +36,40 @@ const ( var ( fsPullIntentsSize = metrics.NewGauge( &metrics.GaugeOpts{ - Subsystem: imageManagerSubsystem, - Name: "ondisk_pullintents", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "imagemanager_ondisk_pullintents", Help: "Number of ImagePullIntents stored on disk.", StabilityLevel: metrics.ALPHA, }, ) fsPulledRecordsSize = metrics.NewGauge( &metrics.GaugeOpts{ - Subsystem: imageManagerSubsystem, - Name: "ondisk_pulledrecords", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "imagemanager_ondisk_pulledrecords", Help: "Number of ImagePulledRecords stored on disk.", StabilityLevel: metrics.ALPHA, }, ) inMemIntentsPercent = metrics.NewGauge( &metrics.GaugeOpts{ - Subsystem: imageManagerSubsystem, - Name: "inmemory_pullintents_usage_percent", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "imagemanager_inmemory_pullintents_usage_percent", Help: "The ImagePullIntents in-memory cache usage in percent.", StabilityLevel: metrics.ALPHA, }, ) inMemPulledRecordsPercent = metrics.NewGauge( &metrics.GaugeOpts{ - Subsystem: imageManagerSubsystem, - Name: "inmemory_pulledrecords_usage_percent", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "imagemanager_inmemory_pulledrecords_usage_percent", Help: "The ImagePulledRecords in-memory cache usage in percent.", StabilityLevel: metrics.ALPHA, }, ) mustPullChecksTotal = metrics.NewCounterVec( &metrics.CounterOpts{ - Subsystem: imageManagerSubsystem, - Name: "image_mustpull_checks_total", + Subsystem: kubeletmetrics.KubeletSubsystem, + Name: "imagemanager_image_mustpull_checks_total", Help: "Counter for how many times kubelet checked whether credentials need to be re-verified to access an image", StabilityLevel: metrics.ALPHA, }, @@ -109,51 +107,51 @@ func NewMeteringRecordsAccessor(pullRecordsAccessor sizeExposedPullRecordsAccess } } -func (m *meteringRecordsAccessor) WriteImagePullIntent(image string) error { - if err := m.sizeExposedPullRecordsAccessor.WriteImagePullIntent(image); err != nil { +func (m *meteringRecordsAccessor) WriteImagePullIntent(logger klog.Logger, image string) error { + if err := m.sizeExposedPullRecordsAccessor.WriteImagePullIntent(logger, image); err != nil { return err } - m.recordIntentsSize() + m.recordIntentsSize(logger) return nil } -func (m *meteringRecordsAccessor) DeleteImagePullIntent(image string) error { - if err := m.sizeExposedPullRecordsAccessor.DeleteImagePullIntent(image); err != nil { +func (m *meteringRecordsAccessor) DeleteImagePullIntent(logger klog.Logger, image string) error { + if err := m.sizeExposedPullRecordsAccessor.DeleteImagePullIntent(logger, image); err != nil { return err } - m.recordIntentsSize() + m.recordIntentsSize(logger) return nil } -func (m *meteringRecordsAccessor) WriteImagePulledRecord(record *kubeletconfiginternal.ImagePulledRecord) error { - if err := m.sizeExposedPullRecordsAccessor.WriteImagePulledRecord(record); err != nil { +func (m *meteringRecordsAccessor) WriteImagePulledRecord(logger klog.Logger, record *kubeletconfiginternal.ImagePulledRecord) error { + if err := m.sizeExposedPullRecordsAccessor.WriteImagePulledRecord(logger, record); err != nil { return err } - m.recordPulledRecordsSize() + m.recordPulledRecordsSize(logger) return nil } -func (m *meteringRecordsAccessor) DeleteImagePulledRecord(imageRef string) error { - if err := m.sizeExposedPullRecordsAccessor.DeleteImagePulledRecord(imageRef); err != nil { +func (m *meteringRecordsAccessor) DeleteImagePulledRecord(logger klog.Logger, imageRef string) error { + if err := m.sizeExposedPullRecordsAccessor.DeleteImagePulledRecord(logger, imageRef); err != nil { return err } - m.recordPulledRecordsSize() + m.recordPulledRecordsSize(logger) return nil } -func (m *meteringRecordsAccessor) recordIntentsSize() { +func (m *meteringRecordsAccessor) recordIntentsSize(logger klog.Logger) { intentsSize, err := m.sizeExposedPullRecordsAccessor.intentsSize() if err != nil { - klog.V(4).ErrorS(err, "failed to read number of ImagePullIntents, can't update metric", "metricName", m.intentsSize.Name) + logger.V(4).Info("failed to read number of ImagePullIntents, can't update metric", "metricName", m.intentsSize.Name, "error", err) return } m.intentsSize.Set(float64(intentsSize)) } -func (m *meteringRecordsAccessor) recordPulledRecordsSize() { +func (m *meteringRecordsAccessor) recordPulledRecordsSize(logger klog.Logger) { pulledRecordsSize, err := m.sizeExposedPullRecordsAccessor.pulledRecordsSize() if err != nil { - klog.V(4).ErrorS(err, "failed to read number of ImagePulledRecords, can't update metric", "metricName", m.pulledRecordsSize.Name) + logger.V(4).Info("failed to read number of ImagePulledRecords, can't update metric", "metricName", m.pulledRecordsSize.Name, "error", err) return } m.pulledRecordsSize.Set(float64(pulledRecordsSize)) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/noop_pull_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/noop_pull_manager.go index be9505824a..db94690981 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/noop_pull_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/images/pullmanager/noop_pull_manager.go @@ -20,6 +20,7 @@ import ( "context" "time" + "k8s.io/klog/v2" kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" ) @@ -27,7 +28,7 @@ var _ ImagePullManager = &NoopImagePullManager{} type NoopImagePullManager struct{} -func (m *NoopImagePullManager) RecordPullIntent(string) error { return nil } +func (m *NoopImagePullManager) RecordPullIntent(klog.Logger, string) error { return nil } func (m *NoopImagePullManager) RecordImagePulled(context.Context, string, string, *kubeletconfiginternal.ImagePullCredentials) { } func (m *NoopImagePullManager) RecordImagePullFailed(context.Context, string) {} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 42a399da40..f912a7b54b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -43,13 +43,13 @@ import ( "k8s.io/client-go/informers" ndf "k8s.io/component-helpers/nodedeclaredfeatures" - ndffeatures "k8s.io/component-helpers/nodedeclaredfeatures/features" "k8s.io/mount-utils" apiequality "k8s.io/apimachinery/pkg/api/equality" v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" utilfs "k8s.io/kubernetes/pkg/util/filesystem" + utilpod "k8s.io/kubernetes/pkg/util/pod" netutils "k8s.io/utils/net" "k8s.io/utils/ptr" @@ -63,6 +63,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" versionutil "k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/server/dynamiccertificates" "k8s.io/apiserver/pkg/server/flagz" utilfeature "k8s.io/apiserver/pkg/util/feature" coreinformersv1 "k8s.io/client-go/informers/core/v1" @@ -71,6 +72,7 @@ import ( corelisters "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" + certutil "k8s.io/client-go/util/cert" "k8s.io/client-go/util/certificate" "k8s.io/client-go/util/flowcontrol" cloudprovider "k8s.io/cloud-provider" @@ -89,6 +91,7 @@ import ( kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1" "k8s.io/kubernetes/pkg/kubelet/apis/podresources" + "k8s.io/kubernetes/pkg/kubelet/apis/pods" "k8s.io/kubernetes/pkg/kubelet/cadvisor" kubeletcertificate "k8s.io/kubernetes/pkg/kubelet/certificate" "k8s.io/kubernetes/pkg/kubelet/clustertrustbundle" @@ -292,11 +295,11 @@ func getContainerEtcHostsPath() string { // SyncHandler is an interface implemented by Kubelet, for testability type SyncHandler interface { - HandlePodAdditions(pods []*v1.Pod) - HandlePodUpdates(pods []*v1.Pod) - HandlePodRemoves(pods []*v1.Pod) - HandlePodReconcile(pods []*v1.Pod) - HandlePodSyncs(pods []*v1.Pod) + HandlePodAdditions(ctx context.Context, pods []*v1.Pod) + HandlePodUpdates(ctx context.Context, pods []*v1.Pod) + HandlePodRemoves(ctx context.Context, pods []*v1.Pod) + HandlePodReconcile(ctx context.Context, pods []*v1.Pod) + HandlePodSyncs(ctx context.Context, pods []*v1.Pod) HandlePodCleanups(ctx context.Context) error } @@ -307,11 +310,12 @@ type Option func(*Kubelet) type Bootstrap interface { GetConfiguration() kubeletconfiginternal.KubeletConfiguration BirthCry() - StartGarbageCollection() - ListenAndServe(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsOptions *server.TLSOptions, auth server.AuthInterface, tp trace.TracerProvider) + StartGarbageCollection(ctx context.Context) + ListenAndServe(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsConfig *tls.Config, auth server.AuthInterface, tp trace.TracerProvider) ListenAndServeReadOnly(ctx context.Context, address net.IP, port uint, tp trace.TracerProvider) ListenAndServePodResources(ctx context.Context) - Run(<-chan kubetypes.PodUpdate) + ListenAndServePods(ctx context.Context) + Run(ctx context.Context, updates <-chan kubetypes.PodUpdate) } // Dependencies is a bin for things we might consider "injected dependencies" -- objects constructed @@ -335,12 +339,13 @@ type Dependencies struct { OSInterface kubecontainer.OSInterface PodConfig *config.PodConfig ProbeManager prober.Manager - Recorder record.EventRecorder + Recorder record.EventRecorderLogger Subpather subpath.Interface TracerProvider trace.TracerProvider VolumePlugins []volume.VolumePlugin DynamicPluginProber volume.DynamicPluginProber TLSOptions *server.TLSOptions + TLSConfig *tls.Config RemoteRuntimeService internalapi.RuntimeService RemoteImageService internalapi.ImageManagerService PodStartupLatencyTracker util.PodStartupLatencyTracker @@ -373,7 +378,8 @@ func newCrashLoopBackOff(kubeCfg *kubeletconfiginternal.KubeletConfiguration) (t // makePodSourceConfig creates a config.PodConfig from the given // KubeletConfiguration or returns an error. -func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *Dependencies, nodeName types.NodeName, nodeHasSynced func() bool) (*config.PodConfig, error) { +func makePodSourceConfig(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *Dependencies, nodeName types.NodeName, nodeHasSynced func() bool) (*config.PodConfig, error) { + logger := klog.FromContext(ctx) manifestURLHeader := make(http.Header) if len(kubeCfg.StaticPodURLHeader) > 0 { for k, v := range kubeCfg.StaticPodURLHeader { @@ -384,42 +390,39 @@ func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ku } // source of all configuration - cfg := config.NewPodConfig(config.PodConfigNotificationIncremental, kubeDeps.Recorder, kubeDeps.PodStartupLatencyTracker) + cfg := config.NewPodConfig(kubeDeps.Recorder, kubeDeps.PodStartupLatencyTracker) - // TODO: it needs to be replaced by a proper context in the future - ctx := context.TODO() - logger := klog.FromContext(ctx) // define file config source if kubeCfg.StaticPodPath != "" { - klog.InfoS("Adding static pod path", "path", kubeCfg.StaticPodPath) + logger.Info("Adding static pod path", "path", kubeCfg.StaticPodPath) config.NewSourceFile(logger, kubeCfg.StaticPodPath, nodeName, kubeCfg.FileCheckFrequency.Duration, cfg.Channel(ctx, kubetypes.FileSource)) } // define url config source if kubeCfg.StaticPodURL != "" { - klog.InfoS("Adding pod URL with HTTP header", "URL", kubeCfg.StaticPodURL, "header", manifestURLHeader) + logger.Info("Adding pod URL with HTTP header", "URL", kubeCfg.StaticPodURL, "header", manifestURLHeader) config.NewSourceURL(logger, kubeCfg.StaticPodURL, manifestURLHeader, nodeName, kubeCfg.HTTPCheckFrequency.Duration, cfg.Channel(ctx, kubetypes.HTTPSource)) } if kubeDeps.KubeClient != nil { - klog.InfoS("Adding apiserver pod source") + logger.Info("Adding apiserver pod source") config.NewSourceApiserver(logger, kubeDeps.KubeClient, nodeName, nodeHasSynced, cfg.Channel(ctx, kubetypes.ApiserverSource)) } return cfg, nil } // PreInitRuntimeService will init runtime service before RunKubelet. -func PreInitRuntimeService(kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *Dependencies) error { +func PreInitRuntimeService(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *Dependencies) error { remoteImageEndpoint := kubeCfg.ImageServiceEndpoint if remoteImageEndpoint == "" && kubeCfg.ContainerRuntimeEndpoint != "" { remoteImageEndpoint = kubeCfg.ContainerRuntimeEndpoint } var err error - logger := klog.Background() - if kubeDeps.RemoteRuntimeService, err = remote.NewRemoteRuntimeService(kubeCfg.ContainerRuntimeEndpoint, kubeCfg.RuntimeRequestTimeout.Duration, kubeDeps.TracerProvider, &logger); err != nil { + useStreaming := utilfeature.DefaultFeatureGate.Enabled(features.CRIListStreaming) + if kubeDeps.RemoteRuntimeService, err = remote.NewRemoteRuntimeService(ctx, kubeCfg.ContainerRuntimeEndpoint, kubeCfg.RuntimeRequestTimeout.Duration, kubeDeps.TracerProvider, useStreaming); err != nil { return err } - if kubeDeps.RemoteImageService, err = remote.NewRemoteImageService(remoteImageEndpoint, kubeCfg.RuntimeRequestTimeout.Duration, kubeDeps.TracerProvider, &logger); err != nil { + if kubeDeps.RemoteImageService, err = remote.NewRemoteImageService(ctx, remoteImageEndpoint, kubeCfg.RuntimeRequestTimeout.Duration, kubeDeps.TracerProvider, useStreaming); err != nil { return err } @@ -490,18 +493,18 @@ func NewMainKubelet(ctx context.Context, return kubeInformers.Core().V1().Nodes().Informer().HasSynced() } kubeInformers.Start(wait.NeverStop) - klog.InfoS("Attempting to sync node with API server") + logger.Info("Attempting to sync node with API server") } else { // we don't have a client to sync! nodeIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) nodeLister = corelisters.NewNodeLister(nodeIndexer) nodeHasSynced = func() bool { return true } - klog.InfoS("Kubelet is running in standalone mode, will skip API server sync") + logger.Info("Kubelet is running in standalone mode, will skip API server sync") } if kubeDeps.PodConfig == nil { var err error - kubeDeps.PodConfig, err = makePodSourceConfig(kubeCfg, kubeDeps, nodeName, nodeHasSynced) + kubeDeps.PodConfig, err = makePodSourceConfig(ctx, kubeCfg, kubeDeps, nodeName, nodeHasSynced) if err != nil { return nil, err } @@ -573,10 +576,10 @@ func NewMainKubelet(ctx context.Context, if utilfeature.DefaultFeatureGate.Enabled(features.KubeletInUserNamespace) { // oomwatcher.NewWatcher returns "open /dev/kmsg: operation not permitted" error, // when running in a user namespace with sysctl value `kernel.dmesg_restrict=1`. - klog.V(2).InfoS("Failed to create an oomWatcher (running in UserNS, ignoring)", "err", err) + logger.V(2).Info("Failed to create an oomWatcher (running in UserNS, ignoring)", "err", err) oomWatcher = nil } else { - klog.ErrorS(err, "Failed to create an oomWatcher (running in UserNS, Hint: enable KubeletInUserNamespace feature flag to ignore the error)") + logger.Error(err, "Failed to create an oomWatcher (running in UserNS, Hint: enable KubeletInUserNamespace feature flag to ignore the error)") return nil, err } } else { @@ -588,7 +591,7 @@ func NewMainKubelet(ctx context.Context, for _, ipEntry := range kubeCfg.ClusterDNS { ip := netutils.ParseIPSloppy(ipEntry) if ip == nil { - klog.InfoS("Invalid clusterDNS IP", "IP", ipEntry) + logger.Info("Invalid clusterDNS IP", "IP", ipEntry) } else { clusterDNS = append(clusterDNS, ip) } @@ -653,6 +656,7 @@ func NewMainKubelet(ctx context.Context, nodeStatusMaxImages: nodeStatusMaxImages, tracer: tracer, nodeStartupLatencyTracker: kubeDeps.NodeStartupLatencyTracker, + podStartupLatencyTracker: kubeDeps.PodStartupLatencyTracker, healthChecker: kubeDeps.HealthChecker, flagz: kubeDeps.Flagz, } @@ -694,18 +698,23 @@ func NewMainKubelet(ctx context.Context, klet.livenessManager = proberesults.NewManager() klet.readinessManager = proberesults.NewManager() klet.startupManager = proberesults.NewManager() - klet.podCache = kubecontainer.NewCache() + podCache := kubecontainer.NewCache() + klet.podCache = podCache klet.mirrorPodClient = kubepod.NewBasicMirrorClient(klet.kubeClient, string(nodeName), nodeLister) klet.podManager = kubepod.NewBasicPodManager() klet.statusManager = status.NewManager(klet.kubeClient, klet.podManager, klet, kubeDeps.PodStartupLatencyTracker) + + if utilfeature.DefaultFeatureGate.Enabled(features.PodsAPI) { + broadcaster := pods.NewBroadcaster() + klet.podsServer = pods.NewPodsServer(broadcaster, klet.podManager, klet.statusManager) + klet.statusManager.AddPodUpdateNotifier(klet.podsServer) + } klet.allocationManager = allocation.NewManager( klet.getRootDir(), - klet.containerManager.GetNodeConfig(), - klet.containerManager.GetNodeAllocatableAbsolute(), klet.statusManager, - func(pod *v1.Pod) { klet.HandlePodSyncs([]*v1.Pod{pod}) }, + klet.syncPodNow, klet.GetActivePods, klet.podManager.GetPodByUID, klet.sourcesReady, @@ -713,7 +722,6 @@ func NewMainKubelet(ctx context.Context, ) klet.resourceAnalyzer = serverstats.NewResourceAnalyzer(ctx, klet, kubeCfg.VolumeStatsAggPeriod.Duration, kubeDeps.Recorder) - klet.runtimeService = kubeDeps.RemoteRuntimeService if managed.IsEnabled() { @@ -815,10 +823,12 @@ func NewMainKubelet(ctx context.Context, kubeCfg.MemorySwap.SwapBehavior, kubeDeps.ContainerManager.GetNodeAllocatableAbsolute, *kubeCfg.MemoryThrottlingFactor, - kubeDeps.PodStartupLatencyTracker, + kubeCfg.MemoryReservationPolicy, + klet.podStartupLatencyTracker, kubeDeps.TracerProvider, tokenManager, getServiceAccount, + klet.podStartupLatencyTracker, ) if err != nil { return nil, err @@ -827,6 +837,7 @@ func NewMainKubelet(ctx context.Context, klet.streamingRuntime = runtime klet.runner = runtime klet.allocationManager.SetContainerRuntime(runtime) + resizeAdmitHandler := allocation.NewPodResizesAdmitHandler(klet.containerManager, runtime, klet.allocationManager, logger) runtimeCache, err := kubecontainer.NewRuntimeCache(klet.containerRuntime, runtimeCacheRefreshPeriod) if err != nil { @@ -871,7 +882,7 @@ func NewMainKubelet(ctx context.Context, RelistPeriod: eventedPlegRelistPeriod, RelistThreshold: eventedPlegRelistThreshold, } - klet.pleg = pleg.NewGenericPLEG(logger, klet.containerRuntime, eventChannel, genericRelistDuration, klet.podCache, clock.RealClock{}) + klet.pleg = pleg.NewGenericPLEG(logger, klet.containerRuntime, eventChannel, genericRelistDuration, podCache, clock.RealClock{}) // In case Evented PLEG has to fall back on Generic PLEG due to an error, // Evented PLEG should be able to reset the Generic PLEG relisting duration // to the default value. @@ -880,7 +891,7 @@ func NewMainKubelet(ctx context.Context, RelistThreshold: genericPlegRelistThreshold, } klet.eventedPleg, err = pleg.NewEventedPLEG(logger, klet.containerRuntime, klet.runtimeService, eventChannel, - klet.podCache, klet.pleg, eventedPlegMaxStreamRetries, eventedRelistDuration, clock.RealClock{}) + podCache, klet.pleg, eventedPlegMaxStreamRetries, eventedRelistDuration, clock.RealClock{}) if err != nil { return nil, err } @@ -889,7 +900,7 @@ func NewMainKubelet(ctx context.Context, RelistPeriod: genericPlegRelistPeriod, RelistThreshold: genericPlegRelistThreshold, } - klet.pleg = pleg.NewGenericPLEG(logger, klet.containerRuntime, eventChannel, genericRelistDuration, klet.podCache, clock.RealClock{}) + klet.pleg = pleg.NewGenericPLEG(logger, klet.containerRuntime, eventChannel, genericRelistDuration, podCache, clock.RealClock{}) } klet.runtimeState = newRuntimeState(maxWaitForContainerRuntime) @@ -898,7 +909,7 @@ func NewMainKubelet(ctx context.Context, klet.runtimeState.addHealthCheck("EventedPLEG", klet.eventedPleg.Healthy) } if _, err := klet.updatePodCIDR(ctx, kubeCfg.PodCIDR); err != nil { - klog.ErrorS(err, "Pod CIDR update failed") + logger.Error(err, "Pod CIDR update failed") } // setup containerGC @@ -917,26 +928,74 @@ func NewMainKubelet(ctx context.Context, klet.imageManager = imageManager if kubeDeps.TLSOptions != nil { + kubeDeps.TLSConfig = &tls.Config{} + + kubeDeps.TLSConfig.MinVersion = kubeDeps.TLSOptions.MinVersion + kubeDeps.TLSConfig.CipherSuites = kubeDeps.TLSOptions.CipherSuites + kubeDeps.TLSConfig.CurvePreferences = kubeDeps.TLSOptions.CurvePreferences + + getServingCertificate := func() *tls.Certificate { return nil } + + // kubelet configuration that automatically rotates serving certs if kubeCfg.ServerTLSBootstrap && utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) { - klet.serverCertificateManager, err = kubeletcertificate.NewKubeletServerCertificateManager(klet.kubeClient, kubeCfg, klet.nodeName, klet.getLastObservedNodeAddresses, certDirectory) + klet.serverCertificateManager, err = kubeletcertificate.NewKubeletServerCertificateManager(klet.kubeClient, kubeCfg, klet.nodeName, func() []v1.NodeAddress { + return klet.getLastObservedNodeAddresses(ctx) + }, certDirectory) if err != nil { return nil, fmt.Errorf("failed to initialize certificate manager: %w", err) } + getServingCertificate = klet.serverCertificateManager.Current - } else if kubeDeps.TLSOptions.CertFile != "" && kubeDeps.TLSOptions.KeyFile != "" && utilfeature.DefaultFeatureGate.Enabled(features.ReloadKubeletServerCertificateFile) { - klet.serverCertificateManager, err = kubeletcertificate.NewKubeletServerCertificateDynamicFileManager(kubeDeps.TLSOptions.CertFile, kubeDeps.TLSOptions.KeyFile) - if err != nil { - return nil, fmt.Errorf("failed to initialize file based certificate manager: %w", err) + } else if kubeDeps.TLSOptions.CertFile != "" && kubeDeps.TLSOptions.KeyFile != "" { + + if utilfeature.DefaultFeatureGate.Enabled(features.ReloadKubeletServerCertificateFile) { + // kubelet configuration that reloads serving certs from the disk when updated + klet.serverCertificateManager, err = kubeletcertificate.NewKubeletServerCertificateDynamicFileManager(kubeDeps.TLSOptions.CertFile, kubeDeps.TLSOptions.KeyFile) + if err != nil { + return nil, fmt.Errorf("failed to initialize file based certificate manager: %w", err) + } + getServingCertificate = klet.serverCertificateManager.Current + + } else { + // kubelet configuration that sets static serving certs + servingCert, err := tls.LoadX509KeyPair(kubeDeps.TLSOptions.CertFile, kubeDeps.TLSOptions.KeyFile) + if err != nil { + return nil, fmt.Errorf("failed to load certificate: %w", err) + } + getServingCertificate = func() *tls.Certificate { return &servingCert } } } - if klet.serverCertificateManager != nil { - kubeDeps.TLSOptions.Config.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) { - cert := klet.serverCertificateManager.Current() - if cert == nil { - return nil, fmt.Errorf("no serving certificate available for the kubelet") + kubeDeps.TLSConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) { + cert := getServingCertificate() + if cert == nil { + return nil, fmt.Errorf("no serving certificate available for the kubelet") + } + return cert, nil + } + + if kubeDeps.TLSOptions.ClientCAFile != "" { + // Populate PeerCertificates in requests, but don't reject connections without verified certificates + kubeDeps.TLSConfig.ClientAuth = tls.RequestClientCert + + if utilfeature.DefaultFeatureGate.Enabled(features.ReloadKubeletClientCAFile) { + // kubelet configuration that reloads Client CA Bundle from the disk when updated + klet.clientCAManager = dynamiccertificates.NewDynamicServingCertificateController(kubeDeps.TLSConfig.Clone(), kubeDeps.Auth, nil, nil, nil) + + err := klet.clientCAManager.RunOnce() + if err != nil { + return nil, fmt.Errorf("unable to load client CA file %s: %w", kubeDeps.TLSOptions.ClientCAFile, err) } - return cert, nil + + kubeDeps.TLSConfig.GetConfigForClient = klet.clientCAManager.GetConfigForClient + + } else { + // kubelet configuration that sets static Client CA Bundle + clientCAs, err := certutil.NewPool(kubeDeps.TLSOptions.ClientCAFile) + if err != nil { + return nil, fmt.Errorf("unable to load client CA file %s: %w", kubeDeps.TLSOptions.ClientCAFile, err) + } + kubeDeps.TLSConfig.ClientCAs = clientCAs } } } @@ -956,9 +1015,9 @@ func NewMainKubelet(ctx context.Context, var clusterTrustBundleManager clustertrustbundle.Manager = &clustertrustbundle.NoopManager{} if kubeDeps.KubeClient != nil && utilfeature.DefaultFeatureGate.Enabled(features.ClusterTrustBundleProjection) { clusterTrustBundleManager = clustertrustbundle.NewLazyInformerManager(ctx, kubeDeps.KubeClient, 2*int(kubeCfg.MaxPods)) - klog.InfoS("ClusterTrustBundle informer will be started eventually once a trust bundle is requested") + logger.Info("ClusterTrustBundle informer will be started eventually once a trust bundle is requested") } else { - klog.InfoS("Not starting ClusterTrustBundle informer because we are in static kubelet mode or the ClusterTrustBundleProjection featuregate is disabled") + logger.Info("Not starting ClusterTrustBundle informer because we are in static kubelet mode or the ClusterTrustBundleProjection featuregate is disabled") } if kubeDeps.KubeClient != nil && utilfeature.DefaultFeatureGate.Enabled(features.PodCertificateRequest) { @@ -985,7 +1044,7 @@ func NewMainKubelet(ctx context.Context, metrics.RegisterCollectors(collectors.PodCertificateCollectorFor(podCertificateManager)) } else { klet.podCertificateManager = &podcertificate.NoOpManager{} - klog.InfoS("Not starting PodCertificateRequest manager because we are in static kubelet mode or the PodCertificateProjection feature gate is disabled") + logger.Info("Not starting PodCertificateRequest manager because we are in static kubelet mode or the PodCertificateProjection feature gate is disabled") } // NewInitializedVolumePluginMgr initializes some storageErrors on the Kubelet runtimeState (in csi_plugin.go init) @@ -1031,28 +1090,29 @@ func NewMainKubelet(ctx context.Context, // setup eviction manager evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, - killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock, kubeCfg.LocalStorageCapacityIsolation) + killPodNow(ctx, klet.podWorkers, kubeDeps.Recorder), klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock, kubeCfg.LocalStorageCapacityIsolation) klet.evictionManager = evictionManager + handlers := []lifecycle.PodAdmitHandler{} + handlers = append(handlers, evictionAdmitHandler) if utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures) { + if status, err := klet.containerRuntime.Status(ctx); err == nil && status != nil { + klet.runtimeState.setRuntimeFeatures(status.Features) + } else if err != nil { + logger.V(4).Info("Unable to prefetch container runtime features for node declared features", "err", err) + } v, err := versionutil.Parse(version.Get().String()) if err != nil { return nil, fmt.Errorf("failed to parse version: %w", err) } - framework, err := ndf.New(ndffeatures.AllFeatures) - if err != nil { - return nil, fmt.Errorf("failed to create node feature helper: %w", err) - } + framework := ndf.DefaultFramework klet.version = v klet.nodeDeclaredFeaturesFramework = framework klet.nodeDeclaredFeatures = klet.discoverNodeDeclaredFeatures() - klet.nodeDeclaredFeaturesSet = ndf.NewFeatureSet(klet.nodeDeclaredFeatures...) + klet.nodeDeclaredFeaturesSet = framework.MustMapSorted(klet.nodeDeclaredFeatures) } - handlers := []lifecycle.PodAdmitHandler{} - handlers = append(handlers, evictionAdmitHandler) - // Safe, allowed sysctls can always be used as unsafe sysctls in the spec. // Hence, we concatenate those two lists. safeAndUnsafeSysctls := append(sysctl.SafeSysctlAllowlist(ctx), allowedUnsafeSysctls...) @@ -1072,7 +1132,7 @@ func NewMainKubelet(ctx context.Context, handlers = append(handlers, klet.containerManager.GetAllocateResourcesPodAdmitHandler()) - criticalPodAdmissionHandler := preemption.NewCriticalPodAdmissionHandler(klet.getAllocatedPods, killPodNow(klet.podWorkers, kubeDeps.Recorder), kubeDeps.Recorder) + criticalPodAdmissionHandler := preemption.NewCriticalPodAdmissionHandler(klet.getAllocatedPods, killPodNow(ctx, klet.podWorkers, kubeDeps.Recorder), kubeDeps.Recorder) handlers = append(handlers, lifecycle.NewPredicateAdmitHandler(klet.GetCachedNode, criticalPodAdmissionHandler, klet.containerManager.UpdatePluginResources)) // apply functional Option's for _, opt := range kubeDeps.Options { @@ -1111,7 +1171,7 @@ func NewMainKubelet(ctx context.Context, Recorder: kubeDeps.Recorder, NodeRef: nodeRef, GetPodsFunc: klet.GetActivePods, - KillPodFunc: killPodNow(klet.podWorkers, kubeDeps.Recorder), + KillPodFunc: killPodNow(ctx, klet.podWorkers, kubeDeps.Recorder), SyncNodeStatusFunc: klet.syncNodeStatus, ShutdownGracePeriodRequested: kubeCfg.ShutdownGracePeriod.Duration, ShutdownGracePeriodCriticalPods: kubeCfg.ShutdownGracePeriodCriticalPods.Duration, @@ -1120,7 +1180,8 @@ func NewMainKubelet(ctx context.Context, }) klet.shutdownManager = shutdownManager handlers = append(handlers, shutdownManager) - klet.allocationManager.AddPodAdmitHandlers(handlers) + + klet.allocationManager.AddPodAdmitHandlers(append([]lifecycle.PodAdmitHandler{resizeAdmitHandler}, handlers...)) var usernsIDsPerPod *int64 if kubeCfg.UserNamespaces != nil { @@ -1321,7 +1382,7 @@ type Kubelet struct { startupManager proberesults.Manager // The EventRecorder to use - recorder record.EventRecorder + recorder record.EventRecorderLogger // Policy for handling garbage collection of dead containers. containerGC kubecontainer.GC @@ -1339,6 +1400,9 @@ type Kubelet struct { // Handles certificate rotations. serverCertificateManager certificate.Manager + // handles reloading of ClientCA from the disk + clientCAManager *dynamiccertificates.DynamicServingCertificateController + // Indicates that the node initialization happens in an external cloud controller externalCloudProvider bool // Reference to this node. @@ -1415,7 +1479,7 @@ type Kubelet struct { eventedPleg pleg.PodLifecycleEventGenerator // Store kubecontainer.PodStatus for all pods. - podCache kubecontainer.Cache + podCache kubecontainer.ROCache // os is a facade for various syscalls that need to be mocked during testing. os kubecontainer.OSInterface @@ -1530,11 +1594,17 @@ type Kubelet struct { // Track node startup latencies nodeStartupLatencyTracker util.NodeStartupLatencyTracker + // Track pod startup latencies + podStartupLatencyTracker util.PodStartupLatencyTracker + // Health check kubelet healthChecker watchdog.HealthChecker // flagz is the Reader interface to get flags for flagz page. flagz flagz.Reader + + // podsServer is the server that provides the pods gRPC service. + podsServer *pods.PodsServer } // ListPodStats is delegated to StatsProvider, which implements stats.Provider interface @@ -1589,7 +1659,7 @@ func (kl *Kubelet) RlimitStats() (*statsapi.RlimitStats, error) { // 4. the pod-resources directory // 5. the checkpoint directory // 6. the pod logs root directory -func (kl *Kubelet) setupDataDirs() error { +func (kl *Kubelet) setupDataDirs(logger klog.Logger) error { if cleanedRoot := filepath.Clean(kl.rootDirectory); cleanedRoot != kl.rootDirectory { return fmt.Errorf("rootDirectory not in canonical form: expected %s, was %s", cleanedRoot, kl.rootDirectory) } @@ -1624,24 +1694,24 @@ func (kl *Kubelet) setupDataDirs() error { if selinux.GetEnabled() { err := selinux.SetFileLabel(pluginRegistrationDir, kubeletconfig.KubeletPluginsDirSELinuxLabel) if err != nil { - klog.InfoS("Unprivileged containerized plugins might not work, could not set selinux context on plugin registration dir", "path", pluginRegistrationDir, "err", err) + logger.Info("Unprivileged containerized plugins might not work, could not set selinux context on plugin registration dir", "path", pluginRegistrationDir, "err", err) } err = selinux.SetFileLabel(pluginsDir, kubeletconfig.KubeletPluginsDirSELinuxLabel) if err != nil { - klog.InfoS("Unprivileged containerized plugins might not work, could not set selinux context on plugins dir", "path", pluginsDir, "err", err) + logger.Info("Unprivileged containerized plugins might not work, could not set selinux context on plugins dir", "path", pluginsDir, "err", err) } } return nil } // StartGarbageCollection starts garbage collection threads. -func (kl *Kubelet) StartGarbageCollection() { +func (kl *Kubelet) StartGarbageCollection(ctx context.Context) { + logger := klog.FromContext(ctx) loggedContainerGCFailure := false go wait.Until(func() { - ctx := context.Background() if err := kl.containerGC.GarbageCollect(ctx); err != nil { - klog.ErrorS(err, "Container garbage collection failed") - kl.recorder.Eventf(kl.nodeRef, v1.EventTypeWarning, events.ContainerGCFailed, err.Error()) + logger.Error(err, "Container garbage collection failed") + kl.recorder.WithLogger(logger).Eventf(kl.nodeRef, v1.EventTypeWarning, events.ContainerGCFailed, "%s", err.Error()) loggedContainerGCFailure = true } else { var vLevel klog.Level = 4 @@ -1650,28 +1720,27 @@ func (kl *Kubelet) StartGarbageCollection() { loggedContainerGCFailure = false } - klog.V(vLevel).InfoS("Container garbage collection succeeded") + logger.V(int(vLevel)).Info("Container garbage collection succeeded") } }, ContainerGCPeriod, wait.NeverStop) // when the high threshold is set to 100, and the max age is 0 (or the max age feature is disabled) // stub the image GC manager if kl.kubeletConfiguration.ImageGCHighThresholdPercent == 100 && kl.kubeletConfiguration.ImageMaximumGCAge.Duration == 0 { - klog.V(2).InfoS("ImageGCHighThresholdPercent is set 100 and ImageMaximumGCAge is 0, Disable image GC") + logger.V(2).Info("ImageGCHighThresholdPercent is set 100 and ImageMaximumGCAge is 0, Disable image GC") return } prevImageGCFailed := false beganGC := time.Now() go wait.Until(func() { - ctx := context.Background() if err := kl.imageManager.GarbageCollect(ctx, beganGC); err != nil { if prevImageGCFailed { - klog.ErrorS(err, "Image garbage collection failed multiple times in a row") + logger.Error(err, "Image garbage collection failed multiple times in a row") // Only create an event for repeated failures - kl.recorder.Event(kl.nodeRef, v1.EventTypeWarning, events.ImageGCFailed, err.Error()) + kl.recorder.WithLogger(logger).Event(kl.nodeRef, v1.EventTypeWarning, events.ImageGCFailed, err.Error()) } else { - klog.ErrorS(err, "Image garbage collection failed once. Stats initialization may not have completed yet") + logger.Error(err, "Image garbage collection failed once. Stats initialization may not have completed yet") } prevImageGCFailed = true } else { @@ -1681,7 +1750,7 @@ func (kl *Kubelet) StartGarbageCollection() { prevImageGCFailed = false } - klog.V(vLevel).InfoS("Image garbage collection succeeded") + logger.V(int(vLevel)).Info("Image garbage collection succeeded") } }, ImageGCPeriod, wait.NeverStop) } @@ -1689,6 +1758,7 @@ func (kl *Kubelet) StartGarbageCollection() { // initializeModules will initialize internal modules that do not require the container runtime to be up. // Note that the modules here must not depend on modules that are not initialized here. func (kl *Kubelet) initializeModules(ctx context.Context) error { + logger := klog.FromContext(ctx) // Prometheus metrics. metrics.Register() metrics.RegisterCollectors( @@ -1699,7 +1769,7 @@ func (kl *Kubelet) initializeModules(ctx context.Context) error { servermetrics.Register() // Setup filesystem directories. - if err := kl.setupDataDirs(); err != nil { + if err := kl.setupDataDirs(logger); err != nil { return err } @@ -1726,6 +1796,11 @@ func (kl *Kubelet) initializeModules(ctx context.Context) error { kl.serverCertificateManager.Start() } + // Start the client CA manager if it was enabled. + if kl.clientCAManager != nil { + go kl.clientCAManager.Run(1, ctx.Done()) + } + // Start out of memory watcher. if kl.oomWatcher != nil { if err := kl.oomWatcher.Start(ctx, kl.nodeRef); err != nil { @@ -1741,9 +1816,10 @@ func (kl *Kubelet) initializeModules(ctx context.Context) error { // initializeRuntimeDependentModules will initialize internal modules that require the container runtime to be up. func (kl *Kubelet) initializeRuntimeDependentModules(ctx context.Context) { + logger := klog.FromContext(ctx) if err := kl.cadvisor.Start(); err != nil { // Fail kubelet and rely on the babysitter to retry starting kubelet. - klog.ErrorS(err, "Failed to start cAdvisor") + logger.Error(err, "Failed to start cAdvisor") os.Exit(1) } @@ -1751,16 +1827,16 @@ func (kl *Kubelet) initializeRuntimeDependentModules(ctx context.Context) { // ignore any errors, since if stats collection is not successful, the container manager will fail to start below. kl.StatsProvider.GetCgroupStats("/", true) // Start container manager. - node, err := kl.getNodeAnyWay() + node, err := kl.getNodeAnyWay(ctx) if err != nil { // Fail kubelet and rely on the babysitter to retry starting kubelet. - klog.ErrorS(err, "Kubelet failed to get node info") + logger.Error(err, "Kubelet failed to get node info") os.Exit(1) } // containerManager must start after cAdvisor because it needs filesystem capacity information if err := kl.containerManager.Start(ctx, node, kl.GetActivePods, kl.getNodeAnyWay, kl.sourcesReady, kl.statusManager, kl.runtimeService, kl.supportLocalStorageCapacityIsolation()); err != nil { // Fail kubelet and rely on the babysitter to retry starting kubelet. - klog.ErrorS(err, "Failed to start ContainerManager") + logger.Error(err, "Failed to start ContainerManager") os.Exit(1) } // eviction manager must start after cadvisor because it needs to know if the container runtime has a dedicated imagefs @@ -1778,19 +1854,19 @@ func (kl *Kubelet) initializeRuntimeDependentModules(ctx context.Context) { } // Start the plugin manager - klog.V(4).InfoS("Starting plugin manager") + logger.V(4).Info("Starting plugin manager") go kl.pluginManager.Run(ctx, kl.sourcesReady, wait.NeverStop) - err = kl.shutdownManager.Start() + err = kl.shutdownManager.Start(ctx) if err != nil { // The shutdown manager is not critical for kubelet, so log failure, but don't block Kubelet startup if there was a failure starting it. - klog.ErrorS(err, "Failed to start node shutdown manager") + logger.Error(err, "Failed to start node shutdown manager") } } // Run starts the kubelet reacting to config updates -func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { - ctx := context.Background() +func (kl *Kubelet) Run(ctx context.Context, updates <-chan kubetypes.PodUpdate) { + logger := klog.FromContext(ctx) if kl.logServer == nil { file := http.FileServer(http.Dir(nodeLogDir)) if utilfeature.DefaultFeatureGate.Enabled(features.NodeLogQuery) && kl.kubeletConfiguration.EnableSystemLogQuery { @@ -1824,17 +1900,17 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { } } if kl.kubeClient == nil { - klog.InfoS("No API server defined - no node status update will be sent") + logger.Info("No API server defined - no node status update will be sent") } if err := kl.initializeModules(ctx); err != nil { - kl.recorder.Eventf(kl.nodeRef, v1.EventTypeWarning, events.KubeletSetupFailed, err.Error()) - klog.ErrorS(err, "Failed to initialize internal modules") + kl.recorder.WithLogger(logger).Eventf(kl.nodeRef, v1.EventTypeWarning, events.KubeletSetupFailed, "%s", err.Error()) + logger.Error(err, "Failed to initialize internal modules") os.Exit(1) } if err := kl.cgroupVersionCheck(); err != nil { - klog.V(2).InfoS("Warning: cgroup check", "error", err) + logger.V(2).Info("Warning: cgroup check", "error", err) } // Start the allocation manager @@ -1858,13 +1934,15 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { go func() { // Call updateRuntimeUp once before syncNodeStatus to make sure kubelet had already checked runtime state // otherwise when restart kubelet, syncNodeStatus will report node notReady in first report period - kl.updateRuntimeUp() - wait.JitterUntil(kl.syncNodeStatus, kl.nodeStatusUpdateFrequency, 0.04, true, wait.NeverStop) + kl.updateRuntimeUp(ctx) + wait.JitterUntil(func() { kl.syncNodeStatus(ctx) }, kl.nodeStatusUpdateFrequency, 0.04, true, wait.NeverStop) }() go kl.fastStatusUpdateOnce() - // start syncing lease + // Keep renewing the node lease until the kubelet exits. + // This intentionally does not use the kubelet context so lease renewal can + // continue during graceful shutdown. go kl.nodeLeaseController.Run(context.Background()) // Mirror pods for static pods may not be created immediately during node startup @@ -1874,11 +1952,11 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { // mirror pods are created as soon as the node registers. go kl.fastStaticPodsRegistration(ctx) } - go wait.Until(kl.updateRuntimeUp, 5*time.Second, wait.NeverStop) + go wait.UntilWithContext(ctx, kl.updateRuntimeUp, 5*time.Second) // Set up iptables util rules if kl.makeIPTablesUtilChains { - kl.initNetworkUtil() + kl.initNetworkUtil(logger) } // Start component sync loops. @@ -1953,7 +2031,7 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { // This operation writes all events that are dispatched in order to provide // the most accurate information possible about an error situation to aid debugging. // Callers should not write an event if this operation returns an error. -func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (isTerminal bool, err error) { +func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (isTerminal bool, postSync func(), err error) { ctx, otelSpan := kl.tracer.Start(ctx, "syncPod", trace.WithAttributes( semconv.K8SPodUIDKey.String(string(pod.UID)), attribute.String("k8s.pod", klog.KObj(pod).String()), @@ -1962,13 +2040,13 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType semconv.K8SNamespaceNameKey.String(pod.Namespace), )) logger := klog.FromContext(ctx) - klog.V(4).InfoS("SyncPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("SyncPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) defer func() { if err != nil { otelSpan.RecordError(err) otelSpan.SetStatus(codes.Error, err.Error()) } - klog.V(4).InfoS("SyncPod exit", "pod", klog.KObj(pod), "podUID", pod.UID, "isTerminal", isTerminal) + logger.V(4).Info("SyncPod exit", "pod", klog.KObj(pod), "podUID", pod.UID, "isTerminal", isTerminal) otelSpan.End() }() @@ -1987,7 +2065,7 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType // since kubelet first saw the pod if firstSeenTime is set. metrics.PodWorkerStartDuration.Observe(metrics.SinceInSeconds(firstSeenTime)) } else { - klog.V(3).InfoS("First seen time not recorded for pod", + logger.V(3).Info("First seen time not recorded for pod", "podUID", pod.UID, "pod", klog.KObj(pod)) } @@ -1999,8 +2077,8 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType kl.statusManager.SetPodResizeInProgressCondition(pod.UID, "", "", pod.Generation) } else if generation, cleared := kl.statusManager.ClearPodResizeInProgressCondition(pod.UID); cleared { // (Allocated == Actual) => clear the resize in-progress status. - msg := events.PodResizeCompletedMsg(pod, generation) - kl.recorder.Eventf(pod, v1.EventTypeNormal, events.ResizeCompleted, msg) + msg := events.PodResizeCompletedMsg(logger, pod, generation) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeNormal, events.ResizeCompleted, "%s", msg) } // TODO(natasha41575): There is a race condition here, where the goroutine in the // allocation manager may allocate a new resize and unconditionally set the @@ -2008,7 +2086,7 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType } // Generate final API pod status with pod and status manager status - apiPodStatus := kl.generateAPIPodStatus(pod, podStatus, false) + apiPodStatus := kl.generateAPIPodStatus(ctx, pod, podStatus, false) // The pod IP may be changed in generateAPIPodStatus if the pod is using host network. (See #24576) // TODO(random-liu): After writing pod spec into container labels, check whether pod is using host network, and // set pod IP to hostIP directly in runtime.GetPodStatus @@ -2024,7 +2102,7 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType if apiPodStatus.Phase == v1.PodSucceeded || apiPodStatus.Phase == v1.PodFailed { kl.statusManager.SetPodStatus(logger, pod, apiPodStatus) isTerminal = true - return isTerminal, nil + return isTerminal, nil, nil } // Record the time it takes for the pod to become running @@ -2039,8 +2117,8 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType // If the network plugin is not ready, only start the pod if it uses the host network if err := kl.runtimeState.networkErrors(); err != nil && !kubecontainer.IsHostNetworkPod(pod) { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.NetworkNotReady, "%s: %v", NetworkNotReadyErrorMsg, err) - return false, fmt.Errorf("%s: %v", NetworkNotReadyErrorMsg, err) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.NetworkNotReady, "%s: %v", NetworkNotReadyErrorMsg, err) + return false, nil, fmt.Errorf("%s: %v", NetworkNotReadyErrorMsg, err) } // ensure the kubelet knows about referenced secrets or configmaps used by the pod @@ -2081,9 +2159,9 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType podKilled = true } else { if wait.Interrupted(err) { - return false, nil + return false, nil, nil } - klog.ErrorS(err, "KillPod failed", "pod", klog.KObj(pod), "podStatus", podStatus) + logger.Error(err, "KillPod failed", "pod", klog.KObj(pod), "podStatus", podStatus) } } // Create and Update pod's Cgroups @@ -2104,18 +2182,16 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType } if !podKilled || !runOnce { if !pcm.Exists(pod) { - // TODO: Pass logger from context once contextual logging migration is complete - if err := kl.containerManager.UpdateQOSCgroups(klog.TODO()); err != nil { - klog.V(2).InfoS("Failed to update QoS cgroups while syncing pod", "pod", klog.KObj(pod), "err", err) + if err := kl.containerManager.UpdateQOSCgroups(logger); err != nil { + logger.V(2).Info("Failed to update QoS cgroups while syncing pod", "pod", klog.KObj(pod), "err", err) } - // TODO: Pass logger from context once contextual logging migration is complete - if err := pcm.EnsureExists(klog.TODO(), pod); err != nil { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedToCreatePodContainer, "unable to ensure pod container exists: %v", err) - return false, fmt.Errorf("failed to ensure that the pod: %v cgroups exist and are correctly applied: %v", pod.UID, err) + if err := pcm.EnsureExists(logger, pod); err != nil { + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedToCreatePodContainer, "unable to ensure pod container exists: %v", err) + return false, nil, fmt.Errorf("failed to ensure that the pod: %v cgroups exist and are correctly applied: %v", pod.UID, err) } if err = kl.containerRuntime.UpdateActuatedPodLevelResources(pod); err != nil { - return false, fmt.Errorf("failed to update the state of pod-level resources for the pod %v : %w", pod.UID, err) + return false, nil, fmt.Errorf("failed to update the state of pod-level resources for the pod %v : %w", pod.UID, err) } } } @@ -2126,28 +2202,28 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType // Make data directories for the pod if err := kl.makePodDataDirs(pod); err != nil { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedToMakePodDataDirectories, "error making pod data directories: %v", err) - klog.ErrorS(err, "Unable to make pod data directories for pod", "pod", klog.KObj(pod)) - return false, err + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedToMakePodDataDirectories, "error making pod data directories: %v", err) + logger.Error(err, "Unable to make pod data directories for pod", "pod", klog.KObj(pod)) + return false, nil, err } // Wait for volumes to attach/mount if err := kl.volumeManager.WaitForAttachAndMount(ctx, pod); err != nil { var volumeAttachLimitErr *volumemanager.VolumeAttachLimitExceededError if errors.As(err, &volumeAttachLimitErr) { - kl.rejectPod(pod, volumemanager.VolumeAttachmentLimitExceededReason, volumeAttachLimitErr.Error()) + kl.rejectPod(ctx, pod, volumemanager.VolumeAttachmentLimitExceededReason, volumeAttachLimitErr.Error()) recordAdmissionRejection(volumemanager.VolumeAttachmentLimitExceededReason) - return true, nil + return true, nil, nil } if !wait.Interrupted(err) { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedMountVolume, "Unable to attach or mount volumes: %v", err) - klog.ErrorS(err, "Unable to attach or mount volumes for pod; skipping pod", "pod", klog.KObj(pod)) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedMountVolume, "Unable to attach or mount volumes: %v", err) + logger.Error(err, "Unable to attach or mount volumes for pod; skipping pod", "pod", klog.KObj(pod)) } - return false, err + return false, nil, err } // Fetch the pull secrets for the pod - pullSecrets := kl.getPullSecretsForPod(pod) + pullSecrets := kl.getPullSecretsForPod(logger, pod) // Ensure the pod is being probed kl.probeManager.AddPod(ctx, pod) @@ -2170,19 +2246,50 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType result := kl.containerRuntime.SyncPod(sctx, pod, podStatus, pullSecrets, kl.crashLoopBackOff, restartingAllContainers) kl.reasonCache.Update(pod.UID, result) + // If we just performed a RestartAllContainers reset, we want to immediately + // trigger another sync to start the containers, rather than waiting for PLEG + // or the periodic resync. + if utilfeature.DefaultFeatureGate.Enabled(features.RestartAllContainersOnContainerExits) && + restartingAllContainers && result.Error() == nil { + shouldRequeue := false + for _, r := range result.SyncResults { + if r.Action == kubecontainer.RemoveContainer && r.Error == nil { + shouldRequeue = true + break + } + } + if shouldRequeue { + // This will not cause an infinite loop because UpdatePod merges concurrent updates + // to the same pod. Because all containers are removed, the subsequent SyncPod + // execution will unset the AllContainersRestarting condition and break the cycle. + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ + Pod: pod, + MirrorPod: mirrorPod, + UpdateType: kubetypes.SyncPodUpdate, + }) + } + } + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { for _, r := range result.SyncResults { if r.Action == kubecontainer.ResizePodInPlace && r.Error != nil { // If the condition already exists, the observedGeneration does not get updated. if generation, updated := kl.statusManager.SetPodResizeInProgressCondition(pod.UID, v1.PodReasonError, r.Message, pod.Generation); updated { - msg := events.PodResizeErrorMsg(pod, generation, r.Message) - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.ResizeError, msg) + msg := events.PodResizeErrorMsg(logger, pod, generation, r.Message) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.ResizeError, "%s", msg) } } } } - return false, result.Error() + err = result.Error() + if len(result.SyncResults) > 0 && err == nil { + postSync = func() { + kl.RequestPodRelist(pod.UID) + } + } + + return false, postSync, err } // SyncTerminatingPod is expected to terminate all running containers in a pod. Once this method @@ -2194,13 +2301,12 @@ func (kl *Kubelet) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType // during eviction). This method is not guaranteed to be called if a pod is force deleted from the // configuration and the kubelet is restarted - SyncTerminatingRuntimePod handles those orphaned // pods. -func (kl *Kubelet) SyncTerminatingPod(_ context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, gracePeriod *int64, podStatusFn func(*v1.PodStatus)) (err error) { +func (kl *Kubelet) SyncTerminatingPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, gracePeriod *int64, podStatusFn func(*v1.PodStatus)) (err error) { // TODO(#113606): connect this with the incoming context parameter, which comes from the pod worker. // Currently, using that context causes test failures. - ctx := context.Background() - logger := klog.FromContext(ctx) - klog.V(4).InfoS("SyncTerminatingPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) + ctx = klog.NewContext(context.TODO(), logger) + logger.V(4).Info("SyncTerminatingPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) ctx, otelSpan := kl.tracer.Start(ctx, "syncTerminatingPod", trace.WithAttributes( semconv.K8SPodUIDKey.String(string(pod.UID)), @@ -2214,29 +2320,28 @@ func (kl *Kubelet) SyncTerminatingPod(_ context.Context, pod *v1.Pod, podStatus otelSpan.SetStatus(codes.Error, err.Error()) } otelSpan.End() - klog.V(4).InfoS("SyncTerminatingPod exit", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("SyncTerminatingPod exit", "pod", klog.KObj(pod), "podUID", pod.UID) }() - apiPodStatus := kl.generateAPIPodStatus(pod, podStatus, false) + apiPodStatus := kl.generateAPIPodStatus(ctx, pod, podStatus, false) if podStatusFn != nil { podStatusFn(&apiPodStatus) } kl.statusManager.SetPodStatus(logger, pod, apiPodStatus) if gracePeriod != nil { - klog.V(4).InfoS("Pod terminating with grace period", "pod", klog.KObj(pod), "podUID", pod.UID, "gracePeriod", *gracePeriod) + logger.V(4).Info("Pod terminating with grace period", "pod", klog.KObj(pod), "podUID", pod.UID, "gracePeriod", *gracePeriod) } else { - klog.V(4).InfoS("Pod terminating with grace period", "pod", klog.KObj(pod), "podUID", pod.UID, "gracePeriod", nil) + logger.V(4).Info("Pod terminating with grace period", "pod", klog.KObj(pod), "podUID", pod.UID, "gracePeriod", nil) } kl.probeManager.StopLivenessAndStartup(pod) p := kubecontainer.ConvertPodStatusToRunningPod(kl.getRuntime().Type(), podStatus) if err := kl.killPod(ctx, pod, p, gracePeriod); err != nil { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedToKillPod, "error killing pod: %v", err) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedToKillPod, "error killing pod: %v", err) // there was an error killing the pod, so we return that error directly - utilruntime.HandleError(err) - return err + return fmt.Errorf("error killing terminating pod: %w", err) } // Once the containers are stopped, we can stop probing for liveness and readiness. @@ -2250,10 +2355,23 @@ func (kl *Kubelet) SyncTerminatingPod(_ context.Context, pod *v1.Pod, podStatus // catch race conditions introduced by callers updating pod status out of order. // TODO: have KillPod return the terminal status of stopped containers and write that into the // cache immediately - stoppedPodStatus, err := kl.containerRuntime.GetPodStatus(ctx, pod.UID, pod.Name, pod.Namespace) + runtimePod, err := kl.containerRuntime.GetPod(ctx, pod.UID) if err != nil { - klog.ErrorS(err, "Unable to read pod status prior to final pod termination", "pod", klog.KObj(pod), "podUID", pod.UID) - return err + if errors.Is(err, kubecontainer.ErrPodNotFound) { + // If pod sandboxes were already cleaned up, proceed with an empty runtimePod. + runtimePod = &kubecontainer.Pod{ + ID: pod.UID, + Name: pod.Name, + Namespace: pod.Namespace, + Timestamp: kl.clock.Now(), + } + } else { + return fmt.Errorf("unable to get pod prior to final pod termination: %w", err) + } + } + stoppedPodStatus, err := kl.containerRuntime.GetPodStatus(ctx, runtimePod) + if err != nil { + return fmt.Errorf("unable to read pod status prior to final pod termination: %w", err) } preserveDataFromBeforeStopping(stoppedPodStatus, podStatus) var runningContainers []string @@ -2264,19 +2382,19 @@ func (kl *Kubelet) SyncTerminatingPod(_ context.Context, pod *v1.Pod, podStatus FinishedAt string } var containers []container - klogV := klog.V(4) - klogVEnabled := klogV.Enabled() + loggerV := logger.V(4) + loggerVEnabled := loggerV.Enabled() for _, s := range stoppedPodStatus.ContainerStatuses { if s.State == kubecontainer.ContainerStateRunning { runningContainers = append(runningContainers, s.ID.String()) } - if klogVEnabled { + if loggerVEnabled { containers = append(containers, container{Name: s.Name, State: string(s.State), ExitCode: s.ExitCode, FinishedAt: s.FinishedAt.UTC().Format(time.RFC3339Nano)}) } } - if klogVEnabled { + if loggerVEnabled { sort.Slice(containers, func(i, j int) bool { return containers[i].Name < containers[j].Name }) - klog.V(4).InfoS("Post-termination container state", "pod", klog.KObj(pod), "podUID", pod.UID, "containers", containers) + logger.V(4).Info("Post-termination container state", "pod", klog.KObj(pod), "podUID", pod.UID, "containers", containers) } if len(runningContainers) > 0 { return fmt.Errorf("detected running containers after a successful KillPod, CRI violation: %v", runningContainers) @@ -2295,11 +2413,11 @@ func (kl *Kubelet) SyncTerminatingPod(_ context.Context, pod *v1.Pod, podStatus // The computation is done here to ensure the pod status used for it contains // information about the container end states (including exit codes) - when // SyncTerminatedPod is called the containers may already be removed. - apiPodStatus = kl.generateAPIPodStatus(pod, stoppedPodStatus, true) + apiPodStatus = kl.generateAPIPodStatus(ctx, pod, stoppedPodStatus, true) kl.statusManager.SetPodStatus(logger, pod, apiPodStatus) // we have successfully stopped all containers, the pod is terminating, our status is "done" - klog.V(4).InfoS("Pod termination stopped all running containers", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod termination stopped all running containers", "pod", klog.KObj(pod), "podUID", pod.UID) return nil } @@ -2320,25 +2438,26 @@ func preserveDataFromBeforeStopping(stoppedPodStatus, podStatus *kubecontainer.P // that the remnant of the running pod is terminated and allow garbage collection to proceed. We do // not update the status of the pod because with the source of configuration removed, we have no // place to send that status. -func (kl *Kubelet) SyncTerminatingRuntimePod(_ context.Context, runningPod *kubecontainer.Pod) error { +func (kl *Kubelet) SyncTerminatingRuntimePod(ctx context.Context, runningPod *kubecontainer.Pod) error { // TODO(#113606): connect this with the incoming context parameter, which comes from the pod worker. // Currently, using that context causes test failures. - ctx := context.Background() + logger := klog.FromContext(ctx) + ctx = klog.NewContext(context.TODO(), logger) pod := runningPod.ToAPIPod() - klog.V(4).InfoS("SyncTerminatingRuntimePod enter", "pod", klog.KObj(pod), "podUID", pod.UID) - defer klog.V(4).InfoS("SyncTerminatingRuntimePod exit", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("SyncTerminatingRuntimePod enter", "pod", klog.KObj(pod), "podUID", pod.UID) + defer logger.V(4).Info("SyncTerminatingRuntimePod exit", "pod", klog.KObj(pod), "podUID", pod.UID) // we kill the pod directly since we have lost all other information about the pod. - klog.V(4).InfoS("Orphaned running pod terminating without grace period", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Orphaned running pod terminating without grace period", "pod", klog.KObj(pod), "podUID", pod.UID) // TODO: this should probably be zero, to bypass any waiting (needs fixes in container runtime) gracePeriod := int64(1) if err := kl.killPod(ctx, pod, *runningPod, &gracePeriod); err != nil { - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedToKillPod, "error killing pod: %v", err) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedToKillPod, "error killing pod: %v", err) // there was an error killing the pod, so we return that error directly utilruntime.HandleError(err) return err } - klog.V(4).InfoS("Pod termination stopped all running orphaned containers", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod termination stopped all running orphaned containers", "pod", klog.KObj(pod), "podUID", pod.UID) return nil } @@ -2360,12 +2479,12 @@ func (kl *Kubelet) SyncTerminatedPod(ctx context.Context, pod *v1.Pod, podStatus )) logger := klog.FromContext(ctx) defer otelSpan.End() - klog.V(4).InfoS("SyncTerminatedPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) - defer klog.V(4).InfoS("SyncTerminatedPod exit", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("SyncTerminatedPod enter", "pod", klog.KObj(pod), "podUID", pod.UID) + defer logger.V(4).Info("SyncTerminatedPod exit", "pod", klog.KObj(pod), "podUID", pod.UID) // generate the final status of the pod // TODO: should we simply fold this into TerminatePod? that would give a single pod update - apiPodStatus := kl.generateAPIPodStatus(pod, podStatus, true) + apiPodStatus := kl.generateAPIPodStatus(ctx, pod, podStatus, true) kl.statusManager.SetPodStatus(logger, pod, apiPodStatus) @@ -2374,20 +2493,20 @@ func (kl *Kubelet) SyncTerminatedPod(ctx context.Context, pod *v1.Pod, podStatus if err := kl.volumeManager.WaitForUnmount(ctx, pod); err != nil { return err } - klog.V(4).InfoS("Pod termination unmounted volumes", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod termination unmounted volumes", "pod", klog.KObj(pod), "podUID", pod.UID) // This waiting loop relies on the background cleanup which starts after pod workers respond // true for ShouldPodRuntimeBeRemoved, which happens after `SyncTerminatingPod` is completed. if err := wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, func(ctx context.Context) (bool, error) { - volumesExist := kl.podVolumesExist(pod.UID) + volumesExist := kl.podVolumesExist(logger, pod.UID) if volumesExist { - klog.V(3).InfoS("Pod is terminated, but some volumes have not been cleaned up", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(3).Info("Pod is terminated, but some volumes have not been cleaned up", "pod", klog.KObj(pod), "podUID", pod.UID) } return !volumesExist, nil }); err != nil { return err } - klog.V(3).InfoS("Pod termination cleaned up volume paths", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(3).Info("Pod termination cleaned up volume paths", "pod", klog.KObj(pod), "podUID", pod.UID) // After volume unmount is complete, let the secret and configmap managers know we're done with this pod if kl.secretManager != nil { @@ -2408,14 +2527,14 @@ func (kl *Kubelet) SyncTerminatedPod(ctx context.Context, pod *v1.Pod, podStatus if err := pcm.Destroy(logger, name); err != nil { return err } - klog.V(4).InfoS("Pod termination removed cgroups", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod termination removed cgroups", "pod", klog.KObj(pod), "podUID", pod.UID) } kl.usernsManager.Release(logger, pod.UID) // mark the final pod status kl.statusManager.TerminatePod(logger, pod) - klog.V(4).InfoS("Pod is terminated and will need no more status updates", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod is terminated and will need no more status updates", "pod", klog.KObj(pod), "podUID", pod.UID) return nil } @@ -2462,7 +2581,7 @@ func (kl *Kubelet) getPodsToSync() []*v1.Pod { // // deletePod returns an error if not all sources are ready or the pod is not // found in the runtime cache. -func (kl *Kubelet) deletePod(pod *v1.Pod) error { +func (kl *Kubelet) deletePod(ctx context.Context, pod *v1.Pod) error { if pod == nil { return fmt.Errorf("deletePod does not allow nil pod") } @@ -2471,8 +2590,8 @@ func (kl *Kubelet) deletePod(pod *v1.Pod) error { // for sources that haven't reported yet. return fmt.Errorf("skipping delete because sources aren't ready yet") } - klog.V(3).InfoS("Pod has been deleted and must be killed", "pod", klog.KObj(pod), "podUID", pod.UID) - kl.podWorkers.UpdatePod(UpdatePodOptions{ + klog.FromContext(ctx).V(3).Info("Pod has been deleted and must be killed", "pod", klog.KObj(pod), "podUID", pod.UID) + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, UpdateType: kubetypes.SyncPodKill, }) @@ -2482,9 +2601,10 @@ func (kl *Kubelet) deletePod(pod *v1.Pod) error { // rejectPod records an event about the pod with the given reason and message, // and updates the pod to the failed phase in the status manager. -func (kl *Kubelet) rejectPod(pod *v1.Pod, reason, message string) { - kl.recorder.Eventf(pod, v1.EventTypeWarning, reason, message) - kl.statusManager.SetPodStatus(klog.TODO(), pod, v1.PodStatus{ +func (kl *Kubelet) rejectPod(ctx context.Context, pod *v1.Pod, reason, message string) { + logger := klog.FromContext(ctx) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, reason, "%s", message) + kl.statusManager.SetPodStatus(logger, pod, v1.PodStatus{ QOSClass: v1qos.GetPodQOS(pod), // keep it as is Phase: v1.PodFailed, Reason: reason, @@ -2513,7 +2633,8 @@ func recordAdmissionRejection(reason string) { // no changes are seen to the configuration, will synchronize the last known desired // state every sync-frequency seconds. Never returns. func (kl *Kubelet) syncLoop(ctx context.Context, updates <-chan kubetypes.PodUpdate, handler SyncHandler) { - klog.InfoS("Starting kubelet main sync loop") + logger := klog.FromContext(ctx) + logger.Info("Starting kubelet main sync loop") // The syncTicker wakes up kubelet to checks if there are any pod workers // that need to be sync'd. A one-second period is sufficient because the // sync interval is defaulted to 10s. @@ -2537,7 +2658,7 @@ func (kl *Kubelet) syncLoop(ctx context.Context, updates <-chan kubetypes.PodUpd for { if err := kl.runtimeState.runtimeErrors(); err != nil { - klog.ErrorS(err, "Skipping pod synchronization") + logger.Error(err, "Skipping pod synchronization") // exponential backoff time.Sleep(duration) duration = time.Duration(math.Min(float64(max), factor*float64(duration))) @@ -2594,36 +2715,33 @@ func (kl *Kubelet) syncLoopIteration(ctx context.Context, configCh <-chan kubety // Update from a config source; dispatch it to the right handler // callback. if !open { - klog.ErrorS(nil, "Update channel is closed, exiting the sync loop") + logger.Error(nil, "Update channel is closed, exiting the sync loop") return false } switch u.Op { case kubetypes.ADD: - klog.V(2).InfoS("SyncLoop ADD", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) + logger.V(2).Info("SyncLoop ADD", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) // After restarting, kubelet will get all existing pods through // ADD as if they are new pods. These pods will then go through the // admission process and *may* be rejected. This can be resolved // once we have checkpointing. - handler.HandlePodAdditions(u.Pods) + handler.HandlePodAdditions(ctx, u.Pods) case kubetypes.UPDATE: - klog.V(2).InfoS("SyncLoop UPDATE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) - handler.HandlePodUpdates(u.Pods) + logger.V(2).Info("SyncLoop UPDATE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) + handler.HandlePodUpdates(ctx, u.Pods) case kubetypes.REMOVE: - klog.V(2).InfoS("SyncLoop REMOVE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) - handler.HandlePodRemoves(u.Pods) + logger.V(2).Info("SyncLoop REMOVE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) + handler.HandlePodRemoves(ctx, u.Pods) case kubetypes.RECONCILE: - klog.V(4).InfoS("SyncLoop RECONCILE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) - handler.HandlePodReconcile(u.Pods) + logger.V(4).Info("SyncLoop RECONCILE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) + handler.HandlePodReconcile(ctx, u.Pods) case kubetypes.DELETE: - klog.V(2).InfoS("SyncLoop DELETE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) + logger.V(2).Info("SyncLoop DELETE", "source", u.Source, "pods", klog.KObjSlice(u.Pods)) // DELETE is treated as a UPDATE because of graceful deletion. - handler.HandlePodUpdates(u.Pods) - case kubetypes.SET: - // TODO: Do we want to support this? - klog.ErrorS(nil, "Kubelet does not support snapshot update") + handler.HandlePodUpdates(ctx, u.Pods) default: - klog.ErrorS(nil, "Invalid operation type received", "operation", u.Op) + logger.Error(nil, "Invalid operation type received", "operation", u.Op) } kl.sourcesReady.AddSource(u.Source) @@ -2631,17 +2749,17 @@ func (kl *Kubelet) syncLoopIteration(ctx context.Context, configCh <-chan kubety if isSyncPodWorthy(e) { // PLEG event for a pod; sync it. if pod, ok := kl.podManager.GetPodByUID(e.ID); ok { - klog.V(2).InfoS("SyncLoop (PLEG): event for pod", "pod", klog.KObj(pod), "event", e) - handler.HandlePodSyncs([]*v1.Pod{pod}) + logger.V(2).Info("SyncLoop (PLEG): event for pod", "pod", klog.KObj(pod), "event", e) + handler.HandlePodSyncs(ctx, []*v1.Pod{pod}) } else { // If the pod no longer exists, ignore the event. - klog.V(4).InfoS("SyncLoop (PLEG): pod does not exist, ignore irrelevant event", "event", e) + logger.V(4).Info("SyncLoop (PLEG): pod does not exist, ignore irrelevant event", "event", e) } } if e.Type == pleg.ContainerDied { if containerID, ok := e.Data.(string); ok { - kl.cleanUpContainersInPod(e.ID, containerID) + kl.cleanUpContainersInPod(ctx, e.ID, containerID) } } case <-syncCh: @@ -2650,11 +2768,11 @@ func (kl *Kubelet) syncLoopIteration(ctx context.Context, configCh <-chan kubety if len(podsToSync) == 0 { break } - klog.V(4).InfoS("SyncLoop (SYNC) pods", "total", len(podsToSync), "pods", klog.KObjSlice(podsToSync)) - handler.HandlePodSyncs(podsToSync) + logger.V(4).Info("SyncLoop (SYNC) pods", "total", len(podsToSync), "pods", klog.KObjSlice(podsToSync)) + handler.HandlePodSyncs(ctx, podsToSync) case update := <-kl.livenessManager.Updates(): if update.Result == proberesults.Failure { - handleProbeSync(kl, update, handler, "liveness", "unhealthy") + handleProbeSync(ctx, kl, update, handler, "liveness", "unhealthy") } case update := <-kl.readinessManager.Updates(): ready := update.Result == proberesults.Success @@ -2664,7 +2782,7 @@ func (kl *Kubelet) syncLoopIteration(ctx context.Context, configCh <-chan kubety if ready { status = "ready" } - handleProbeSync(kl, update, handler, "readiness", status) + handleProbeSync(ctx, kl, update, handler, "readiness", status) case update := <-kl.startupManager.Updates(): started := update.Result == proberesults.Success kl.statusManager.SetContainerStartup(logger, update.PodUID, update.ContainerID, started) @@ -2673,60 +2791,62 @@ func (kl *Kubelet) syncLoopIteration(ctx context.Context, configCh <-chan kubety if started { status = "started" } - handleProbeSync(kl, update, handler, "startup", status) + handleProbeSync(ctx, kl, update, handler, "startup", status) case update := <-kl.containerManager.Updates(): pods := []*v1.Pod{} for _, p := range update.PodUIDs { if pod, ok := kl.podManager.GetPodByUID(types.UID(p)); ok { - klog.V(3).InfoS("SyncLoop (containermanager): event for pod", "pod", klog.KObj(pod), "event", update) + logger.V(3).Info("SyncLoop (containermanager): event for pod", "pod", klog.KObj(pod), "event", update) pods = append(pods, pod) } else { // If the pod no longer exists, ignore the event. - klog.V(4).InfoS("SyncLoop (containermanager): pod does not exist, ignore devices updates", "event", update) + logger.V(4).Info("SyncLoop (containermanager): pod does not exist, ignore devices updates", "event", update) } } if len(pods) > 0 { // Updating the pod by syncing it again // We do not apply the optimization by updating the status directly, but can do it later - handler.HandlePodSyncs(pods) + handler.HandlePodSyncs(ctx, pods) } case <-housekeepingCh: if !kl.sourcesReady.AllReady() { // If the sources aren't ready or volume manager has not yet synced the states, // skip housekeeping, as we may accidentally delete pods from unready sources. - klog.V(4).InfoS("SyncLoop (housekeeping, skipped): sources aren't ready yet") + logger.V(4).Info("SyncLoop (housekeeping, skipped): sources aren't ready yet") } else { start := time.Now() - klog.V(4).InfoS("SyncLoop (housekeeping)") + logger.V(4).Info("SyncLoop (housekeeping)") if err := handler.HandlePodCleanups(ctx); err != nil { - klog.ErrorS(err, "Failed cleaning pods") + logger.Error(err, "Failed cleaning pods") } duration := time.Since(start) if duration > housekeepingWarningDuration { - klog.ErrorS(fmt.Errorf("housekeeping took too long"), "Housekeeping took longer than expected", "expected", housekeepingWarningDuration, "actual", duration.Round(time.Millisecond)) + logger.Error(fmt.Errorf("housekeeping took too long"), "Housekeeping took longer than expected", "expected", housekeepingWarningDuration, "actual", duration.Round(time.Millisecond)) } - klog.V(4).InfoS("SyncLoop (housekeeping) end", "duration", duration.Round(time.Millisecond)) + logger.V(4).Info("SyncLoop (housekeeping) end", "duration", duration.Round(time.Millisecond)) } } return true } -func handleProbeSync(kl *Kubelet, update proberesults.Update, handler SyncHandler, probe, status string) { +func handleProbeSync(ctx context.Context, kl *Kubelet, update proberesults.Update, handler SyncHandler, probe, status string) { + logger := klog.FromContext(ctx) // We should not use the pod from manager, because it is never updated after initialization. pod, ok := kl.podManager.GetPodByUID(update.PodUID) if !ok { // If the pod no longer exists, ignore the update. - klog.V(4).InfoS("SyncLoop (probe): ignore irrelevant update", "probe", probe, "status", status, "update", update) + logger.V(4).Info("SyncLoop (probe): ignore irrelevant update", "probe", probe, "status", status, "update", update) return } - klog.V(1).InfoS("SyncLoop (probe)", "probe", probe, "status", status, "pod", klog.KObj(pod)) - handler.HandlePodSyncs([]*v1.Pod{pod}) + logger.V(1).Info("SyncLoop (probe)", "probe", probe, "status", status, "pod", klog.KObj(pod)) + handler.HandlePodSyncs(ctx, []*v1.Pod{pod}) } // HandlePodAdditions is the callback in SyncHandler for pods being added from // a config source. -func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) { +func (kl *Kubelet) HandlePodAdditions(ctx context.Context, pods []*v1.Pod) { start := kl.clock.Now() + logger := klog.FromContext(ctx) sort.Sort(sliceutils.PodsByCreationTime(pods)) var pendingResizes []types.UID for _, pod := range pods { @@ -2736,15 +2856,15 @@ func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) { // the apiserver and no action (other than cleanup) is required. kl.podManager.AddPod(pod) - kl.podCertificateManager.TrackPod(context.TODO(), pod) + kl.podCertificateManager.TrackPod(ctx, pod) pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(pod) if wasMirror { if pod == nil { - klog.V(2).InfoS("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) + logger.V(2).Info("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) continue } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodUpdate, @@ -2765,7 +2885,7 @@ func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) { // We failed pods that we rejected, so activePods include all admitted // pods that are alive. if ok, reason, message := kl.allocationManager.AddPod(kl.GetActivePods(), pod); !ok { - kl.rejectPod(pod, reason, message) + kl.rejectPod(ctx, pod, reason, message) // We avoid recording the metric in canAdmitPod because it's called // repeatedly during a resize, which would inflate the metric. // Instead, we record the metric here in HandlePodAdditions for new pods @@ -2784,7 +2904,7 @@ func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) { } } } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodCreate, @@ -2804,8 +2924,9 @@ func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) { // HandlePodUpdates is the callback in the SyncHandler interface for pods // being updated from a config source. -func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) { +func (kl *Kubelet) HandlePodUpdates(ctx context.Context, pods []*v1.Pod) { start := kl.clock.Now() + logger := klog.FromContext(ctx) for _, pod := range pods { oldPod, _ := kl.podManager.GetPodByUID(pod.UID) kl.podManager.UpdatePod(pod) @@ -2813,7 +2934,7 @@ func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) { pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(pod) if wasMirror { if pod == nil { - klog.V(2).InfoS("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) + logger.V(2).Info("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) continue } } @@ -2834,28 +2955,28 @@ func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) { } } - if utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures) { + if utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures) && oldPod != nil { oldPodInfo := &ndf.PodInfo{Spec: &oldPod.Spec, Status: &oldPod.Status} newPodInfo := &ndf.PodInfo{Spec: &pod.Spec, Status: &pod.Status} reqs, err := kl.nodeDeclaredFeaturesFramework.InferForPodUpdate(oldPodInfo, newPodInfo, kl.version) if err != nil { - klog.ErrorS(err, "Failed to infer required features for pod update", "pod", klog.KObj(pod)) + logger.Error(err, "Failed to infer required features for pod update", "pod", klog.KObj(pod)) } - if reqs.Len() != 0 { - matchResult, err := ndf.MatchNodeFeatureSet(reqs, kl.nodeDeclaredFeaturesSet) + if !reqs.IsEmpty() { + matchResult, err := kl.nodeDeclaredFeaturesFramework.MatchNodeFeatureSet(reqs, kl.nodeDeclaredFeaturesSet) if err != nil { - klog.ErrorS(err, "Failed to match pod features with the node", "pod", klog.KObj(pod)) + logger.Error(err, "Failed to match pod features with the node", "pod", klog.KObj(pod)) } if !matchResult.IsMatch { missingNodeDeclaredFeatures := strings.Join(matchResult.UnsatisfiedRequirements, ", ") - klog.ErrorS(nil, "Pod requires node features that are not available", "missingFeatures", missingNodeDeclaredFeatures) - kl.recorder.Eventf(pod, v1.EventTypeWarning, events.FailedNodeDeclaredFeaturesCheck, "Pod requires node features that are not available: %s", missingNodeDeclaredFeatures) + logger.Error(nil, "Pod requires node features that are not available", "missingFeatures", missingNodeDeclaredFeatures) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, events.FailedNodeDeclaredFeaturesCheck, "Pod requires node features that are not available: %s", missingNodeDeclaredFeatures) } } } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodUpdate, @@ -2864,9 +2985,8 @@ func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) { } } -// recordResizeOperaations records if any of the pod level resources or -// containers need to be resized, and returns -// true if so +// recordResizeOperations records if any of the pod level resources or +// containers need to be resized, and returns true if so func recordResizeOperations(oldPod, newPod *v1.Pod) bool { if oldPod == nil { // This should never happen. @@ -2875,7 +2995,6 @@ func recordResizeOperations(oldPod, newPod *v1.Pod) bool { hasResize := recordContainerResizeOperations(oldPod, newPod) || recordPodLevelResourceResizeOperations(oldPod, newPod) return hasResize - } // recordPodLevelResourceResizeOperations records if any of the pod level resources need to be resized, and returns @@ -2952,20 +3071,21 @@ func resizeOperationForResources(new, old *resource.Quantity) string { // HandlePodRemoves is the callback in the SyncHandler interface for pods // being removed from a config source. -func (kl *Kubelet) HandlePodRemoves(pods []*v1.Pod) { +func (kl *Kubelet) HandlePodRemoves(ctx context.Context, pods []*v1.Pod) { start := kl.clock.Now() + logger := klog.FromContext(ctx) for _, pod := range pods { - kl.podCertificateManager.ForgetPod(context.TODO(), pod) + kl.podCertificateManager.ForgetPod(ctx, pod) kl.podManager.RemovePod(pod) kl.allocationManager.RemovePod(pod.UID) pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(pod) if wasMirror { if pod == nil { - klog.V(2).InfoS("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) + logger.V(2).Info("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) continue } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodUpdate, @@ -2976,8 +3096,8 @@ func (kl *Kubelet) HandlePodRemoves(pods []*v1.Pod) { // Deletion is allowed to fail because the periodic cleanup routine // will trigger deletion again. - if err := kl.deletePod(pod); err != nil { - klog.V(2).InfoS("Failed to delete pod", "pod", klog.KObj(pod), "err", err) + if err := kl.deletePod(ctx, pod); err != nil { + logger.V(2).Info("Failed to delete pod", "pod", klog.KObj(pod), "err", err) } } @@ -2989,9 +3109,11 @@ func (kl *Kubelet) HandlePodRemoves(pods []*v1.Pod) { // HandlePodReconcile is the callback in the SyncHandler interface for pods // that should be reconciled. Pods are reconciled when only the status of the // pod is updated in the API. -func (kl *Kubelet) HandlePodReconcile(pods []*v1.Pod) { +func (kl *Kubelet) HandlePodReconcile(ctx context.Context, pods []*v1.Pod) { start := kl.clock.Now() + logger := klog.FromContext(ctx) retryPendingResizes := false + var triggerReason string hasPendingResizes := kl.allocationManager.HasPendingResizes() for _, pod := range pods { // Update the pod in pod manager, status manager will do periodically reconcile according @@ -3002,16 +3124,22 @@ func (kl *Kubelet) HandlePodReconcile(pods []*v1.Pod) { pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(pod) if wasMirror { if pod == nil { - klog.V(2).InfoS("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) + logger.V(2).Info("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) continue } // Static pods should be reconciled the same way as regular pods } if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { - // If there are pending resizes, check whether the requests shrank as a result of the status - // resources changing. if hasPendingResizes && !retryPendingResizes && oldPod != nil { + // If the pod has reached a terminal phase, we retry all pending resizes. + if podutil.IsPodTerminal(pod) && !podutil.IsPodTerminal(oldPod) { + retryPendingResizes = true + triggerReason = allocation.TriggerReasonPodTerminated + } + + // If there are pending resizes, check whether the requests shrank as a result of the status + // resources changing. opts := resourcehelper.PodResourcesOptions{ UseStatusResources: true, SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), @@ -3026,8 +3154,11 @@ func (kl *Kubelet) HandlePodReconcile(pods []*v1.Pod) { newRequest := resourcehelper.PodRequests(allocatedPod, opts) // If cpu or memory requests shrank, then retry the pending resizes. - retryPendingResizes = newRequest.Memory().Cmp(*oldRequest.Memory()) < 0 || - newRequest.Cpu().Cmp(*oldRequest.Cpu()) < 0 + if newRequest.Memory().Cmp(*oldRequest.Memory()) < 0 || + newRequest.Cpu().Cmp(*oldRequest.Cpu()) < 0 { + retryPendingResizes = true + triggerReason = allocation.TriggerReasonPodResized + } } } @@ -3040,7 +3171,7 @@ func (kl *Kubelet) HandlePodReconcile(pods []*v1.Pod) { // be different than Sync, or if there is a better place for it. For instance, we have // needsReconcile in kubelet/config, here, and in status_manager. if status.NeedToReconcilePodReadiness(pod) { - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodSync, @@ -3062,29 +3193,30 @@ func (kl *Kubelet) HandlePodReconcile(pods []*v1.Pod) { if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { if retryPendingResizes { - kl.allocationManager.RetryPendingResizes(allocation.TriggerReasonPodResized) + kl.allocationManager.RetryPendingResizes(triggerReason) } } } // HandlePodSyncs is the callback in the syncHandler interface for pods // that should be dispatched to pod workers for sync. -func (kl *Kubelet) HandlePodSyncs(pods []*v1.Pod) { +func (kl *Kubelet) HandlePodSyncs(ctx context.Context, pods []*v1.Pod) { start := kl.clock.Now() + logger := klog.FromContext(ctx) for _, pod := range pods { pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(pod) if wasMirror { if pod == nil { - klog.V(2).InfoS("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) + logger.V(2).Info("Unable to find pod for mirror pod, skipping", "mirrorPod", klog.KObj(mirrorPod), "mirrorPodUID", mirrorPod.UID) continue } // Syncing a mirror pod is a programmer error since the intent of sync is to // batch notify all pending work. We should make it impossible to double sync, // but for now log a programmer error to prevent accidental introduction. - klog.V(3).InfoS("Programmer error, HandlePodSyncs does not expect to receive mirror pods", "podUID", pod.UID, "mirrorPodUID", mirrorPod.UID) + logger.V(3).Info("Programmer error, HandlePodSyncs does not expect to receive mirror pods", "podUID", pod.UID, "mirrorPodUID", mirrorPod.UID) continue } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ Pod: pod, MirrorPod: mirrorPod, UpdateType: kubetypes.SyncPodSync, @@ -3120,29 +3252,29 @@ func (kl *Kubelet) SyncLoopHealthCheck(req *http.Request) error { // the runtime dependent modules when the container runtime first comes up, // and returns an error if the status check fails. If the status check is OK, // update the container runtime uptime in the kubelet runtimeState. -func (kl *Kubelet) updateRuntimeUp() { +func (kl *Kubelet) updateRuntimeUp(ctx context.Context) { + logger := klog.FromContext(ctx) kl.updateRuntimeMux.Lock() defer kl.updateRuntimeMux.Unlock() - ctx := context.Background() s, err := kl.containerRuntime.Status(ctx) if err != nil { - klog.ErrorS(err, "Container runtime sanity check failed") + logger.Error(err, "Container runtime sanity check failed") return } if s == nil { - klog.ErrorS(nil, "Container runtime status is nil") + logger.Error(nil, "Container runtime status is nil") return } // Periodically log the whole runtime status for debugging. - klog.V(4).InfoS("Container runtime status", "status", s) - klogErrorS := klog.ErrorS + logger.V(4).Info("Container runtime status", "status", s) + loggerInfo := logger.Info if !kl.containerRuntimeReadyExpected { - klogErrorS = klog.V(4).ErrorS + loggerInfo = logger.V(4).Info } networkReady := s.GetRuntimeCondition(kubecontainer.NetworkReady) if networkReady == nil || !networkReady.Status { - klogErrorS(nil, "Container runtime network not ready", "networkReady", networkReady) + loggerInfo("Container runtime network not ready", "networkReady", networkReady) kl.runtimeState.setNetworkState(fmt.Errorf("container runtime network not ready: %v", networkReady)) } else { // Set nil if the container runtime network is ready. @@ -3152,7 +3284,7 @@ func (kl *Kubelet) updateRuntimeUp() { runtimeReady := s.GetRuntimeCondition(kubecontainer.RuntimeReady) // If RuntimeReady is not set or is false, report an error. if runtimeReady == nil || !runtimeReady.Status { - klogErrorS(nil, "Container runtime not ready", "runtimeReady", runtimeReady) + loggerInfo("Container runtime not ready", "runtimeReady", runtimeReady) kl.runtimeState.setRuntimeState(fmt.Errorf("container runtime not ready: %v", runtimeReady)) return } @@ -3178,9 +3310,9 @@ func (kl *Kubelet) BirthCry() { } // ListenAndServe runs the kubelet HTTP server. -func (kl *Kubelet) ListenAndServe(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsOptions *server.TLSOptions, +func (kl *Kubelet) ListenAndServe(ctx context.Context, kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsConfig *tls.Config, auth server.AuthInterface, tp trace.TracerProvider) { - server.ListenAndServeKubeletServer(ctx, kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, kubeCfg, tlsOptions, auth, tp) + server.ListenAndServeKubeletServer(ctx, kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, kubeCfg, tlsConfig, auth, tp) } // ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode. @@ -3201,30 +3333,56 @@ func (pp *kubeletPodsProvider) GetPods() []*v1.Pod { } func (pp *kubeletPodsProvider) GetPodByName(namespace, name string) (*v1.Pod, bool) { - return pp.kl.podManager.GetPodByName(namespace, name) + pod, found := pp.kl.podManager.GetPodByName(namespace, name) + if !found { + return nil, false + } + // use the same filtering logic as GetActivePods + if pp.kl.isPodInactive(pod) { + return nil, false + } + return pod, true } -// ListenAndServePodResources runs the kubelet podresources grpc service +// ListenAndServePodResources runs the kubelet podresources grpc service. func (kl *Kubelet) ListenAndServePodResources(ctx context.Context) { - endpoint, err := util.LocalEndpoint(kl.getPodResourcesDir(), podresources.Socket) - if err != nil { - klog.V(2).InfoS("Failed to get local endpoint for PodResources endpoint", "err", err) - return - } + if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPodResourcesGet) { + endpoint, err := util.LocalEndpoint(kl.getPodResourcesDir(), podresources.Socket) + if err != nil { + klog.FromContext(ctx).V(2).Info("Failed to get local endpoint for PodResources endpoint", "err", err) + return + } + + providers := podresources.PodResourcesProviders{ + Pods: &kubeletPodsProvider{kl: kl}, + Devices: kl.containerManager, + Cpus: kl.containerManager, + Memory: kl.containerManager, + DynamicResources: kl.containerManager, + } - providers := podresources.PodResourcesProviders{ - Pods: &kubeletPodsProvider{kl: kl}, - Devices: kl.containerManager, - Cpus: kl.containerManager, - Memory: kl.containerManager, - DynamicResources: kl.containerManager, + server.ListenAndServePodResources(ctx, endpoint, providers) } +} - server.ListenAndServePodResources(ctx, endpoint, providers) +// ListenAndServePod initializes an HTTP server to serve the Pod API. +func (kl *Kubelet) ListenAndServePods(ctx context.Context) { + if utilfeature.DefaultFeatureGate.Enabled(features.PodsAPI) { + endpoint, err := util.LocalEndpoint(kl.getPodsAPIDir(), pods.Socket) + if err != nil { + klog.FromContext(ctx).Error(err, "Failed to get local endpoint for pod api") + return + } + server.ListenAndServePodsServer( + ctx, + endpoint, + kl.podsServer, + ) + } } // Delete the eligible dead container instances in a pod. Depending on the configuration, the latest dead containers may be kept around. -func (kl *Kubelet) cleanUpContainersInPod(podID types.UID, exitedContainerID string) { +func (kl *Kubelet) cleanUpContainersInPod(ctx context.Context, podID types.UID, exitedContainerID string) { if podStatus, err := kl.podCache.Get(podID); err == nil { // When an evicted or deleted pod has already synced, all containers can be removed. removeAll := kl.podWorkers.ShouldPodContentBeRemoved(podID) @@ -3327,6 +3485,7 @@ func (kl *Kubelet) UnprepareDynamicResources(ctx context.Context, pod *v1.Pod) e // Ensure Mirror Pod for Static Pod exists and matches the current pod definition. // The function logs and ignores any errors. func (kl *Kubelet) tryReconcileMirrorPods(ctx context.Context, staticPod, mirrorPod *v1.Pod) { + logger := klog.FromContext(ctx) if !kubetypes.IsStaticPod(staticPod) { return } @@ -3335,26 +3494,26 @@ func (kl *Kubelet) tryReconcileMirrorPods(ctx context.Context, staticPod, mirror if mirrorPod.DeletionTimestamp != nil || !kubepod.IsMirrorPodOf(mirrorPod, staticPod) { // The mirror pod is semantically different from the static pod. Remove // it. The mirror pod will get recreated later. - klog.InfoS("Trying to delete pod", "pod", klog.KObj(mirrorPod), "podUID", mirrorPod.UID) + logger.Info("Trying to delete pod", "pod", klog.KObj(mirrorPod), "podUID", mirrorPod.UID) podFullName := kubecontainer.GetPodFullName(staticPod) if ok, err := kl.mirrorPodClient.DeleteMirrorPod(ctx, podFullName, &mirrorPod.UID); err != nil { - klog.ErrorS(err, "Failed deleting mirror pod", "pod", klog.KObj(mirrorPod)) + logger.Error(err, "Failed deleting mirror pod", "pod", klog.KObj(mirrorPod)) } else if ok { deleted = ok - klog.InfoS("Deleted mirror pod as it didn't match the static Pod", "pod", klog.KObj(mirrorPod)) + logger.Info("Deleted mirror pod as it didn't match the static Pod", "pod", klog.KObj(mirrorPod)) } } } if mirrorPod == nil || deleted { - node, err := kl.GetNode() + node, err := kl.GetNode(ctx) if err != nil { - klog.ErrorS(err, "No need to create a mirror pod, since failed to get node info from the cluster", "node", klog.KRef("", string(kl.nodeName))) + logger.Error(err, "No need to create a mirror pod, since failed to get node info from the cluster", "node", klog.KRef("", string(kl.nodeName))) } else if node.DeletionTimestamp != nil { - klog.InfoS("No need to create a mirror pod, since node has been removed from the cluster", "node", klog.KRef("", string(kl.nodeName))) + logger.Info("No need to create a mirror pod, since node has been removed from the cluster", "node", klog.KRef("", string(kl.nodeName))) } else { - klog.InfoS("Creating a mirror pod for static pod", "pod", klog.KObj(staticPod)) + logger.Info("Creating a mirror pod for static pod", "pod", klog.KObj(staticPod)) if err := kl.mirrorPodClient.CreateMirrorPod(ctx, staticPod); err != nil { - klog.ErrorS(err, "Failed creating a mirror pod", "pod", klog.KObj(staticPod)) + logger.Error(err, "Failed creating a mirror pod", "pod", klog.KObj(staticPod)) } } } @@ -3362,16 +3521,17 @@ func (kl *Kubelet) tryReconcileMirrorPods(ctx context.Context, staticPod, mirror // Ensure Mirror Pod for Static Pod exists as soon as node is registered. func (kl *Kubelet) fastStaticPodsRegistration(ctx context.Context) { + logger := klog.FromContext(ctx) if err := wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, func(ctx context.Context) (bool, error) { - _, err := kl.GetNode() + _, err := kl.GetNode(ctx) if err == nil { return true, nil } - klog.V(4).ErrorS(err, "Unable to register mirror pod because node is not registered yet", "node", klog.KRef("", string(kl.nodeName))) + logger.Error(err, "Unable to register mirror pod because node is not registered yet", "node", klog.KRef("", string(kl.nodeName))) return false, nil }); err != nil { - klog.V(4).ErrorS(err, "Failed to wait until node is registered", "node", klog.KRef("", string(kl.nodeName))) + logger.Error(err, "Failed to wait until node is registered", "node", klog.KRef("", string(kl.nodeName))) } staticPodToMirrorPodMap := kl.podManager.GetStaticPodToMirrorPodMap() @@ -3380,6 +3540,55 @@ func (kl *Kubelet) fastStaticPodsRegistration(ctx context.Context) { } } -func (kl *Kubelet) SetPodWatchCondition(podUID types.UID, conditionKey string, condition pleg.WatchCondition) { - kl.pleg.SetPodWatchCondition(podUID, conditionKey, condition) +func (kl *Kubelet) RequestPodReinspect(podUID types.UID) { + kl.pleg.RequestReinspect(podUID) +} + +func (kl *Kubelet) RequestPodRelist(podUID types.UID) { + kl.pleg.RequestRelist(podUID) +} + +func (kl *Kubelet) syncPodNow(pod *v1.Pod) { + kl.HandlePodSyncs(context.Background(), []*v1.Pod{pod}) + kl.RequestPodRelist(pod.UID) +} + +// OnPodSandboxReady is the callback implementation invoked by the container runtime after +// all three requirements (sandbox, networking, volumes) are ready to immediately update +// the `PodReadyToStartContainers` pod status condition to `True`. +// This method implements the RuntimeHelper interface. +// Ref: https://github.com/kubernetes/kubernetes/issues/134460 +func (kl *Kubelet) OnPodSandboxReady(ctx context.Context, pod *v1.Pod) error { + if !utilfeature.DefaultFeatureGate.Enabled(features.PodReadyToStartContainersCondition) { + return nil + } + + logger := klog.FromContext(ctx) + logger.V(3).Info("OnPodSandboxReady callback invoked", "pod", klog.KObj(pod), "podUID", pod.UID) + + // update the status asynchronously to avoid blocking the SyncPod flow + go func() { + existingStatus, ok := kl.statusManager.GetPodStatus(pod.UID) + if !ok { + existingStatus = pod.Status + } + + cachedStatus := existingStatus.DeepCopy() + + readySandboxCondition := v1.PodCondition{ + Type: v1.PodReadyToStartContainers, + Status: v1.ConditionTrue, + ObservedGeneration: podutil.CalculatePodConditionObservedGeneration(cachedStatus, pod.Generation, v1.PodReadyToStartContainers), + } + + cachedStatus.Conditions = utilpod.ReplaceOrAppendPodCondition(cachedStatus.Conditions, &readySandboxCondition) + + kl.statusManager.SetPodStatus(logger, pod, *cachedStatus) + + logger.V(3).Info("Successfully updated PodReadyToStartContainers condition after sandbox creation", + "pod", klog.KObj(pod), + "podUID", pod.UID) + }() + + return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go index b822d4e9d0..f35c696779 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go @@ -133,8 +133,8 @@ func (kl *Kubelet) HandlerSupportsUserNamespaces(rtHandler string) (bool, error) } // GetKubeletMappings gets the additional IDs allocated for the Kubelet. -func (kl *Kubelet) GetKubeletMappings(idsPerPod uint32) (uint32, uint32, error) { - return kl.getKubeletMappings(idsPerPod) +func (kl *Kubelet) GetKubeletMappings(logger klog.Logger, idsPerPod uint32) (uint32, uint32, error) { + return kl.getKubeletMappings(logger, idsPerPod) } func (kl *Kubelet) GetMaxPods() int { @@ -216,11 +216,16 @@ func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string { return filepath.Join(kl.getPodDir(podUID), kubeletconfig.DefaultKubeletContainersDirName, ctrName) } -// getPodResourcesSocket returns the full path to the directory containing the pod resources socket +// getPodResourcesDir returns the full path to the directory containing the pod resources socket func (kl *Kubelet) getPodResourcesDir() string { return filepath.Join(kl.getRootDir(), kubeletconfig.DefaultKubeletPodResourcesDirName) } +// getPodsAPIDir returns the full path to the directory containing the pods API socket +func (kl *Kubelet) getPodsAPIDir() string { + return filepath.Join(kl.getRootDir(), kubeletconfig.DefaultKubeletPodsAPIDirName) +} + // GetPods returns all pods bound to the kubelet and their spec, and the mirror // pods. func (kl *Kubelet) GetPods() []*v1.Pod { @@ -286,9 +291,9 @@ func (kl *Kubelet) getRuntime() kubecontainer.Runtime { } // GetNode returns the node info for the configured node name of this Kubelet. -func (kl *Kubelet) GetNode() (*v1.Node, error) { +func (kl *Kubelet) GetNode(ctx context.Context) (*v1.Node, error) { if kl.kubeClient == nil { - return kl.initialNode(context.TODO()) + return kl.initialNode(ctx) } return kl.nodeLister.Get(string(kl.nodeName)) } @@ -298,11 +303,11 @@ func (kl *Kubelet) GetNode() (*v1.Node, error) { // Return kubelet's nodeInfo for this node, except on error or if in standalone mode, // in which case return a manufactured nodeInfo representing a node with no pods, // zero capacity, and the default labels. -func (kl *Kubelet) getNodeAnyWay() (*v1.Node, error) { - if n, err := kl.GetNode(); err == nil { +func (kl *Kubelet) getNodeAnyWay(ctx context.Context) (*v1.Node, error) { + if n, err := kl.GetNode(ctx); err == nil { return n, nil } - return kl.initialNode(context.TODO()) + return kl.initialNode(ctx) } // GetNodeConfig returns the container manager node config. @@ -317,8 +322,8 @@ func (kl *Kubelet) GetPodCgroupRoot() string { // getHostIPsAnyWay attempts to return the host IPs from kubelet's nodeInfo, or // the initialNode. -func (kl *Kubelet) getHostIPsAnyWay() ([]net.IP, error) { - node, err := kl.getNodeAnyWay() +func (kl *Kubelet) getHostIPsAnyWay(ctx context.Context) ([]net.IP, error) { + node, err := kl.getNodeAnyWay(ctx) if err != nil { return nil, err } @@ -334,20 +339,20 @@ func (kl *Kubelet) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 { // getPodVolumePathListFromDisk returns a list of the volume paths by reading the // volume directories for the given pod from the disk. -func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, error) { +func (kl *Kubelet) getPodVolumePathListFromDisk(logger klog.Logger, podUID types.UID) ([]string, error) { volumes := []string{} podVolDir := kl.getPodVolumesDir(podUID) if pathExists, pathErr := mount.PathExists(podVolDir); pathErr != nil { return volumes, fmt.Errorf("error checking if path %q exists: %v", podVolDir, pathErr) } else if !pathExists { - klog.V(6).InfoS("Path does not exist", "path", podVolDir) + logger.V(6).Info("Path does not exist", "path", podVolDir) return volumes, nil } volumePluginDirs, err := os.ReadDir(podVolDir) if err != nil { - klog.ErrorS(err, "Could not read directory", "path", podVolDir) + logger.Error(err, "Could not read directory", "path", podVolDir) return volumes, err } for _, volumePluginDir := range volumePluginDirs { @@ -378,9 +383,9 @@ func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, err return volumes, nil } -func (kl *Kubelet) getMountedVolumePathListFromDisk(podUID types.UID) ([]string, error) { +func (kl *Kubelet) getMountedVolumePathListFromDisk(logger klog.Logger, podUID types.UID) ([]string, error) { mountedVolumes := []string{} - volumePaths, err := kl.getPodVolumePathListFromDisk(podUID) + volumePaths, err := kl.getPodVolumePathListFromDisk(logger, podUID) if err != nil { return mountedVolumes, err } @@ -403,7 +408,7 @@ func (kl *Kubelet) getMountedVolumePathListFromDisk(podUID types.UID) ([]string, // getPodVolumeSubpathListFromDisk returns a list of the volume-subpath paths by reading the // subpath directories for the given pod from the disk. -func (kl *Kubelet) getPodVolumeSubpathListFromDisk(podUID types.UID) ([]string, error) { +func (kl *Kubelet) getPodVolumeSubpathListFromDisk(logger klog.Logger, podUID types.UID) ([]string, error) { volumes := []string{} podSubpathsDir := kl.getPodVolumeSubpathsDir(podUID) @@ -416,7 +421,7 @@ func (kl *Kubelet) getPodVolumeSubpathListFromDisk(podUID types.UID) ([]string, // Explicitly walks /// volumePluginDirs, err := os.ReadDir(podSubpathsDir) if err != nil { - klog.ErrorS(err, "Could not read directory", "path", podSubpathsDir) + logger.Error(err, "Could not read directory", "path", podSubpathsDir) return volumes, err } for _, volumePluginDir := range volumePluginDirs { @@ -467,10 +472,11 @@ func (kl *Kubelet) setCachedMachineInfo(info *cadvisorapiv1.MachineInfo) { } // getLastStableNodeAddresses returns the last observed node addresses. -func (kl *Kubelet) getLastObservedNodeAddresses() []v1.NodeAddress { - node, err := kl.GetNode() +func (kl *Kubelet) getLastObservedNodeAddresses(ctx context.Context) []v1.NodeAddress { + logger := klog.FromContext(ctx) + node, err := kl.GetNode(ctx) if err != nil || node == nil { - klog.V(4).InfoS("fail to obtain node from local cache", "node", kl.nodeName, "error", err) + logger.V(4).Info("fail to obtain node from local cache", "node", kl.nodeName, "error", err) return nil } return node.Status.Addresses diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go index 45b208f960..b6f0aadaa2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go @@ -28,6 +28,7 @@ import ( // updatePodCIDR updates the pod CIDR in the runtime state if it is different // from the current CIDR. Return true if pod CIDR is actually changed. func (kl *Kubelet) updatePodCIDR(ctx context.Context, cidr string) (bool, error) { + logger := klog.FromContext(ctx) kl.updatePodCIDRMux.Lock() defer kl.updatePodCIDRMux.Unlock() @@ -44,7 +45,7 @@ func (kl *Kubelet) updatePodCIDR(ctx context.Context, cidr string) (bool, error) // But it is better to be on the safe side to still return true here. return true, fmt.Errorf("failed to update pod CIDR: %v", err) } - klog.InfoS("Updating Pod CIDR", "originalPodCIDR", podCIDR, "newPodCIDR", cidr) + logger.Info("Updating Pod CIDR", "originalPodCIDR", podCIDR, "newPodCIDR", cidr) kl.runtimeState.setPodCIDR(cidr) return true, nil } @@ -52,8 +53,6 @@ func (kl *Kubelet) updatePodCIDR(ctx context.Context, cidr string) (bool, error) // GetPodDNS returns DNS settings for the pod. // This function is defined in kubecontainer.RuntimeHelper interface so we // have to implement it. -func (kl *Kubelet) GetPodDNS(pod *v1.Pod) (*runtimeapi.DNSConfig, error) { - // Use context.TODO() because we currently do not have a proper context to pass in. - // Replace this with an appropriate context when refactoring this function to accept a context parameter. - return kl.dnsConfigurer.GetPodDNS(context.TODO(), pod) +func (kl *Kubelet) GetPodDNS(ctx context.Context, pod *v1.Pod) (*runtimeapi.DNSConfig, error) { + return kl.dnsConfigurer.GetPodDNS(ctx, pod) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_linux.go index 05cad40e86..b330cce559 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. @@ -36,7 +35,7 @@ const ( KubeFirewallChain utiliptables.Chain = "KUBE-FIREWALL" ) -func (kl *Kubelet) initNetworkUtil() { +func (kl *Kubelet) initNetworkUtil(logger klog.Logger) { iptClients := utiliptables.NewBestEffort() if len(iptClients) == 0 { // We don't log this as an error because kubelet itself doesn't need any @@ -44,33 +43,33 @@ func (kl *Kubelet) initNetworkUtil() { // and because we *expect* this to fail on hosts where only nftables is // supported (in which case there can't be any other components using // iptables that would need these rules anyway). - klog.InfoS("No iptables support on this system; not creating the KUBE-IPTABLES-HINT chain") + logger.Info("No iptables support on this system; not creating the KUBE-IPTABLES-HINT chain") return } for family := range iptClients { iptClient := iptClients[family] - if kl.syncIPTablesRules(iptClient) { - klog.InfoS("Initialized iptables rules.", "protocol", iptClient.Protocol()) + if kl.syncIPTablesRules(logger, iptClient) { + logger.Info("Initialized iptables rules.", "protocol", iptClient.Protocol()) go iptClient.Monitor( utiliptables.Chain("KUBE-KUBELET-CANARY"), []utiliptables.Table{utiliptables.TableMangle, utiliptables.TableNAT, utiliptables.TableFilter}, - func() { kl.syncIPTablesRules(iptClient) }, + func() { kl.syncIPTablesRules(logger, iptClient) }, 1*time.Minute, wait.NeverStop, ) } else { - klog.InfoS("Failed to initialize iptables rules; some functionality may be missing.", "protocol", iptClient.Protocol()) + logger.Info("Failed to initialize iptables rules; some functionality may be missing.", "protocol", iptClient.Protocol()) } } } // syncIPTablesRules ensures the KUBE-IPTABLES-HINT chain exists, and the martian packet // protection rule is installed. -func (kl *Kubelet) syncIPTablesRules(iptClient utiliptables.Interface) bool { +func (kl *Kubelet) syncIPTablesRules(logger klog.Logger, iptClient utiliptables.Interface) bool { // Create hint chain so other components can see whether we are using iptables-legacy // or iptables-nft. if _, err := iptClient.EnsureChain(utiliptables.TableMangle, KubeIPTablesHintChain); err != nil { - klog.ErrorS(err, "Failed to ensure that iptables hint chain exists") + logger.Error(err, "Failed to ensure that iptables hint chain exists") return false } @@ -84,16 +83,16 @@ func (kl *Kubelet) syncIPTablesRules(iptClient utiliptables.Interface) bool { // created by kube-proxy. if _, err := iptClient.EnsureChain(utiliptables.TableFilter, KubeFirewallChain); err != nil { - klog.ErrorS(err, "Failed to ensure that filter table KUBE-FIREWALL chain exists") + logger.Error(err, "Failed to ensure that filter table KUBE-FIREWALL chain exists") return false } if _, err := iptClient.EnsureRule(utiliptables.Prepend, utiliptables.TableFilter, utiliptables.ChainOutput, "-j", string(KubeFirewallChain)); err != nil { - klog.ErrorS(err, "Failed to ensure that OUTPUT chain jumps to KUBE-FIREWALL") + logger.Error(err, "Failed to ensure that OUTPUT chain jumps to KUBE-FIREWALL") return false } if _, err := iptClient.EnsureRule(utiliptables.Prepend, utiliptables.TableFilter, utiliptables.ChainInput, "-j", string(KubeFirewallChain)); err != nil { - klog.ErrorS(err, "Failed to ensure that INPUT chain jumps to KUBE-FIREWALL") + logger.Error(err, "Failed to ensure that INPUT chain jumps to KUBE-FIREWALL") return false } @@ -110,7 +109,7 @@ func (kl *Kubelet) syncIPTablesRules(iptClient utiliptables.Interface) bool { "-m", "conntrack", "!", "--ctstate", "RELATED,ESTABLISHED,DNAT", "-j", "DROP"); err != nil { - klog.ErrorS(err, "Failed to ensure rule to drop invalid localhost packets in filter table KUBE-FIREWALL chain") + logger.Error(err, "Failed to ensure rule to drop invalid localhost packets in filter table KUBE-FIREWALL chain") return false } } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_others.go index 666849166c..0901debe84 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network_others.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2018 The Kubernetes Authors. @@ -19,5 +18,7 @@ limitations under the License. package kubelet +import "k8s.io/klog/v2" + // Do nothing. -func (kl *Kubelet) initNetworkUtil() {} +func (kl *Kubelet) initNetworkUtil(logger klog.Logger) {} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_declared_features.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_declared_features.go index 9bbe246b8f..e05b9c46df 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_declared_features.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_declared_features.go @@ -36,15 +36,17 @@ func (a FeatureGateAdapter) Enabled(key string) bool { // discoverNodeDeclaredFeatures determines the final set of node features to be declared by using the discovery library. func (kl *Kubelet) discoverNodeDeclaredFeatures() []string { - staticConfig := nodedeclaredfeatures.StaticConfiguration{ - CPUManagerPolicy: kl.containerManager.GetNodeConfig().CPUManagerPolicy, + adaptedFG := FeatureGateAdapter{FeatureGate: utilfeature.DefaultFeatureGate} + + runtimeFeatures := nodedeclaredfeatures.RuntimeFeatures{} + if features := kl.runtimeState.runtimeFeatures(); features != nil { + runtimeFeatures.UserNamespacesHostNetwork = features.UserNamespacesHostNetwork } - adaptedFG := FeatureGateAdapter{FeatureGate: utilfeature.DefaultFeatureGate} cfg := &nodedeclaredfeatures.NodeConfiguration{ - FeatureGates: adaptedFG, - StaticConfig: staticConfig, - Version: kl.version, + FeatureGates: adaptedFG, + Version: kl.version, + RuntimeFeatures: runtimeFeatures, } return kl.nodeDeclaredFeaturesFramework.DiscoverNodeFeatures(cfg) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go index 2f64369bc5..fcf8e69c7e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go @@ -52,10 +52,11 @@ import ( // registerWithAPIServer registers the node with the cluster master. It is safe // to call multiple times, but not concurrently (kl.registrationCompleted is // not locked). -func (kl *Kubelet) registerWithAPIServer() { +func (kl *Kubelet) registerWithAPIServer(ctx context.Context) { if kl.registrationCompleted { return } + logger := klog.FromContext(ctx) kl.nodeStartupLatencyTracker.RecordAttemptRegisterNode() @@ -68,16 +69,16 @@ func (kl *Kubelet) registerWithAPIServer() { step = 7 * time.Second } - node, err := kl.initialNode(context.TODO()) + node, err := kl.initialNode(ctx) if err != nil { - klog.ErrorS(err, "Unable to construct v1.Node object for kubelet") + logger.Error(err, "Unable to construct v1.Node object for kubelet") continue } - klog.InfoS("Attempting to register node", "node", klog.KObj(node)) - registered := kl.tryRegisterWithAPIServer(node) + logger.Info("Attempting to register node", "node", klog.KObj(node)) + registered := kl.tryRegisterWithAPIServer(ctx, node) if registered { - klog.InfoS("Successfully registered node", "node", klog.KObj(node)) + logger.Info("Successfully registered node", "node", klog.KObj(node)) kl.registrationCompleted = true return } @@ -89,8 +90,9 @@ func (kl *Kubelet) registerWithAPIServer() { // successful. If a node with the same name already exists, it reconciles the // value of the annotation for controller-managed attach-detach of attachable // persistent volumes for the node. -func (kl *Kubelet) tryRegisterWithAPIServer(node *v1.Node) bool { - _, err := kl.kubeClient.CoreV1().Nodes().Create(context.TODO(), node, metav1.CreateOptions{}) +func (kl *Kubelet) tryRegisterWithAPIServer(ctx context.Context, node *v1.Node) bool { + logger := klog.FromContext(ctx) + _, err := kl.kubeClient.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) if err == nil { kl.nodeStartupLatencyTracker.RecordRegisteredNewNode() return true @@ -102,43 +104,43 @@ func (kl *Kubelet) tryRegisterWithAPIServer(node *v1.Node) bool { case apierrors.IsForbidden(err): // Creating nodes is forbidden, but node may still exist, attempt to get the node. if utilfeature.DefaultFeatureGate.Enabled(features.KubeletRegistrationGetOnExistsOnly) { - klog.ErrorS(err, "Unable to register node with API server, reason is forbidden", "node", klog.KObj(node)) + logger.Error(err, "Unable to register node with API server, reason is forbidden", "node", klog.KObj(node)) return false } default: - klog.ErrorS(err, "Unable to register node with API server", "node", klog.KObj(node)) + logger.Error(err, "Unable to register node with API server", "node", klog.KObj(node)) return false } - existingNode, err := kl.kubeClient.CoreV1().Nodes().Get(context.TODO(), string(kl.nodeName), metav1.GetOptions{}) + existingNode, err := kl.kubeClient.CoreV1().Nodes().Get(ctx, string(kl.nodeName), metav1.GetOptions{}) if err != nil { - klog.ErrorS(err, "Unable to register node with API server, error getting existing node", "node", klog.KObj(node)) + logger.Error(err, "Unable to register node with API server, error getting existing node", "node", klog.KObj(node)) return false } if existingNode == nil { - klog.InfoS("Unable to register node with API server, no node instance returned", "node", klog.KObj(node)) + logger.Info("Unable to register node with API server, no node instance returned", "node", klog.KObj(node)) return false } originalNode := existingNode.DeepCopy() - klog.InfoS("Node was previously registered", "node", klog.KObj(node)) + logger.Info("Node was previously registered", "node", klog.KObj(node)) // Edge case: the node was previously registered; reconcile // the value of the controller-managed attach-detach // annotation. - requiresUpdate := kl.reconcileCMADAnnotationWithExistingNode(node, existingNode) + requiresUpdate := kl.reconcileCMADAnnotationWithExistingNode(logger, node, existingNode) requiresUpdate = kl.updateDefaultLabels(node, existingNode) || requiresUpdate - requiresUpdate = kl.reconcileExtendedResource(node, existingNode) || requiresUpdate - requiresUpdate = kl.reconcileHugePageResource(node, existingNode) || requiresUpdate + requiresUpdate = kl.reconcileExtendedResource(logger, node, existingNode) || requiresUpdate + requiresUpdate = kl.reconcileHugePageResource(logger, node, existingNode) || requiresUpdate if managed.IsEnabled() { requiresUpdate = kl.addManagementNodeCapacity(node, existingNode) || requiresUpdate } requiresUpdate = kl.reconcileSharedCPUsNodeCapacity(node, existingNode) || requiresUpdate if requiresUpdate { if _, _, err := nodeutil.PatchNodeStatus(kl.kubeClient.CoreV1(), types.NodeName(kl.nodeName), originalNode, existingNode); err != nil { - klog.ErrorS(err, "Unable to reconcile node with API server,error updating node", "node", klog.KObj(node)) + logger.Error(err, "Unable to reconcile node with API server,error updating node", "node", klog.KObj(node)) return false } } @@ -185,7 +187,7 @@ func (kl *Kubelet) reconcileSharedCPUsNodeCapacity(initialNode, existingNode *v1 } // reconcileHugePageResource will update huge page capacity for each page size and remove huge page sizes no longer supported -func (kl *Kubelet) reconcileHugePageResource(initialNode, existingNode *v1.Node) bool { +func (kl *Kubelet) reconcileHugePageResource(logger klog.Logger, initialNode, existingNode *v1.Node) bool { requiresUpdate := updateDefaultResources(initialNode, existingNode) supportedHugePageResources := sets.Set[string]{} @@ -224,7 +226,7 @@ func (kl *Kubelet) reconcileHugePageResource(initialNode, existingNode *v1.Node) if !supportedHugePageResources.Has(string(resourceName)) { delete(existingNode.Status.Capacity, resourceName) delete(existingNode.Status.Allocatable, resourceName) - klog.InfoS("Removing huge page resource which is no longer supported", "resourceName", resourceName) + logger.Info("Removing huge page resource which is no longer supported", "resourceName", resourceName) requiresUpdate = true } } @@ -232,13 +234,13 @@ func (kl *Kubelet) reconcileHugePageResource(initialNode, existingNode *v1.Node) } // Zeros out extended resource capacity during reconciliation. -func (kl *Kubelet) reconcileExtendedResource(initialNode, node *v1.Node) bool { +func (kl *Kubelet) reconcileExtendedResource(logger klog.Logger, initialNode, node *v1.Node) bool { requiresUpdate := updateDefaultResources(initialNode, node) // Check with the device manager to see if node has been recreated, in which case extended resources should be zeroed until they are available if kl.containerManager.ShouldResetExtendedResourceCapacity() { for k := range node.Status.Capacity { if v1helper.IsExtendedResourceName(k) { - klog.InfoS("Zero out resource capacity in existing node", "resourceName", k, "node", klog.KObj(node)) + logger.Info("Zero out resource capacity in existing node", "resourceName", k, "node", klog.KObj(node)) node.Status.Capacity[k] = *resource.NewQuantity(int64(0), resource.DecimalSI) node.Status.Allocatable[k] = *resource.NewQuantity(int64(0), resource.DecimalSI) requiresUpdate = true @@ -314,7 +316,7 @@ func (kl *Kubelet) updateDefaultLabels(initialNode, existingNode *v1.Node) bool // reconcileCMADAnnotationWithExistingNode reconciles the controller-managed // attach-detach annotation on a new node and the existing node, returning // whether the existing node must be updated. -func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *v1.Node) bool { +func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(logger klog.Logger, node, existingNode *v1.Node) bool { var ( existingCMAAnnotation = existingNode.Annotations[volutil.ControllerManagedAttachAnnotation] newCMAAnnotation, newSet = node.Annotations[volutil.ControllerManagedAttachAnnotation] @@ -328,10 +330,10 @@ func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *v // not have the same value, update the existing node with // the correct value of the annotation. if !newSet { - klog.InfoS("Controller attach-detach setting changed to false; updating existing Node") + logger.Info("Controller attach-detach setting changed to false; updating existing Node") delete(existingNode.Annotations, volutil.ControllerManagedAttachAnnotation) } else { - klog.InfoS("Controller attach-detach setting changed to true; updating existing Node") + logger.Info("Controller attach-detach setting changed to true; updating existing Node") if existingNode.Annotations == nil { existingNode.Annotations = make(map[string]string) } @@ -344,6 +346,7 @@ func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *v // initialNode constructs the initial v1.Node for this Kubelet, incorporating node // labels, information from the cloud provider, and Kubelet configuration. func (kl *Kubelet) initialNode(ctx context.Context) (*v1.Node, error) { + logger := klog.FromContext(ctx) node := &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: string(kl.nodeName), @@ -385,16 +388,16 @@ func (kl *Kubelet) initialNode(ctx context.Context) (*v1.Node, error) { node.Annotations = make(map[string]string) } - klog.V(2).InfoS("Setting node annotation to enable volume controller attach/detach") + logger.V(2).Info("Setting node annotation to enable volume controller attach/detach") node.Annotations[volutil.ControllerManagedAttachAnnotation] = "true" } else { - klog.V(2).InfoS("Controller attach/detach is disabled for this node; Kubelet will attach and detach volumes") + logger.V(2).Info("Controller attach/detach is disabled for this node; Kubelet will attach and detach volumes") } // @question: should this be place after the call to the cloud provider? which also applies labels for k, v := range kl.nodeLabels { if cv, found := node.ObjectMeta.Labels[k]; found { - klog.InfoS("the node label will overwrite default setting", "labelKey", k, "labelValue", v, "default", cv) + logger.Info("the node label will overwrite default setting", "labelKey", k, "labelValue", v, "default", cv) } node.ObjectMeta.Labels[k] = v } @@ -419,6 +422,7 @@ func (kl *Kubelet) initialNode(ctx context.Context) (*v1.Node, error) { // syncNodeStatus. Its return value indicates whether the loop running it should exit // (final run), and it also sets kl.containerRuntimeReadyExpected. func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (completed bool) { + logger := klog.FromContext(ctx) kl.syncNodeStatusMux.Lock() defer func() { kl.syncNodeStatusMux.Unlock() @@ -433,19 +437,19 @@ func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (comp }() if timeout { - klog.ErrorS(nil, "Node not becoming ready in time after startup") + logger.Error(nil, "Node not becoming ready in time after startup") return true } - originalNode, err := kl.GetNode() + originalNode, err := kl.GetNode(ctx) if err != nil { - klog.ErrorS(err, "Error getting the current node from lister") + logger.Error(err, "Error getting the current node from lister") return false } readyIdx, originalNodeReady := nodeutil.GetNodeCondition(&originalNode.Status, v1.NodeReady) if readyIdx == -1 { - klog.ErrorS(nil, "Node does not have NodeReady condition", "originalNode", originalNode) + logger.Error(nil, "Node does not have NodeReady condition", "originalNode", originalNode) return false } @@ -455,7 +459,7 @@ func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (comp // This is in addition to the regular syncNodeStatus logic so we can get the container runtime status earlier. // This function itself has a mutex and it doesn't recursively call fastNodeStatusUpdate or syncNodeStatus. - kl.updateRuntimeUp() + kl.updateRuntimeUp(ctx) node, changed := kl.updateNode(ctx, originalNode) @@ -466,7 +470,7 @@ func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (comp readyIdx, nodeReady := nodeutil.GetNodeCondition(&node.Status, v1.NodeReady) if readyIdx == -1 { - klog.ErrorS(nil, "Node does not have NodeReady condition", "node", node) + logger.Error(nil, "Node does not have NodeReady condition", "node", node) return false } @@ -474,15 +478,15 @@ func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (comp return false } - klog.InfoS("Fast updating node status as it just became ready") + logger.Info("Fast updating node status as it just became ready") if _, err := kl.patchNodeStatus(originalNode, node); err != nil { // The originalNode is probably stale, but we know that the current state of kubelet would turn // the node to be ready. Retry using syncNodeStatus() which fetches from the apiserver. - klog.ErrorS(err, "Error updating node status, will retry with syncNodeStatus") + logger.Error(err, "Error updating node status, will retry with syncNodeStatus") // The reversed kl.syncNodeStatusMux.Unlock/Lock() below to allow kl.syncNodeStatus() execution. kl.syncNodeStatusMux.Unlock() - kl.syncNodeStatus() + kl.syncNodeStatus(ctx) // This lock action is unnecessary if we add a flag to check in the defer before unlocking it, // but having it here makes the logic a bit easier to read. kl.syncNodeStatusMux.Lock() @@ -495,33 +499,34 @@ func (kl *Kubelet) fastNodeStatusUpdate(ctx context.Context, timeout bool) (comp // syncNodeStatus should be called periodically from a goroutine. // It synchronizes node status to master if there is any change or enough time // passed from the last sync, registering the kubelet first if necessary. -func (kl *Kubelet) syncNodeStatus() { +func (kl *Kubelet) syncNodeStatus(ctx context.Context) { + logger := klog.FromContext(ctx) kl.syncNodeStatusMux.Lock() defer kl.syncNodeStatusMux.Unlock() - ctx := context.Background() if kl.kubeClient == nil || kl.heartbeatClient == nil { return } if kl.registerNode { // This will exit immediately if it doesn't need to do anything. - kl.registerWithAPIServer() + kl.registerWithAPIServer(ctx) } if err := kl.updateNodeStatus(ctx); err != nil { - klog.ErrorS(err, "Unable to update node status") + logger.Error(err, "Unable to update node status") } } // updateNodeStatus updates node status to master with retries if there is any // change or enough time passed from the last sync. func (kl *Kubelet) updateNodeStatus(ctx context.Context) error { - klog.V(5).InfoS("Updating node status") + logger := klog.FromContext(ctx) + logger.V(5).Info("Updating node status") for i := 0; i < nodeStatusUpdateRetry; i++ { if err := kl.tryUpdateNodeStatus(ctx, i); err != nil { if i > 0 && kl.onRepeatedHeartbeatFailure != nil { kl.onRepeatedHeartbeatFailure() } - klog.ErrorS(err, "Error updating node status, will retry") + logger.Error(err, "Error updating node status, will retry") } else { return nil } @@ -593,6 +598,7 @@ func (kl *Kubelet) calculateDelay() time.Duration { // updateNode creates a copy of originalNode and runs update logic on it. // It returns the updated node object and a bool indicating if anything has been changed. func (kl *Kubelet) updateNode(ctx context.Context, originalNode *v1.Node) (*v1.Node, bool) { + logger := klog.FromContext(ctx) node := originalNode.DeepCopy() podCIDRChanged := false @@ -603,7 +609,7 @@ func (kl *Kubelet) updateNode(ctx context.Context, originalNode *v1.Node) (*v1.N var err error podCIDRs := strings.Join(node.Spec.PodCIDRs, ",") if podCIDRChanged, err = kl.updatePodCIDR(ctx, podCIDRs); err != nil { - klog.ErrorS(err, "Error updating pod CIDR") + logger.Error(err, "Error updating pod CIDR") } } @@ -679,25 +685,26 @@ func (kl *Kubelet) markVolumesFromNode(node *v1.Node) { // recordNodeStatusEvent records an event of the given type with the given // message for the node. -func (kl *Kubelet) recordNodeStatusEvent(eventType, event string) { - klog.V(2).InfoS("Recording event message for node", "node", klog.KRef("", string(kl.nodeName)), "event", event) +func (kl *Kubelet) recordNodeStatusEvent(logger klog.Logger, eventType, event string) { + logger.V(2).Info("Recording event message for node", "node", klog.KRef("", string(kl.nodeName)), "event", event) kl.recorder.Eventf(kl.nodeRef, eventType, event, "Node %s status is now: %s", kl.nodeName, event) } // recordEvent records an event for this node, the Kubelet's nodeRef is passed to the recorder func (kl *Kubelet) recordEvent(eventType, event, message string) { - kl.recorder.Eventf(kl.nodeRef, eventType, event, message) + kl.recorder.Eventf(kl.nodeRef, eventType, event, "%s", message) } // record if node schedulable change. func (kl *Kubelet) recordNodeSchedulableEvent(ctx context.Context, node *v1.Node) error { + logger := klog.FromContext(ctx) kl.lastNodeUnschedulableLock.Lock() defer kl.lastNodeUnschedulableLock.Unlock() if kl.lastNodeUnschedulable != node.Spec.Unschedulable { if node.Spec.Unschedulable { - kl.recordNodeStatusEvent(v1.EventTypeNormal, events.NodeNotSchedulable) + kl.recordNodeStatusEvent(logger, v1.EventTypeNormal, events.NodeNotSchedulable) } else { - kl.recordNodeStatusEvent(v1.EventTypeNormal, events.NodeSchedulable) + kl.recordNodeStatusEvent(logger, v1.EventTypeNormal, events.NodeSchedulable) } kl.lastNodeUnschedulable = node.Spec.Unschedulable } @@ -709,10 +716,11 @@ func (kl *Kubelet) recordNodeSchedulableEvent(ctx context.Context, node *v1.Node // TODO(madhusudancs): Simplify the logic for setting node conditions and // refactor the node status condition code out to a different file. func (kl *Kubelet) setNodeStatus(ctx context.Context, node *v1.Node) { + logger := klog.FromContext(ctx) for i, f := range kl.setNodeStatusFuncs { - klog.V(5).InfoS("Setting node status condition code", "position", i, "node", klog.KObj(node)) + logger.V(5).Info("Setting node status condition code", "position", i, "node", klog.KObj(node)) if err := f(ctx, node); err != nil { - klog.ErrorS(err, "Failed to set some node status fields", "node", klog.KObj(node)) + logger.Error(err, "Failed to set some node status fields", "node", klog.KObj(node)) } } if utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures) && kl.nodeDeclaredFeatures != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_others.go index 2b4d8b5957..7c411ba9af 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_windows.go index 524159278e..a0a3832faf 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_nodecache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_nodecache.go index 5491d944c8..0d0ac097c5 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_nodecache.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_nodecache.go @@ -38,7 +38,7 @@ func (kl *Kubelet) GetCachedNode(ctx context.Context, useCache bool) (*v1.Node, // and returns the newer one. func (kl *Kubelet) getCachedNode(ctx context.Context) (*v1.Node, error) { logger := klog.FromContext(ctx) - informerNode, err := kl.GetNode() + informerNode, err := kl.GetNode(ctx) if err != nil { if kl.cachedNode != nil { logger.Error(err, "failed to list node; using cached node") diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go index 42a58b0dfd..88e98b9f0f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go @@ -46,9 +46,9 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" resourcehelper "k8s.io/component-helpers/resource" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" + "k8s.io/cri-streaming/pkg/streaming/portforward" + remotecommandserver "k8s.io/cri-streaming/pkg/streaming/remotecommand" "k8s.io/klog/v2" - "k8s.io/kubelet/pkg/cri/streaming/portforward" - remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/api/v1/resource" podshelper "k8s.io/kubernetes/pkg/apis/core/pods" @@ -60,6 +60,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/images" + "k8s.io/kubernetes/pkg/kubelet/kuberuntime" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/status" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" @@ -127,7 +128,7 @@ func parseGetSubIdsOutput(input string) (uint32, uint32, error) { // is installed, then the single mapping specified both for user and group IDs will be used. // If the tool is not installed, or there are no IDs configured, the default mapping is returned. // The default mapping includes the entire IDs range except IDs below idsPerPod. -func (kl *Kubelet) getKubeletMappings(idsPerPod uint32) (uint32, uint32, error) { +func (kl *Kubelet) getKubeletMappings(logger klog.Logger, idsPerPod uint32) (uint32, uint32, error) { // default mappings to return if there is no specific configuration defaultFirstID := idsPerPod // We cast defaultFirstID to 64 bits, as otherwise any operation (including subtraction) @@ -151,7 +152,7 @@ func (kl *Kubelet) getKubeletMappings(idsPerPod uint32) (uint32, uint32, error) var unknownUserErr user.UnknownUserError if goerrors.As(err, &unknownUserErr) { // if the user is not found, we assume that the user is not configured - klog.V(5).InfoS("user namespaces: user not found, using default mappings", "user", kubeletUser) + logger.V(5).Info("user namespaces: user not found, using default mappings", "user", kubeletUser) return defaultFirstID, defaultLen, nil } return 0, 0, err @@ -161,7 +162,7 @@ func (kl *Kubelet) getKubeletMappings(idsPerPod uint32) (uint32, uint32, error) cmd, err := exec.LookPath(execName) if err != nil { if os.IsNotExist(err) { - klog.V(2).InfoS("user namespaces: executable not found, using default mappings", "executable", execName, "err", err) + logger.V(2).Info("user namespaces: executable not found, using default mappings", "executable", execName, "err", err) return defaultFirstID, defaultLen, nil } return 0, 0, err @@ -177,7 +178,7 @@ func (kl *Kubelet) getKubeletMappings(idsPerPod uint32) (uint32, uint32, error) if string(outUids) != string(outGids) { return 0, 0, fmt.Errorf("mismatched subuids and subgids for user %q", kubeletUser) } - klog.V(5).InfoS("user namespaces: user found, using mappings from getsubids", "user", kubeletUser) + logger.V(5).Info("user namespaces: user found, using mappings from getsubids", "user", kubeletUser) return parseGetSubIdsOutput(string(outUids)) } @@ -227,7 +228,7 @@ func (kl *Kubelet) getAllocatedPods() []*v1.Pod { // makeBlockVolumes maps the raw block devices specified in the path of the container // Experimental -func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVolumes kubecontainer.VolumeMap, blkutil volumepathhandler.BlockVolumePathHandler) ([]kubecontainer.DeviceInfo, error) { +func (kl *Kubelet) makeBlockVolumes(logger klog.Logger, pod *v1.Pod, container *v1.Container, podVolumes kubecontainer.VolumeMap, blkutil volumepathhandler.BlockVolumePathHandler) ([]kubecontainer.DeviceInfo, error) { var devices []kubecontainer.DeviceInfo for _, device := range container.VolumeDevices { // check path is absolute @@ -236,7 +237,7 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol } vol, ok := podVolumes[device.Name] if !ok || vol.BlockVolumeMapper == nil { - klog.ErrorS(nil, "Block volume cannot be satisfied for container, because the volume is missing or the volume mapper is nil", "containerName", container.Name, "device", device) + logger.Error(nil, "Block volume cannot be satisfied for container, because the volume is missing or the volume mapper is nil", "containerName", container.Name, "device", device) return nil, fmt.Errorf("cannot find volume %q to pass into container %q", device.Name, container.Name) } // Get a symbolic link associated to a block device under pod device path @@ -250,7 +251,7 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol if vol.ReadOnly { permission = "r" } - klog.V(4).InfoS("Device will be attached to container in the corresponding path on host", "containerName", container.Name, "path", symlinkPath) + logger.V(4).Info("Device will be attached to container in the corresponding path on host", "containerName", container.Name, "path", symlinkPath) devices = append(devices, kubecontainer.DeviceInfo{PathOnHost: symlinkPath, PathInContainer: device.DevicePath, Permissions: permission}) } } @@ -274,9 +275,9 @@ func shouldMountHostsFile(pod *v1.Pod, podIPs []string) bool { } // makeMounts determines the mount points for the given container. -func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain string, podIPs []string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar, supportsRRO bool, imageVolumes kubecontainer.ImageVolumes) ([]kubecontainer.Mount, func(), error) { +func makeMounts(logger klog.Logger, pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain string, podIPs []string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar, supportsRRO bool, imageVolumes kubecontainer.ImageVolumes) ([]kubecontainer.Mount, func(), error) { mountEtcHostsFile := shouldMountHostsFile(pod, podIPs) - klog.V(3).InfoS("Creating hosts mount for container", "pod", klog.KObj(pod), "containerName", container.Name, "podIPs", podIPs, "path", mountEtcHostsFile) + logger.V(3).Info("Creating hosts mount for container", "pod", klog.KObj(pod), "containerName", container.Name, "podIPs", podIPs, "path", mountEtcHostsFile) mounts := []kubecontainer.Mount{} var cleanupAction func() for i, mount := range container.VolumeMounts { @@ -284,7 +285,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath) vol, ok := podVolumes[mount.Name] if !ok || vol.Mounter == nil { - klog.ErrorS(nil, "Mount cannot be satisfied for the container, because the volume is missing or the volume mounter (vol.Mounter) is nil", + logger.Error(nil, "Mount cannot be satisfied for the container, because the volume is missing or the volume mounter (vol.Mounter) is nil", "containerName", container.Name, "ok", ok, "volumeMounter", mount) return nil, cleanupAction, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name) } @@ -340,7 +341,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h hostPath = filepath.Join(volumePath, subPath) if subPathExists, err := hu.PathExists(hostPath); err != nil { - klog.ErrorS(nil, "Could not determine if subPath exists, will not attempt to change its permissions", "path", hostPath) + logger.Error(nil, "Could not determine if subPath exists, will not attempt to change its permissions", "path", hostPath) } else if !subPathExists { // Create the sub path now because if it's auto-created later when referenced, it may have an // incorrect ownership and mode. For example, the sub path directory must have at least g+rwx @@ -353,7 +354,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h } if err := subpather.SafeMakeDir(subPath, volumePath, perm); err != nil { // Don't pass detailed error back to the user because it could give information about host filesystem - klog.ErrorS(err, "Failed to create subPath directory for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name) + logger.Error(nil, "Failed to create subPath directory for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name) return nil, cleanupAction, fmt.Errorf("failed to create subPath directory for volumeMount %q of container %q", mount.Name, container.Name) } } @@ -367,7 +368,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h }) if err != nil { // Don't pass detailed error back to the user because it could give information about host filesystem - klog.ErrorS(err, "Failed to prepare subPath for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name) + logger.Error(nil, "Failed to prepare subPath for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name) return nil, cleanupAction, fmt.Errorf("failed to prepare subPath for volumeMount %q of container %q", mount.Name, container.Name) } } @@ -388,7 +389,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h if err != nil { return nil, cleanupAction, err } - klog.V(5).InfoS("Mount has propagation", "pod", klog.KObj(pod), "containerName", container.Name, "volumeMountName", mount.Name, "propagation", propagation) + logger.V(5).Info("Mount has propagation", "pod", klog.KObj(pod), "containerName", container.Name, "volumeMountName", mount.Name, "propagation", propagation) mustMountRO := vol.Mounter.GetAttributes().ReadOnly rro, err := resolveRecursiveReadOnly(mount, supportsRRO) @@ -552,14 +553,14 @@ func hostsEntriesFromHostAliases(hostAliases []v1.HostAlias) []byte { } // truncatePodHostnameIfNeeded truncates the pod hostname if it's longer than 63 chars. -func truncatePodHostnameIfNeeded(podName, hostname string) (string, error) { +func truncatePodHostnameIfNeeded(logger klog.Logger, podName, hostname string) (string, error) { // Cap hostname at 63 chars (specification is 64bytes which is 63 chars and the null terminating char). const hostnameMaxLen = 63 if len(hostname) <= hostnameMaxLen { return hostname, nil } truncated := hostname[:hostnameMaxLen] - klog.ErrorS(nil, "Hostname for pod was too long, truncated it", "podName", podName, "hostnameMaxLen", hostnameMaxLen, "truncatedHostname", truncated) + logger.Error(nil, "Hostname for pod was too long, truncated it", "podName", podName, "hostnameMaxLen", hostnameMaxLen, "truncatedHostname", truncated) // hostname should not end with '-' or '.' truncated = strings.TrimRight(truncated, "-.") if len(truncated) == 0 { @@ -570,15 +571,13 @@ func truncatePodHostnameIfNeeded(podName, hostname string) (string, error) { } // GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace -func (kl *Kubelet) GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { - // Use context.TODO() because we currently do not have a proper logger to pass in. - // This should be replaced with an appropriate context when refactoring this function to accept a context parameter. - return kl.usernsManager.GetOrCreateUserNamespaceMappings(context.TODO(), pod, runtimeHandler) +func (kl *Kubelet) GetOrCreateUserNamespaceMappings(logger klog.Logger, pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { + return kl.usernsManager.GetOrCreateUserNamespaceMappings(logger, pod, runtimeHandler) } // GeneratePodHostNameAndDomain creates a hostname and domain name for a pod, // given that pod's spec and annotations or returns an error. -func (kl *Kubelet) GeneratePodHostNameAndDomain(pod *v1.Pod) (string, string, error) { +func (kl *Kubelet) GeneratePodHostNameAndDomain(logger klog.Logger, pod *v1.Pod) (string, string, error) { clusterDomain := kl.dnsConfigurer.ClusterDomain if utilfeature.DefaultFeatureGate.Enabled(features.HostnameOverride) && pod.Spec.HostnameOverride != nil { @@ -586,7 +585,7 @@ func (kl *Kubelet) GeneratePodHostNameAndDomain(pod *v1.Pod) (string, string, er if msgs := utilvalidation.IsDNS1123Subdomain(hostname); len(msgs) != 0 { return "", "", fmt.Errorf("pod HostnameOverride %q is not a valid DNS subdomain: %s", hostname, strings.Join(msgs, ";")) } - truncatedHostname, err := truncatePodHostnameIfNeeded(pod.Name, hostname) + truncatedHostname, err := truncatePodHostnameIfNeeded(logger, pod.Name, hostname) if err != nil { return "", "", err } @@ -601,7 +600,7 @@ func (kl *Kubelet) GeneratePodHostNameAndDomain(pod *v1.Pod) (string, string, er hostname = pod.Spec.Hostname } - hostname, err := truncatePodHostnameIfNeeded(pod.Name, hostname) + hostname, err := truncatePodHostnameIfNeeded(logger, pod.Name, hostname) if err != nil { return "", "", err } @@ -627,14 +626,15 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string { // GenerateRunContainerOptions generates the RunContainerOptions, which can be used by // the container runtime to set parameters for launching a container. func (kl *Kubelet) GenerateRunContainerOptions(ctx context.Context, pod *v1.Pod, container *v1.Container, podIP string, podIPs []string, imageVolumes kubecontainer.ImageVolumes) (*kubecontainer.RunContainerOptions, func(), error) { - supportsRRO := kl.runtimeClassSupportsRecursiveReadOnlyMounts(pod) + logger := klog.FromContext(ctx) + supportsRRO := kl.runtimeClassSupportsRecursiveReadOnlyMounts(logger, pod) opts, err := kl.containerManager.GetResources(ctx, pod, container) if err != nil { return nil, nil, err } // The value of hostname is the short host name and it is sent to makeMounts to create /etc/hosts file. - hostname, hostDomainName, err := kl.GeneratePodHostNameAndDomain(pod) + hostname, hostDomainName, err := kl.GeneratePodHostNameAndDomain(logger, pod) if err != nil { return nil, nil, err } @@ -643,20 +643,20 @@ func (kl *Kubelet) GenerateRunContainerOptions(ctx context.Context, pod *v1.Pod, volumes := kl.volumeManager.GetMountedVolumesForPod(podName) blkutil := volumepathhandler.NewBlockVolumePathHandler() - blkVolumes, err := kl.makeBlockVolumes(pod, container, volumes, blkutil) + blkVolumes, err := kl.makeBlockVolumes(logger, pod, container, volumes, blkutil) if err != nil { return nil, nil, err } opts.Devices = append(opts.Devices, blkVolumes...) - envs, err := kl.makeEnvironmentVariables(pod, container, podIP, podIPs, volumes) + envs, err := kl.makeEnvironmentVariables(ctx, pod, container, podIP, podIPs, volumes) if err != nil { return nil, nil, err } opts.Envs = append(opts.Envs, envs...) // only podIPs is sent to makeMounts, as podIPs is populated even if dual-stack feature flag is not enabled. - mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIPs, volumes, kl.hostutil, kl.subpather, opts.Envs, supportsRRO, imageVolumes) + mounts, cleanupAction, err := makeMounts(logger, pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIPs, volumes, kl.hostutil, kl.subpather, opts.Envs, supportsRRO, imageVolumes) if err != nil { return nil, cleanupAction, err } @@ -667,7 +667,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(ctx context.Context, pod *v1.Pod, if len(container.TerminationMessagePath) != 0 { p := kl.getPodContainerDir(pod.UID, container.Name) if err := os.MkdirAll(p, 0750); err != nil { - klog.ErrorS(err, "Error on creating dir", "path", p) + logger.Error(err, "Error on creating dir", "path", p) } else { opts.PodContainerDir = p } @@ -731,7 +731,8 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string, enableServiceLinks bool) (map[ } // Make the environment variables for a pod in the given namespace. -func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP string, podIPs []string, podVolumes kubecontainer.VolumeMap) ([]kubecontainer.EnvVar, error) { +func (kl *Kubelet) makeEnvironmentVariables(ctx context.Context, pod *v1.Pod, container *v1.Container, podIP string, podIPs []string, podVolumes kubecontainer.VolumeMap) ([]kubecontainer.EnvVar, error) { + logger := klog.FromContext(ctx) if pod.Spec.EnableServiceLinks == nil { return nil, fmt.Errorf("nil pod.spec.enableServiceLinks encountered, cannot construct envvars") } @@ -766,7 +767,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container var ( configMaps = make(map[string]*v1.ConfigMap) secrets = make(map[string]*v1.Secret) - tmpEnv = make(map[string]string) + tmpEnv = make(map[string]string) // TODO: switch to map[string][]byte ) // Env will override EnvFrom variables. @@ -798,6 +799,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container k = envFrom.Prefix + k } + // TODO: validate no NUL bytes tmpEnv[k] = v } case envFrom.SecretRef != nil: @@ -825,6 +827,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container k = envFrom.Prefix + k } + // TODO: validate no NUL bytes tmpEnv[k] = string(v) } } @@ -851,12 +854,12 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // Step 1b: resolve alternate env var sources switch { case envVar.ValueFrom.FieldRef != nil: - runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP, podIPs) + runtimeVal, err = kl.podFieldSelectorRuntimeValue(ctx, envVar.ValueFrom.FieldRef, pod, podIP, podIPs) if err != nil { return result, err } case envVar.ValueFrom.ResourceFieldRef != nil: - defaultedPod, defaultedContainer, err := kl.defaultPodLimitsForDownwardAPI(pod, container) + defaultedPod, defaultedContainer, err := kl.defaultPodLimitsForDownwardAPI(ctx, pod, container) if err != nil { return result, err } @@ -918,6 +921,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container } return result, fmt.Errorf("couldn't find key %v in Secret %v/%v", key, pod.Namespace, name) } + // TODO: validate no NUL bytes runtimeVal = string(runtimeValBytes) case utilfeature.DefaultFeatureGate.Enabled(features.EnvFiles) && envVar.ValueFrom.FileKeyRef != nil: f := envVar.ValueFrom.FileKeyRef @@ -943,7 +947,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container runtimeVal, err = envutil.ParseEnv(envFilePath, key) if err != nil { - klog.ErrorS(err, "Failed to parse env file", "pod", klog.KObj(pod)) + logger.Error(err, "Failed to parse env file", "pod", klog.KObj(pod)) return result, fmt.Errorf("couldn't parse env file") } @@ -982,7 +986,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container // podFieldSelectorRuntimeValue returns the runtime value of the given // selector for a pod. -func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string, podIPs []string) (string, error) { +func (kl *Kubelet) podFieldSelectorRuntimeValue(ctx context.Context, fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string, podIPs []string) (string, error) { internalFieldPath, _, err := podshelper.ConvertDownwardAPIFieldLabel(fs.APIVersion, fs.FieldPath, "") if err != nil { return "", err @@ -1000,13 +1004,13 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod case "spec.serviceAccountName": return pod.Spec.ServiceAccountName, nil case "status.hostIP": - hostIPs, err := kl.getHostIPsAnyWay() + hostIPs, err := kl.getHostIPsAnyWay(ctx) if err != nil { return "", err } return hostIPs[0].String(), nil case "status.hostIPs": - hostIPs, err := kl.getHostIPsAnyWay() + hostIPs, err := kl.getHostIPsAnyWay(ctx) if err != nil { return "", err } @@ -1036,13 +1040,13 @@ func containerResourceRuntimeValue(fs *v1.ResourceFieldSelector, pod *v1.Pod, co // the pod status contains the result of the last syncPod, otherwise it may fail to // terminate newly created containers and sandboxes. func (kl *Kubelet) killPod(ctx context.Context, pod *v1.Pod, p kubecontainer.Pod, gracePeriodOverride *int64) error { + logger := klog.FromContext(ctx) // Call the container runtime KillPod method which stops all known running containers of the pod if err := kl.containerRuntime.KillPod(ctx, pod, p, gracePeriodOverride); err != nil { return err } - // TODO: Pass logger from context once contextual logging migration is complete - if err := kl.containerManager.UpdateQOSCgroups(klog.TODO()); err != nil { - klog.V(2).InfoS("Failed to update QoS cgroups while killing pod", "err", err) + if err := kl.containerManager.UpdateQOSCgroups(logger); err != nil { + logger.V(2).Info("Failed to update QoS cgroups while killing pod", "err", err) } return nil } @@ -1064,7 +1068,7 @@ func (kl *Kubelet) makePodDataDirs(pod *v1.Pod) error { // getPullSecretsForPod inspects the Pod and retrieves the referenced pull // secrets. -func (kl *Kubelet) getPullSecretsForPod(pod *v1.Pod) []v1.Secret { +func (kl *Kubelet) getPullSecretsForPod(logger klog.Logger, pod *v1.Pod) []v1.Secret { pullSecrets := []v1.Secret{} failedPullSecrets := []string{} @@ -1076,7 +1080,7 @@ func (kl *Kubelet) getPullSecretsForPod(pod *v1.Pod) []v1.Secret { } secret, err := kl.secretManager.GetSecret(pod.Namespace, secretRef.Name) if err != nil { - klog.InfoS("Unable to retrieve pull secret, the image pull may not succeed.", "pod", klog.KObj(pod), "secret", klog.KObj(secret), "err", err) + logger.Info("Unable to retrieve pull secret, the image pull may not succeed.", "pod", klog.KObj(pod), "secret", klog.KObj(secret), "err", err) failedPullSecrets = append(failedPullSecrets, secretRef.Name) continue } @@ -1085,7 +1089,7 @@ func (kl *Kubelet) getPullSecretsForPod(pod *v1.Pod) []v1.Secret { } if len(failedPullSecrets) > 0 { - kl.recorder.Eventf(pod, v1.EventTypeWarning, "FailedToRetrieveImagePullSecret", "Unable to retrieve some image pull secrets (%s); attempting to pull the image may not succeed.", strings.Join(failedPullSecrets, ", ")) + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, "FailedToRetrieveImagePullSecret", "Unable to retrieve some image pull secrets (%s); attempting to pull the image may not succeed.", strings.Join(failedPullSecrets, ", ")) } return pullSecrets @@ -1125,22 +1129,31 @@ func (kl *Kubelet) PodIsFinished(pod *v1.Pod) bool { func (kl *Kubelet) filterOutInactivePods(pods []*v1.Pod) []*v1.Pod { filteredPods := make([]*v1.Pod, 0, len(pods)) for _, p := range pods { - // if a pod is fully terminated by UID, it should be excluded from the - // list of pods - if kl.podWorkers.IsPodKnownTerminated(p.UID) { + if kl.isPodInactive(p) { continue } - - // terminal pods are considered inactive UNLESS they are actively terminating - if kl.isAdmittedPodTerminal(p) && !kl.podWorkers.IsPodTerminationRequested(p.UID) { - continue - } - filteredPods = append(filteredPods, p) } return filteredPods } +// isPodInactive returns true if the pod is in a terminal phase +// or is known to be fully terminated. This method should only be used +// when the pod being processed is upstream of the pod worker, i.e. +// the pods the pod manager is aware of. +func (kl *Kubelet) isPodInactive(p *v1.Pod) bool { + // if a pod is fully terminated by UID, it should be excluded from the + // list of pods + if kl.podWorkers.IsPodKnownTerminated(p.UID) { + return true + } + // terminal pods are considered inactive UNLESS they are actively terminating + if kl.isAdmittedPodTerminal(p) && !kl.podWorkers.IsPodTerminationRequested(p.UID) { + return true + } + return false +} + // isAdmittedPodTerminal returns true if the provided config source pod is in // a terminal phase, or if the Kubelet has already indicated the pod has reached // a terminal phase but the config source has not accepted it yet. This method @@ -1165,7 +1178,7 @@ func (kl *Kubelet) isAdmittedPodTerminal(pod *v1.Pod) bool { // removeOrphanedPodStatuses removes obsolete entries in podStatus where // the pod is no longer considered bound to this node. -func (kl *Kubelet) removeOrphanedPodStatuses(pods []*v1.Pod, mirrorPods []*v1.Pod) { +func (kl *Kubelet) removeOrphanedPodStatuses(logger klog.Logger, pods []*v1.Pod, mirrorPods []*v1.Pod) { podUIDs := make(map[types.UID]bool) for _, pod := range pods { podUIDs[pod.UID] = true @@ -1173,7 +1186,7 @@ func (kl *Kubelet) removeOrphanedPodStatuses(pods []*v1.Pod, mirrorPods []*v1.Po for _, pod := range mirrorPods { podUIDs[pod.UID] = true } - kl.statusManager.RemoveOrphanedStatuses(klog.TODO(), podUIDs) + kl.statusManager.RemoveOrphanedStatuses(logger, podUIDs) } // HandlePodCleanups performs a series of cleanup work, including terminating @@ -1190,6 +1203,7 @@ func (kl *Kubelet) removeOrphanedPodStatuses(pods []*v1.Pod, mirrorPods []*v1.Po // are updated with a fixed UID (most should use a dynamic UID), and no config // updates are delivered to the pod workers while this method is running. func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { + logger := klog.FromContext(ctx) // The kubelet lacks checkpointing, so we need to introspect the set of pods // in the cgroup tree prior to inspecting the set of pods in our pod manager. // this ensures our view of the cgroup tree does not mistakenly observe pods @@ -1220,8 +1234,8 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { // These two conditions could be alleviated by checkpointing kubelet. // Stop the workers for terminated pods not in the config source - klog.V(3).InfoS("Clean up pod workers for terminated pods") - workingPods := kl.podWorkers.SyncKnownPods(allPods) + logger.V(3).Info("Clean up pod workers for terminated pods") + workingPods := kl.podWorkers.SyncKnownPods(logger, allPods) // Reconcile: At this point the pod workers have been pruned to the set of // desired pods. Pods that must be restarted due to UID reuse, or leftover @@ -1260,28 +1274,28 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { // We need the latest state to avoid delaying restarts of static pods that reuse // a UID. if err := kl.runtimeCache.ForceUpdateIfOlder(ctx, kl.clock.Now()); err != nil { - klog.ErrorS(err, "Error listing containers") + logger.Error(err, "Error listing containers") return err } runningRuntimePods, err := kl.runtimeCache.GetPods(ctx) if err != nil { - klog.ErrorS(err, "Error listing containers") + logger.Error(err, "Error listing containers") return err } // Stop probing pods that are not running - klog.V(3).InfoS("Clean up probes for terminated pods") + logger.V(3).Info("Clean up probes for terminated pods") kl.probeManager.CleanupPods(possiblyRunningPods) // Remove orphaned pod statuses not in the total list of known config pods - klog.V(3).InfoS("Clean up orphaned pod statuses") - kl.removeOrphanedPodStatuses(allPods, mirrorPods) + logger.V(3).Info("Clean up orphaned pod statuses") + kl.removeOrphanedPodStatuses(logger, allPods, mirrorPods) kl.allocationManager.RemoveOrphanedPods(allPodsByUID) // Remove orphaned pod user namespace allocations (if any). - klog.V(3).InfoS("Clean up orphaned pod user namespace allocations") + logger.V(3).Info("Clean up orphaned pod user namespace allocations") if err = kl.usernsManager.CleanupOrphanedPodUsernsAllocations(ctx, allPods, runningRuntimePods); err != nil { - klog.ErrorS(err, "Failed cleaning up orphaned pod user namespaces allocations") + logger.Error(err, "Failed cleaning up orphaned pod user namespaces allocations") } // Remove orphaned volumes from pods that are known not to have any @@ -1291,25 +1305,25 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { // TODO: this method could more aggressively cleanup terminated pods // in the future (volumes, mount dirs, logs, and containers could all be // better separated) - klog.V(3).InfoS("Clean up orphaned pod directories") - err = kl.cleanupOrphanedPodDirs(allPods, runningRuntimePods) + logger.V(3).Info("Clean up orphaned pod directories") + err = kl.cleanupOrphanedPodDirs(logger, allPods, runningRuntimePods) if err != nil { // We want all cleanup tasks to be run even if one of them failed. So // we just log an error here and continue other cleanup tasks. // This also applies to the other clean up tasks. - klog.ErrorS(err, "Failed cleaning up orphaned pod directories") + logger.Error(err, "Failed cleaning up orphaned pod directories") } // Remove any orphaned mirror pods (mirror pods are tracked by name via the // pod worker) - klog.V(3).InfoS("Clean up orphaned mirror pods") + logger.V(3).Info("Clean up orphaned mirror pods") for _, podFullname := range orphanedMirrorPodFullnames { if !kl.podWorkers.IsPodForMirrorPodTerminatingByFullName(podFullname) { _, err := kl.mirrorPodClient.DeleteMirrorPod(ctx, podFullname, nil) if err != nil { - klog.ErrorS(err, "Encountered error when deleting mirror pod", "podName", podFullname) + logger.Error(err, "Encountered error when deleting mirror pod", "podName", podFullname) } else { - klog.V(3).InfoS("Deleted mirror pod", "podName", podFullname) + logger.V(3).Info("Deleted mirror pod", "podName", podFullname) } } } @@ -1339,14 +1353,14 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { continue } - klog.V(3).InfoS("Pod will be restarted because it is in the desired set and not known to the pod workers (likely due to UID reuse)", "podUID", desiredPod.UID) + logger.V(3).Info("Pod will be restarted because it is in the desired set and not known to the pod workers (likely due to UID reuse)", "podUID", desiredPod.UID) isStatic := kubetypes.IsStaticPod(desiredPod) pod, mirrorPod, wasMirror := kl.podManager.GetPodAndMirrorPod(desiredPod) if pod == nil || wasMirror { - klog.V(2).InfoS("Programmer error, restartable pod was a mirror pod but activePods should never contain a mirror pod", "podUID", desiredPod.UID) + logger.V(2).Info("Programmer error, restartable pod was a mirror pod but activePods should never contain a mirror pod", "podUID", desiredPod.UID) continue } - kl.podWorkers.UpdatePod(UpdatePodOptions{ + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ UpdateType: kubetypes.SyncPodCreate, Pod: pod, MirrorPod: mirrorPod, @@ -1374,8 +1388,8 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { // force-deletion of such pods, yet preventing re-entry of the routine in the // next invocation of HandlePodCleanups. for _, pod := range kl.filterTerminalPodsToDelete(allPods, runningRuntimePods, workingPods) { - klog.V(3).InfoS("Handling termination and deletion of the pod to pod workers", "pod", klog.KObj(pod), "podUID", pod.UID) - kl.podWorkers.UpdatePod(UpdatePodOptions{ + logger.V(3).Info("Handling termination and deletion of the pod to pod workers", "pod", klog.KObj(pod), "podUID", pod.UID) + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ UpdateType: kubetypes.SyncPodKill, Pod: pod, }) @@ -1397,8 +1411,8 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { killPodOptions := &KillPodOptions{ PodTerminationGracePeriodSecondsOverride: &one, } - klog.V(2).InfoS("Clean up containers for orphaned pod we had not seen before", "podUID", runningPod.ID, "killPodOptions", killPodOptions) - kl.podWorkers.UpdatePod(UpdatePodOptions{ + logger.V(2).Info("Clean up containers for orphaned pod we had not seen before", "podUID", runningPod.ID, "killPodOptions", killPodOptions) + kl.podWorkers.UpdatePod(ctx, UpdatePodOptions{ UpdateType: kubetypes.SyncPodKill, RunningPod: runningPod, KillPodOptions: killPodOptions, @@ -1437,15 +1451,15 @@ func (kl *Kubelet) HandlePodCleanups(ctx context.Context) error { } if len(counts) > 0 { // in case a combination is lost - klog.V(3).InfoS("Programmer error, did not report a kubelet_working_pods metric for a value returned by SyncKnownPods", "counts", counts) + logger.V(3).Info("Programmer error, did not report a kubelet_working_pods metric for a value returned by SyncKnownPods", "counts", counts) } // Remove any cgroups in the hierarchy for pods that are definitely no longer // running (not in the container runtime). if kl.cgroupsPerQOS { pcm := kl.containerManager.NewPodContainerManager() - klog.V(3).InfoS("Clean up orphaned pod cgroups") - kl.cleanupOrphanedPodCgroups(pcm, cgroupPods, possiblyRunningPods) + logger.V(3).Info("Clean up orphaned pod cgroups") + kl.cleanupOrphanedPodCgroups(logger, pcm, cgroupPods, possiblyRunningPods) } // Cleanup any backoff entries. @@ -1636,7 +1650,7 @@ func (kl *Kubelet) GetKubeletContainerLogs(ctx context.Context, podFullName, con } // getPhase returns the phase of a pod given its container info. -func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal, podHasInitialized bool) v1.PodPhase { +func getPhase(logger klog.Logger, pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal, podHasInitialized bool) v1.PodPhase { spec := pod.Spec pendingRestartableInitContainers := 0 pendingRegularInitContainers := 0 @@ -1804,7 +1818,7 @@ func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal, podHasIniti !podHasInitialized): fallthrough case waiting > 0: - klog.V(5).InfoS("Pod waiting > 0, pending") + logger.V(5).Info("Pod waiting > 0, pending") // One or more containers has not been started return v1.PodPending case running > 0 && unknown == 0: @@ -1855,7 +1869,7 @@ func getPhase(pod *v1.Pod, info []v1.ContainerStatus, podIsTerminal, podHasIniti // and in the process of restarting return v1.PodRunning default: - klog.V(5).InfoS("Pod default case, pending") + logger.V(5).Info("Pod default case, pending") return v1.PodPending } } @@ -1874,28 +1888,29 @@ func (kl *Kubelet) determinePodResizeStatus(allocatedPod *v1.Pod, podIsTerminal // generateAPIPodStatus creates the final API pod status for a pod, given the // internal pod status. This method should only be called from within sync*Pod methods. -func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.PodStatus, podIsTerminal bool) v1.PodStatus { - klog.V(3).InfoS("Generating pod status", "podIsTerminal", podIsTerminal, "pod", klog.KObj(pod)) +func (kl *Kubelet) generateAPIPodStatus(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, podIsTerminal bool) v1.PodStatus { + logger := klog.FromContext(ctx) + logger.V(3).Info("Generating pod status", "podIsTerminal", podIsTerminal, "pod", klog.KObj(pod)) // use the previous pod status, or the api status, as the basis for this pod oldPodStatus, found := kl.statusManager.GetPodStatus(pod.UID) if !found { oldPodStatus = pod.Status } - s := kl.convertStatusToAPIStatus(pod, podStatus, oldPodStatus) + s := kl.convertStatusToAPIStatus(ctx, pod, podStatus, oldPodStatus) // calculate the next phase and preserve reason allStatus := append(append([]v1.ContainerStatus{}, s.ContainerStatuses...), s.InitContainerStatuses...) - s.Phase = getPhase(pod, allStatus, podIsTerminal, kubecontainer.HasAnyActiveRegularContainerStarted(&pod.Spec, podStatus)) - klog.V(4).InfoS("Got phase for pod", "pod", klog.KObj(pod), "oldPhase", oldPodStatus.Phase, "phase", s.Phase) + s.Phase = getPhase(logger, pod, allStatus, podIsTerminal, kubecontainer.HasAnyActiveRegularContainerStarted(&pod.Spec, podStatus)) + logger.V(4).Info("Got phase for pod", "pod", klog.KObj(pod), "oldPhase", oldPodStatus.Phase, "phase", s.Phase) // Perform a three-way merge between the statuses from the status manager, // runtime, and generated status to ensure terminal status is correctly set. if s.Phase != v1.PodFailed && s.Phase != v1.PodSucceeded { switch { case oldPodStatus.Phase == v1.PodFailed || oldPodStatus.Phase == v1.PodSucceeded: - klog.V(4).InfoS("Status manager phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", oldPodStatus.Phase) + logger.V(4).Info("Status manager phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", oldPodStatus.Phase) s.Phase = oldPodStatus.Phase case pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded: - klog.V(4).InfoS("API phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", pod.Status.Phase) + logger.V(4).Info("API phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", pod.Status.Phase) s.Phase = pod.Status.Phase } } @@ -1926,16 +1941,13 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded { // API server shows terminal phase; transitions are not allowed if s.Phase != pod.Status.Phase { - klog.ErrorS(nil, "Pod attempted illegal phase transition", "pod", klog.KObj(pod), "originalStatusPhase", pod.Status.Phase, "apiStatusPhase", s.Phase, "apiStatus", s) + logger.Error(nil, "Pod attempted illegal phase transition", "pod", klog.KObj(pod), "originalStatusPhase", pod.Status.Phase, "apiStatusPhase", s.Phase, "apiStatus", s) // Force back to phase from the API server s.Phase = pod.Status.Phase } } - // Use context.TODO() because we currently do not have a proper context to pass in. - // Replace this with an appropriate context when refactoring this function to accept a context parameter. - // ensure the probe managers have up to date status for containers - kl.probeManager.UpdatePodStatus(context.TODO(), pod, s) + kl.probeManager.UpdatePodStatus(ctx, pod, s) // update the allocated resources status if utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) { @@ -1992,13 +2004,13 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po } // set HostIP/HostIPs and initialize PodIP/PodIPs for host network pods if kl.kubeClient != nil { - hostIPs, err := kl.getHostIPsAnyWay() + hostIPs, err := kl.getHostIPsAnyWay(ctx) if err != nil { - klog.V(4).InfoS("Cannot get host IPs", "err", err) + logger.V(4).Info("Cannot get host IPs", "err", err) } else { if s.HostIP != "" { if utilnet.IPFamilyOfString(s.HostIP) != utilnet.IPFamilyOf(hostIPs[0]) { - kl.recorder.Eventf(pod, v1.EventTypeWarning, "HostIPsIPFamilyMismatch", + kl.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, "HostIPsIPFamilyMismatch", "Kubelet detected an IPv%s node IP (%s), but the cloud provider selected an IPv%s node IP (%s); pass an explicit `--node-ip` to kubelet to fix this.", utilnet.IPFamilyOfString(s.HostIP), s.HostIP, utilnet.IPFamilyOf(hostIPs[0]), hostIPs[0].String()) } @@ -2068,7 +2080,8 @@ func (kl *Kubelet) sortPodIPs(podIPs []string) []string { // convertStatusToAPIStatus initialize an api PodStatus for the given pod from // the given internal pod status and the previous state of the pod from the API. // It is purely transformative and does not alter the kubelet state at all. -func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontainer.PodStatus, oldPodStatus v1.PodStatus) *v1.PodStatus { +func (kl *Kubelet) convertStatusToAPIStatus(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, oldPodStatus v1.PodStatus) *v1.PodStatus { + logger := klog.FromContext(ctx) var apiPodStatus v1.PodStatus // copy pod status IPs to avoid race conditions with PodStatus #102806 @@ -2092,18 +2105,33 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontaine podRestarting = kubecontainer.ShouldAllContainersRestart(pod, podStatus, &oldPodStatus) } + var imageVolumeNames sets.Set[string] + if utilfeature.DefaultFeatureGate.Enabled(features.ImageVolumeWithDigest) { + imageVolumeNames = sets.New[string]() + for _, podVolume := range pod.Spec.Volumes { + if podVolume.Image == nil { + continue + } + imageVolumeNames.Insert(podVolume.Name) + } + } + apiPodStatus.ContainerStatuses = kl.convertToAPIContainerStatuses( + ctx, pod, podStatus, oldPodStatus.ContainerStatuses, pod.Spec.Containers, + imageVolumeNames, len(pod.Spec.InitContainers) > 0, false, podRestarting, ) apiPodStatus.InitContainerStatuses = kl.convertToAPIContainerStatuses( + ctx, pod, podStatus, oldPodStatus.InitContainerStatuses, pod.Spec.InitContainers, + imageVolumeNames, len(pod.Spec.InitContainers) > 0, true, podRestarting, @@ -2116,16 +2144,18 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontaine // #80875: By now we've iterated podStatus 3 times. We could refactor this to make a single // pass through podStatus.ContainerStatuses apiPodStatus.EphemeralContainerStatuses = kl.convertToAPIContainerStatuses( + ctx, pod, podStatus, oldPodStatus.EphemeralContainerStatuses, ecSpecs, + imageVolumeNames, len(pod.Spec.InitContainers) > 0, false, podRestarting, ) if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) { - apiPodStatus.Resources = kl.convertToAPIPodLevelResourcesStatus(pod, oldPodStatus) + apiPodStatus.Resources = kl.convertToAPIPodLevelResourcesStatus(logger, pod, oldPodStatus) opts := resourcehelper.PodResourcesOptions{ SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), } @@ -2136,7 +2166,7 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *v1.Pod, podStatus *kubecontaine } func getEffectiveAllocatedResources(allocatedPod *v1.Pod) *v1.ResourceRequirements { - allocatedResources := allocatedPod.Spec.Resources + allocatedResources := allocatedPod.Spec.Resources.DeepCopy() if allocatedResources == nil { allocatedResources = &v1.ResourceRequirements{} } @@ -2148,7 +2178,7 @@ func getEffectiveAllocatedResources(allocatedPod *v1.Pod) *v1.ResourceRequiremen return allocatedResources } -func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(allocatedPod *v1.Pod, oldPodStatus v1.PodStatus) *v1.ResourceRequirements { +func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(logger klog.Logger, allocatedPod *v1.Pod, oldPodStatus v1.PodStatus) *v1.ResourceRequirements { if allocatedPod.Status.Phase != v1.PodRunning { return getEffectiveAllocatedResources(allocatedPod) } @@ -2160,12 +2190,12 @@ func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(allocatedPod *v1.Pod, old pcm := kl.containerManager.NewPodContainerManager() memoryConfig, err := pcm.GetPodCgroupConfig(allocatedPod, v1.ResourceMemory) if err != nil { - klog.ErrorS(err, "failed to read memory cgroup config for the pod", "podName", allocatedPod.Name) + logger.Error(err, "failed to read memory cgroup config for the pod", "podName", allocatedPod.Name) } memoryLimit := cm.MemoryLimitsFromConfig(memoryConfig) cpuConfig, err := pcm.GetPodCgroupConfig(allocatedPod, v1.ResourceCPU) if err != nil { - klog.ErrorS(err, "failed to read memory cgroup limits for the pod", "podName", allocatedPod.Name) + logger.Error(err, "failed to read memory cgroup limits for the pod", "podName", allocatedPod.Name) } @@ -2214,7 +2244,9 @@ func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(allocatedPod *v1.Pod, old SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), } aggregatedResources := resourcehelper.PodRequests(allocatedPod, opts) - resources.Requests[v1.ResourceMemory] = aggregatedResources[v1.ResourceMemory] + if val, ok := aggregatedResources[v1.ResourceMemory]; ok { + resources.Requests[v1.ResourceMemory] = val + } } // TODO: Once we begin persisting memory Request from the PodSpec to cgroups, @@ -2244,10 +2276,8 @@ func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(allocatedPod *v1.Pod, old // convertToAPIContainerStatuses converts the given internal container // statuses into API container statuses. -func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecontainer.PodStatus, previousStatus []v1.ContainerStatus, containers []v1.Container, hasInitContainers, isInitContainer, podRestarting bool) []v1.ContainerStatus { - // Use klog.TODO() because we currently do not have a proper logger to pass in. - // This should be replaced with an appropriate logger when refactoring this function to accept a logger parameter. - logger := klog.TODO() +func (kl *Kubelet) convertToAPIContainerStatuses(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, previousStatus []v1.ContainerStatus, containers []v1.Container, imageVolumeNames sets.Set[string], hasInitContainers, isInitContainer bool, podRestarting bool) []v1.ContainerStatus { + logger := klog.FromContext(ctx) convertContainerStatus := func(cs *kubecontainer.Status, oldStatus *v1.ContainerStatus) *v1.ContainerStatus { cid := cs.ID.String() status := &v1.ContainerStatus{ @@ -2266,8 +2296,55 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon if oldStatus.RestartCount > status.RestartCount { status.RestartCount = oldStatus.RestartCount } + // Normal container restarts preserve the old container in the runtime so kubelet + // can query its termination status. RestartAllContainers removes old containers, + // so we must manually propagate LastTerminationState when the container ID changes. + if oldStatus.ContainerID != status.ContainerID && oldStatus.State.Terminated != nil { + status.LastTerminationState.Terminated = oldStatus.State.Terminated + } else if oldStatus.LastTerminationState.Terminated != nil { + status.LastTerminationState.Terminated = oldStatus.LastTerminationState.Terminated + } } } + if utilfeature.DefaultFeatureGate.Enabled(features.ImageVolumeWithDigest) && imageVolumeNames.Len() > 0 { + for i := range status.VolumeMounts { + volumeName := status.VolumeMounts[i].Name + if !imageVolumeNames.Has(volumeName) { + continue + } + + var imageSpec kubecontainer.ImageSpec + for _, curVolumeMount := range cs.Mounts { + if curVolumeMount.Image == nil || curVolumeMount.Name != volumeName { + continue + } + imageSpec = kuberuntime.ToKubeContainerImageSpec(&runtimeapi.Image{ + Id: curVolumeMount.Image.Image, + Spec: curVolumeMount.Image, + }) + break + } + + if imageSpec.Image == "" { + logger.Error(fmt.Errorf("image was not found"), "", "pod", pod.Name, "container", cs.Name, "volume", volumeName) + continue + } + + imageRef, err := kl.containerRuntime.GetImageRef(ctx, imageSpec) + if err != nil { + logger.Error(err, "error getting image volume digest", "volume", volumeName) + continue + } + if status.VolumeMounts[i].VolumeStatus == nil { + status.VolumeMounts[i].VolumeStatus = &v1.VolumeStatus{} + } + if status.VolumeMounts[i].VolumeStatus.Image == nil { + status.VolumeMounts[i].VolumeStatus.Image = &v1.ImageVolumeStatus{} + } + status.VolumeMounts[i].VolumeStatus.Image.ImageRef = imageRef + } + } + switch { case cs.State == kubecontainer.ContainerStateRunning: status.State.Running = &v1.ContainerStateRunning{StartedAt: metav1.NewTime(cs.StartedAt)} @@ -2424,7 +2501,7 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon defaultWaitingState = v1.ContainerState{Waiting: &v1.ContainerStateWaiting{Reason: PodInitializing}} } - supportsRRO := kl.runtimeClassSupportsRecursiveReadOnlyMounts(pod) + supportsRRO := kl.runtimeClassSupportsRecursiveReadOnlyMounts(logger, pod) for _, container := range containers { status := &v1.ContainerStatus{ @@ -2444,12 +2521,12 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon if vol.ReadOnly { rroMode := v1.RecursiveReadOnlyDisabled if b, err := resolveRecursiveReadOnly(vol, supportsRRO); err != nil { - klog.ErrorS(err, "failed to resolve recursive read-only mode", "mode", *vol.RecursiveReadOnly) + logger.Error(err, "failed to resolve recursive read-only mode", "mode", *vol.RecursiveReadOnly) } else if b { if utilfeature.DefaultFeatureGate.Enabled(features.RecursiveReadOnlyMounts) { rroMode = v1.RecursiveReadOnlyEnabled } else { - klog.ErrorS(nil, "recursive read-only mount needs feature gate to be enabled", + logger.Error(nil, "recursive read-only mount needs feature gate to be enabled", "featureGate", features.RecursiveReadOnlyMounts) } } @@ -2620,6 +2697,31 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *v1.Pod, podStatus *kubecon if s != nil && s.State == kubecontainer.ContainerStateExited && s.ExitCode == 0 { continue } + // When pod status is not persisted, init container status may be lost. + // This can occur in the following scenarios: + // 1. Static pods + // 2. Regular pods where init container status failed to sync to the API server + // (e.g., due to control plane issues, though this is rare) + // + // In these cases, if the init container has already been removed from the runtime, + // kubelet cannot determine its status. However, we can infer that non-restartable + // init containers have completed successfully if regular containers have been created. + // Note: Restartable init containers (sidecars) should remain in waiting state and + // will be restarted by the kubelet. + isSidecar := container.RestartPolicy != nil && *container.RestartPolicy == v1.ContainerRestartPolicyAlways + if s == nil && + kuberuntime.HasAnyRegularContainerCreated(pod, podStatus) && + !isSidecar && + statuses[container.Name].State.Waiting != nil { + statuses[container.Name].State = v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Reason: "Completed", + Message: "Unable to get init container status from container runtime and pod has been initialized, treat it as exited normally", + ExitCode: 0, + }, + } + continue + } } // If a container should be restarted in next syncpod, it is *Waiting*. if !kubecontainer.ShouldContainerBeRestarted(logger, &container, pod, podStatus) { @@ -2753,7 +2855,7 @@ func (kl *Kubelet) GetPortForward(ctx context.Context, podName, podNamespace str // cleanupOrphanedPodCgroups removes cgroups that should no longer exist. // it reconciles the cached state of cgroupPods with the specified list of runningPods -func (kl *Kubelet) cleanupOrphanedPodCgroups(pcm cm.PodContainerManager, cgroupPods map[types.UID]cm.CgroupName, possiblyRunningPods map[types.UID]sets.Empty) { +func (kl *Kubelet) cleanupOrphanedPodCgroups(logger klog.Logger, pcm cm.PodContainerManager, cgroupPods map[types.UID]cm.CgroupName, possiblyRunningPods map[types.UID]sets.Empty) { // Iterate over all the found pods to verify if they should be running for uid, val := range cgroupPods { // if the pod is in the running set, its not a candidate for cleanup @@ -2765,45 +2867,43 @@ func (kl *Kubelet) cleanupOrphanedPodCgroups(pcm cm.PodContainerManager, cgroupP // so any memory backed volumes don't have their charges propagated to the // parent croup. If the volumes still exist, reduce the cpu shares for any // process in the cgroup to the minimum value while we wait. - if podVolumesExist := kl.podVolumesExist(uid); podVolumesExist { - klog.V(3).InfoS("Orphaned pod found, but volumes not yet removed. Reducing cpu to minimum", "podUID", uid) - // TODO: Pass logger from context once contextual logging migration is complete - if err := pcm.ReduceCPULimits(klog.TODO(), val); err != nil { - klog.InfoS("Failed to reduce cpu time for pod pending volume cleanup", "podUID", uid, "err", err) + if podVolumesExist := kl.podVolumesExist(logger, uid); podVolumesExist { + logger.V(3).Info("Orphaned pod found, but volumes not yet removed. Reducing cpu to minimum", "podUID", uid) + if err := pcm.ReduceCPULimits(logger, val); err != nil { + logger.Info("Failed to reduce cpu time for pod pending volume cleanup", "podUID", uid, "err", err) } continue } - klog.V(3).InfoS("Orphaned pod found, removing pod cgroups", "podUID", uid) + logger.V(3).Info("Orphaned pod found, removing pod cgroups", "podUID", uid) // Destroy all cgroups of pods that should not be running, // by first killing all the attached processes in these cgroups. // The error return value of Destroy is explicitly checked and logged, // but errors are tolerated since the housekeeping loop loop would // again try to delete these unwanted pod cgroups. - // TODO: Pass logger from context once contextual logging migration is complete go func() { - if err := pcm.Destroy(klog.TODO(), val); err != nil { - klog.InfoS("Failed to destroy orphaned pod cgroup", "podUID", uid, "err", err) + if err := pcm.Destroy(logger, val); err != nil { + logger.Info("Failed to destroy orphaned pod cgroup", "podUID", uid, "err", err) } }() } } -func (kl *Kubelet) runtimeClassSupportsRecursiveReadOnlyMounts(pod *v1.Pod) bool { +func (kl *Kubelet) runtimeClassSupportsRecursiveReadOnlyMounts(logger klog.Logger, pod *v1.Pod) bool { if kl.runtimeClassManager == nil { return false } runtimeHandlerName, err := kl.runtimeClassManager.LookupRuntimeHandler(pod.Spec.RuntimeClassName) if err != nil { - klog.ErrorS(err, "failed to look up the runtime handler", "runtimeClassName", pod.Spec.RuntimeClassName) + logger.Error(err, "failed to look up the runtime handler", "runtimeClassName", pod.Spec.RuntimeClassName) return false } runtimeHandlers := kl.runtimeState.runtimeHandlers() - return runtimeHandlerSupportsRecursiveReadOnlyMounts(runtimeHandlerName, runtimeHandlers) + return runtimeHandlerSupportsRecursiveReadOnlyMounts(logger, runtimeHandlerName, runtimeHandlers) } // runtimeHandlerSupportsRecursiveReadOnlyMounts checks whether the runtime handler supports recursive read-only mounts. // The kubelet feature gate is not checked here. -func runtimeHandlerSupportsRecursiveReadOnlyMounts(runtimeHandlerName string, runtimeHandlers []kubecontainer.RuntimeHandler) bool { +func runtimeHandlerSupportsRecursiveReadOnlyMounts(logger klog.Logger, runtimeHandlerName string, runtimeHandlers []kubecontainer.RuntimeHandler) bool { if len(runtimeHandlers) == 0 { // The runtime does not support returning the handler list. // No need to print a warning here. @@ -2814,7 +2914,7 @@ func runtimeHandlerSupportsRecursiveReadOnlyMounts(runtimeHandlerName string, ru return h.SupportsRecursiveReadOnlyMounts } } - klog.ErrorS(nil, "Unknown runtime handler", "runtimeHandlerName", runtimeHandlerName) + logger.Error(nil, "Unknown runtime handler", "runtimeHandlerName", runtimeHandlerName) return false } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_resources.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_resources.go index 0a7a1ad105..462cbd9965 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_resources.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_resources.go @@ -17,6 +17,7 @@ limitations under the License. package kubelet import ( + "context" "fmt" "k8s.io/klog/v2" @@ -35,12 +36,12 @@ import ( // If a container has no limits specified, it defaults to the pod-level resources. // If neither container-level nor pod-level resources limits are specified, it defaults // to the node's allocatable resources. -func (kl *Kubelet) defaultPodLimitsForDownwardAPI(pod *corev1.Pod, container *corev1.Container) (*corev1.Pod, *corev1.Container, error) { +func (kl *Kubelet) defaultPodLimitsForDownwardAPI(ctx context.Context, pod *corev1.Pod, container *corev1.Container) (*corev1.Pod, *corev1.Container, error) { if pod == nil { return nil, nil, fmt.Errorf("invalid input, pod cannot be nil") } - node, err := kl.getNodeAnyWay() + node, err := kl.getNodeAnyWay(ctx) if err != nil { return nil, nil, fmt.Errorf("failed to find node object, expected a node") } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_server_journal.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_server_journal.go index cecc6529a9..6e2ea27d21 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_server_journal.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_server_journal.go @@ -501,7 +501,7 @@ func heuristicsCopyFileLog(ctx context.Context, w io.Writer, logDir, logFileName func safeServiceName(s string) error { // Max length of a service name is 256 across supported OSes if len(s) > maxServiceLength { - return fmt.Errorf("length must be less than 100") + return fmt.Errorf("length must be less than %d", maxServiceLength) } if reServiceNameUnsafeCharacters.MatchString(s) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go index 40320dcdf5..199dcb28e3 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go @@ -75,20 +75,20 @@ func (kl *Kubelet) ListBlockVolumesForPod(podUID types.UID) (map[string]volume.B // podVolumesExist checks with the volume manager and returns true any of the // pods for the specified volume are mounted or are uncertain. -func (kl *Kubelet) podVolumesExist(podUID types.UID) bool { +func (kl *Kubelet) podVolumesExist(logger klog.Logger, podUID types.UID) bool { if kl.volumeManager.HasPossiblyMountedVolumesForPod(volumetypes.UniquePodName(podUID)) { return true } // TODO: This checks pod volume paths and whether they are mounted. If checking returns error, podVolumesExist will return true // which means we consider volumes might exist and requires further checking. // There are some volume plugins such as flexvolume might not have mounts. See issue #61229 - volumePaths, err := kl.getMountedVolumePathListFromDisk(podUID) + volumePaths, err := kl.getMountedVolumePathListFromDisk(logger, podUID) if err != nil { - klog.ErrorS(err, "Pod found, but error occurred during checking mounted volumes from disk", "podUID", podUID) + logger.Error(err, "Pod found, but error occurred during checking mounted volumes from disk", "podUID", podUID) return true } if len(volumePaths) > 0 { - klog.V(4).InfoS("Pod found, but volumes are still mounted on disk", "podUID", podUID, "paths", volumePaths) + logger.V(4).Info("Pod found, but volumes are still mounted on disk", "podUID", podUID, "paths", volumePaths) return true } @@ -116,11 +116,11 @@ func (kl *Kubelet) newVolumeMounterFromPlugins(spec *volume.Spec, pod *v1.Pod) ( // when this is called, so it effectively does a recursive rmdir instead of // RemoveAll to ensure it only removes empty directories and files that were // used as mount points, but not content of the mount points. -func (kl *Kubelet) removeOrphanedPodVolumeDirs(uid types.UID) []error { +func (kl *Kubelet) removeOrphanedPodVolumeDirs(logger klog.Logger, uid types.UID) []error { orphanVolumeErrors := []error{} // If there are still volume directories, attempt to rmdir them - volumePaths, err := kl.getPodVolumePathListFromDisk(uid) + volumePaths, err := kl.getPodVolumePathListFromDisk(logger, uid) if err != nil { orphanVolumeErrors = append(orphanVolumeErrors, fmt.Errorf("orphaned pod %q found, but error occurred during reading volume dir from disk: %v", uid, err)) return orphanVolumeErrors @@ -136,7 +136,7 @@ func (kl *Kubelet) removeOrphanedPodVolumeDirs(uid types.UID) []error { } // If there are any volume-subpaths, attempt to remove them - subpathVolumePaths, err := kl.getPodVolumeSubpathListFromDisk(uid) + subpathVolumePaths, err := kl.getPodVolumeSubpathListFromDisk(logger, uid) if err != nil { orphanVolumeErrors = append(orphanVolumeErrors, fmt.Errorf("orphaned pod %q found, but error occurred during reading of volume-subpaths dir from disk: %v", uid, err)) return orphanVolumeErrors @@ -145,7 +145,7 @@ func (kl *Kubelet) removeOrphanedPodVolumeDirs(uid types.UID) []error { for _, subpathVolumePath := range subpathVolumePaths { // Remove both files and empty directories here, as the subpath may have been a bind-mount of a file or a directory. if err := os.Remove(subpathVolumePath); err != nil { - orphanVolumeErrors = append(orphanVolumeErrors, fmt.Errorf("orphaned pod %q found, but failed to rmdir() subpath at path %v: %v", uid, subpathVolumePath, err)) + orphanVolumeErrors = append(orphanVolumeErrors, fmt.Errorf("orphaned pod %q found, but failed to remove subpath at path %v: %w", uid, subpathVolumePath, err)) } else { klog.InfoS("Cleaned up orphaned volume subpath from pod", "podUID", uid, "path", subpathVolumePath) } @@ -166,7 +166,7 @@ func (kl *Kubelet) removeOrphanedPodVolumeDirs(uid types.UID) []error { // cleanupOrphanedPodDirs removes the volumes of pods that should not be // running and that have no containers running. Note that we roll up logs here since it runs in the main loop. -func (kl *Kubelet) cleanupOrphanedPodDirs(pods []*v1.Pod, runningPods []*kubecontainer.Pod) error { +func (kl *Kubelet) cleanupOrphanedPodDirs(logger klog.Logger, pods []*v1.Pod, runningPods []*kubecontainer.Pod) error { allPods := sets.New[string]() for _, pod := range pods { allPods.Insert(string(pod.UID)) @@ -195,14 +195,14 @@ func (kl *Kubelet) cleanupOrphanedPodDirs(pods []*v1.Pod, runningPods []*kubecon // Doing so may result in corruption of data. // TODO: getMountedVolumePathListFromDisk() call may be redundant with // kl.getPodVolumePathListFromDisk(). Can this be cleaned up? - if podVolumesExist := kl.podVolumesExist(uid); podVolumesExist { + if podVolumesExist := kl.podVolumesExist(logger, uid); podVolumesExist { errorPods++ - klog.V(3).InfoS("Orphaned pod found, but volumes are not cleaned up", "podUID", uid) + logger.V(3).Info("Orphaned pod found, but volumes are not cleaned up", "podUID", uid) continue } - // Attempt to remove the pod volumes directory and its subdirs - podVolumeErrors := kl.removeOrphanedPodVolumeDirs(uid) + // Attempt to remove the pod volumes directory and its subdirectories + podVolumeErrors := kl.removeOrphanedPodVolumeDirs(logger, uid) if len(podVolumeErrors) > 0 { errorPods++ orphanVolumeErrors = append(orphanVolumeErrors, podVolumeErrors...) @@ -214,7 +214,7 @@ func (kl *Kubelet) cleanupOrphanedPodDirs(pods []*v1.Pod, runningPods []*kubecon continue } - // Call RemoveAllOneFilesystem for remaining subdirs under the pod directory + // Call RemoveAllOneFilesystem for remaining subdirectories under the pod directory podDir := kl.getPodDir(uid) podSubdirs, err := os.ReadDir(podDir) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubeletconfig/defaults.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubeletconfig/defaults.go index 7f4577ab15..953df29198 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubeletconfig/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubeletconfig/defaults.go @@ -27,6 +27,7 @@ const ( DefaultKubeletContainersDirName = "containers" DefaultKubeletPluginContainersDirName = "plugin-containers" DefaultKubeletPodResourcesDirName = "pod-resources" + DefaultKubeletPodsAPIDirName = "pods-api" KubeletPluginsDirSELinuxLabel = "system_u:object_r:container_file_t:s0" KubeletContainersSharedSELinuxLabel = "system_u:object_r:container_file_t:s0" DefaultKubeletCheckpointsDirName = "checkpoints" diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/convert.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/convert.go index e64c6bada7..7e6ff5673b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/convert.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/convert.go @@ -27,7 +27,7 @@ import ( // This file contains help function to kuberuntime types to CRI runtime API types, or vice versa. -func toKubeContainerImageSpec(image *runtimeapi.Image) kubecontainer.ImageSpec { +func ToKubeContainerImageSpec(image *runtimeapi.Image) kubecontainer.ImageSpec { var annotations []kubecontainer.Annotation if image.Spec != nil && len(image.Spec.Annotations) > 0 { @@ -60,7 +60,7 @@ func toKubeContainerImageSpec(image *runtimeapi.Image) kubecontainer.ImageSpec { return spec } -func toRuntimeAPIImageSpec(imageSpec kubecontainer.ImageSpec) *runtimeapi.ImageSpec { +func ToRuntimeAPIImageSpec(imageSpec kubecontainer.ImageSpec) *runtimeapi.ImageSpec { var annotations = make(map[string]string) if imageSpec.Annotations != nil { for _, a := range imageSpec.Annotations { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go index dad8c88c4d..8b21bb0949 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go @@ -97,10 +97,6 @@ func (f *fakePodPullingTimeRecorder) RecordImageFinishedPulling(podUID types.UID func newFakeKubeRuntimeManager(ctx context.Context, runtimeService internalapi.RuntimeService, imageService internalapi.ImageManagerService, machineInfo *cadvisorapi.MachineInfo, osInterface kubecontainer.OSInterface, runtimeHelper kubecontainer.RuntimeHelper, tracer trace.Tracer) (*kubeGenericRuntimeManager, error) { recorder := &record.FakeRecorder{} - logManager, err := logs.NewContainerLogManager(runtimeService, osInterface, "1", 2, 10, metav1.Duration{Duration: 10 * time.Second}) - if err != nil { - return nil, err - } kubeRuntimeManager := &kubeGenericRuntimeManager{ recorder: recorder, cpuCFSQuota: false, @@ -116,7 +112,7 @@ func newFakeKubeRuntimeManager(ctx context.Context, runtimeService internalapi.R seccompProfileRoot: fakeSeccompProfileRoot, internalLifecycle: cm.NewFakeInternalContainerLifecycle(), logReduction: logreduction.NewLogReduction(identicalErrorDelay), - logManager: logManager, + logManager: logs.NewStubContainerLogManager(), memoryThrottlingFactor: 0.9, podLogsDirectory: fakePodLogsDirectory, actuatedState: state.NewStateMemory(nil), diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers.go index 97eb705595..ad4fb4367a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers.go @@ -36,26 +36,28 @@ import ( "k8s.io/kubernetes/pkg/security/apparmor" ) -type podsByID []*kubecontainer.Pod +type containerByCreatedThenID []*runtimeapi.Container -func (b podsByID) Len() int { return len(b) } -func (b podsByID) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b podsByID) Less(i, j int) bool { return b[i].ID < b[j].ID } - -type containersByID []*kubecontainer.Container - -func (b containersByID) Len() int { return len(b) } -func (b containersByID) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b containersByID) Less(i, j int) bool { return b[i].ID.ID < b[j].ID.ID } +func (b containerByCreatedThenID) Len() int { return len(b) } +func (b containerByCreatedThenID) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b containerByCreatedThenID) Less(i, j int) bool { + if b[i].CreatedAt != b[j].CreatedAt { + return b[i].CreatedAt > (b[j].CreatedAt) + } + return b[i].Id < b[j].Id +} // Newest first. -type podSandboxByCreated []*runtimeapi.PodSandbox - -func (p podSandboxByCreated) Len() int { return len(p) } -func (p podSandboxByCreated) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p podSandboxByCreated) Less(i, j int) bool { - if p[i].Metadata == nil || p[j].Metadata == nil { - return p[i].CreatedAt > p[j].CreatedAt +type podSandboxByCreatedThenID []*runtimeapi.PodSandbox + +func (p podSandboxByCreatedThenID) Len() int { return len(p) } +func (p podSandboxByCreatedThenID) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p podSandboxByCreatedThenID) Less(i, j int) bool { + if p[i].Metadata == nil || p[j].Metadata == nil || (p[i].Metadata.Attempt == p[j].Metadata.Attempt) { + if p[i].CreatedAt != p[j].CreatedAt { + return p[i].CreatedAt > p[j].CreatedAt + } + return p[i].Id < p[j].Id } return p[i].Metadata.Attempt > p[j].Metadata.Attempt } @@ -119,6 +121,8 @@ func (m *kubeGenericRuntimeManager) toKubeContainer(ctx context.Context, c *runt Image: c.Image.Image, Hash: annotatedInfo.Hash, State: toKubeContainerState(c.State), + PodSandboxID: c.PodSandboxId, + CreatedAt: c.CreatedAt, }, nil } @@ -132,8 +136,10 @@ func (m *kubeGenericRuntimeManager) sandboxToKubeContainer(s *runtimeapi.PodSand } return &kubecontainer.Container{ - ID: kubecontainer.ContainerID{Type: m.runtimeName, ID: s.Id}, - State: kubecontainer.SandboxToContainerState(s.State), + ID: kubecontainer.ContainerID{Type: m.runtimeName, ID: s.Id}, + State: kubecontainer.SandboxToContainerState(s.State), + PodSandboxID: s.Id, + CreatedAt: s.CreatedAt, }, nil } @@ -255,7 +261,8 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus, handlers []*runtimeap var retFeatures *kubecontainer.RuntimeFeatures if features != nil { retFeatures = &kubecontainer.RuntimeFeatures{ - SupplementalGroupsPolicy: features.SupplementalGroupsPolicy, + SupplementalGroupsPolicy: features.SupplementalGroupsPolicy, + UserNamespacesHostNetwork: features.UserNamespacesHostNetwork, } } return &kubecontainer.RuntimeStatus{Conditions: conditions, Handlers: retHandlers, Features: retFeatures} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_linux.go index a3b1ab2c30..9de005cdbf 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. @@ -20,29 +19,10 @@ limitations under the License. package kuberuntime import ( - "math" - v1 "k8s.io/api/core/v1" "k8s.io/kubernetes/pkg/kubelet/cm" ) -// sharesToMilliCPU converts CpuShares (cpu.shares) to milli-CPU value -func sharesToMilliCPU(shares int64) int64 { - milliCPU := int64(0) - if shares >= int64(cm.MinShares) { - milliCPU = int64(math.Ceil(float64(shares*cm.MilliCPUToCPU) / float64(cm.SharesPerCPU))) - } - return milliCPU -} - -// quotaToMilliCPU converts cpu.cfs_quota_us and cpu.cfs_period_us to milli-CPU value -func quotaToMilliCPU(quota int64, period int64) int64 { - if quota == -1 { - return int64(0) - } - return (quota * cm.MilliCPUToCPU) / period -} - func subtractOverheadFromResourceConfig(resCfg *cm.ResourceConfig, pod *v1.Pod) *cm.ResourceConfig { if resCfg == nil { return nil @@ -59,7 +39,7 @@ func subtractOverheadFromResourceConfig(resCfg *cm.ResourceConfig, pod *v1.Pod) } if rc.CPUShares != nil { - totalCPUMilli := sharesToMilliCPU(int64(*rc.CPUShares)) + totalCPUMilli := cm.SharesToMilliCPU(int64(*rc.CPUShares)) cpuShares := cm.MilliCPUToShares(totalCPUMilli - cpu.MilliValue()) rc.CPUShares = &cpuShares } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_unsupported.go index 95693fadda..b94aa78e9f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/helpers_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/instrumented_services.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/instrumented_services.go index 52896d59b1..8b17a03421 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/instrumented_services.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/instrumented_services.go @@ -181,7 +181,7 @@ func (in instrumentedRuntimeService) RunPodSandbox(ctx context.Context, config * const operation = "run_podsandbox" startTime := time.Now() defer recordOperation(operation, startTime) - defer metrics.RunPodSandboxDuration.WithLabelValues(runtimeHandler).Observe(metrics.SinceInSeconds(startTime)) + defer metrics.RunPodSandboxDuration.ObserveSince(startTime, runtimeHandler)() out, err := in.service.RunPodSandbox(ctx, config, runtimeHandler) recordError(operation, err) @@ -335,11 +335,11 @@ func (in instrumentedImageManagerService) ImageFsInfo(ctx context.Context) (*run return fsInfo, nil } -func (in instrumentedImageManagerService) Close() error { +func (in instrumentedImageManagerService) Close(ctx context.Context) error { const operation = "close" defer recordOperation(operation, time.Now()) - err := in.service.Close() + err := in.service.Close(ctx) recordError(operation, err) return err } @@ -389,11 +389,11 @@ func (in instrumentedRuntimeService) RuntimeConfig(ctx context.Context) (*runtim return out, err } -func (in instrumentedRuntimeService) Close() error { +func (in instrumentedRuntimeService) Close(ctx context.Context) error { const operation = "close" defer recordOperation(operation, time.Now()) - err := in.service.Close() + err := in.service.Close(ctx) recordError(operation, err) return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go index 88b34a14ea..39d178a900 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -34,14 +34,12 @@ import ( "time" codes "google.golang.org/grpc/codes" + crierror "k8s.io/cri-api/pkg/errors" "github.com/opencontainers/selinux/go-selinux" grpcstatus "google.golang.org/grpc/status" - "github.com/armon/circbuf" - "k8s.io/klog/v2" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubetypes "k8s.io/apimachinery/pkg/types" @@ -50,6 +48,7 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" remote "k8s.io/cri-client/pkg" + "k8s.io/klog/v2" kubelettypes "k8s.io/kubelet/pkg/types" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/features" @@ -63,6 +62,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/pkg/util/tail" volumeutil "k8s.io/kubernetes/pkg/volume/util" + "k8s.io/utils/buffer" ) var ( @@ -100,7 +100,7 @@ func (m *kubeGenericRuntimeManager) recordContainerEvent(ctx context.Context, po if containerID != "" { eventMessage = strings.Replace(eventMessage, containerID, container.Name, -1) } - m.recorder.Event(ref, eventType, reason, eventMessage) + m.recorder.WithLogger(logger).Event(ref, eventType, reason, eventMessage) } // startSpec wraps the spec required to start a container, either a regular/init container @@ -400,7 +400,7 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(ctx context.Context, e := opts.Envs[idx] envs[idx] = &runtimeapi.KeyValue{ Key: e.Name, - Value: e.Value, + Value: []byte(e.Value), } } config.Envs = envs @@ -438,7 +438,12 @@ func (m *kubeGenericRuntimeManager) updatePodSandboxResources(ctx context.Contex _, err := m.runtimeService.UpdatePodSandboxResources(ctx, podResourcesRequest) if err != nil { stat, _ := grpcstatus.FromError(err) - if stat.Code() == codes.Unimplemented { + // Containerd 2.2 returns an error with code 'Unknown' and message 'not implemented yet' instead of + // an error with code 'Unimplemented'. + // This is being fixed in https://github.com/containerd/containerd/pull/13023, so this hardcoded + // string check can be removed once containerd 2.2 is no longer supported. + const unimplementedMsg = "not implemented" + if stat.Code() == codes.Unimplemented || (stat.Code() == codes.Unknown && strings.Contains(stat.Message(), unimplementedMsg)) { logger.V(3).Info("updatePodSandboxResources failed: unimplemented; this call is best-effort: proceeding with resize", "sandboxID", sandboxID) return nil } @@ -535,27 +540,6 @@ func (m *kubeGenericRuntimeManager) makeMounts(opts *kubecontainer.RunContainerO return volumeMounts } -// getKubeletContainers lists containers managed by kubelet. -// The boolean parameter specifies whether returns all containers including -// those already exited and dead containers (used for garbage collection). -func (m *kubeGenericRuntimeManager) getKubeletContainers(ctx context.Context, allContainers bool) ([]*runtimeapi.Container, error) { - logger := klog.FromContext(ctx) - filter := &runtimeapi.ContainerFilter{} - if !allContainers { - filter.State = &runtimeapi.ContainerStateValue{ - State: runtimeapi.ContainerState_CONTAINER_RUNNING, - } - } - - containers, err := m.runtimeService.ListContainers(ctx, filter) - if err != nil { - logger.Error(err, "ListContainers failed") - return nil, err - } - - return containers, nil -} - // makeUID returns a randomly generated string. func makeUID() string { return fmt.Sprintf("%08x", rand.Uint32()) @@ -590,11 +574,11 @@ func getTerminationMessage(status *runtimeapi.ContainerStatus, terminationMessag // by path. It reads up to max log lines. func (m *kubeGenericRuntimeManager) readLastStringFromContainerLogs(ctx context.Context, path string) string { value := int64(kubecontainer.MaxContainerTerminationMessageLogLines) - buf, _ := circbuf.NewBuffer(kubecontainer.MaxContainerTerminationMessageLogLength) + buf, _ := buffer.NewTypedRingFixed[byte](kubecontainer.MaxContainerTerminationMessageLogLength) if err := m.ReadLogs(ctx, path, "", &v1.PodLogOptions{TailLines: &value}, buf, buf); err != nil { return fmt.Sprintf("Error on reading termination message from logs: %v", err) } - return buf.String() + return string(buf.Slice()) } func (m *kubeGenericRuntimeManager) convertToKubeContainerStatus(ctx context.Context, podUID kubetypes.UID, status *runtimeapi.ContainerStatus) (cStatus *kubecontainer.Status) { @@ -620,25 +604,60 @@ func (m *kubeGenericRuntimeManager) convertToKubeContainerStatus(ctx context.Con return cStatus } +type listOptions struct { + // podUID of the pod to filter to. + // Optional. + podUID kubetypes.UID + // onlyRunningReady filters the results to only ready sandboxes or running containers. + // Optional. + onlyRunningReady bool +} + +func (o *listOptions) containerFilter() *runtimeapi.ContainerFilter { + filter := &runtimeapi.ContainerFilter{} + if o.podUID != "" { + filter.LabelSelector = map[string]string{kubelettypes.KubernetesPodUIDLabel: string(o.podUID)} + } + if o.onlyRunningReady { + filter.State = &runtimeapi.ContainerStateValue{ + State: runtimeapi.ContainerState_CONTAINER_RUNNING, + } + } + return filter +} + +func (o *listOptions) sandboxFilter() *runtimeapi.PodSandboxFilter { + filter := &runtimeapi.PodSandboxFilter{} + if o.podUID != "" { + filter.LabelSelector = map[string]string{kubelettypes.KubernetesPodUIDLabel: string(o.podUID)} + } + if o.onlyRunningReady { + filter.State = &runtimeapi.PodSandboxStateValue{ + State: runtimeapi.PodSandboxState_SANDBOX_READY, + } + } + return filter +} + +func (m *kubeGenericRuntimeManager) getContainers(ctx context.Context, opts listOptions) ([]*runtimeapi.Container, error) { + return m.runtimeService.ListContainers(ctx, opts.containerFilter()) +} + +func (m *kubeGenericRuntimeManager) getSandboxes(ctx context.Context, opts listOptions) ([]*runtimeapi.PodSandbox, error) { + return m.runtimeService.ListPodSandbox(ctx, opts.sandboxFilter()) +} + // getPodContainerStatuses gets all containers' statuses for the pod. -func (m *kubeGenericRuntimeManager) getPodContainerStatuses(ctx context.Context, uid kubetypes.UID, name, namespace, activePodSandboxID string) ([]*kubecontainer.Status, []*kubecontainer.Status, error) { +func (m *kubeGenericRuntimeManager) getPodContainerStatuses(ctx context.Context, pod *kubecontainer.Pod, activePodSandboxID string) ([]*kubecontainer.Status, []*kubecontainer.Status, error) { logger := klog.FromContext(ctx) - // Select all containers of the given pod. - containers, err := m.runtimeService.ListContainers(ctx, &runtimeapi.ContainerFilter{ - LabelSelector: map[string]string{kubelettypes.KubernetesPodUIDLabel: string(uid)}, - }) - if err != nil { - logger.Error(err, "ListContainers error") - return nil, nil, err - } isManagedPod := managed.IsManagedPodFromRuntimeService(ctx, m.runtimeService, activePodSandboxID) statuses := []*kubecontainer.Status{} activeContainerStatuses := []*kubecontainer.Status{} // TODO: optimization: set maximum number of containers per container name to examine. - for _, c := range containers { - resp, err := m.runtimeService.ContainerStatus(ctx, c.Id, false) + for _, c := range pod.Containers { + resp, err := m.runtimeService.ContainerStatus(ctx, c.ID.ID, false) // Between List (ListContainers) and check (ContainerStatus) another thread might remove a container, and that is normal. // The previous call (ListContainers) never fails due to a pod container not existing. // Therefore, this method should not either, but instead act as if the previous call failed, @@ -648,19 +667,19 @@ func (m *kubeGenericRuntimeManager) getPodContainerStatuses(ctx context.Context, } if err != nil { // Merely log this here; GetPodStatus will actually report the error out. - logger.V(4).Info("ContainerStatus return error", "containerID", c.Id, "err", err) + logger.V(4).Info("ContainerStatus return error", "containerID", c.ID.ID, "err", err) return nil, nil, err } status := resp.GetStatus() if status == nil { return nil, nil, remote.ErrContainerStatusNil } - cStatus := m.convertToKubeContainerStatus(ctx, uid, status) + cStatus := m.convertToKubeContainerStatus(ctx, pod.ID, status) if isManagedPod && cStatus.Resources != nil { // Clear CPU resources for managed pods (workload-pinned) cStatus.Resources.CPURequest, cStatus.Resources.CPULimit = nil, nil } statuses = append(statuses, cStatus) - if c.PodSandboxId == activePodSandboxID { + if c.PodSandboxID == activePodSandboxID { activeContainerStatuses = append(activeContainerStatuses, cStatus) } } @@ -773,7 +792,7 @@ func (m *kubeGenericRuntimeManager) executePreStopHook(ctx context.Context, pod done := make(chan struct{}) go func() { defer close(done) - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) if _, err := m.runner.Run(ctx, containerID, pod, containerSpec, containerSpec.Lifecycle.PreStop); err != nil { logger.Error(err, "PreStop hook failed", "pod", klog.KObj(pod), "podUID", pod.UID, "containerName", containerSpec.Name, "containerID", containerID.String()) @@ -929,7 +948,7 @@ func (m *kubeGenericRuntimeManager) killContainersWithSyncResult(ctx context.Con } for _, container := range runningPod.Containers { go func(container *kubecontainer.Container) { - defer utilruntime.HandleCrash() + defer utilruntime.HandleCrashWithContext(ctx) defer wg.Done() killContainerResult := kubecontainer.NewSyncResult(kubecontainer.KillContainer, container.Name) @@ -981,7 +1000,7 @@ func (m *kubeGenericRuntimeManager) pruneInitContainersBeforeStart(ctx context.C } // prune all other init containers that match this container name logger.V(4).Info("Removing init container", "containerName", status.Name, "containerID", status.ID.ID, "count", count) - if err := m.removeContainer(ctx, status.ID.ID); err != nil { + if err := m.removeContainer(ctx, status.ID.ID, false); err != nil { utilruntime.HandleError(fmt.Errorf("failed to remove pod init container %q: %v; Skipping pod %q", status.Name, err, format.Pod(pod))) continue } @@ -1007,7 +1026,7 @@ func (m *kubeGenericRuntimeManager) purgeInitContainers(ctx context.Context, pod count++ // Purge all init containers that match this container name logger.V(4).Info("Removing init container", "containerName", status.Name, "containerID", status.ID.ID, "count", count) - if err := m.removeContainer(ctx, status.ID.ID); err != nil { + if err := m.removeContainer(ctx, status.ID.ID, false); err != nil { utilruntime.HandleError(fmt.Errorf("failed to remove pod init container %q: %v; Skipping pod %q", status.Name, err, format.Pod(pod))) continue } @@ -1015,9 +1034,9 @@ func (m *kubeGenericRuntimeManager) purgeInitContainers(ctx context.Context, pod } } -// hasAnyRegularContainerCreated returns true if any regular container has been +// HasAnyRegularContainerCreated returns true if any regular container has been // created, which indicates all init containers have been initialized. -func hasAnyRegularContainerCreated(pod *v1.Pod, podStatus *kubecontainer.PodStatus) bool { +func HasAnyRegularContainerCreated(pod *v1.Pod, podStatus *kubecontainer.PodStatus) bool { for _, container := range pod.Spec.Containers { status := podStatus.FindContainerStatusByName(container.Name) if status == nil { @@ -1127,6 +1146,10 @@ func (m *kubeGenericRuntimeManager) computeInitContainerActions(ctx context.Cont case kubecontainer.ContainerStateRunning: if !podutil.IsRestartableInitContainer(container) { + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScalingInitContainers) { + // computePodResizeAction updates 'changes' if resize policy requires restarting this container + _ = m.computePodResizeAction(ctx, pod, i, true, status, changes) + } break } else { // If container is restartable if container.StartupProbe != nil { @@ -1354,13 +1377,14 @@ func (m *kubeGenericRuntimeManager) RunInContainer(ctx context.Context, id kubec return append(stdout, stderr...), err } -// removeContainer removes the container and the container logs. +// removeContainer removes the container and optionally the container logs. // Notice that we remove the container logs first, so that container will not be removed if // container logs are failed to be removed, and kubelet will retry this later. This guarantees -// that container logs to be removed with the container. +// that container logs to be removed with the container if specified. // Notice that we assume that the container should only be removed in non-running state, and // it will not write container logs anymore in that state. -func (m *kubeGenericRuntimeManager) removeContainer(ctx context.Context, containerID string) error { +// If the logs are kept, they will be preserved until the pod is removed and kubelet GC is triggered. +func (m *kubeGenericRuntimeManager) removeContainer(ctx context.Context, containerID string, keepLogs bool) error { logger := klog.FromContext(ctx) logger.V(4).Info("Removing container", "containerID", containerID) // Call internal container post-stop lifecycle hook. @@ -1370,8 +1394,10 @@ func (m *kubeGenericRuntimeManager) removeContainer(ctx context.Context, contain // Remove the container log. // TODO: Separate log and container lifecycle management. - if err := m.removeContainerLog(ctx, containerID); err != nil { - return err + if !keepLogs { + if err := m.removeContainerLog(ctx, containerID); err != nil { + return err + } } // Remove the container. return m.runtimeService.RemoveContainer(ctx, containerID) @@ -1407,7 +1433,7 @@ func (m *kubeGenericRuntimeManager) removeContainerLog(ctx context.Context, cont // DeleteContainer removes a container. func (m *kubeGenericRuntimeManager) DeleteContainer(ctx context.Context, containerID kubecontainer.ContainerID) error { - return m.removeContainer(ctx, containerID.ID) + return m.removeContainer(ctx, containerID.ID, false) } // setTerminationGracePeriod determines the grace period to use when killing a container diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go index 3a09289b4c..b103e840fd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. @@ -43,6 +42,7 @@ import ( v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" kubeapiqos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" kubefeatures "k8s.io/kubernetes/pkg/features" + kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/qos" @@ -79,7 +79,7 @@ func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(ctx con // generateLinuxContainerConfig generates linux container config for kubelet runtime v1. func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(ctx context.Context, container *v1.Container, pod *v1.Pod, uid *int64, username string, nsTarget *kubecontainer.ContainerID, enforceMemoryQoS bool) (*runtimeapi.LinuxContainerConfig, error) { - sc, err := m.determineEffectiveSecurityContext(pod, container, uid, username) + sc, err := m.determineEffectiveSecurityContext(ctx, pod, container, uid, username) if err != nil { return nil, err } @@ -155,8 +155,17 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerResources(ctx context. unified := map[string]string{} memoryRequest := container.Resources.Requests.Memory().Value() memoryLimit := container.Resources.Limits.Memory().Value() - if memoryRequest != 0 { - unified[cm.Cgroup2MemoryMin] = strconv.FormatInt(memoryRequest, 10) + if memoryRequest != 0 && m.memoryReservationPolicy == kubeletconfiginternal.TieredReservationMemoryReservationPolicy { + // Guaranteed pods get memory.min (hard protection). + // Burstable pods get memory.low (soft protection). + if kubeapiqos.GetPodQOS(pod) == v1.PodQOSGuaranteed { + unified[cm.Cgroup2MemoryMin] = strconv.FormatInt(memoryRequest, 10) + } else { + unified[cm.Cgroup2MemoryLow] = strconv.FormatInt(memoryRequest, 10) + } + } else { + unified[cm.Cgroup2MemoryMin] = "0" + unified[cm.Cgroup2MemoryLow] = "0" } // Guaranteed pods by their QoS definition requires that memory request equals memory limit and cpu request must equal cpu limit. @@ -387,13 +396,13 @@ func toKubeContainerResources(statusResources *runtimeapi.ContainerResources) *k if runtimeStatusResources != nil { var cpuLimit, memLimit, cpuRequest *resource.Quantity if runtimeStatusResources.CpuPeriod > 0 { - milliCPU := quotaToMilliCPU(runtimeStatusResources.CpuQuota, runtimeStatusResources.CpuPeriod) + milliCPU := cm.QuotaToMilliCPU(runtimeStatusResources.CpuQuota, runtimeStatusResources.CpuPeriod) if milliCPU > 0 { cpuLimit = resource.NewMilliQuantity(milliCPU, resource.DecimalSI) } } if runtimeStatusResources.CpuShares > 0 { - milliCPU := sharesToMilliCPU(runtimeStatusResources.CpuShares) + milliCPU := cm.SharesToMilliCPU(runtimeStatusResources.CpuShares) if milliCPU > 0 { cpuRequest = resource.NewMilliQuantity(milliCPU, resource.DecimalSI) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go index 2d38841101..9b4bb31a51 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go index b58fdb7a35..05ae4afd60 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_gc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_gc.go index 2691f64d5c..0bfb961eee 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_gc.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_gc.go @@ -147,7 +147,7 @@ func (cgc *containerGC) removeOldestN(ctx context.Context, containers []containe continue } } - if err := cgc.manager.removeContainer(ctx, containers[i].id); err != nil { + if err := cgc.manager.removeContainer(ctx, containers[i].id, false); err != nil { logger.Error(err, "Failed to remove container", "containerID", containers[i].id) } } @@ -190,7 +190,7 @@ func (cgc *containerGC) removeSandbox(ctx context.Context, sandboxID string) { // evictableContainers gets all containers that are evictable. Evictable containers are: not running // and created more than MinAge ago. func (cgc *containerGC) evictableContainers(ctx context.Context, minAge time.Duration) (containersByEvictUnit, error) { - containers, err := cgc.manager.getKubeletContainers(ctx, true) + containers, err := cgc.manager.getContainers(ctx, listOptions{}) if err != nil { return containersByEvictUnit{}, err } @@ -279,12 +279,12 @@ func (cgc *containerGC) evictContainers(ctx context.Context, gcPolicy kubecontai // 3. belong to a non-existent (i.e., already removed) pod, or is not the // most recently created sandbox for the pod. func (cgc *containerGC) evictSandboxes(ctx context.Context, evictNonDeletedPods bool) error { - containers, err := cgc.manager.getKubeletContainers(ctx, true) + containers, err := cgc.manager.getContainers(ctx, listOptions{}) if err != nil { return err } - sandboxes, err := cgc.manager.getKubeletSandboxes(ctx, true) + sandboxes, err := cgc.manager.getSandboxes(ctx, listOptions{}) if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_image.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_image.go index 3d9b94cc50..2eecc2eee6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_image.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_image.go @@ -33,7 +33,7 @@ import ( func (m *kubeGenericRuntimeManager) PullImage(ctx context.Context, image kubecontainer.ImageSpec, credentials []crededentialprovider.TrackedAuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, *crededentialprovider.TrackedAuthConfig, error) { logger := klog.FromContext(ctx) img := image.Image - imgSpec := toRuntimeAPIImageSpec(image) + imgSpec := ToRuntimeAPIImageSpec(image) if len(credentials) == 0 { logger.V(3).Info("Pulling image without credentials", "image", img) @@ -74,7 +74,7 @@ func (m *kubeGenericRuntimeManager) PullImage(ctx context.Context, image kubecon // the local storage. It returns ("", nil) if the image isn't in the local storage. func (m *kubeGenericRuntimeManager) GetImageRef(ctx context.Context, image kubecontainer.ImageSpec) (string, error) { logger := klog.FromContext(ctx) - resp, err := m.imageService.ImageStatus(ctx, toRuntimeAPIImageSpec(image), false) + resp, err := m.imageService.ImageStatus(ctx, ToRuntimeAPIImageSpec(image), false) if err != nil { logger.Error(err, "Failed to get image status", "image", image.Image) return "", err @@ -87,7 +87,7 @@ func (m *kubeGenericRuntimeManager) GetImageRef(ctx context.Context, image kubec func (m *kubeGenericRuntimeManager) GetImageSize(ctx context.Context, image kubecontainer.ImageSpec) (uint64, error) { logger := klog.FromContext(ctx) - resp, err := m.imageService.ImageStatus(ctx, toRuntimeAPIImageSpec(image), false) + resp, err := m.imageService.ImageStatus(ctx, ToRuntimeAPIImageSpec(image), false) if err != nil { logger.Error(err, "Failed to get image status", "image", image.Image) return 0, err @@ -126,7 +126,7 @@ func (m *kubeGenericRuntimeManager) ListImages(ctx context.Context) ([]kubeconta Size: int64(img.Size), RepoTags: img.RepoTags, RepoDigests: img.RepoDigests, - Spec: toKubeContainerImageSpec(img), + Spec: ToKubeContainerImageSpec(img), Pinned: img.Pinned, }) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_logs.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_logs.go index 73d26df5c5..3123e6bc4b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_logs.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_logs.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/cri-client/pkg/logs" - "k8s.io/klog/v2" ) // ReadLogs read the container log and redirect into stdout and stderr. @@ -31,7 +30,19 @@ import ( // just pass in empty string "". func (m *kubeGenericRuntimeManager) ReadLogs(ctx context.Context, path, containerID string, apiOpts *v1.PodLogOptions, stdout, stderr io.Writer) error { // Convert v1.PodLogOptions into internal log options. - opts := logs.NewLogOptions(apiOpts, time.Now()) - logger := klog.FromContext(ctx) - return logs.ReadLogs(ctx, &logger, path, containerID, opts, m.runtimeService, stdout, stderr) + now := time.Now() + opts := &logs.LogOptions{ + TailLines: apiOpts.TailLines, + LimitBytes: apiOpts.LimitBytes, + Follow: apiOpts.Follow, + Timestamp: apiOpts.Timestamps, + } + if apiOpts.SinceSeconds != nil { + opts.Since = now.Add(-time.Duration(*apiOpts.SinceSeconds) * time.Second) + } + if apiOpts.SinceTime != nil && apiOpts.SinceTime.After(opts.Since) { + opts.Since = apiOpts.SinceTime.Time + } + + return logs.ReadLogs(ctx, path, containerID, opts, m.runtimeService, stdout, stderr) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go index 818ca633a1..faee7e9338 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -106,9 +106,14 @@ type podStateProvider interface { ShouldPodRuntimeBeRemoved(kubetypes.UID) bool } +type PodInitContainerTimeRecorder interface { + RecordInitContainerStarted(podUID kubetypes.UID, startedAt time.Time) + RecordInitContainerFinished(podUID kubetypes.UID, finishedAt time.Time) +} + type kubeGenericRuntimeManager struct { runtimeName string - recorder record.EventRecorder + recorder record.EventRecorderLogger osInterface kubecontainer.OSInterface // machineInfo contains the machine information. @@ -184,6 +189,8 @@ type kubeGenericRuntimeManager struct { // Memory throttling factor for MemoryQoS memoryThrottlingFactor float64 + // Memory reservation policy for MemoryQoS memory.min behavior + memoryReservationPolicy kubeletconfiginternal.MemoryReservationPolicy // Root directory used to store pod logs podLogsDirectory string @@ -191,6 +198,9 @@ type kubeGenericRuntimeManager struct { // Swap controller availability check function (Linux only) // Uses sync.OnceValue for lazy initialization getSwapControllerAvailable func() bool + + // Records first initContainer start time and last initContainer finish time + podInitContainerTimeRecorder PodInitContainerTimeRecorder } // KubeGenericRuntime is a interface contains interfaces for container runtime and command. @@ -203,7 +213,7 @@ type KubeGenericRuntime interface { // NewKubeGenericRuntimeManager creates a new kubeGenericRuntimeManager func NewKubeGenericRuntimeManager( ctx context.Context, - recorder record.EventRecorder, + recorder record.EventRecorderLogger, livenessManager proberesults.Manager, readinessManager proberesults.Manager, startupManager proberesults.Manager, @@ -236,10 +246,12 @@ func NewKubeGenericRuntimeManager( memorySwapBehavior string, getNodeAllocatable func() v1.ResourceList, memoryThrottlingFactor float64, + memoryReservationPolicy kubeletconfiginternal.MemoryReservationPolicy, podPullingTimeRecorder images.ImagePodPullingTimeRecorder, tracerProvider trace.TracerProvider, tokenManager *token.Manager, getServiceAccount plugin.GetServiceAccountFunc, + podInitContainerTimeRecorder PodInitContainerTimeRecorder, ) (KubeGenericRuntime, []images.PostImageGCHook, error) { logger := klog.FromContext(ctx) @@ -247,29 +259,31 @@ func NewKubeGenericRuntimeManager( imageService = newInstrumentedImageManagerService(imageService) tracer := tracerProvider.Tracer(instrumentationScope) kubeRuntimeManager := &kubeGenericRuntimeManager{ - recorder: recorder, - singleProcessOOMKill: singleProcessOOMKill, - cpuCFSQuota: cpuCFSQuota, - cpuCFSQuotaPeriod: cpuCFSQuotaPeriod, - seccompProfileRoot: filepath.Join(rootDirectory, "seccomp"), - livenessManager: livenessManager, - readinessManager: readinessManager, - startupManager: startupManager, - machineInfo: machineInfo, - osInterface: osInterface, - runtimeHelper: runtimeHelper, - runtimeService: runtimeService, - imageService: imageService, - containerManager: containerManager, - internalLifecycle: containerManager.InternalContainerLifecycle(), - logManager: logManager, - runtimeClassManager: runtimeClassManager, - logReduction: logreduction.NewLogReduction(identicalErrorDelay), - seccompDefault: seccompDefault, - memorySwapBehavior: memorySwapBehavior, - getNodeAllocatable: getNodeAllocatable, - memoryThrottlingFactor: memoryThrottlingFactor, - podLogsDirectory: podLogsDirectory, + recorder: recorder, + singleProcessOOMKill: singleProcessOOMKill, + cpuCFSQuota: cpuCFSQuota, + cpuCFSQuotaPeriod: cpuCFSQuotaPeriod, + seccompProfileRoot: filepath.Join(rootDirectory, "seccomp"), + livenessManager: livenessManager, + readinessManager: readinessManager, + startupManager: startupManager, + machineInfo: machineInfo, + osInterface: osInterface, + runtimeHelper: runtimeHelper, + runtimeService: runtimeService, + imageService: imageService, + containerManager: containerManager, + internalLifecycle: containerManager.InternalContainerLifecycle(), + logManager: logManager, + runtimeClassManager: runtimeClassManager, + logReduction: logreduction.NewLogReduction(identicalErrorDelay), + seccompDefault: seccompDefault, + memorySwapBehavior: memorySwapBehavior, + getNodeAllocatable: getNodeAllocatable, + memoryThrottlingFactor: memoryThrottlingFactor, + memoryReservationPolicy: memoryReservationPolicy, + podLogsDirectory: podLogsDirectory, + podInitContainerTimeRecorder: podInitContainerTimeRecorder, } // Initialize swap controller availability check with lazy evaluation @@ -314,7 +328,7 @@ func NewKubeGenericRuntimeManager( return nil, nil, err } - fsRecordAccessor, err := imagepullmanager.NewFSPullRecordsAccessor(rootDirectory) + fsRecordAccessor, err := imagepullmanager.NewFSPullRecordsAccessor(logger, rootDirectory) if err != nil { return nil, nil, fmt.Errorf("failed to setup the FSPullRecordsAccessor: %w", err) } @@ -325,7 +339,7 @@ func NewKubeGenericRuntimeManager( pullRecordsCacheSize = 5 * maxPods ) - memCacheRecordsAccessor := imagepullmanager.NewCachedPullRecordsAccessor(fsRecordAccessor, intentCacheSize, pullRecordsCacheSize, maxParallelPulls) + memCacheRecordsAccessor := imagepullmanager.NewCachedPullRecordsAccessor(logger, fsRecordAccessor, intentCacheSize, pullRecordsCacheSize, maxParallelPulls) imagePullManager, err = imagepullmanager.NewImagePullManager(ctx, memCacheRecordsAccessor, imagePullCredentialsVerificationPolicy, kubeRuntimeManager, maxParallelPulls) if err != nil { @@ -422,16 +436,58 @@ func (m *kubeGenericRuntimeManager) Status(ctx context.Context) (*kubecontainer. return toKubeRuntimeStatus(resp.GetStatus(), resp.GetRuntimeHandlers(), resp.GetFeatures()), nil } +// GetPod fetches the current sandboxes & containers for a pod. +func (m *kubeGenericRuntimeManager) GetPod(ctx context.Context, podUID kubetypes.UID) (*kubecontainer.Pod, error) { + pods, err := m.getPods(ctx, listOptions{podUID: podUID}) + if err != nil { + return nil, err + } + + pod := pods[podUID] + if pod == nil { + return nil, kubecontainer.ErrPodNotFound + } + return pod, nil +} + // GetPods returns a list of containers grouped by pods. The boolean parameter // specifies whether the runtime returns all containers including those already // exited and dead containers (used for garbage collection). func (m *kubeGenericRuntimeManager) GetPods(ctx context.Context, all bool) ([]*kubecontainer.Pod, error) { + logger := klog.FromContext(ctx) + pods, err := m.getPods(ctx, listOptions{onlyRunningReady: !all}) + if err != nil { + return nil, err + } + + // Convert map to list. + var result []*kubecontainer.Pod + for _, pod := range pods { + result = append(result, pod) + } + + // There are scenarios where multiple pods are running in parallel having + // the same name, because one of them have not been fully terminated yet. + // To avoid unexpected behavior on container name based search (for example + // by calling *Kubelet.findContainer() without specifying a pod ID), we now + // return the list of pods ordered by their creation time. + sort.SliceStable(result, func(i, j int) bool { + return result[i].CreatedAt > result[j].CreatedAt + }) + logger.V(4).Info("Retrieved pods from runtime", "all", all) + return result, nil +} + +func (m *kubeGenericRuntimeManager) getPods(ctx context.Context, opts listOptions) (map[kubetypes.UID]*kubecontainer.Pod, error) { logger := klog.FromContext(ctx) pods := make(map[kubetypes.UID]*kubecontainer.Pod) - sandboxes, err := m.getKubeletSandboxes(ctx, all) + timestamp := time.Now() + sandboxes, err := m.getSandboxes(ctx, opts) if err != nil { return nil, err } + // Sort sandboxes by creation time, newest first. + sort.Sort(podSandboxByCreatedThenID(sandboxes)) for i := range sandboxes { s := sandboxes[i] if s.Metadata == nil { @@ -444,6 +500,7 @@ func (m *kubeGenericRuntimeManager) GetPods(ctx context.Context, all bool) ([]*k ID: podUID, Name: s.Metadata.Name, Namespace: s.Metadata.Namespace, + Timestamp: timestamp, } } p := pods[podUID] @@ -456,10 +513,17 @@ func (m *kubeGenericRuntimeManager) GetPods(ctx context.Context, all bool) ([]*k p.CreatedAt = uint64(s.GetCreatedAt()) } - containers, err := m.getKubeletContainers(ctx, all) + containers, err := m.getContainers(ctx, opts) if err != nil { return nil, err } + // Sort containers: newest CreatedAt first, then by container ID for stability. + // There are scenarios where multiple pods are running in parallel having + // the same name, because one of them have not been fully terminated yet. + // To avoid unexpected behavior on container name based search (for example + // by calling *Kubelet.findContainer() without specifying a pod ID), we + // return the list of pods ordered by their creation time. + sort.Sort(containerByCreatedThenID(containers)) for i := range containers { c := containers[i] if c.Metadata == nil { @@ -474,6 +538,7 @@ func (m *kubeGenericRuntimeManager) GetPods(ctx context.Context, all bool) ([]*k ID: labelledInfo.PodUID, Name: labelledInfo.PodName, Namespace: labelledInfo.PodNamespace, + Timestamp: timestamp, } pods[labelledInfo.PodUID] = pod } @@ -487,22 +552,7 @@ func (m *kubeGenericRuntimeManager) GetPods(ctx context.Context, all bool) ([]*k pod.Containers = append(pod.Containers, converted) } - // Convert map to list. - var result []*kubecontainer.Pod - for _, pod := range pods { - result = append(result, pod) - } - - // There are scenarios where multiple pods are running in parallel having - // the same name, because one of them have not been fully terminated yet. - // To avoid unexpected behavior on container name based search (for example - // by calling *Kubelet.findContainer() without specifying a pod ID), we now - // return the list of pods ordered by their creation time. - sort.SliceStable(result, func(i, j int) bool { - return result[i].CreatedAt > result[j].CreatedAt - }) - logger.V(4).Info("Retrieved pods from runtime", "all", all) - return result, nil + return pods, nil } // containerKillReason explains what killed a given container @@ -529,14 +579,6 @@ type containerToKillInfo struct { reason containerKillReason } -// containerResources holds the set of resources applicable to the running container -type containerResources struct { - memoryLimit int64 - memoryRequest int64 - cpuLimit int64 - cpuRequest int64 -} - // containerToUpdateInfo contains necessary information to update a container's resources. type containerToUpdateInfo struct { // The spec of the container. @@ -544,9 +586,9 @@ type containerToUpdateInfo struct { // ID of the runtime container that needs resource update kubeContainerID kubecontainer.ContainerID // Desired resources for the running container - desiredContainerResources containerResources + desiredContainerResources resourceRequirements // Most recently configured resources on the running container - currentContainerResources *containerResources + currentContainerResources *resourceRequirements } // containerToRemoveInfo contains necessary information to update a container's resources. @@ -599,8 +641,9 @@ type podActions struct { UpdatePodLevelResources bool } -// podLevelResources holds the set of resources applicable to the running pod -type podLevelResources struct { +// resourceRequirements summarizes the set of resources applicable to the +// running pod or container in kuberuntime context. +type resourceRequirements struct { memoryLimit int64 memoryRequest int64 cpuLimit int64 @@ -634,8 +677,8 @@ func containerSucceeded(c *v1.Container, podStatus *kubecontainer.PodStatus) boo return cStatus.State == kubecontainer.ContainerStateExited && cStatus.ExitCode == 0 } -func containerResourcesFromRequirements(podRequirements, containerRequirements *v1.ResourceRequirements) containerResources { - resources := containerResources{ +func containerResourcesFromRequirements(podRequirements, containerRequirements *v1.ResourceRequirements) resourceRequirements { + resources := resourceRequirements{ memoryLimit: containerRequirements.Limits.Memory().Value(), memoryRequest: containerRequirements.Requests.Memory().Value(), cpuLimit: containerRequirements.Limits.Cpu().MilliValue(), @@ -652,12 +695,12 @@ func containerResourcesFromRequirements(podRequirements, containerRequirements * return resources } -func podResourcesFromRequirements(requirements *v1.ResourceRequirements) podLevelResources { +func podResourcesFromRequirements(requirements *v1.ResourceRequirements) resourceRequirements { if requirements == nil { - return podLevelResources{} + return resourceRequirements{} } - return podLevelResources{ + return resourceRequirements{ memoryLimit: requirements.Limits.Memory().Value(), memoryRequest: requirements.Requests.Memory().Value(), cpuLimit: requirements.Limits.Cpu().MilliValue(), @@ -668,14 +711,14 @@ func podResourcesFromRequirements(requirements *v1.ResourceRequirements) podLeve // computePodResizeAction determines the actions required (if any) to resize the given container. // Returns whether to keep (true) or restart (false) the container. // TODO(vibansal): Make this function to be agnostic to whether it is dealing with a restartable init container or not (i.e. remove the argument `isRestartableInitContainer`). -func (m *kubeGenericRuntimeManager) computePodResizeAction(ctx context.Context, pod *v1.Pod, containerIdx int, isRestartableInitContainer bool, kubeContainerStatus *kubecontainer.Status, changes *podActions) (keepContainer bool) { +func (m *kubeGenericRuntimeManager) computePodResizeAction(ctx context.Context, pod *v1.Pod, containerIdx int, initContainer bool, kubeContainerStatus *kubecontainer.Status, changes *podActions) (keepContainer bool) { logger := klog.FromContext(ctx) if resizable, _, _ := allocation.IsInPlacePodVerticalScalingAllowed(pod); !resizable { return true } var container v1.Container - if isRestartableInitContainer { + if initContainer { container = pod.Spec.InitContainers[containerIdx] } else { container = pod.Spec.Containers[containerIdx] @@ -750,7 +793,9 @@ func (m *kubeGenericRuntimeManager) computePodResizeAction(ctx context.Context, container: &container, message: fmt.Sprintf("Container %s resize requires restart", container.Name), } - if isRestartableInitContainer { + if initContainer { + // Validation prevents non-restartable init containers from being marked for restart, + // so we know this init container is restartable. changes.InitContainersToStart = append(changes.InitContainersToStart, containerIdx) } else { changes.ContainersToStart = append(changes.ContainersToStart, containerIdx) @@ -788,7 +833,7 @@ func (m *kubeGenericRuntimeManager) doPodResizeAction(ctx context.Context, pod * enforceCPULimits = false logger.V(2).Info("Disabled CFS quota", "pod", klog.KObj(pod)) } - podResources := cm.ResourceConfigForPod(pod, enforceCPULimits, uint64((m.cpuCFSQuotaPeriod.Duration)/time.Microsecond), false) + podResources := cm.ResourceConfigForPod(pod, enforceCPULimits, uint64((m.cpuCFSQuotaPeriod.Duration)/time.Microsecond), false, kubeletconfiginternal.NoneMemoryReservationPolicy) if podResources == nil { logger.Error(nil, "Unable to get resource configuration", "pod", klog.KObj(pod)) resizeResult.Fail(kubecontainer.ErrResizePodInPlace, fmt.Sprintf("unable to get resource configuration processing resize for pod %q", format.Pod(pod))) @@ -888,23 +933,26 @@ func (m *kubeGenericRuntimeManager) doPodResizeAction(ctx context.Context, pod * } resizedResources.Memory = podResources.Memory } + + // Notify the runtime first. If this fails, the runtime has rejected the resize. + mergedPodResources := mergeResourceConfig(currentPodResources, resizedResources) + if err = m.updatePodSandboxResources(ctx, podContainerChanges.SandboxID, pod, mergedPodResources); err != nil { + return fmt.Errorf("failed to notify runtime for UpdatePodSandboxResources (resource=%s); resize rejected: %w", rName, err) + } + + // Actuate the pod-level cgroup change. err = pcm.SetPodCgroupConfig(logger, pod, resizedResources) if err != nil { logger.Error(err, "Failed to set cgroup config", "resource", rName, "pod", klog.KObj(pod)) + // If cgroup adjustment fails, notify the runtime to revert to the previous resources. + if rollbackErr := m.updatePodSandboxResources(ctx, podContainerChanges.SandboxID, pod, currentPodResources); rollbackErr != nil { + logger.Error(rollbackErr, "Failed to notify runtime to rollback UpdatePodSandboxResources", "resource", rName, "pod", klog.KObj(pod)) + } return err } - currentPodResources = mergeResourceConfig(currentPodResources, resizedResources) - if err = m.updatePodSandboxResources(ctx, podContainerChanges.SandboxID, pod, currentPodResources); err != nil { - logger.Error(err, "Failed to notify runtime for UpdatePodSandboxResources", "resource", rName, "pod", klog.KObj(pod)) - // Don't propagate the error since the updatePodSandboxResources call is best-effort. - } - - if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) { - if err = updateActuatedPodLevelResources(rName); err != nil { - logger.Error(err, "Failed to update pod-level actuated resources", "resource", rName, "pod", klog.KObj(pod)) - } - } + // Update our tracking of the current state. + currentPodResources = mergedPodResources return nil } @@ -933,6 +981,7 @@ func (m *kubeGenericRuntimeManager) doPodResizeAction(ctx context.Context, pod * return err } } + // At downsizing, requests should shrink prior to limits in order to keep "requests <= limits". if newPodCgReqValue < currPodCgReqValue { // TODO: Pass logger from context once contextual logging migration is complete @@ -946,12 +995,18 @@ func (m *kubeGenericRuntimeManager) doPodResizeAction(ctx context.Context, pod * return err } } + + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) && podContainerChanges.UpdatePodLevelResources { + if err = updateActuatedPodLevelResources(rName); err != nil { + logger.Error(err, "Failed to update pod-level actuated resources", "resource", rName, "pod", klog.KObj(pod)) + } + } return err } // Always update the pod status once. Even if there was a resize error, the resize may have been // partially actuated. - defer m.runtimeHelper.SetPodWatchCondition(pod.UID, "doPodResizeAction", func(*kubecontainer.PodStatus) bool { return true }) + defer m.runtimeHelper.RequestPodReinspect(pod.UID) if len(podContainerChanges.ContainersToUpdate[v1.ResourceMemory]) > 0 || podContainerChanges.UpdatePodResources || podContainerChanges.UpdatePodLevelResources { if podResources.Memory == nil { @@ -1188,7 +1243,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(ctx context.Context, pod * // If there is any regular container, it means all init containers have // been initialized. - hasInitialized = hasAnyRegularContainerCreated(pod, podStatus) + hasInitialized = HasAnyRegularContainerCreated(pod, podStatus) if hasInitialized { changes.CreateSandbox = false @@ -1387,10 +1442,11 @@ func (m *kubeGenericRuntimeManager) computePodLevelResourcesResizeAction(ctx con // 2. Kill pod sandbox if necessary. // 3. Kill any containers that should not be running. // 4. Create sandbox if necessary. -// 5. Create ephemeral containers. -// 6. Create init containers. -// 7. Resize running containers (if InPlacePodVerticalScaling==true) -// 8. Create normal containers. +// 5. Invoke OnPodSandboxReady to notify Kubelet to update pod status. +// 6. Create ephemeral containers. +// 7. Create init containers. +// 8. Resize running containers (if InPlacePodVerticalScaling==true) +// 9. Create normal containers. func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff, restartAllContainers bool) (result kubecontainer.PodSyncResult) { logger := klog.FromContext(ctx) // Step 1: Compute sandbox and container changes. @@ -1402,7 +1458,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po logger.Error(err, "Couldn't make a ref to pod", "pod", klog.KObj(pod)) } if podContainerChanges.SandboxID != "" { - m.recorder.Eventf(ref, v1.EventTypeNormal, events.SandboxChanged, "Pod sandbox changed, it will be killed and re-created.") + m.recorder.WithLogger(logger).Eventf(ref, v1.EventTypeNormal, events.SandboxChanged, "Pod sandbox changed, it will be killed and re-created.") } else { logger.V(4).Info("SyncPod received new pod, will create a sandbox for it", "pod", klog.KObj(pod)) } @@ -1456,8 +1512,8 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po return } } - // TODO(yuanwang04): Revisit whether container logs should be persisted. - if err := m.removeContainer(ctx, containerInfo.containerID.ID); err != nil { + // The logs of removed containers will be preserved until the pod is deleted and GC is triggered. + if err := m.removeContainer(ctx, containerInfo.containerID.ID, true); err != nil { removeContainerResult.Fail(kubecontainer.ErrRemoveContainer, err.Error()) logger.Error(err, "removeContainer for pod failed", "containerName", cName, "containerID", containerInfo.containerID, "pod", klog.KObj(pod)) return @@ -1534,7 +1590,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po logger.Error(referr, "Couldn't make a ref to pod", "pod", klog.KObj(pod)) return } - m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedPrepareDynamicResources, "Failed to prepare dynamic resources: %v", err) + m.recorder.WithLogger(logger).Eventf(ref, v1.EventTypeWarning, events.FailedPrepareDynamicResources, "Failed to prepare dynamic resources: %v", err) logger.Error(err, "Failed to prepare dynamic resources", "pod", klog.KObj(pod)) return } @@ -1560,7 +1616,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po if referr != nil { logger.Error(referr, "Couldn't make a ref to pod", "pod", klog.KObj(pod)) } - m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedCreatePodSandBox, "Failed to create pod sandbox: %v", err) + m.recorder.WithLogger(logger).Eventf(ref, v1.EventTypeWarning, events.FailedCreatePodSandBox, "Failed to create pod sandbox: %v", err) return } logger.V(4).Info("Created PodSandbox for pod", "podSandboxID", podSandboxID, "pod", klog.KObj(pod)) @@ -1571,7 +1627,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po if referr != nil { logger.Error(referr, "Couldn't make a ref to pod", "pod", klog.KObj(pod)) } - m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedStatusPodSandBox, "Unable to get pod sandbox status: %v", err) + m.recorder.WithLogger(logger).Eventf(ref, v1.EventTypeWarning, events.FailedStatusPodSandBox, "Unable to get pod sandbox status: %v", err) logger.Error(err, "Failed to get pod sandbox status; Skipping pod", "pod", klog.KObj(pod)) result.Fail(err) return @@ -1588,6 +1644,16 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po podIPs = m.determinePodSandboxIPs(ctx, pod.Namespace, pod.Name, resp.GetStatus()) logger.V(4).Info("Determined the ip for pod after sandbox changed", "IPs", podIPs, "pod", klog.KObj(pod)) } + + // Step 5: invoke the sandbox ready callback before image pulling . + // At this point, dynamic resources are prepared (at PrepareDynamicResources() call above) + // and volumes are already mounted (at the kubelet SyncPod() level), so, + // all requirements (sandbox, networking, volumes) are met to set `PodReadyToStartContainers=True` condition. + logger.V(4).Info("Pod sandbox and network ready, invoking callback", "pod", klog.KObj(pod), "podIPs", podIPs) + if err := m.runtimeHelper.OnPodSandboxReady(ctx, pod); err != nil { + // log the error but continue the pod creation process, to retain the existing behaviour + logger.Error(err, "Failed to invoke sandbox ready callback, continuing with pod creation", "pod", klog.KObj(pod)) + } } // the start containers routines depend on pod ip(as in primary pod ip) @@ -1599,20 +1665,17 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po } // Get podSandboxConfig for containers to start. - configPodSandboxResult := kubecontainer.NewSyncResult(kubecontainer.ConfigPodSandbox, podSandboxID) - result.AddSyncResult(configPodSandboxResult) podSandboxConfig, err := m.generatePodSandboxConfig(ctx, pod, podContainerChanges.Attempt) if err != nil { - message := fmt.Sprintf("GeneratePodSandboxConfig for pod %q failed: %v", format.Pod(pod), err) logger.Error(err, "GeneratePodSandboxConfig for pod failed", "pod", klog.KObj(pod)) - configPodSandboxResult.Fail(kubecontainer.ErrConfigPodSandbox, message) + result.Fail(fmt.Errorf("GeneratePodSandboxConfig for pod %q failed: %w", format.Pod(pod), err)) return } imageVolumePullResults, err := m.getImageVolumes(ctx, pod, podSandboxConfig, pullSecrets) if err != nil { logger.Error(err, "Get image volumes for pod failed", "pod", klog.KObj(pod)) - configPodSandboxResult.Fail(kubecontainer.ErrConfigPodSandbox, err.Error()) + result.Fail(err) return } @@ -1665,11 +1728,19 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po } return err } + if typeName == "init container" { + // Don't measure restartable init containers (sidecars) + if !podutil.IsRestartableInitContainer(spec.container) { + if m.podInitContainerTimeRecorder != nil { + m.podInitContainerTimeRecorder.RecordInitContainerStarted(pod.UID, time.Now()) + } + } + } return nil } - // Step 5: start ephemeral containers + // Step 6: start ephemeral containers // These are started "prior" to init containers to allow running ephemeral containers even when there // are errors starting an init container. In practice init containers will start first since ephemeral // containers cannot be specified on pod creation. @@ -1677,7 +1748,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po start(ctx, "ephemeral container", metrics.EphemeralContainer, ephemeralContainerStartSpec(&pod.Spec.EphemeralContainers[idx])) } - // Step 6: start init containers. + // Step 7: start init containers. for _, idx := range podContainerChanges.InitContainersToStart { container := &pod.Spec.InitContainers[idx] // Start the next init container. @@ -1694,19 +1765,34 @@ func (m *kubeGenericRuntimeManager) SyncPod(ctx context.Context, pod *v1.Pod, po logger.V(4).Info("Completed init container for pod", "containerName", container.Name, "pod", klog.KObj(pod)) } - // Step 7: For containers in podContainerChanges.ContainersToUpdate[CPU,Memory] list, invoke UpdateContainerResources + for _, cs := range podStatus.ContainerStatuses { + // Check if this is an init container + for _, init := range pod.Spec.InitContainers { + // Don't measure restartable init containers (sidecars) + if podutil.IsRestartableInitContainer(&init) { + continue + } + if cs.Name == init.Name && cs.State == kubecontainer.ContainerStateExited && !cs.FinishedAt.IsZero() { + if m.podInitContainerTimeRecorder != nil { + m.podInitContainerTimeRecorder.RecordInitContainerFinished(pod.UID, cs.FinishedAt) + } + } + } + } + + // Step 8: For containers in podContainerChanges.ContainersToUpdate[CPU,Memory] list, invoke UpdateContainerResources if resizable, _, _ := allocation.IsInPlacePodVerticalScalingAllowed(pod); resizable { if len(podContainerChanges.ContainersToUpdate) > 0 || podContainerChanges.UpdatePodResources || podContainerChanges.UpdatePodLevelResources { - result.SyncResults = append(result.SyncResults, m.doPodResizeAction(ctx, pod, podStatus, podContainerChanges)) + result.AddSyncResult(m.doPodResizeAction(ctx, pod, podStatus, podContainerChanges)) } } - // Step 8: start containers in podContainerChanges.ContainersToStart. + // Step 9: start containers in podContainerChanges.ContainersToStart. for _, idx := range podContainerChanges.ContainersToStart { start(ctx, "container", metrics.Container, containerStartSpec(&pod.Spec.Containers[idx])) } - return + return result } // incrementImageVolumeMetrics increments the image volume mount metrics @@ -1840,8 +1926,8 @@ func (m *kubeGenericRuntimeManager) doBackOff(ctx context.Context, pod *v1.Pod, key := GetBackoffKey(pod, container) if backOff.IsInBackOffSince(key, ts) { if containerRef, err := kubecontainer.GenerateContainerRef(pod, container); err == nil { - m.recorder.Eventf(containerRef, v1.EventTypeWarning, events.BackOffStartContainer, - fmt.Sprintf("Back-off restarting failed container %s in pod %s", container.Name, format.Pod(pod))) + m.recorder.WithLogger(logger).Eventf(containerRef, v1.EventTypeWarning, events.BackOffStartContainer, + "Back-off restarting failed container %s in pod %s", container.Name, format.Pod(pod)) } backoff := backOff.Get(key) err := fmt.Errorf("back-off %s restarting failed container=%s pod=%s", backoff, container.Name, format.Pod(pod)) @@ -1909,7 +1995,7 @@ func (m *kubeGenericRuntimeManager) GeneratePodStatus(event *runtimeapi.Containe // GetPodStatus retrieves the status of the pod, including the // information of all containers in the pod that are visible in Runtime. -func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubetypes.UID, name, namespace string) (*kubecontainer.PodStatus, error) { +func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, pod *kubecontainer.Pod) (*kubecontainer.PodStatus, error) { logger := klog.FromContext(ctx) // Now we retain restart count of container as a container label. Each time a container // restarts, pod will read the restart count from the registered dead container, increment @@ -1924,33 +2010,30 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety // Anyhow, we only promised "best-effort" restart count reporting, we can just ignore // these limitations now. // TODO: move this comment to SyncPod. - podSandboxIDs, err := m.getSandboxIDByPodUID(ctx, uid, nil) - if err != nil { - return nil, err - } + podFullName := format.PodDesc(pod.Name, pod.Namespace, pod.ID) + logger = logger.WithValues("pod", podFullName) + ctx = klog.NewContext(ctx, logger) - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - UID: uid, - }, + podSandboxIDs := make([]string, len(pod.Sandboxes)) + for i, s := range pod.Sandboxes { + podSandboxIDs[i] = s.ID.ID } - podFullName := format.Pod(pod) - - logger.V(4).Info("getSandboxIDByPodUID got sandbox IDs for pod", "podSandboxID", podSandboxIDs, "pod", klog.KObj(pod)) - sandboxStatuses := []*runtimeapi.PodSandboxStatus{} containerStatuses := []*kubecontainer.Status{} activeContainerStatuses := []*kubecontainer.Status{} - timestamp := time.Now() + + // Since we rely on the sandbox & container IDs in the kubecontainer.Pod, we must be + // conservative and use it's timestamp as the status timestamp. Otherwise, we risk reporting a + // newer PodStatus timestamp that is missing Sandboxes or Containers that should have been + // present at that time. + timestamp := pod.Timestamp podIPs := []string{} var activePodSandboxID string for idx, podSandboxID := range podSandboxIDs { resp, err := m.runtimeService.PodSandboxStatus(ctx, podSandboxID, false) - // Between List (getSandboxIDByPodUID) and check (PodSandboxStatus) another thread might remove a container, and that is normal. + // Between List (ListPodSandbox) and check (PodSandboxStatus) another thread might remove a container, and that is normal. // The previous call (getSandboxIDByPodUID) never fails due to a pod sandbox not existing. // Therefore, this method should not either, but instead act as if the previous call failed, // which means the error should be ignored. @@ -1958,7 +2041,7 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety continue } if err != nil { - logger.Error(err, "PodSandboxStatus of sandbox for pod", "podSandboxID", podSandboxID, "pod", klog.KObj(pod)) + logger.Error(err, "PodSandboxStatus of sandbox for pod", "podSandboxID", podSandboxID) return nil, err } if resp.GetStatus() == nil { @@ -1968,7 +2051,7 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety sandboxStatuses = append(sandboxStatuses, resp.Status) // Only get pod IP from latest sandbox if idx == 0 && resp.Status.State == runtimeapi.PodSandboxState_SANDBOX_READY { - podIPs = m.determinePodSandboxIPs(ctx, namespace, name, resp.Status) + podIPs = m.determinePodSandboxIPs(ctx, pod.Namespace, pod.Name, resp.Status) activePodSandboxID = podSandboxID } @@ -1979,11 +2062,11 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety // e.g. CI job 'pull-kubernetes-e2e-gce-alpha-features' will runs with // features gate enabled, which includes Evented PLEG, but uses the // runtime without Evented PLEG support. - logger.V(4).Info("Runtime does not set pod status timestamp", "pod", klog.KObj(pod)) - containerStatuses, activeContainerStatuses, err = m.getPodContainerStatuses(ctx, uid, name, namespace, activePodSandboxID) + logger.V(4).Info("Runtime does not set pod status timestamp") + containerStatuses, activeContainerStatuses, err = m.getPodContainerStatuses(ctx, pod, activePodSandboxID) if err != nil { if m.logReduction.ShouldMessageBePrinted(err.Error(), podFullName) { - logger.Error(err, "getPodContainerStatuses for pod failed", "pod", klog.KObj(pod)) + logger.Error(err, "getPodContainerStatuses for pod failed") } return nil, err } @@ -1992,7 +2075,7 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety // timestamp from sandboxStatus. timestamp = time.Unix(0, resp.Timestamp) for _, cs := range resp.ContainersStatuses { - cStatus := m.convertToKubeContainerStatus(ctx, uid, cs) + cStatus := m.convertToKubeContainerStatus(ctx, pod.ID, cs) containerStatuses = append(containerStatuses, cStatus) } } @@ -2001,10 +2084,11 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety if !utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { // Get statuses of all containers visible in the pod. - containerStatuses, activeContainerStatuses, err = m.getPodContainerStatuses(ctx, uid, name, namespace, activePodSandboxID) + var err error + containerStatuses, activeContainerStatuses, err = m.getPodContainerStatuses(ctx, pod, activePodSandboxID) if err != nil { if m.logReduction.ShouldMessageBePrinted(err.Error(), podFullName) { - logger.Error(err, "getPodContainerStatuses for pod failed", "pod", klog.KObj(pod)) + logger.Error(err, "getPodContainerStatuses for pod failed") } return nil, err } @@ -2012,9 +2096,9 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety m.logReduction.ClearID(podFullName) return &kubecontainer.PodStatus{ - ID: uid, - Name: name, - Namespace: namespace, + ID: pod.ID, + Name: pod.Name, + Namespace: pod.Namespace, IPs: podIPs, SandboxStatuses: sandboxStatuses, ContainerStatuses: containerStatuses, @@ -2142,11 +2226,15 @@ func (m *kubeGenericRuntimeManager) isPodLevelResourcesResizeInProgress(allocate return false } - if allocatedPod.Spec.Resources == nil { + if allocatedPod.Spec.Resources == nil || podStatus == nil { + return false + } + + actuatedPodResources, found := m.actuatedState.GetPodLevelResources(allocatedPod.UID) + if !found || actuatedPodResources == nil { return false } - actuatedPodResources, _ := m.actuatedState.GetPodLevelResources(allocatedPod.UID) allocatedPodResources := allocatedPod.Spec.Resources return !cpuMemoryResourcesEqual(actuatedPodResources, allocatedPodResources) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go index 0b9293c780..843838cae2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go @@ -27,7 +27,6 @@ import ( kubetypes "k8s.io/apimachinery/pkg/types" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" - "k8s.io/kubelet/pkg/types" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" runtimeutil "k8s.io/kubernetes/pkg/kubelet/kuberuntime/util" "k8s.io/kubernetes/pkg/kubelet/util" @@ -92,7 +91,7 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(ctx context.Context Annotations: newPodAnnotations(pod), } - dnsConfig, err := m.runtimeHelper.GetPodDNS(pod) + dnsConfig, err := m.runtimeHelper.GetPodDNS(ctx, pod) if err != nil { return nil, err } @@ -100,7 +99,7 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(ctx context.Context if !kubecontainer.IsHostNetworkPod(pod) { // TODO: Add domain support in new runtime interface - podHostname, podDomain, err := m.runtimeHelper.GeneratePodHostNameAndDomain(pod) + podHostname, podDomain, err := m.runtimeHelper.GeneratePodHostNameAndDomain(logger, pod) if err != nil { return nil, err } @@ -136,7 +135,7 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(ctx context.Context podSandboxConfig.PortMappings = portMappings } - lc, err := m.generatePodSandboxLinuxConfig(pod) + lc, err := m.generatePodSandboxLinuxConfig(ctx, pod) if err != nil { return nil, err } @@ -161,7 +160,7 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(ctx context.Context // We've to call PodSandboxLinuxConfig always irrespective of the underlying OS as securityContext is not part of // podSandboxConfig. It is currently part of LinuxPodSandboxConfig. In future, if we have securityContext pulled out // in podSandboxConfig we should be able to use it. -func (m *kubeGenericRuntimeManager) generatePodSandboxLinuxConfig(pod *v1.Pod) (*runtimeapi.LinuxPodSandboxConfig, error) { +func (m *kubeGenericRuntimeManager) generatePodSandboxLinuxConfig(ctx context.Context, pod *v1.Pod) (*runtimeapi.LinuxPodSandboxConfig, error) { cgroupParent := m.runtimeHelper.GetPodCgroupParent(pod) lc := &runtimeapi.LinuxPodSandboxConfig{ CgroupParent: cgroupParent, @@ -193,7 +192,7 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxLinuxConfig(pod *v1.Pod) ( if sc.RunAsGroup != nil && runtime.GOOS != "windows" { lc.SecurityContext.RunAsGroup = &runtimeapi.Int64Value{Value: int64(*sc.RunAsGroup)} } - namespaceOptions, err := runtimeutil.NamespacesForPod(pod, m.runtimeHelper, m.runtimeClassManager) + namespaceOptions, err := runtimeutil.NamespacesForPod(ctx, pod, m.runtimeHelper, m.runtimeClassManager) if err != nil { return nil, err } @@ -279,28 +278,6 @@ func (m *kubeGenericRuntimeManager) generatePodSandboxWindowsConfig(pod *v1.Pod) return wc, nil } -// getKubeletSandboxes lists all (or just the running) sandboxes managed by kubelet. -func (m *kubeGenericRuntimeManager) getKubeletSandboxes(ctx context.Context, all bool) ([]*runtimeapi.PodSandbox, error) { - logger := klog.FromContext(ctx) - var filter *runtimeapi.PodSandboxFilter - if !all { - readyState := runtimeapi.PodSandboxState_SANDBOX_READY - filter = &runtimeapi.PodSandboxFilter{ - State: &runtimeapi.PodSandboxStateValue{ - State: readyState, - }, - } - } - - resp, err := m.runtimeService.ListPodSandbox(ctx, filter) - if err != nil { - logger.Error(err, "Failed to list pod sandboxes") - return nil, err - } - - return resp, nil -} - // determinePodSandboxIP determines the IP addresses of the given pod sandbox. func (m *kubeGenericRuntimeManager) determinePodSandboxIPs(ctx context.Context, podNamespace, podName string, podSandbox *runtimeapi.PodSandboxStatus) []string { logger := klog.FromContext(ctx) @@ -334,19 +311,11 @@ func (m *kubeGenericRuntimeManager) determinePodSandboxIPs(ctx context.Context, return podIPs } -// getPodSandboxID gets the sandbox id by podUID and returns ([]sandboxID, error). +// getPodSandboxIDByPodUID gets the sandbox id by podUID and returns ([]sandboxID, error). // Param state could be nil in order to get all sandboxes belonging to same pod. -func (m *kubeGenericRuntimeManager) getSandboxIDByPodUID(ctx context.Context, podUID kubetypes.UID, state *runtimeapi.PodSandboxState) ([]string, error) { +func (m *kubeGenericRuntimeManager) getSandboxIDByPodUID(ctx context.Context, podUID kubetypes.UID) ([]string, error) { logger := klog.FromContext(ctx) - filter := &runtimeapi.PodSandboxFilter{ - LabelSelector: map[string]string{types.KubernetesPodUIDLabel: string(podUID)}, - } - if state != nil { - filter.State = &runtimeapi.PodSandboxStateValue{ - State: *state, - } - } - sandboxes, err := m.runtimeService.ListPodSandbox(ctx, filter) + sandboxes, err := m.getSandboxes(ctx, listOptions{podUID: podUID}) if err != nil { logger.Error(err, "Failed to list sandboxes for pod", "podUID", podUID) return nil, err @@ -358,7 +327,7 @@ func (m *kubeGenericRuntimeManager) getSandboxIDByPodUID(ctx context.Context, po // Sort with newest first. sandboxIDs := make([]string, len(sandboxes)) - sort.Sort(podSandboxByCreated(sandboxes)) + sort.Sort(podSandboxByCreatedThenID(sandboxes)) for i, s := range sandboxes { sandboxIDs[i] = s.Id } @@ -368,7 +337,7 @@ func (m *kubeGenericRuntimeManager) getSandboxIDByPodUID(ctx context.Context, po // GetPortForward gets the endpoint the runtime will serve the port-forward request from. func (m *kubeGenericRuntimeManager) GetPortForward(ctx context.Context, podName, podNamespace string, podUID kubetypes.UID, ports []int32) (*url.URL, error) { - sandboxIDs, err := m.getSandboxIDByPodUID(ctx, podUID, nil) + sandboxIDs, err := m.getSandboxIDByPodUID(ctx, podUID) if err != nil { return nil, fmt.Errorf("failed to find sandboxID for pod %s: %v", format.PodDesc(podName, podNamespace, podUID), err) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_linux.go index 35acabb9c4..a3ae9c1337 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_unsupported.go index e3d6a829a0..a269c808ab 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_windows.go index d71d980c1a..a3000fe675 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_sandbox_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context.go index 6842eee02c..cd4bac5fdf 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context.go @@ -17,6 +17,7 @@ limitations under the License. package kuberuntime import ( + "context" "fmt" v1 "k8s.io/api/core/v1" @@ -26,7 +27,7 @@ import ( ) // determineEffectiveSecurityContext gets container's security context from v1.Pod and v1.Container. -func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container, uid *int64, username string) (*runtimeapi.LinuxContainerSecurityContext, error) { +func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(ctx context.Context, pod *v1.Pod, container *v1.Container, uid *int64, username string) (*runtimeapi.LinuxContainerSecurityContext, error) { effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container) synthesized := convertToRuntimeSecurityContext(effectiveSc) if synthesized == nil { @@ -57,7 +58,7 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po } // set namespace options and supplemental groups. - namespaceOptions, err := runtimeutil.NamespacesForPod(pod, m.runtimeHelper, m.runtimeClassManager) + namespaceOptions, err := runtimeutil.NamespacesForPod(ctx, pod, m.runtimeHelper, m.runtimeClassManager) if err != nil { return nil, err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_others.go index 5b8ff561f9..e16ba7b7c7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_windows.go index c2b3daa07b..77348045d2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/security_context_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go index a3c7ce42ba..7987d3854e 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go @@ -108,7 +108,8 @@ type RuntimeHandlerResolver interface { // namespacesForPod returns the runtimeapi.NamespaceOption for a given pod. // An empty or nil pod can be used to get the namespace defaults for v1.Pod. -func NamespacesForPod(pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper, rcManager RuntimeHandlerResolver) (*runtimeapi.NamespaceOption, error) { +func NamespacesForPod(ctx context.Context, pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper, rcManager RuntimeHandlerResolver) (*runtimeapi.NamespaceOption, error) { + logger := klog.FromContext(ctx) runtimeHandler := "" if pod != nil && rcManager != nil { var err error @@ -117,7 +118,7 @@ func NamespacesForPod(pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper, rc return nil, err } } - userNs, err := runtimeHelper.GetOrCreateUserNamespaceMappings(pod, runtimeHandler) + userNs, err := runtimeHelper.GetOrCreateUserNamespaceMappings(logger, pod, runtimeHandler) if err != nil { return nil, err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_linux.go index 137d652d1a..6f9bbdcb2d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_unsupported.go index 3ece076ba3..a286606e9c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_windows.go index 1db1b527b3..e55520f100 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/features_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2025 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go index 9ff769a648..c2de1e8c03 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go @@ -60,7 +60,8 @@ type handlerRunner struct { } type podStatusProvider interface { - GetPodStatus(ctx context.Context, uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) + GetPod(ctx context.Context, podUID types.UID) (*kubecontainer.Pod, error) + GetPodStatus(ctx context.Context, pod *kubecontainer.Pod) (*kubecontainer.PodStatus, error) } // NewHandlerRunner returns a configured lifecycle handler for a container. @@ -129,10 +130,13 @@ func (hr *handlerRunner) runHTTPHandler(ctx context.Context, pod *v1.Pod, contai host := handler.HTTPGet.Host podIP := host if len(host) == 0 { - status, err := hr.containerManager.GetPodStatus(ctx, pod.UID, pod.Name, pod.Namespace) + runtimePod, err := hr.containerManager.GetPod(ctx, pod.UID) if err != nil { - logger.Error(err, "Unable to get pod info, event handlers may be invalid.", "pod", klog.KObj(pod)) - return err + return fmt.Errorf("unable to get pod, event handlers may be invalid: %w", err) + } + status, err := hr.containerManager.GetPodStatus(ctx, runtimePod) + if err != nil { + return fmt.Errorf("unable to get pod status, event handlers may be invalid: %w", err) } if len(status.IPs) == 0 { return fmt.Errorf("failed to find networking container: %v", status) @@ -267,11 +271,11 @@ func (c *declaredFeaturesAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmit } } - if reqs.Len() == 0 { + if reqs.IsEmpty() { return PodAdmitResult{Admit: true} } - matchResult, err := ndf.MatchNodeFeatureSet(reqs, c.ndfSet) + matchResult, err := c.ndfFramework.MatchNodeFeatureSet(reqs, c.ndfSet) if err != nil { return PodAdmitResult{ Admit: false, diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go index 3be7adade5..864c69dc8f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go @@ -16,7 +16,7 @@ limitations under the License. package lifecycle -import "k8s.io/api/core/v1" +import v1 "k8s.io/api/core/v1" // PodAdmitAttributes is the context for a pod admission decision. // The member fields of this struct should never be mutated. @@ -25,8 +25,20 @@ type PodAdmitAttributes struct { Pod *v1.Pod // all pods bound to the kubelet excluding the pod being evaluated OtherPods []*v1.Pod + // the operation being performed; either "add" or "resize" + Operation Operation } +// Operation represents the type of operation being performed on a pod. +type Operation string + +const ( + // AddOperation indicates that the pod is being added to the kubelet. + AddOperation Operation = "add" + // ResizeOperation indicates that the pod is being resized. + ResizeOperation Operation = "resize" +) + // PodAdmitResult provides the result of a pod admission decision. type PodAdmitResult struct { // if true, the pod should be admitted. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go index 62c9c30008..0052a824ef 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go @@ -33,6 +33,7 @@ import ( schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" + schedutil "k8s.io/kubernetes/pkg/scheduler/util" "k8s.io/utils/ptr" ) @@ -346,6 +347,20 @@ func rejectPodAdmissionBasedOnSupplementalGroupsPolicy(pod *v1.Pod, node *v1.Nod } func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) *v1.Pod { + isResourceBackedByDRA := func(resourceName v1.ResourceName, containerName string) bool { + if !utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource) { + return false + } + if pod.Status.ExtendedResourceClaimStatus == nil { + return false + } + for _, resourceMapping := range pod.Status.ExtendedResourceClaimStatus.RequestMappings { + if v1.ResourceName(resourceMapping.ResourceName) == resourceName && resourceMapping.ContainerName == containerName { + return true + } + } + return false + } filterExtendedResources := func(containers []v1.Container) { for i, c := range containers { // We only handle requests in Requests but not Limits because the @@ -353,6 +368,9 @@ func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulerframework.No // does not use Limits. filteredResources := make(v1.ResourceList) for rName, rQuant := range c.Resources.Requests { + if schedutil.IsDRAExtendedResourceName(rName) && isResourceBackedByDRA(rName, c.Name) { + continue + } if v1helper.IsExtendedResourceName(rName) { if _, found := nodeInfo.Allocatable.ScalarResources[rName]; !found { continue diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/managed/managed.go b/vendor/k8s.io/kubernetes/pkg/kubelet/managed/managed.go index bd78adeee1..e990656b09 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/managed/managed.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/managed/managed.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "strings" + "sync/atomic" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -29,7 +30,7 @@ import ( ) var ( - pinnedManagementEnabled bool + pinnedManagementEnabled atomic.Bool pinnedManagementFilename = "/etc/kubernetes/openshift-workload-pinning" ) @@ -62,18 +63,18 @@ func init() { func readEnablementFile() { if _, err := os.Stat(pinnedManagementFilename); err == nil { - pinnedManagementEnabled = true + pinnedManagementEnabled.Store(true) } } // TestOnlySetEnabled allows changing the state of management partition enablement // This method MUST NOT be used outside of test code func TestOnlySetEnabled(enabled bool) { - pinnedManagementEnabled = enabled + pinnedManagementEnabled.Store(enabled) } func IsEnabled() bool { - return pinnedManagementEnabled + return pinnedManagementEnabled.Load() } // IsPodManaged returns true and the name of the workload if enabled. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go index 7ae4c1b669..5e0fc20e33 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go @@ -51,6 +51,7 @@ const ( PLEGDiscardEventsKey = "pleg_discard_events" PLEGRelistIntervalKey = "pleg_relist_interval_seconds" PLEGLastSeenKey = "pleg_last_seen_seconds" + PLEGPodRelistDurationKey = "pleg_pod_relist_duration_seconds" EventedPLEGConnErrKey = "evented_pleg_connection_error_count" EventedPLEGConnKey = "evented_pleg_connection_success_count" EventedPLEGConnLatencyKey = "evented_pleg_connection_latency_seconds" @@ -100,6 +101,7 @@ const ( StartedPodsTotalKey = "started_pods_total" StartedPodsErrorsTotalKey = "started_pods_errors_total" StartedContainersTotalKey = "started_containers_total" + TerminatedContainersTotalKey = "terminated_containers_total" StartedContainersErrorsTotalKey = "started_containers_errors_total" // Metrics to track HostProcess container usage by this kubelet @@ -113,6 +115,23 @@ const ( // Metrics to track ephemeral container usage by this kubelet ManagedEphemeralContainersKey = "managed_ephemeral_containers" + // Metrics to track resource managers allocation + ResourceManagerAllocationTotalKey = "resource_manager_allocations_total" + + ResourceManagerAllocationErrorsTotalKey = "resource_manager_allocation_errors_total" + + ResourceManagerContainerAssignmentsKey = "resource_manager_container_assignments" + + ResourceManagerPod = "pod" + ResourceManagerNode = "node" + + ResourceManagerCPU = "cpu" + ResourceManagerMemory = "memory" + + ResourceManagerExclusiveNode = "node_exclusive" + ResourceManagerSharedPod = "pod_shared" + ResourceManagerExclusivePod = "pod_exclusive" + // Metrics to track the CPU manager behavior CPUManagerPinningRequestsTotalKey = "cpu_manager_pinning_requests_total" CPUManagerPinningErrorsTotalKey = "cpu_manager_pinning_errors_total" @@ -146,6 +165,10 @@ const ( DRAOperationsDurationKey = "operations_duration_seconds" DRAGRPCOperationsDurationKey = "grpc_operations_duration_seconds" + // Metric keys for MemoryQoS + MemoryQoSNodeMemoryMinBytesKey = "memory_qos_node_memory_min_bytes" + MemoryQoSNodeMemoryLowBytesKey = "memory_qos_node_memory_low_bytes" + // Values used in metric labels Container = "container" InitContainer = "init_container" @@ -179,6 +202,9 @@ const ( // Metric key for podcertificate states. PodCertificateStatesKey = "podcertificate_states" + + // Metric key for podsapi + PodWatchEventsDroppedKey = "pod_watch_events_dropped_total" ) type imageSizeBucket struct { @@ -386,6 +412,17 @@ var ( StabilityLevel: metrics.ALPHA, }, ) + // PLEGPodRelistDuration is a Histogram that tracks the duration (in seconds) it takes for relisting a single pod in the Kubelet's + // Pod Lifecycle Event Generator (PLEG). + PLEGPodRelistDuration = metrics.NewHistogram( + &metrics.HistogramOpts{ + Subsystem: KubeletSubsystem, + Name: PLEGPodRelistDurationKey, + Help: "Duration in seconds for relisting a single pod in PLEG.", + Buckets: metrics.DefBuckets, + StabilityLevel: metrics.ALPHA, + }, + ) // EventedPLEGConnErr is a Counter that tracks the number of errors encountered during // the establishment of streaming connection with the CRI runtime. @@ -729,6 +766,16 @@ var ( }, []string{"container_type"}, ) + // TerminatedContainersTotal is a counter that tracks the number of container terminations + TerminatedContainersTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: KubeletSubsystem, + Name: TerminatedContainersTotalKey, + Help: "Cumulative number of container terminations.", + StabilityLevel: metrics.ALPHA, + }, + []string{"container_type", "exit_code", "reason"}, + ) // StartedContainersTotal is a counter that tracks the number of errors creating containers StartedContainersErrorsTotal = metrics.NewCounterVec( &metrics.CounterOpts{ @@ -907,6 +954,26 @@ var ( }, ) + // MemoryQoSNodeMemoryMinBytes tracks total cgroup v2 memory.min (hard protection) for Guaranteed pods. + MemoryQoSNodeMemoryMinBytes = metrics.NewGauge( + &metrics.GaugeOpts{ + Subsystem: KubeletSubsystem, + Name: MemoryQoSNodeMemoryMinBytesKey, + Help: "Total cgroup v2 memory.min in bytes for Guaranteed pods. This memory is hard-reserved and never reclaimed by the kernel.", + StabilityLevel: metrics.ALPHA, + }, + ) + + // MemoryQoSNodeMemoryLowBytes tracks total cgroup v2 memory.low (soft protection) for Burstable pods. + MemoryQoSNodeMemoryLowBytes = metrics.NewGauge( + &metrics.GaugeOpts{ + Subsystem: KubeletSubsystem, + Name: MemoryQoSNodeMemoryLowBytesKey, + Help: "Total cgroup v2 memory.low in bytes for Burstable pods. This memory is soft-reserved and may be reclaimed under extreme pressure.", + StabilityLevel: metrics.ALPHA, + }, + ) + // TopologyManagerAdmissionRequestsTotal tracks the number of times the pod spec will cause the topology manager to admit a pod TopologyManagerAdmissionRequestsTotal = metrics.NewCounter( &metrics.CounterOpts{ @@ -1193,6 +1260,49 @@ var ( }, []string{"retry_trigger"}, ) + + // ResourceManagerAllocationsTotal counts the total number of exclusive resource + // allocations performed by a manager. The `source` label distinguishes between + // allocations drawn from the node-level pool versus a pre-allocated pod-level pool. + ResourceManagerAllocationsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Name: ResourceManagerAllocationTotalKey, + Help: "Number of exclusive resource allocations performed by a resource manager.", + }, + []string{"resource_name", "source"}, + ) + + // ResourceManagerAllocationErrorsTotal counts errors encountered during exclusive + // resource allocation, distinguished by the intended allocation source. + ResourceManagerAllocationErrorsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Name: ResourceManagerAllocationErrorsTotalKey, + Help: "Number of errors encountered during exclusive resource allocation.", + }, + []string{"resource_name", "source"}, + ) + + // ResourceManagerContainerAssignments counts the total number of containers with + // a specific type of resource assignment. This provides visibility into how many + // containers were allocated with exclusive resources (from the node or pod pool) + // versus the pod-level shared pool. + ResourceManagerContainerAssignments = metrics.NewCounterVec( + &metrics.CounterOpts{ + Name: ResourceManagerContainerAssignmentsKey, + Help: "Number of containers with a specific type of resource assignment.", + }, + []string{"resource_name", "assignment_type"}, + ) + + // PodWatchEventsDroppedTotal tracks the number of dropped pod watch events. + PodWatchEventsDroppedTotal = metrics.NewCounter( + &metrics.CounterOpts{ + Subsystem: KubeletSubsystem, + Name: PodWatchEventsDroppedKey, + Help: "Cumulative number of pod watch events dropped.", + StabilityLevel: metrics.ALPHA, + }, + ) ) var registerMetrics sync.Once @@ -1222,6 +1332,7 @@ func Register() { legacyregistry.MustRegister(PLEGDiscardEvents) legacyregistry.MustRegister(PLEGRelistInterval) legacyregistry.MustRegister(PLEGLastSeen) + legacyregistry.MustRegister(PLEGPodRelistDuration) legacyregistry.MustRegister(EventedPLEGConnErr) legacyregistry.MustRegister(EventedPLEGConn) legacyregistry.MustRegister(EventedPLEGConnLatency) @@ -1247,10 +1358,8 @@ func Register() { legacyregistry.MustRegister(PodResourcesEndpointRequestsGetAllocatableCount) legacyregistry.MustRegister(PodResourcesEndpointErrorsListCount) legacyregistry.MustRegister(PodResourcesEndpointErrorsGetAllocatableCount) - if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPodResourcesGet) { - legacyregistry.MustRegister(PodResourcesEndpointRequestsGetCount) - legacyregistry.MustRegister(PodResourcesEndpointErrorsGetCount) - } + legacyregistry.MustRegister(PodResourcesEndpointRequestsGetCount) + legacyregistry.MustRegister(PodResourcesEndpointErrorsGetCount) if utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesSupport) { legacyregistry.MustRegister(StartedUserNamespacedPodsTotal) legacyregistry.MustRegister(StartedUserNamespacedPodsErrorsTotal) @@ -1258,6 +1367,7 @@ func Register() { legacyregistry.MustRegister(StartedPodsTotal) legacyregistry.MustRegister(StartedPodsErrorsTotal) legacyregistry.MustRegister(StartedContainersTotal) + legacyregistry.MustRegister(TerminatedContainersTotal) legacyregistry.MustRegister(StartedContainersErrorsTotal) legacyregistry.MustRegister(StartedHostProcessContainersTotal) legacyregistry.MustRegister(StartedHostProcessContainersErrorsTotal) @@ -1272,6 +1382,10 @@ func Register() { legacyregistry.MustRegister(ContainerAlignedComputeResourcesFailure) legacyregistry.MustRegister(MemoryManagerPinningRequestTotal) legacyregistry.MustRegister(MemoryManagerPinningErrorsTotal) + if utilfeature.DefaultFeatureGate.Enabled(features.MemoryQoS) { + legacyregistry.MustRegister(MemoryQoSNodeMemoryMinBytes) + legacyregistry.MustRegister(MemoryQoSNodeMemoryLowBytes) + } legacyregistry.MustRegister(TopologyManagerAdmissionRequestsTotal) legacyregistry.MustRegister(TopologyManagerAdmissionErrorsTotal) legacyregistry.MustRegister(TopologyManagerAdmissionDuration) @@ -1311,6 +1425,14 @@ func Register() { legacyregistry.MustRegister(PodInProgressResizes) legacyregistry.MustRegister(PodDeferredAcceptedResizes) } + + if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResourceManagers) { + legacyregistry.MustRegister(ResourceManagerAllocationsTotal) + legacyregistry.MustRegister(ResourceManagerAllocationErrorsTotal) + legacyregistry.MustRegister(ResourceManagerContainerAssignments) + } + + legacyregistry.MustRegister(PodWatchEventsDroppedTotal) }) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns.go index 64d0f0fb0e..03e8d72cd9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns.go @@ -58,7 +58,7 @@ const ( // Configurer is used for setting up DNS resolver configuration when launching pods. type Configurer struct { - recorder record.EventRecorder + recorder record.EventRecorderLogger getHostDNSConfig func(klog.Logger, string) (*runtimeapi.DNSConfig, error) nodeRef *v1.ObjectReference nodeIPs []net.IP @@ -74,7 +74,7 @@ type Configurer struct { } // NewConfigurer returns a DNS configurer for launching pods. -func NewConfigurer(recorder record.EventRecorder, nodeRef *v1.ObjectReference, nodeIPs []net.IP, clusterDNS []net.IP, clusterDomain, resolverConfig string) *Configurer { +func NewConfigurer(recorder record.EventRecorderLogger, nodeRef *v1.ObjectReference, nodeIPs []net.IP, clusterDNS []net.IP, clusterDomain, resolverConfig string) *Configurer { return &Configurer{ recorder: recorder, getHostDNSConfig: getHostDNSConfig, @@ -140,7 +140,7 @@ func (c *Configurer) formDNSSearchFitsLimits(logger klog.Logger, composedSearch if limitsExceeded { err := fmt.Errorf("Search Line limits were exceeded, some search paths have been omitted, the applied search line is: %s", strings.Join(composedSearch, " ")) - c.recorder.Event(pod, v1.EventTypeWarning, "DNSConfigForming", err.Error()) + c.recorder.WithLogger(logger).Event(pod, v1.EventTypeWarning, "DNSConfigForming", err.Error()) logger.Error(err, "Search Line limits exceeded") } return composedSearch @@ -150,7 +150,7 @@ func (c *Configurer) formDNSNameserversFitsLimits(logger klog.Logger, nameserver if len(nameservers) > validation.MaxDNSNameservers { nameservers = nameservers[0:validation.MaxDNSNameservers] err := fmt.Errorf("Nameserver limits were exceeded, some nameservers have been omitted, the applied nameserver line is: %s", strings.Join(nameservers, " ")) - c.recorder.Event(pod, v1.EventTypeWarning, "DNSConfigForming", err.Error()) + c.recorder.WithLogger(logger).Event(pod, v1.EventTypeWarning, "DNSConfigForming", err.Error()) logger.Error(err, "Nameserver limits exceeded") } return nameservers @@ -178,7 +178,7 @@ func (c *Configurer) generateSearchesForDNSClusterFirst(hostSearch []string, pod func (c *Configurer) CheckLimitsForResolvConf(logger klog.Logger) { f, err := os.Open(c.ResolverConfig) if err != nil { - c.recorder.Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", err.Error()) + c.recorder.WithLogger(logger).Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", err.Error()) logger.V(4).Info("Check limits for resolv.conf failed at file open", "err", err) return } @@ -186,7 +186,7 @@ func (c *Configurer) CheckLimitsForResolvConf(logger klog.Logger) { _, hostSearch, _, err := parseResolvConf(f) if err != nil { - c.recorder.Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", err.Error()) + c.recorder.WithLogger(logger).Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", err.Error()) logger.V(4).Info("Check limits for resolv.conf failed at parse resolv.conf", "err", err) return } @@ -199,7 +199,7 @@ func (c *Configurer) CheckLimitsForResolvConf(logger klog.Logger) { if len(hostSearch) > domainCountLimit { log := fmt.Sprintf("Resolv.conf file '%s' contains search line consisting of more than %d domains!", c.ResolverConfig, domainCountLimit) - c.recorder.Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) + c.recorder.WithLogger(logger).Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) logger.V(4).Info("Check limits for resolv.conf failed", "eventlog", log) return } @@ -207,7 +207,7 @@ func (c *Configurer) CheckLimitsForResolvConf(logger klog.Logger) { for _, search := range hostSearch { if len(search) > utilvalidation.DNS1123SubdomainMaxLength { log := fmt.Sprintf("Resolv.conf file %q contains a search path which length is more than allowed %d chars!", c.ResolverConfig, utilvalidation.DNS1123SubdomainMaxLength) - c.recorder.Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) + c.recorder.WithLogger(logger).Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) logger.V(4).Info("Check limits for resolv.conf failed", "eventlog", log) return } @@ -215,7 +215,7 @@ func (c *Configurer) CheckLimitsForResolvConf(logger klog.Logger) { if len(strings.Join(hostSearch, " ")) > maxDNSSearchListChars { log := fmt.Sprintf("Resolv.conf file '%s' contains search line which length is more than allowed %d chars!", c.ResolverConfig, maxDNSSearchListChars) - c.recorder.Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) + c.recorder.WithLogger(logger).Event(c.nodeRef, v1.EventTypeWarning, "CheckLimitsForResolvConf", log) logger.V(4).Info("Check limits for resolv.conf failed", "eventlog", log) return } @@ -416,8 +416,8 @@ func (c *Configurer) GetPodDNS(ctx context.Context, pod *v1.Pod) (*runtimeapi.DN } // clusterDNS is not known. Pod with ClusterDNSFirst Policy cannot be created. nodeErrorMsg := fmt.Sprintf("kubelet does not have ClusterDNS IP configured and cannot create Pod using %q policy. Falling back to %q policy.", v1.DNSClusterFirst, v1.DNSDefault) - c.recorder.Eventf(c.nodeRef, v1.EventTypeWarning, "MissingClusterDNS", nodeErrorMsg) - c.recorder.Eventf(pod, v1.EventTypeWarning, "MissingClusterDNS", "pod: %q. %s", format.Pod(pod), nodeErrorMsg) + c.recorder.WithLogger(logger).Eventf(c.nodeRef, v1.EventTypeWarning, "MissingClusterDNS", "%s", nodeErrorMsg) + c.recorder.WithLogger(logger).Eventf(pod, v1.EventTypeWarning, "MissingClusterDNS", "pod: %q. %s", format.Pod(pod), nodeErrorMsg) // Fallback to DNSDefault. fallthrough case podDNSHost: diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_other.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_other.go index 8d5f5caa7d..df2b81b86a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_other.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_other.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_windows.go index cb1651bf5e..79d69f761a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/dns/dns_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager.go index 2d7786f71f..fa36cd11c1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager.go @@ -42,7 +42,7 @@ type Manager interface { lifecycle.PodAdmitHandler Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult - Start() error + Start(ctx context.Context) error ShutdownStatus() error } @@ -54,7 +54,7 @@ type Config struct { NodeRef *v1.ObjectReference GetPodsFunc eviction.ActivePodsFunc KillPodFunc eviction.KillPodFunc - SyncNodeStatusFunc func() + SyncNodeStatusFunc func(context.Context) ShutdownGracePeriodRequested time.Duration ShutdownGracePeriodCriticalPods time.Duration ShutdownGracePeriodByPodPriority []kubeletconfig.ShutdownGracePeriodByPodPriority @@ -71,7 +71,7 @@ func (managerStub) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmit } // Start is a no-op always returning nil for non linux platforms. -func (managerStub) Start() error { +func (managerStub) Start(context.Context) error { return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_linux.go index 8a78f874cb..cb01d05311 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2020 The Kubernetes Authors. @@ -21,6 +20,7 @@ limitations under the License. package nodeshutdown import ( + "context" "fmt" "path/filepath" "sync" @@ -63,7 +63,7 @@ type managerImpl struct { nodeRef *v1.ObjectReference getPods eviction.ActivePodsFunc - syncNodeStatus func() + syncNodeStatus func(context.Context) dbusCon dbusInhibiter inhibitLock systemd.InhibitLock @@ -144,8 +144,8 @@ func (m *managerImpl) setMetrics() { } // Start starts the node shutdown manager and will start watching the node for shutdown events. -func (m *managerImpl) Start() error { - stop, err := m.start() +func (m *managerImpl) Start(ctx context.Context) error { + stop, err := m.start(ctx) if err != nil { return err } @@ -157,7 +157,7 @@ func (m *managerImpl) Start() error { time.Sleep(dbusReconnectPeriod) m.logger.V(1).Info("Restarting watch for node shutdown events") - stop, err = m.start() + stop, err = m.start(ctx) if err != nil { m.logger.Error(err, "Unable to watch the node for shutdown events") } @@ -168,7 +168,7 @@ func (m *managerImpl) Start() error { return nil } -func (m *managerImpl) start() (chan struct{}, error) { +func (m *managerImpl) start(ctx context.Context) (chan struct{}, error) { systemBus, err := systemDbus() if err != nil { return nil, err @@ -275,7 +275,7 @@ func (m *managerImpl) start() (chan struct{}, error) { if isShuttingDown { // Update node status and ready condition - go m.syncNodeStatus() + go m.syncNodeStatus(ctx) m.processShutdownEvent() } else { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_others.go index ca43e737fe..7a1185b9ce 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_others.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_windows.go index 4c129d499d..a47de9386d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/nodeshutdown_manager_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. @@ -21,6 +20,7 @@ limitations under the License. package nodeshutdown import ( + "context" "fmt" "path/filepath" "strings" @@ -56,7 +56,7 @@ type managerImpl struct { nodeRef *v1.ObjectReference getPods eviction.ActivePodsFunc - syncNodeStatus func() + syncNodeStatus func(context.Context) nodeShuttingDownMutex sync.Mutex nodeShuttingDownNow bool @@ -136,7 +136,7 @@ func (m *managerImpl) setMetrics() { } // Start starts the node shutdown manager and will start watching the node for shutdown events. -func (m *managerImpl) Start() error { +func (m *managerImpl) Start(_ context.Context) error { m.logger.V(1).Info("Shutdown manager get started") _, err := m.start() @@ -247,7 +247,7 @@ func (m *managerImpl) ProcessShutdownEvent() error { m.nodeShuttingDownNow = true m.nodeShuttingDownMutex.Unlock() - go m.syncNodeStatus() + go m.syncNodeStatus(context.TODO()) m.logger.V(1).Info("Shutdown manager processing preshutdown event") activePods := m.getPods() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_linux.go index 18b6b9be86..0223d65ba0 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_others.go index f077b00afc..c35b8c9c84 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodeshutdown/systemd/inhibit_others.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/nodestatus/setters.go b/vendor/k8s.io/kubernetes/pkg/kubelet/nodestatus/setters.go index 4a22a830fe..f7bc8c7729 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/nodestatus/setters.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/nodestatus/setters.go @@ -473,10 +473,11 @@ func ReadyCondition( storageErrorsFunc func() error, // typically Kubelet.runtimeState.storageErrors cmStatusFunc func() cm.Status, // typically Kubelet.containerManager.Status nodeShutdownManagerErrorsFunc func() error, // typically kubelet.shutdownManager.errors. - recordEventFunc func(eventType, event string), // typically Kubelet.recordNodeStatusEvent + recordEventFunc func(logger klog.Logger, eventType, event string), // typically Kubelet.recordNodeStatusEvent localStorageCapacityIsolation bool, ) Setter { return func(ctx context.Context, node *v1.Node) error { + logger := klog.FromContext(ctx) // NOTE(aaronlevy): NodeReady condition needs to be the last in the list of node conditions. // This is due to an issue with version skewed kubelet and master components. // ref: https://github.com/kubernetes/kubernetes/issues/16961 @@ -539,9 +540,9 @@ func ReadyCondition( } if needToRecordEvent { if newNodeReadyCondition.Status == v1.ConditionTrue { - recordEventFunc(v1.EventTypeNormal, events.NodeReady) + recordEventFunc(logger, v1.EventTypeNormal, events.NodeReady) } else { - recordEventFunc(v1.EventTypeNormal, events.NodeNotReady) + recordEventFunc(logger, v1.EventTypeNormal, events.NodeNotReady) logger := klog.FromContext(ctx) logger.Info("Node became not ready", "node", klog.KObj(node), "condition", newNodeReadyCondition) } @@ -553,9 +554,10 @@ func ReadyCondition( // MemoryPressureCondition returns a Setter that updates the v1.NodeMemoryPressure condition on the node. func MemoryPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock.Now pressureFunc func() bool, // typically Kubelet.evictionManager.IsUnderMemoryPressure - recordEventFunc func(eventType, event string), // typically Kubelet.recordNodeStatusEvent + recordEventFunc func(logger klog.Logger, eventType, event string), // typically Kubelet.recordNodeStatusEvent ) Setter { return func(ctx context.Context, node *v1.Node) error { + logger := klog.FromContext(ctx) currentTime := metav1.NewTime(nowFunc()) var condition *v1.NodeCondition @@ -594,14 +596,14 @@ func MemoryPressureCondition(nowFunc func() time.Time, // typically Kubelet.cloc condition.Reason = "KubeletHasInsufficientMemory" condition.Message = "kubelet has insufficient memory available" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasInsufficientMemory") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasInsufficientMemory") } } else if condition.Status != v1.ConditionFalse { condition.Status = v1.ConditionFalse condition.Reason = "KubeletHasSufficientMemory" condition.Message = "kubelet has sufficient memory available" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasSufficientMemory") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasSufficientMemory") } if newCondition { @@ -614,9 +616,10 @@ func MemoryPressureCondition(nowFunc func() time.Time, // typically Kubelet.cloc // PIDPressureCondition returns a Setter that updates the v1.NodePIDPressure condition on the node. func PIDPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock.Now pressureFunc func() bool, // typically Kubelet.evictionManager.IsUnderPIDPressure - recordEventFunc func(eventType, event string), // typically Kubelet.recordNodeStatusEvent + recordEventFunc func(logger klog.Logger, eventType, event string), // typically Kubelet.recordNodeStatusEvent ) Setter { return func(ctx context.Context, node *v1.Node) error { + logger := klog.FromContext(ctx) currentTime := metav1.NewTime(nowFunc()) var condition *v1.NodeCondition @@ -655,14 +658,14 @@ func PIDPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock.N condition.Reason = "KubeletHasInsufficientPID" condition.Message = "kubelet has insufficient PID available" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasInsufficientPID") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasInsufficientPID") } } else if condition.Status != v1.ConditionFalse { condition.Status = v1.ConditionFalse condition.Reason = "KubeletHasSufficientPID" condition.Message = "kubelet has sufficient PID available" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasSufficientPID") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasSufficientPID") } if newCondition { @@ -675,9 +678,10 @@ func PIDPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock.N // DiskPressureCondition returns a Setter that updates the v1.NodeDiskPressure condition on the node. func DiskPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock.Now pressureFunc func() bool, // typically Kubelet.evictionManager.IsUnderDiskPressure - recordEventFunc func(eventType, event string), // typically Kubelet.recordNodeStatusEvent + recordEventFunc func(logger klog.Logger, eventType, event string), // typically Kubelet.recordNodeStatusEvent ) Setter { return func(ctx context.Context, node *v1.Node) error { + logger := klog.FromContext(ctx) currentTime := metav1.NewTime(nowFunc()) var condition *v1.NodeCondition @@ -716,14 +720,14 @@ func DiskPressureCondition(nowFunc func() time.Time, // typically Kubelet.clock. condition.Reason = "KubeletHasDiskPressure" condition.Message = "kubelet has disk pressure" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasDiskPressure") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasDiskPressure") } } else if condition.Status != v1.ConditionFalse { condition.Status = v1.ConditionFalse condition.Reason = "KubeletHasNoDiskPressure" condition.Message = "kubelet has no disk pressure" condition.LastTransitionTime = currentTime - recordEventFunc(v1.EventTypeNormal, "NodeHasNoDiskPressure") + recordEventFunc(logger, v1.EventTypeNormal, "NodeHasNoDiskPressure") } if newCondition { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_linux.go index c0344c52a3..b0e4027b59 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2015 The Kubernetes Authors. @@ -38,7 +37,7 @@ type streamer interface { var _ streamer = &oomparser.OomParser{} type realWatcher struct { - recorder record.EventRecorder + recorder record.EventRecorderLogger oomStreamer streamer } @@ -46,7 +45,7 @@ var _ Watcher = &realWatcher{} // NewWatcher creates and initializes a OOMWatcher backed by Cadvisor as // the oom streamer. -func NewWatcher(recorder record.EventRecorder) (Watcher, error) { +func NewWatcher(recorder record.EventRecorderLogger) (Watcher, error) { // for test purpose _, ok := recorder.(*record.FakeRecorder) if ok { @@ -78,7 +77,7 @@ func (ow *realWatcher) Start(ctx context.Context, ref *v1.ObjectReference) error go func() { logger := klog.FromContext(ctx) - defer runtime.HandleCrash() + defer runtime.HandleCrashWithContext(ctx) for event := range outStream { if event.VictimContainerName == recordEventContainerName { @@ -87,7 +86,7 @@ func (ow *realWatcher) Start(ctx context.Context, ref *v1.ObjectReference) error if event.ProcessName != "" && event.Pid != 0 { eventMsg = fmt.Sprintf("%s, victim process: %s, pid: %d", eventMsg, event.ProcessName, event.Pid) } - ow.recorder.Eventf(ref, v1.EventTypeWarning, systemOOMEvent, eventMsg) + ow.recorder.WithLogger(logger).Eventf(ref, v1.EventTypeWarning, systemOOMEvent, "%s", eventMsg) } } logger.Error(nil, "Unexpectedly stopped receiving OOM notifications") diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_unsupported.go index d0abd9253b..38767c4a18 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/oom/oom_watcher_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/evented.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/evented.go index c0a3ca5c98..2fea1ebb84 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/evented.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/evented.go @@ -118,6 +118,10 @@ func (e *EventedPLEG) Relist() { e.genericPleg.Relist() } +func (e *EventedPLEG) RequestRelist(podUID types.UID) { + e.genericPleg.RequestRelist(podUID) +} + // Start starts the Evented PLEG func (e *EventedPLEG) Start() { e.runningMu.Lock() @@ -416,6 +420,6 @@ func (e *EventedPLEG) updateLatencyMetric(event *runtimeapi.ContainerEventRespon metrics.EventedPLEGConnLatency.Observe(duration.Seconds()) } -func (e *EventedPLEG) SetPodWatchCondition(podUID types.UID, conditionKey string, condition WatchCondition) { - e.genericPleg.SetPodWatchCondition(podUID, conditionKey, condition) +func (e *EventedPLEG) RequestReinspect(podUID types.UID) { + e.genericPleg.RequestReinspect(podUID) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/generic.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/generic.go index 5db6ae40e4..ffa2e75b24 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/generic.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/generic.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" @@ -42,7 +41,7 @@ import ( // // Note that GenericPLEG assumes that a container would not be created, // terminated, and garbage collected within one relist period. If such an -// incident happens, GenenricPLEG would miss all events regarding this +// incident happens, GenericPLEG would miss all events regarding this // container. In the case of relisting failure, the window may become longer. // Note that this assumption is not unique -- many kubelet internal components // rely on terminated containers as tombstones for bookkeeping purposes. The @@ -56,6 +55,7 @@ type GenericPLEG struct { // The channel from which the subscriber listens events. eventChannel chan *PodLifecycleEvent // The internal cache for pod/container information. + // Guarded by relistLock. podRecords podRecords // Time of the last relisting. relistTime atomic.Value @@ -65,7 +65,7 @@ type GenericPLEG struct { clock clock.Clock // Pods that failed to have their status retrieved during a relist. These pods will be // retried during the next relisting. - podsToReinspect map[types.UID]*kubecontainer.Pod + podsToReinspect sync.Map // map: podUID -> empty // Stop the Generic PLEG by closing the channel. stopCh chan struct{} // Locks the relisting of the Generic PLEG @@ -78,17 +78,14 @@ type GenericPLEG struct { relistDuration *RelistDuration // logger is used for contextual logging logger klog.Logger - // watchConditions tracks pod watch conditions, guarded by watchConditionsLock - // watchConditions is a map of pod UID -> condition key -> condition - watchConditions map[types.UID]map[string]versionedWatchCondition - watchConditionsLock sync.Mutex + // relistRequests is the queue of on-demand pod relist requests. + relistRequests chan relistRequest + // globalRelistTimer controls the periodic global relist. + globalRelistTimer clock.Timer } -type versionedWatchCondition struct { - key string - condition WatchCondition - version uint32 -} +// Empty placeholder value for podsToReinspect (shared pointer reduces allocations). +var empty = &struct{}{} // plegContainerState has a one-to-one mapping to the // kubecontainer.State except for the non-existent state. This state @@ -118,6 +115,15 @@ func convertState(state kubecontainer.State) plegContainerState { } } +// relistRequest is used to track on-demand single-pod relist requests. +type relistRequest struct { + // podUID is the UID of the pod to relist. + podUID types.UID + // timestamp is the time the request was made. If the pod has already been relisted by the time + // this request is executed, the request will be skipped. + timestamp time.Time +} + type podRecord struct { old *kubecontainer.Pod current *kubecontainer.Pod @@ -133,14 +139,14 @@ func NewGenericPLEG(logger klog.Logger, runtime kubecontainer.Runtime, eventChan panic("cache cannot be nil") } return &GenericPLEG{ - logger: logger, - relistDuration: relistDuration, - runtime: runtime, - eventChannel: eventChannel, - podRecords: make(podRecords), - cache: cache, - clock: clock, - watchConditions: make(map[types.UID]map[string]versionedWatchCondition), + logger: logger, + relistDuration: relistDuration, + runtime: runtime, + eventChannel: eventChannel, + podRecords: make(podRecords), + cache: cache, + clock: clock, + relistRequests: make(chan relistRequest, 200), } } @@ -155,11 +161,20 @@ func (g *GenericPLEG) Watch() chan *PodLifecycleEvent { func (g *GenericPLEG) Start() { g.runningMu.Lock() defer g.runningMu.Unlock() - if !g.isRunning { - g.isRunning = true - g.stopCh = make(chan struct{}) - go wait.Until(g.Relist, g.relistDuration.RelistPeriod, g.stopCh) + if g.isRunning { + return } + + g.isRunning = true + g.stopCh = make(chan struct{}) + // Set 0 to trigger the first relist immediately + // The RelistPeriod is set after the first relist. + g.globalRelistTimer = g.clock.NewTimer(0) + + go func() { + for g.workerLoopIteration() { + } + }() } func (g *GenericPLEG) Stop() { @@ -168,9 +183,52 @@ func (g *GenericPLEG) Stop() { if g.isRunning { close(g.stopCh) g.isRunning = false + g.globalRelistTimer.Stop() } } +// workerLoopIteration is the primary work dispatcher for the PLEG. It uses non-blocking channel +// reads for a prioritized work selection: +// 1. stop: exit the workerLoop if stopCh has been closed. +// 2. global relist: the global relist timer takes priority over single-pod relists. +// 3. single pod relist: execute a request from the single-pod relist queue. +func (g *GenericPLEG) workerLoopIteration() bool { + // Use non-blocking selects for prioritized selection. + + // First priority: stopCh + select { + case <-g.stopCh: + return false + default: + } + + // Second priority: global Relist + select { + case <-g.globalRelistTimer.C(): + g.Relist() + g.globalRelistTimer.Reset(g.relistDuration.RelistPeriod) + return true + default: + } + + // Fallback: blocking select + select { + case <-g.stopCh: + return false + case <-g.globalRelistTimer.C(): + g.Relist() + g.globalRelistTimer.Reset(g.relistDuration.RelistPeriod) + case req := <-g.relistRequests: + if req.timestamp.After(g.getRelistTime()) { + // The request hasn't already been served by the global relist. + g.relistPod(req.podUID) + } + } + + return true +} + +// This must not be called while the GenericPLEG is running. func (g *GenericPLEG) Update(relistDuration *RelistDuration) { g.relistDuration = relistDuration } @@ -261,111 +319,136 @@ func (g *GenericPLEG) Relist() { // update running pod and container count updateRunningPodAndContainerMetrics(pods) g.podRecords.setCurrent(pods) - g.cleanupOrphanedWatchConditions() - - needsReinspection := make(map[types.UID]*kubecontainer.Pod) for pid := range g.podRecords { - // Compare the old and the current pods, and generate events. - oldPod := g.podRecords.getOld(pid) - pod := g.podRecords.getCurrent(pid) - // Get all containers in the old and the new pod. - allContainers := getContainersFromPods(oldPod, pod) - var events []*PodLifecycleEvent - for _, container := range allContainers { - containerEvents := computeEvents(g.logger, oldPod, pod, &container.ID) - events = append(events, containerEvents...) - } + g.reconcilePodRecord(ctx, pid) + } - watchConditions := g.getPodWatchConditions(pid) - _, reinspect := g.podsToReinspect[pid] + // Update the cache timestamp. This needs to happen *after* + // all pods have been properly updated in the cache. + g.cache.UpdateTime(timestamp) +} - if len(events) == 0 && len(watchConditions) == 0 && !reinspect { - // Nothing else needed for this pod. - continue - } +// reconcilePodRecord compares the old & current pod record and checks for event-worthy state +// changes. If any events are generated, or the pod needs reinspection, it fetches the updated +// status, updates the pod cache, and delivers the events. This function should only be called after +// the current pod record has been updated. +func (g *GenericPLEG) reconcilePodRecord(ctx context.Context, pid types.UID) { + // Compare the old and the current pods, and generate events. + oldPod := g.podRecords.getOld(pid) + pod := g.podRecords.getCurrent(pid) + // Get all containers in the old and the new pod. + allContainers := getContainersFromPods(oldPod, pod) + var events []*PodLifecycleEvent + for _, container := range allContainers { + containerEvents := computeEvents(g.logger, oldPod, pod, &container.ID) + events = append(events, containerEvents...) + } + + _, reinspect := g.podsToReinspect.LoadAndDelete(pid) + + if len(events) == 0 && !reinspect { + // Nothing else needed for this pod. + return + } - // updateCache() will inspect the pod and update the cache. If an - // error occurs during the inspection, we want PLEG to retry again - // in the next relist. To achieve this, we do not update the - // associated podRecord of the pod, so that the change will be - // detect again in the next relist. - // TODO: If many pods changed during the same relist period, - // inspecting the pod and getting the PodStatus to update the cache - // serially may take a while. We should be aware of this and - // parallelize if needed. - status, updated, err := g.updateCache(ctx, pod, pid) - if err != nil { - // Rely on updateCache calling GetPodStatus to log the actual error. - g.logger.V(4).Info("PLEG: Ignoring events for pod", "pod", klog.KRef(pod.Namespace, pod.Name), "err", err) - - // make sure we try to reinspect the pod during the next relisting - needsReinspection[pid] = pod + // updateCache() will inspect the pod and update the cache. If an + // error occurs during the inspection, we want PLEG to retry again + // in the next relist. To achieve this, we do not update the + // associated podRecord of the pod, so that the change will be + // detect again in the next relist. + // TODO: If many pods changed during the same relist period, + // inspecting the pod and getting the PodStatus to update the cache + // serially may take a while. We should be aware of this and + // parallelize if needed. + status, updated, err := g.updateCache(ctx, pod, pid) + if err != nil { + // Rely on updateCache calling GetPodStatus to log the actual error. + g.logger.V(4).Info("PLEG: Ignoring events for pod", "pod", klog.KRef(pod.Namespace, pod.Name), "err", err) - continue - } else if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { - if !updated { - continue - } - } + // make sure we try to reinspect the pod during the next relisting + g.podsToReinspect.Store(pid, empty) - var completedConditions []versionedWatchCondition - for _, condition := range watchConditions { - if condition.condition(status) { - // condition was met: add it to the list of completed conditions. - completedConditions = append(completedConditions, condition) - } - } - if len(completedConditions) > 0 { - g.completeWatchConditions(pid, completedConditions) - // If at least 1 condition completed, emit a ConditionMet event to trigger a pod sync. - // We only emit 1 event even if multiple conditions are met, since SyncPod reevaluates - // all containers in the pod with the latest status. - events = append(events, &PodLifecycleEvent{ID: pid, Type: ConditionMet}) + return + } else if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + if !updated { + return } + } - // Update the internal storage and send out the events. - g.podRecords.update(pid) + if len(events) == 0 { + // Make sure we always trigger a PodSync after a full reinspection. + events = append(events, &PodLifecycleEvent{ID: pid, Type: PodSync}) + } - // Map from containerId to exit code; used as a temporary cache for lookup - containerExitCode := make(map[string]int) + // Update the internal storage and send out the events. + g.podRecords.update(pid) - for i := range events { - // Filter out events that are not reliable and no other components use yet. - if events[i].Type == ContainerChanged { - continue - } - select { - case g.eventChannel <- events[i]: - default: - metrics.PLEGDiscardEvents.Inc() - g.logger.Error(nil, "Event channel is full, discard this relist() cycle event") - } - // Log exit code of containers when they finished in a particular event - if events[i].Type == ContainerDied { - // Fill up containerExitCode map for ContainerDied event when first time appeared - if len(containerExitCode) == 0 && pod != nil { - if err == nil { - for _, containerStatus := range status.ContainerStatuses { - containerExitCode[containerStatus.ID.ID] = containerStatus.ExitCode - } + // Map from containerId to exit code; used as a temporary cache for lookup + containerExitCode := make(map[string]int) + + for i := range events { + // Filter out events that are not reliable and no other components use yet. + if events[i].Type == ContainerChanged { + continue + } + select { + case g.eventChannel <- events[i]: + default: + metrics.PLEGDiscardEvents.Inc() + g.logger.Error(nil, "Event channel is full, discard this relist() cycle event") + } + // Log exit code of containers when they finished in a particular event + if events[i].Type == ContainerDied { + // Fill up containerExitCode map for ContainerDied event when first time appeared + if len(containerExitCode) == 0 && pod != nil { + if err == nil { + for _, containerStatus := range status.ContainerStatuses { + containerExitCode[containerStatus.ID.ID] = containerStatus.ExitCode } } - if containerID, ok := events[i].Data.(string); ok { - if exitCode, ok := containerExitCode[containerID]; ok && pod != nil { - g.logger.V(2).Info("Generic (PLEG): container finished", "podID", pod.ID, "containerID", containerID, "exitCode", exitCode) - } + } + if containerID, ok := events[i].Data.(string); ok { + if exitCode, ok := containerExitCode[containerID]; ok && pod != nil { + g.logger.V(2).Info("Generic (PLEG): container finished", "podID", pod.ID, "containerID", containerID, "exitCode", exitCode) } } } } +} - // Update the cache timestamp. This needs to happen *after* - // all pods have been properly updated in the cache. - g.cache.UpdateTime(timestamp) +func (g *GenericPLEG) relistPod(podUID types.UID) { + g.relistLock.Lock() + defer g.relistLock.Unlock() + + ctx := context.Background() + + g.logger.V(5).Info("GenericPLEG: Relisting Pod", "podUID", podUID) + + startTime := g.clock.Now() + defer func() { + metrics.PLEGPodRelistDuration.Observe(metrics.SinceInSeconds(startTime)) + }() + pod, err := g.runtime.GetPod(ctx, podUID) + if err != nil { + // We don't need to do anything other than log the error here, since it will be retried by + // the next global relist. + g.logger.Error(err, "GenericPLEG: Unable to retrieve pod", "podUID", podUID) + return + } + + // Update current pod record + if pr, ok := g.podRecords[pod.ID]; ok { + pr.current = pod + } else { + g.podRecords[pod.ID] = &podRecord{current: pod} + } + + g.reconcilePodRecord(ctx, podUID) - // make sure we retain the list of pods that need reinspecting the next time relist is called - g.podsToReinspect = needsReinspection + // Since we're not setting the global timestamp, we need to mark this pod as observed in case it + // wasn't modified. + g.cache.SetObservedTime(podUID, pod.Timestamp) } func getContainersFromPods(pods ...*kubecontainer.Pod) []*kubecontainer.Container { @@ -442,9 +525,8 @@ func (g *GenericPLEG) updateCache(ctx context.Context, pod *kubecontainer.Pod, p return nil, true, nil } - timestamp := g.clock.Now() - - status, err := g.runtime.GetPodStatus(ctx, pod.ID, pod.Name, pod.Namespace) + timestamp := pod.Timestamp + status, err := g.runtime.GetPodStatus(ctx, pod) if err != nil { // nolint:logcheck // Not using the result of klog.V inside the // if branch is okay, we just use it to determine whether the @@ -484,86 +566,19 @@ func (g *GenericPLEG) updateCache(ctx context.Context, pod *kubecontainer.Pod, p return status, g.cache.Set(pod.ID, status, err, timestamp), err } -// SetPodWatchCondition flags the pod for reinspection on every Relist iteration until the watch -// condition is met. The condition is keyed so it can be updated before the condition -// is met. -func (g *GenericPLEG) SetPodWatchCondition(podUID types.UID, conditionKey string, condition WatchCondition) { - g.watchConditionsLock.Lock() - defer g.watchConditionsLock.Unlock() - - conditions, ok := g.watchConditions[podUID] - if !ok { - conditions = make(map[string]versionedWatchCondition) - } - - versioned, found := conditions[conditionKey] - if found { - // Watch condition was already set. Increment its version & update the condition function. - versioned.version++ - versioned.condition = condition - conditions[conditionKey] = versioned - } else { - conditions[conditionKey] = versionedWatchCondition{ - key: conditionKey, - condition: condition, - } - } - - g.watchConditions[podUID] = conditions -} - -// getPodWatchConditions returns a list of the active watch conditions for the pod. -func (g *GenericPLEG) getPodWatchConditions(podUID types.UID) []versionedWatchCondition { - g.watchConditionsLock.Lock() - defer g.watchConditionsLock.Unlock() - - podConditions, ok := g.watchConditions[podUID] - if !ok { - return nil - } - - // Flatten the map into a list of conditions. This also serves to create a copy, so the lock can - // be released. - conditions := make([]versionedWatchCondition, 0, len(podConditions)) - for _, condition := range podConditions { - conditions = append(conditions, condition) - } - return conditions +func (g *GenericPLEG) RequestReinspect(podUID types.UID) { + g.podsToReinspect.Store(podUID, empty) } -// completeWatchConditions removes the completed watch conditions, unless they have been updated -// since the condition was checked. -func (g *GenericPLEG) completeWatchConditions(podUID types.UID, completedConditions []versionedWatchCondition) { - g.watchConditionsLock.Lock() - defer g.watchConditionsLock.Unlock() - - conditions, ok := g.watchConditions[podUID] - if !ok { - // Pod was deleted, nothing to do. +func (g *GenericPLEG) RequestRelist(podUID types.UID) { + if !utilfeature.DefaultFeatureGate.Enabled(features.PLEGOnDemandRelist) { return } - for _, completed := range completedConditions { - condition := conditions[completed.key] - // Only clear the condition if it has not been updated. - if condition.version == completed.version { - delete(conditions, completed.key) - } - } - g.watchConditions[podUID] = conditions -} - -// cleanupOrphanedWatchConditions purges the watchConditions map of any pods that were removed from -// the pod records. Events are not emitted for removed pods. -func (g *GenericPLEG) cleanupOrphanedWatchConditions() { - g.watchConditionsLock.Lock() - defer g.watchConditionsLock.Unlock() - - for podUID := range g.watchConditions { - if g.podRecords.getCurrent(podUID) == nil { - // Pod was deleted, remove it from the watch conditions. - delete(g.watchConditions, podUID) - } + select { + case g.relistRequests <- relistRequest{podUID, time.Now()}: + default: + g.logger.Error(nil, "Relist request channel full; dropping relist request", "podUID", podUID) } } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/pleg.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/pleg.go index 08625aba9c..fd13867c16 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/pleg.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pleg/pleg.go @@ -20,7 +20,6 @@ import ( "time" "k8s.io/apimachinery/pkg/types" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) // PodLifeCycleEventType define the event type of pod life cycle events. @@ -47,8 +46,6 @@ const ( PodSync PodLifeCycleEventType = "PodSync" // ContainerChanged - event type when the new state of container is unknown. ContainerChanged PodLifeCycleEventType = "ContainerChanged" - // ConditionMet - event type triggered when any number of watch conditions are met. - ConditionMet PodLifeCycleEventType = "ConditionMet" ) // PodLifecycleEvent is an event that reflects the change of the pod state. @@ -68,10 +65,10 @@ type PodLifecycleEventGenerator interface { Start() Watch() chan *PodLifecycleEvent Healthy() (bool, error) - // SetPodWatchCondition flags the pod for reinspection on every Relist iteration until the watch - // condition is met. The condition is keyed so it can be updated before the condition - // is met. - SetPodWatchCondition(podUID types.UID, conditionKey string, condition WatchCondition) + // RequestReinspect flags the pod for reinspection on the next Relist iteration. + RequestReinspect(podUID types.UID) + // RequestRelist queues up the pod for an on-demand relist. + RequestRelist(podUID types.UID) } // podLifecycleEventGeneratorHandler contains functions that are useful for different PLEGs @@ -82,19 +79,3 @@ type podLifecycleEventGeneratorHandler interface { Update(relistDuration *RelistDuration) Relist() } - -// WatchCondition takes the latest PodStatus, and returns whether the condition is met. -type WatchCondition = func(*kubecontainer.PodStatus) bool - -// RunningContainerWatchCondition wraps a condition on the container status to make a pod -// WatchCondition. If the container is no longer running, the condition is implicitly cleared. -func RunningContainerWatchCondition(containerName string, condition func(*kubecontainer.Status) bool) WatchCondition { - return func(podStatus *kubecontainer.PodStatus) bool { - status := podStatus.FindContainerStatusByName(containerName) - if status == nil || status.State != kubecontainer.ContainerStateRunning { - // Container isn't running. Consider the condition "completed" so it is cleared. - return true - } - return condition(status) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor/operation_generator.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor/operation_generator.go index 745ca23154..725197323d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor/operation_generator.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor/operation_generator.go @@ -130,11 +130,14 @@ func (og *operationGenerator) GenerateRegisterPluginFunc( logger.Error(err, "RegisterPlugin error -- failed to add plugin", "path", socketPath) } if err := handler.RegisterPlugin(infoResp.Name, infoResp.Endpoint, infoResp.SupportedVersions, nil); err != nil { + actualStateOfWorldUpdater.RemovePlugin(socketPath) return og.notifyPlugin(ctx, client, false, fmt.Sprintf("RegisterPlugin error -- plugin registration failed with err: %v", err)) } // Notify is called after register to guarantee that even if notify throws an error Register will always be called after validate if err := og.notifyPlugin(ctx, client, true, ""); err != nil { + actualStateOfWorldUpdater.RemovePlugin(socketPath) + handler.DeRegisterPlugin(infoResp.Name, infoResp.Endpoint) return fmt.Errorf("RegisterPlugin error -- failed to send registration status at socket %s, err: %v", socketPath, err) } return nil diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/plugin_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/plugin_manager.go index 754c30ba31..060664ee3d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/plugin_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/plugin_manager.go @@ -107,7 +107,7 @@ type pluginManager struct { var _ PluginManager = &pluginManager{} func (pm *pluginManager) Run(ctx context.Context, sourcesReady config.SourcesReady, stopCh <-chan struct{}) { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithContext(ctx) logger := klog.FromContext(ctx) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_others.go index 2ecb570238..7edcea12f6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_windows.go index 476ae4fc0c..ae9edc2e03 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/plugin_watcher_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers.go index d2539a8bd7..0f3034e262 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers.go @@ -19,6 +19,7 @@ package kubelet import ( "context" "encoding/json" + "errors" "fmt" "strings" "sync" @@ -164,7 +165,7 @@ type PodWorkers interface { // UpdatePod() calls will be ignored for that pod until it has been forgotten // due to significant time passing. A pod that is terminated will never be // restarted. - UpdatePod(options UpdatePodOptions) + UpdatePod(ctx context.Context, options UpdatePodOptions) // SyncKnownPods removes workers for pods that are not in the desiredPods set // and have been terminated for a significant period of time. Once this method // has been called once, the workers are assumed to be fully initialized and @@ -172,7 +173,7 @@ type PodWorkers interface { // true. It returns a map describing the state of each known pod worker. It // is the responsibility of the caller to re-add any desired pods that are not // returned as knownPods. - SyncKnownPods(desiredPods []*v1.Pod) (knownPods map[types.UID]PodWorkerSync) + SyncKnownPods(logger klog.Logger, desiredPods []*v1.Pod) (knownPods map[types.UID]PodWorkerSync) // IsPodKnownTerminated returns true once SyncTerminatingPod completes // successfully - the provided pod UID it is known by the pod @@ -266,7 +267,7 @@ type podSyncer interface { // pod has reached a terminal state and the presence of the error indicates succeeded or failed. // If an error is returned, the sync was not successful and should be rerun in the future. This // is a long running method and should exit early with context.Canceled if the context is canceled. - SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, error) + SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, func(), error) // SyncTerminatingPod attempts to ensure the pod's containers are no longer running and to collect // any final status. This method is repeatedly invoked with diminishing grace periods until it exits // without error. Once this method exits with no error other components are allowed to tear down @@ -284,7 +285,7 @@ type podSyncer interface { SyncTerminatedPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus) error } -type syncPodFnType func(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, error) +type syncPodFnType func(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, func(), error) type syncTerminatingPodFnType func(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, gracePeriod *int64, podStatusFn func(*v1.PodStatus)) error type syncTerminatingRuntimePodFnType func(ctx context.Context, runningPod *kubecontainer.Pod) error type syncTerminatedPodFnType func(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus) error @@ -308,7 +309,7 @@ func newPodSyncerFuncs(s podSyncer) podSyncerFuncs { var _ podSyncer = podSyncerFuncs{} -func (f podSyncerFuncs) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, error) { +func (f podSyncerFuncs) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, func(), error) { return f.syncPod(ctx, updateType, pod, mirrorPod, podStatus) } func (f podSyncerFuncs) SyncTerminatingPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, gracePeriod *int64, podStatusFn func(*v1.PodStatus)) error { @@ -335,11 +336,6 @@ const ( // podSyncStatus tracks per-pod transitions through the three phases of pod // worker sync (setup, terminating, terminated). type podSyncStatus struct { - // ctx is the context that is associated with the current pod sync. - // TODO: remove this from the struct by having the context initialized - // in startPodSync, the cancelFn used by UpdatePod, and cancellation of - // a parent context for tearing down workers (if needed) on shutdown - ctx context.Context // cancelFn if set is expected to cancel the current podSyncer operation. cancelFn context.CancelFunc @@ -606,7 +602,7 @@ type podWorkers struct { resyncInterval time.Duration // podCache stores kubecontainer.PodStatus for all pods. - podCache kubecontainer.Cache + podCache kubecontainer.ROCache // allocationManager is used to allocate resources for pods allocationManager allocation.Manager @@ -620,7 +616,7 @@ func newPodWorkers( recorder record.EventRecorder, workQueue queue.WorkQueue, resyncInterval, backOffPeriod time.Duration, - podCache kubecontainer.Cache, + podCache kubecontainer.ROCache, allocationManager allocation.Manager, ) PodWorkers { return &podWorkers{ @@ -752,7 +748,8 @@ func isPodStatusCacheTerminal(status *kubecontainer.PodStatus) bool { // UpdatePod carries a configuration change or termination state to a pod. A pod is either runnable, // terminating, or terminated, and will transition to terminating if: deleted on the apiserver, // discovered to have a terminal phase (Succeeded or Failed), or evicted by the kubelet. -func (p *podWorkers) UpdatePod(options UpdatePodOptions) { +func (p *podWorkers) UpdatePod(ctx context.Context, options UpdatePodOptions) { + logger := klog.FromContext(ctx) // Handle when the pod is an orphan (no config) and we only have runtime status by running only // the terminating part of the lifecycle. A running pod contains only a minimal set of information // about the pod @@ -763,7 +760,7 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { if options.Pod == nil { // the sythetic pod created here is used only as a placeholder and not tracked if options.UpdateType != kubetypes.SyncPodKill { - klog.InfoS("Pod update is ignored, runtime pods can only be killed", "pod", klog.KRef(runningPod.Namespace, runningPod.Name), "podUID", runningPod.ID, "updateType", options.UpdateType) + logger.Info("Pod update is ignored, runtime pods can only be killed", "pod", klog.KRef(runningPod.Namespace, runningPod.Name), "podUID", runningPod.ID, "updateType", options.UpdateType) return } uid, ns, name = runningPod.ID, runningPod.Namespace, runningPod.Name @@ -771,12 +768,13 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { } else { options.RunningPod = nil uid, ns, name = options.Pod.UID, options.Pod.Namespace, options.Pod.Name - klog.InfoS("Pod update included RunningPod which is only valid when Pod is not specified", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + logger.Info("Pod update included RunningPod which is only valid when Pod is not specified", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) } } else { uid, ns, name = options.Pod.UID, options.Pod.Namespace, options.Pod.Name } + updateLogger := logger.WithValues("pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) p.podLock.Lock() defer p.podLock.Unlock() @@ -785,7 +783,7 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { now := p.clock.Now() status, ok := p.podSyncStatuses[uid] if !ok { - klog.V(4).InfoS("Pod is being synced for the first time", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is being synced for the first time") firstTime = true status = &podSyncStatus{ syncedAt: now, @@ -850,14 +848,14 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { if !firstTime && status.IsTerminationRequested() { if options.UpdateType == kubetypes.SyncPodCreate { status.restartRequested = true - klog.V(4).InfoS("Pod is terminating but has been requested to restart with same UID, will be reconciled later", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is terminating but has been requested to restart with same UID, will be reconciled later") return } } // once a pod is terminated by UID, it cannot reenter the pod worker (until the UID is purged by housekeeping) if status.IsFinished() { - klog.V(4).InfoS("Pod is finished processing, no further updates", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is finished processing, no further updates") return } @@ -866,25 +864,25 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { if !status.IsTerminationRequested() { switch { case isRuntimePod: - klog.V(4).InfoS("Pod is orphaned and must be torn down", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is orphaned and must be torn down") status.deleted = true status.terminatingAt = now becameTerminating = true case pod.DeletionTimestamp != nil: - klog.V(4).InfoS("Pod is marked for graceful deletion, begin teardown", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is marked for graceful deletion, begin teardown") status.deleted = true status.terminatingAt = now becameTerminating = true case pod.Status.Phase == v1.PodFailed, pod.Status.Phase == v1.PodSucceeded: - klog.V(4).InfoS("Pod is in a terminal phase (success/failed), begin teardown", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is in a terminal phase (success/failed), begin teardown") status.terminatingAt = now becameTerminating = true case options.UpdateType == kubetypes.SyncPodKill: if options.KillPodOptions != nil && options.KillPodOptions.Evict { - klog.V(4).InfoS("Pod is being evicted by the kubelet, begin teardown", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is being evicted by the kubelet, begin teardown") status.evicted = true } else { - klog.V(4).InfoS("Pod is being removed by the kubelet, begin teardown", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(4).Info("Pod is being removed by the kubelet, begin teardown") } status.terminatingAt = now becameTerminating = true @@ -899,7 +897,7 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { // due to housekeeping seeing an older cached version of the runtime pod simply ignore it until // after the pod worker completes. if isRuntimePod { - klog.V(3).InfoS("Pod is waiting for termination, ignoring runtime-only kill until after pod worker is fully terminated", "pod", klog.KRef(ns, name), "podUID", uid, "updateType", options.UpdateType) + updateLogger.V(3).Info("Pod is waiting for termination, ignoring runtime-only kill until after pod worker is fully terminated") return } @@ -966,8 +964,8 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { // TODO: this should be a wait.Until with backoff to handle panics, and // accept a context for shutdown defer runtime.HandleCrash() - defer klog.V(3).InfoS("Pod worker has stopped", "podUID", uid) - p.podWorkerLoop(uid, outCh) + defer logger.V(3).Info("Pod worker has stopped", "podUID", uid) + p.podWorkerLoop(ctx, uid, outCh) }() } @@ -983,14 +981,14 @@ func (p *podWorkers) UpdatePod(options UpdatePodOptions) { status.pendingUpdate.Pod, _ = p.allocationManager.UpdatePodFromAllocation(options.Pod) } status.working = true - klog.V(4).InfoS("Notifying pod of pending update", "pod", klog.KRef(ns, name), "podUID", uid, "workType", status.WorkType()) + updateLogger.V(4).Info("Notifying pod of pending update", "workType", status.WorkType()) select { case podUpdates <- struct{}{}: default: } if (becameTerminating || wasGracePeriodShortened) && status.cancelFn != nil { - klog.V(3).InfoS("Cancelling current pod sync", "pod", klog.KRef(ns, name), "podUID", uid, "workType", status.WorkType()) + updateLogger.V(3).Info("Cancelling current pod sync", "workType", status.WorkType()) status.cancelFn() return } @@ -1035,7 +1033,7 @@ func calculateEffectiveGracePeriod(status *podSyncStatus, pod *v1.Pod, options * // it requeues the pod and returns false. If the pod will never be able to start // because data is missing, or the pod was terminated before start, canEverStart // is false. This method can only be called while holding the pod lock. -func (p *podWorkers) allowPodStart(pod *v1.Pod) (canStart bool, canEverStart bool) { +func (p *podWorkers) allowPodStart(logger klog.Logger, pod *v1.Pod) (canStart bool, canEverStart bool) { if !kubetypes.IsStaticPod(pod) { // TODO: Do we want to allow non-static pods with the same full name? // Note that it may disable the force deletion of pods. @@ -1043,7 +1041,7 @@ func (p *podWorkers) allowPodStart(pod *v1.Pod) (canStart bool, canEverStart boo } status, ok := p.podSyncStatuses[pod.UID] if !ok { - klog.ErrorS(nil, "Pod sync status does not exist, the worker should not be running", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.Error(nil, "Pod sync status does not exist, the worker should not be running", "pod", klog.KObj(pod), "podUID", pod.UID) return false, false } if status.IsTerminationRequested() { @@ -1094,14 +1092,14 @@ func (p *podWorkers) allowStaticPodStart(fullname string, uid types.UID) bool { // cleanupUnstartedPod is invoked if a pod that has never been started receives a termination // signal before it can be started. This method must be called holding the pod lock. -func (p *podWorkers) cleanupUnstartedPod(pod *v1.Pod, status *podSyncStatus) { +func (p *podWorkers) cleanupUnstartedPod(logger klog.Logger, pod *v1.Pod, status *podSyncStatus) { p.cleanupPodUpdates(pod.UID) if status.terminatingAt.IsZero() { - klog.V(4).InfoS("Pod worker is complete but did not have terminatingAt set, likely programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod worker is complete but did not have terminatingAt set, likely programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) } if !status.terminatedAt.IsZero() { - klog.V(4).InfoS("Pod worker is complete and had terminatedAt set, likely programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) + logger.V(4).Info("Pod worker is complete and had terminatedAt set, likely programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) } status.finished = true status.working = false @@ -1121,7 +1119,7 @@ func (p *podWorkers) cleanupUnstartedPod(pod *v1.Pod, status *podSyncStatus) { // This method should ensure that either status.pendingUpdate is cleared and merged into status.activeUpdate, // or when a pod cannot be started status.pendingUpdate remains the same. Pods that have not been started // should never have an activeUpdate because that is exposed to downstream components on started pods. -func (p *podWorkers) startPodSync(podUID types.UID) (ctx context.Context, update podWork, canStart, canEverStart, ok bool) { +func (p *podWorkers) startPodSync(parentCtx context.Context, podUID types.UID) (ctx context.Context, update podWork, canStart, canEverStart, ok bool) { p.podLock.Lock() defer p.podLock.Unlock() @@ -1129,18 +1127,18 @@ func (p *podWorkers) startPodSync(podUID types.UID) (ctx context.Context, update status, ok := p.podSyncStatuses[podUID] if !ok { // pod status has disappeared, the worker should exit - klog.V(4).InfoS("Pod worker no longer has status, worker should exit", "podUID", podUID) return nil, update, false, false, false } + logger := klog.FromContext(parentCtx) if !status.working { // working is used by unit tests to observe whether a worker is currently acting on this pod - klog.V(4).InfoS("Pod should be marked as working by the pod worker, programmer error", "podUID", podUID) + logger.V(4).Info("Pod should be marked as working by the pod worker, programmer error", "podUID", podUID) } if status.pendingUpdate == nil { // no update available, this means we were queued without work being added or there is a // race condition, both of which are unexpected status.working = false - klog.V(4).InfoS("Pod worker received no pending work, programmer error?", "podUID", podUID) + logger.V(4).Info("Pod worker received no pending work, programmer error?", "podUID", podUID) return nil, update, false, false, false } @@ -1154,11 +1152,7 @@ func (p *podWorkers) startPodSync(podUID types.UID) (ctx context.Context, update default: } - // initialize a context for the worker if one does not exist - if status.ctx == nil || status.ctx.Err() == context.Canceled { - status.ctx, status.cancelFn = context.WithCancel(context.Background()) - } - ctx = status.ctx + ctx, status.cancelFn = context.WithCancel(parentCtx) // if we are already started, make our state visible to downstream components if status.IsStarted() { @@ -1178,26 +1172,26 @@ func (p *podWorkers) startPodSync(podUID types.UID) (ctx context.Context, update // asked to start such a pod, but guard here just in case an accident occurs. if update.Options.Pod == nil { status.mergeLastUpdate(update.Options) - klog.V(4).InfoS("Running pod cannot start ever, programmer error", "pod", klog.KObj(update.Options.Pod), "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Running pod cannot start ever, programmer error", "pod", klog.KObj(update.Options.Pod), "podUID", podUID, "updateType", update.WorkType) return ctx, update, false, false, true } // verify we can start - canStart, canEverStart = p.allowPodStart(update.Options.Pod) + canStart, canEverStart = p.allowPodStart(logger, update.Options.Pod) switch { case !canEverStart: - p.cleanupUnstartedPod(update.Options.Pod, status) + p.cleanupUnstartedPod(logger, update.Options.Pod, status) status.working = false if start := update.Options.StartTime; !start.IsZero() { metrics.PodWorkerDuration.WithLabelValues("terminated").Observe(metrics.SinceInSeconds(start)) } - klog.V(4).InfoS("Pod cannot start ever", "pod", klog.KObj(update.Options.Pod), "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Pod cannot start ever", "pod", klog.KObj(update.Options.Pod), "podUID", podUID, "updateType", update.WorkType) return ctx, update, canStart, canEverStart, true case !canStart: // this is the only path we don't start the pod, so we need to put the change back in pendingUpdate status.pendingUpdate = &update.Options status.working = false - klog.V(4).InfoS("Pod cannot start yet", "pod", klog.KObj(update.Options.Pod), "podUID", podUID) + logger.V(4).Info("Pod cannot start yet", "pod", klog.KObj(update.Options.Pod), "podUID", podUID) return ctx, update, canStart, canEverStart, true } @@ -1234,14 +1228,15 @@ func podUIDAndRefForUpdate(update UpdatePodOptions) (types.UID, klog.ObjectRef) // to trigger new UpdatePod calls. SyncKnownPods will only retry pods that are no longer known to the // caller. When a pod transitions working->terminating or terminating->terminated, the next update is // queued immediately and no kubelet action is required. -func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{}) { +func (p *podWorkers) podWorkerLoop(parentCtx context.Context, podUID types.UID, podUpdates <-chan struct{}) { var lastSyncTime time.Time for range podUpdates { - ctx, update, canStart, canEverStart, ok := p.startPodSync(podUID) + ctx, update, canStart, canEverStart, ok := p.startPodSync(parentCtx, podUID) // If we had no update waiting, it means someone initialized the channel without filling out pendingUpdate. if !ok { continue } + logger := klog.FromContext(ctx) // If the pod was terminated prior to the pod being allowed to start, we exit the loop. if !canEverStart { return @@ -1253,7 +1248,7 @@ func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{}) podUID, podRef := podUIDAndRefForUpdate(update.Options) - klog.V(4).InfoS("Processing pod event", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Processing pod event", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) var isTerminal bool err := func() error { // The worker is responsible for ensuring the sync method sees the appropriate @@ -1287,6 +1282,7 @@ func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{}) } // Take the appropriate action (illegal phases are prevented by UpdatePod) + var postSync func() switch { case update.WorkType == TerminatedPod: err = p.podSyncer.SyncTerminatedPod(ctx, update.Options.Pod, status) @@ -1296,7 +1292,7 @@ func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{}) if opt := update.Options.KillPodOptions; opt != nil { gracePeriod = opt.PodTerminationGracePeriodSecondsOverride } - podStatusFn := p.acknowledgeTerminating(podUID) + podStatusFn := p.acknowledgeTerminating(logger, podUID) // if we only have a running pod, terminate it directly if update.Options.RunningPod != nil { @@ -1306,66 +1302,70 @@ func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{}) } default: - isTerminal, err = p.podSyncer.SyncPod(ctx, update.Options.UpdateType, update.Options.Pod, update.Options.MirrorPod, status) + isTerminal, postSync, err = p.podSyncer.SyncPod(ctx, update.Options.UpdateType, update.Options.Pod, update.Options.MirrorPod, status) } lastSyncTime = p.clock.Now() + if postSync != nil { + postSync() + } + return err }() var phaseTransition bool switch { - case err == context.Canceled: + case errors.Is(err, context.Canceled): // when the context is cancelled we expect an update to already be queued - klog.V(2).InfoS("Sync exited with context cancellation error", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + logger.V(2).Info("Sync exited with context cancellation error", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) case err != nil: // we will queue a retry - klog.ErrorS(err, "Error syncing pod, skipping", "pod", podRef, "podUID", podUID) + logger.Error(err, "Error syncing pod, skipping", "pod", podRef, "podUID", podUID) case update.WorkType == TerminatedPod: // we can shut down the worker - p.completeTerminated(podUID) + p.completeTerminated(logger, podUID) if start := update.Options.StartTime; !start.IsZero() { metrics.PodWorkerDuration.WithLabelValues("terminated").Observe(metrics.SinceInSeconds(start)) } - klog.V(4).InfoS("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) return case update.WorkType == TerminatingPod: // pods that don't exist in config don't need to be terminated, other loops will clean them up if update.Options.RunningPod != nil { - p.completeTerminatingRuntimePod(podUID) + p.completeTerminatingRuntimePod(logger, podUID) if start := update.Options.StartTime; !start.IsZero() { metrics.PodWorkerDuration.WithLabelValues(update.Options.UpdateType.String()).Observe(metrics.SinceInSeconds(start)) } - klog.V(4).InfoS("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) return } // otherwise we move to the terminating phase - p.completeTerminating(podUID) + p.completeTerminating(logger, podUID) phaseTransition = true case isTerminal: // if syncPod indicated we are now terminal, set the appropriate pod status to move to terminating - klog.V(4).InfoS("Pod is terminal", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) - p.completeSync(podUID) + logger.V(4).Info("Pod is terminal", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + p.completeSync(logger, podUID) phaseTransition = true } // queue a retry if necessary, then put the next event in the channel if any - p.completeWork(podUID, phaseTransition, err) + p.completeWork(logger, podUID, phaseTransition, err) if start := update.Options.StartTime; !start.IsZero() { metrics.PodWorkerDuration.WithLabelValues(update.Options.UpdateType.String()).Observe(metrics.SinceInSeconds(start)) } - klog.V(4).InfoS("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) + logger.V(4).Info("Processing pod event done", "pod", podRef, "podUID", podUID, "updateType", update.WorkType) } } // acknowledgeTerminating sets the terminating flag on the pod status once the pod worker sees // the termination state so that other components know no new containers will be started in this // pod. It then returns the status function, if any, that applies to this pod. -func (p *podWorkers) acknowledgeTerminating(podUID types.UID) PodStatusFunc { +func (p *podWorkers) acknowledgeTerminating(logger klog.Logger, podUID types.UID) PodStatusFunc { p.podLock.Lock() defer p.podLock.Unlock() @@ -1375,7 +1375,7 @@ func (p *podWorkers) acknowledgeTerminating(podUID types.UID) PodStatusFunc { } if !status.terminatingAt.IsZero() && !status.startedTerminating { - klog.V(4).InfoS("Pod worker has observed request to terminate", "podUID", podUID) + logger.V(4).Info("Pod worker has observed request to terminate", "podUID", podUID) status.startedTerminating = true } @@ -1389,15 +1389,15 @@ func (p *podWorkers) acknowledgeTerminating(podUID types.UID) PodStatusFunc { // be terminated. This happens when the natural pod lifecycle completes - any pod which is not RestartAlways // exits. Unnatural completions, such as evictions, API driven deletion or phase transition, are handled by // UpdatePod. -func (p *podWorkers) completeSync(podUID types.UID) { +func (p *podWorkers) completeSync(logger klog.Logger, podUID types.UID) { p.podLock.Lock() defer p.podLock.Unlock() - klog.V(4).InfoS("Pod indicated lifecycle completed naturally and should now terminate", "podUID", podUID) + logger.V(4).Info("Pod indicated lifecycle completed naturally and should now terminate", "podUID", podUID) status, ok := p.podSyncStatuses[podUID] if !ok { - klog.V(4).InfoS("Pod had no status in completeSync, programmer error?", "podUID", podUID) + logger.V(4).Info("Pod had no status in completeSync, programmer error?", "podUID", podUID) return } @@ -1405,7 +1405,7 @@ func (p *podWorkers) completeSync(podUID types.UID) { if status.terminatingAt.IsZero() { status.terminatingAt = p.clock.Now() } else { - klog.V(4).InfoS("Pod worker attempted to set terminatingAt twice, likely programmer error", "podUID", podUID) + logger.V(4).Info("Pod worker attempted to set terminatingAt twice, likely programmer error", "podUID", podUID) } status.startedTerminating = true @@ -1418,11 +1418,11 @@ func (p *podWorkers) completeSync(podUID types.UID) { // no container is running, no container will be started in the future, and we are ready for // cleanup. This updates the termination state which prevents future syncs and will ensure // other kubelet loops know this pod is not running any containers. -func (p *podWorkers) completeTerminating(podUID types.UID) { +func (p *podWorkers) completeTerminating(logger klog.Logger, podUID types.UID) { p.podLock.Lock() defer p.podLock.Unlock() - klog.V(4).InfoS("Pod terminated all containers successfully", "podUID", podUID) + logger.V(4).Info("Pod terminated all containers successfully", "podUID", podUID) status, ok := p.podSyncStatuses[podUID] if !ok { @@ -1431,7 +1431,7 @@ func (p *podWorkers) completeTerminating(podUID types.UID) { // update the status of the pod if status.terminatingAt.IsZero() { - klog.V(4).InfoS("Pod worker was terminated but did not have terminatingAt set, likely programmer error", "podUID", podUID) + logger.V(4).Info("Pod worker was terminated but did not have terminatingAt set, likely programmer error", "podUID", podUID) } status.terminatedAt = p.clock.Now() for _, ch := range status.notifyPostTerminating { @@ -1449,11 +1449,11 @@ func (p *podWorkers) completeTerminating(podUID types.UID) { // which means an orphaned pod (no config) is terminated and we can exit. Since orphaned // pods have no API representation, we want to exit the loop at this point and ensure no // status is present afterwards - the running pod is truly terminated when this is invoked. -func (p *podWorkers) completeTerminatingRuntimePod(podUID types.UID) { +func (p *podWorkers) completeTerminatingRuntimePod(logger klog.Logger, podUID types.UID) { p.podLock.Lock() defer p.podLock.Unlock() - klog.V(4).InfoS("Pod terminated all orphaned containers successfully and worker can now stop", "podUID", podUID) + logger.V(4).Info("Pod terminated all orphaned containers successfully and worker can now stop", "podUID", podUID) p.cleanupPodUpdates(podUID) @@ -1462,7 +1462,7 @@ func (p *podWorkers) completeTerminatingRuntimePod(podUID types.UID) { return } if status.terminatingAt.IsZero() { - klog.V(4).InfoS("Pod worker was terminated but did not have terminatingAt set, likely programmer error", "podUID", podUID) + logger.V(4).Info("Pod worker was terminated but did not have terminatingAt set, likely programmer error", "podUID", podUID) } status.terminatedAt = p.clock.Now() status.finished = true @@ -1479,11 +1479,11 @@ func (p *podWorkers) completeTerminatingRuntimePod(podUID types.UID) { // completeTerminated is invoked after syncTerminatedPod completes successfully and means we // can stop the pod worker. The pod is finalized at this point. -func (p *podWorkers) completeTerminated(podUID types.UID) { +func (p *podWorkers) completeTerminated(logger klog.Logger, podUID types.UID) { p.podLock.Lock() defer p.podLock.Unlock() - klog.V(4).InfoS("Pod is complete and the worker can now stop", "podUID", podUID) + logger.V(4).Info("Pod is complete and the worker can now stop", "podUID", podUID) p.cleanupPodUpdates(podUID) @@ -1492,10 +1492,10 @@ func (p *podWorkers) completeTerminated(podUID types.UID) { return } if status.terminatingAt.IsZero() { - klog.V(4).InfoS("Pod worker is complete but did not have terminatingAt set, likely programmer error", "podUID", podUID) + logger.V(4).Info("Pod worker is complete but did not have terminatingAt set, likely programmer error", "podUID", podUID) } if status.terminatedAt.IsZero() { - klog.V(4).InfoS("Pod worker is complete but did not have terminatedAt set, likely programmer error", "podUID", podUID) + logger.V(4).Info("Pod worker is complete but did not have terminatedAt set, likely programmer error", "podUID", podUID) } status.finished = true status.working = false @@ -1507,7 +1507,7 @@ func (p *podWorkers) completeTerminated(podUID types.UID) { // completeWork requeues on error or the next sync interval and then immediately executes any pending // work. -func (p *podWorkers) completeWork(podUID types.UID, phaseTransition bool, syncErr error) { +func (p *podWorkers) completeWork(logger klog.Logger, podUID types.UID, phaseTransition bool, syncErr error) { // Requeue the last update if the last sync returned error. switch { case phaseTransition: @@ -1541,9 +1541,9 @@ func (p *podWorkers) completeWork(podUID types.UID, phaseTransition bool, syncEr if status.pendingUpdate != nil { select { case p.podUpdates[podUID] <- struct{}{}: - klog.V(4).InfoS("Requeuing pod due to pending update", "podUID", podUID) + logger.V(4).Info("Requeuing pod due to pending update", "podUID", podUID) default: - klog.V(4).InfoS("Pending update already queued", "podUID", podUID) + logger.V(4).Info("Pending update already queued", "podUID", podUID) } } else { status.working = false @@ -1559,7 +1559,7 @@ func (p *podWorkers) completeWork(podUID types.UID, phaseTransition bool, syncEr // of known workers that are not finished with a value of SyncPodTerminated, // SyncPodKill, or SyncPodSync depending on whether the pod is terminated, terminating, // or syncing. -func (p *podWorkers) SyncKnownPods(desiredPods []*v1.Pod) map[types.UID]PodWorkerSync { +func (p *podWorkers) SyncKnownPods(logger klog.Logger, desiredPods []*v1.Pod) map[types.UID]PodWorkerSync { workers := make(map[types.UID]PodWorkerSync) known := make(map[types.UID]struct{}) for _, pod := range desiredPods { @@ -1588,7 +1588,7 @@ func (p *podWorkers) SyncKnownPods(desiredPods []*v1.Pod) map[types.UID]PodWorke _, knownPod := known[uid] orphan := !knownPod if status.restartRequested || orphan { - if p.removeTerminatedWorker(uid, status, orphan) { + if p.removeTerminatedWorker(logger, uid, status, orphan) { // no worker running, we won't return it continue } @@ -1622,11 +1622,11 @@ func (p *podWorkers) SyncKnownPods(desiredPods []*v1.Pod) map[types.UID]PodWorke // terminated pods to prevent accidentally restarting a terminal pod, which is // proportional to the number of pods described in the pod config. The method // returns true if the worker was completely removed. -func (p *podWorkers) removeTerminatedWorker(uid types.UID, status *podSyncStatus, orphaned bool) bool { +func (p *podWorkers) removeTerminatedWorker(logger klog.Logger, uid types.UID, status *podSyncStatus, orphaned bool) bool { if !status.finished { // If the pod worker has not reached terminal state and the pod is still known, we wait. if !orphaned { - klog.V(4).InfoS("Pod worker has been requested for removal but is still not fully terminated", "podUID", uid) + logger.V(4).Info("Pod worker has been requested for removal but is still not fully terminated", "podUID", uid) return false } @@ -1640,7 +1640,7 @@ func (p *podWorkers) removeTerminatedWorker(uid types.UID, status *podSyncStatus case !status.IsStarted() && !status.observedRuntime: // The pod has not been started, which means we can safely clean up the pod - the // pod worker will shutdown as a result of this change without executing a sync. - klog.V(4).InfoS("Pod is orphaned and has not been started", "podUID", uid) + logger.V(4).Info("Pod is orphaned and has not been started", "podUID", uid) case !status.IsTerminationRequested(): // The pod has been started but termination has not been requested - set the appropriate // timestamp and notify the pod worker. Because the pod has been synced at least once, @@ -1652,22 +1652,22 @@ func (p *podWorkers) removeTerminatedWorker(uid types.UID, status *podSyncStatus status.gracePeriod = 1 } p.requeueLastPodUpdate(uid, status) - klog.V(4).InfoS("Pod is orphaned and still running, began terminating", "podUID", uid) + logger.V(4).Info("Pod is orphaned and still running, began terminating", "podUID", uid) return false default: // The pod is already moving towards termination, notify the pod worker. Because the pod // has been synced at least once, the value of status.activeUpdate will be the fallback for // the next sync. p.requeueLastPodUpdate(uid, status) - klog.V(4).InfoS("Pod is orphaned and still terminating, notified the pod worker", "podUID", uid) + logger.V(4).Info("Pod is orphaned and still terminating, notified the pod worker", "podUID", uid) return false } } if status.restartRequested { - klog.V(4).InfoS("Pod has been terminated but another pod with the same UID was created, remove history to allow restart", "podUID", uid) + logger.V(4).Info("Pod has been terminated but another pod with the same UID was created, remove history to allow restart", "podUID", uid) } else { - klog.V(4).InfoS("Pod has been terminated and is no longer known to the kubelet, remove all history", "podUID", uid) + logger.V(4).Info("Pod has been terminated and is no longer known to the kubelet, remove all history", "podUID", uid) } delete(p.podSyncStatuses, uid) p.cleanupPodUpdates(uid) @@ -1680,7 +1680,7 @@ func (p *podWorkers) removeTerminatedWorker(uid types.UID, status *podSyncStatus // killPodNow returns a KillPodFunc that can be used to kill a pod. // It is intended to be injected into other modules that need to kill a pod. -func killPodNow(podWorkers PodWorkers, recorder record.EventRecorder) eviction.KillPodFunc { +func killPodNow(ctx context.Context, podWorkers PodWorkers, recorder record.EventRecorder) eviction.KillPodFunc { return func(pod *v1.Pod, isEvicted bool, gracePeriodOverride *int64, statusFn func(*v1.PodStatus)) error { // determine the grace period to use when killing the pod gracePeriod := int64(0) @@ -1701,16 +1701,18 @@ func killPodNow(podWorkers PodWorkers, recorder record.EventRecorder) eviction.K // open a channel we block against until we get a result ch := make(chan struct{}, 1) - podWorkers.UpdatePod(UpdatePodOptions{ - Pod: pod, - UpdateType: kubetypes.SyncPodKill, - KillPodOptions: &KillPodOptions{ - CompletedCh: ch, - Evict: isEvicted, - PodStatusFunc: statusFn, - PodTerminationGracePeriodSecondsOverride: gracePeriodOverride, - }, - }) + podWorkers.UpdatePod( + ctx, + UpdatePodOptions{ + Pod: pod, + UpdateType: kubetypes.SyncPodKill, + KillPodOptions: &KillPodOptions{ + CompletedCh: ch, + Evict: isEvicted, + PodStatusFunc: statusFn, + PodTerminationGracePeriodSecondsOverride: gracePeriodOverride, + }, + }) // wait for either a response, or a timeout select { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/podcertificate/podcertificatemanager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/podcertificate/podcertificatemanager.go index ec8c5127e8..9d0048c849 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/podcertificate/podcertificatemanager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/podcertificate/podcertificatemanager.go @@ -25,7 +25,6 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" - "crypto/sha256" "crypto/x509" "encoding/pem" "fmt" @@ -337,7 +336,8 @@ func (m *IssuingManager) queueAllProjectionsForPod(uid types.UID) { } func (m *IssuingManager) Run(ctx context.Context) { - klog.InfoS("podcertificate.IssuingManager starting up") + logger := klog.FromContext(ctx) + logger.Info("podcertificate.IssuingManager starting up") if !cache.WaitForCacheSync(ctx.Done(), m.pcrInformer.HasSynced, m.nodeInformer.HasSynced) { return } @@ -348,7 +348,7 @@ func (m *IssuingManager) Run(ctx context.Context) { m.projectionQueue.ShutDown() - klog.InfoS("podcertificate.IssuingManager shut down") + logger.Info("podcertificate.IssuingManager shut down") } func (m *IssuingManager) runProjectionProcessor(ctx context.Context) { @@ -378,6 +378,8 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey // Remember, returning nil from this function indicates that the work item // was successfully processed, and should be dropped from the queue. + logger := klog.FromContext(ctx) + pod, ok := m.podManager.GetPodByUID(types.UID(key.PodUID)) if !ok { // If we can't find the pod anymore, it's been deleted. Clear all our @@ -462,7 +464,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey // Return nil to remove the projection from the workqueue --- it will be // readded once the PodCertificateRequest appears in the informer cache, // and goes through status updates. - klog.V(4).InfoS("PodCertificateRequest created, moving to credStateWait", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest created, moving to credStateWait", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) return nil case *credStateWait: @@ -495,7 +497,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey Reason: cond.Reason, Message: cond.Message, } - klog.V(4).InfoS("PodCertificateRequest denied, moving to credStateDenied", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest denied, moving to credStateDenied", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) eventMessage := fmt.Sprintf("PodCertificateRequest %s was denied, reason=%q, message=%q", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name, cond.Reason, cond.Message) m.recorder.Eventf(pod, corev1.EventTypeWarning, certificatesv1beta1.PodCertificateRequestConditionTypeDenied, cond.Reason, eventMessage) return nil @@ -504,7 +506,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey Reason: cond.Reason, Message: cond.Message, } - klog.V(4).InfoS("PodCertificateRequest failed, moving to credStateFailed", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest failed, moving to credStateFailed", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) eventMessage := fmt.Sprintf("PodCertificateRequest %s failed, reason=%q, message=%q", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name, cond.Reason, cond.Message) m.recorder.Eventf(pod, corev1.EventTypeWarning, certificatesv1beta1.PodCertificateRequestConditionTypeFailed, cond.Reason, eventMessage) return nil @@ -515,7 +517,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey beginRefreshAt: pcr.Status.BeginRefreshAt.Time.Add(jitterDuration()), notAfter: pcr.Status.NotAfter.Time, } - klog.V(4).InfoS("PodCertificateRequest issued, moving to credStateFresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest issued, moving to credStateFresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) return nil } } @@ -523,17 +525,17 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey // Nothing -- the request is still pending. Return nil to remove the // projection from the workqueue. It will be redriven when the // PodCertificateRequest gets an update. - klog.V(4).InfoS("PodCertificateRequest not in terminal state, remaining in credStateWait", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest not in terminal state, remaining in credStateWait", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) return nil case *credStateDenied: // Nothing to do; this is a permanent error state for the pod. - klog.V(4).InfoS("staying in credStateDenied", "key", key) + logger.V(4).Info("staying in credStateDenied", "key", key) return nil case *credStateFailed: // Nothing to do; this is a permanent error state for the pod. - klog.V(4).InfoS("staying in credStateFailed", "key", key) + logger.V(4).Info("staying in credStateFailed", "key", key) return nil case *credStateFresh: @@ -545,18 +547,18 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey return nil } - klog.V(4).InfoS("Time to refresh", "key", key) + logger.V(4).Info("Time to refresh", "key", key) // The current time is more than 10 minutes past the most recently issued certificate's `beginRefreshAt` timestamp but the state has not been labeled with overdue for refresh. if m.clock.Now().After(state.beginRefreshAt.Add(refreshOverdueDuration)) && !state.eventEmittedForOverdueForRefresh { - klog.V(4).InfoS("Refresh overdue", "key", key) + logger.V(4).Info("Refresh overdue", "key", key) m.recorder.Eventf(pod, corev1.EventTypeWarning, "CertificateOverdueForRefresh", "PodCertificate refresh overdue") state.eventEmittedForOverdueForRefresh = true } // The current time is past the most recently issued certificate's `notAfter` timestamp but the state has not been labelled with expired. if m.clock.Now().After(state.notAfter) && !state.eventEmittedForExpiration { - klog.V(4).InfoS("Certificates expired", "key", key) + logger.V(4).Info("Certificates expired", "key", key) m.recorder.Eventf(pod, corev1.EventTypeWarning, "CertificateExpired", "PodCertificate expired") state.eventEmittedForExpiration = true } @@ -602,7 +604,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey // Return nil to remove the projection from the workqueue --- it will be // readded once the PodCertificateRequest appears in the informer cache, // and goes through status updates. - klog.V(4).InfoS("PodCertificateRequest created, moving to credStateWaitRefresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest created, moving to credStateWaitRefresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) return nil case *credStateWaitRefresh: @@ -640,7 +642,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey Reason: cond.Reason, Message: cond.Message, } - klog.V(4).InfoS("PodCertificateRequest denied, moving to credStateDenied", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest denied, moving to credStateDenied", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) eventMessage := fmt.Sprintf("PodCertificateRequest %s was denied, reason=%q, message=%q", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name, cond.Reason, cond.Message) m.recorder.Eventf(pod, corev1.EventTypeWarning, certificatesv1beta1.PodCertificateRequestConditionTypeDenied, cond.Reason, eventMessage) return nil @@ -649,7 +651,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey Reason: cond.Reason, Message: cond.Message, } - klog.V(4).InfoS("PodCertificateRequest failed, moving to credStateFailed", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest failed, moving to credStateFailed", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) eventMessage := fmt.Sprintf("PodCertificateRequest %s failed, reason=%q, message=%q", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name, cond.Reason, cond.Message) m.recorder.Eventf(pod, corev1.EventTypeWarning, certificatesv1beta1.PodCertificateRequestConditionTypeFailed, cond.Reason, eventMessage) return nil @@ -660,7 +662,7 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey beginRefreshAt: pcr.Status.BeginRefreshAt.Time.Add(jitterDuration()), notAfter: pcr.Status.NotAfter.Time, } - klog.V(4).InfoS("PodCertificateRequest issued, moving to credStateFresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest issued, moving to credStateFresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) return nil } } @@ -668,18 +670,18 @@ func (m *IssuingManager) handleProjection(ctx context.Context, key projectionKey // Nothing -- the request is still pending. Return nil to remove the // projection from the workqueue. It will be redriven when the // PodCertificateRequest gets an update. - klog.V(4).InfoS("PodCertificateRequest not in terminal state, remaining in credStateWaitRefresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) + logger.V(4).Info("PodCertificateRequest not in terminal state, remaining in credStateWaitRefresh", "key", key, "pcr", pcr.ObjectMeta.Namespace+"/"+pcr.ObjectMeta.Name) // The current time is more than 10 minutes past the most recently issued certificate's `beginRefreshAt` timestamp but the state has not been labeled with overdue for refresh. if m.clock.Now().After(state.beginRefreshAt.Add(refreshOverdueDuration)) && !state.eventEmittedForOverdueForRefresh { - klog.V(4).InfoS("Refresh overdue", "key", key) + logger.V(4).Info("Refresh overdue", "key", key) m.recorder.Eventf(pod, corev1.EventTypeWarning, "CertificateOverdueForRefresh", "PodCertificate refresh overdue") state.eventEmittedForOverdueForRefresh = true } // The current time is past the most recently issued certificate's `notAfter` timestamp but the state has not been labeled with expired. if m.clock.Now().After(state.notAfter) && !state.eventEmittedForExpiration { - klog.V(4).InfoS("Certificates expired", "key", key) + logger.V(4).Info("Certificates expired", "key", key) m.recorder.Eventf(pod, corev1.EventTypeWarning, "CertificateExpired", "PodCertificate expired") state.eventEmittedForExpiration = true } @@ -739,18 +741,14 @@ func (m *IssuingManager) createPodCertificateRequest( podName string, podUID types.UID, serviceAccountName string, serviceAccountUID types.UID, nodeName types.NodeName, nodeUID types.UID, - signerName, keyType string, maxExpirationSeconds *int32, userAnnotations map[string]string) ([]byte, *certificatesv1beta1.PodCertificateRequest, error) { - - privateKey, publicKey, proof, err := generateKeyAndProof(keyType, []byte(podUID)) + signerName, keyType string, maxExpirationSeconds *int32, + userAnnotations map[string]string, +) ([]byte, *certificatesv1beta1.PodCertificateRequest, error) { + privateKey, pkcs10Req, err := generateKeyAndProof(keyType) if err != nil { return nil, nil, fmt.Errorf("while generating keypair: %w", err) } - pkixPublicKey, err := x509.MarshalPKIXPublicKey(publicKey) - if err != nil { - return nil, nil, fmt.Errorf("while marshaling public key: %w", err) - } - keyPEM, err := pemEncodeKey(privateKey) if err != nil { return nil, nil, fmt.Errorf("while PEM-encoding private key: %w", err) @@ -762,7 +760,7 @@ func (m *IssuingManager) createPodCertificateRequest( GenerateName: "req-", OwnerReferences: []metav1.OwnerReference{ { - APIVersion: "core/v1", + APIVersion: "v1", Kind: "Pod", Name: podName, UID: podUID, @@ -778,8 +776,7 @@ func (m *IssuingManager) createPodCertificateRequest( NodeName: nodeName, NodeUID: nodeUID, MaxExpirationSeconds: maxExpirationSeconds, - PKIXPublicKey: pkixPublicKey, - ProofOfPossession: proof, + StubPKCS10Request: pkcs10Req, UnverifiedUserAnnotations: userAnnotations, }, } @@ -874,73 +871,57 @@ func (m *IssuingManager) MetricReport() *MetricReport { return report } -func hashBytes(in []byte) []byte { - out := sha256.Sum256(in) - return out[:] -} +func generateKeyAndProof(keyType string) (crypto.PrivateKey, []byte, error) { + var privKey crypto.PrivateKey -func generateKeyAndProof(keyType string, toBeSigned []byte) (privKey crypto.PrivateKey, pubKey crypto.PublicKey, sig []byte, err error) { switch keyType { case "RSA3072": - key, err := rsa.GenerateKey(rand.Reader, 3072) - if err != nil { - return nil, nil, nil, fmt.Errorf("while generating RSA 3072 key: %w", err) - } - sig, err := rsa.SignPSS(rand.Reader, key, crypto.SHA256, hashBytes(toBeSigned), nil) + priv, err := rsa.GenerateKey(rand.Reader, 3072) if err != nil { - return nil, nil, nil, fmt.Errorf("while signing proof: %w", err) + return nil, nil, fmt.Errorf("while generating RSA 3072 key: %w", err) } - return key, &key.PublicKey, sig, nil + privKey = priv case "RSA4096": - key, err := rsa.GenerateKey(rand.Reader, 4096) - if err != nil { - return nil, nil, nil, fmt.Errorf("while generating RSA 4096 key: %w", err) - } - sig, err := rsa.SignPSS(rand.Reader, key, crypto.SHA256, hashBytes(toBeSigned), nil) + priv, err := rsa.GenerateKey(rand.Reader, 4096) if err != nil { - return nil, nil, nil, fmt.Errorf("while signing proof: %w", err) + return nil, nil, fmt.Errorf("while generating RSA 4096 key: %w", err) } - return key, &key.PublicKey, sig, nil + privKey = priv case "ECDSAP256": - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { - return nil, nil, nil, fmt.Errorf("while generating ECDSA P256 key: %w", err) + return nil, nil, fmt.Errorf("while generating ECDSA P256 key: %w", err) } - sig, err := ecdsa.SignASN1(rand.Reader, key, hashBytes(toBeSigned)) - if err != nil { - return nil, nil, nil, fmt.Errorf("while signing proof: %w", err) - } - return key, &key.PublicKey, sig, nil + privKey = priv case "ECDSAP384": - key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) if err != nil { - return nil, nil, nil, fmt.Errorf("while generating ECDSA P384 key: %w", err) + return nil, nil, fmt.Errorf("while generating ECDSA P384 key: %w", err) } - sig, err := ecdsa.SignASN1(rand.Reader, key, hashBytes(toBeSigned)) - if err != nil { - return nil, nil, nil, fmt.Errorf("while signing proof: %w", err) - } - return key, &key.PublicKey, sig, nil + privKey = priv case "ECDSAP521": - key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - return nil, nil, nil, fmt.Errorf("while generating ECDSA P521 key: %w", err) - } - sig, err := ecdsa.SignASN1(rand.Reader, key, hashBytes(toBeSigned)) + priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { - return nil, nil, nil, fmt.Errorf("while signing proof: %w", err) + return nil, nil, fmt.Errorf("while generating ECDSA P521 key: %w", err) } - return key, &key.PublicKey, sig, nil + privKey = priv case "ED25519": - pub, priv, err := ed25519.GenerateKey(rand.Reader) + _, priv, err := ed25519.GenerateKey(rand.Reader) if err != nil { - return nil, nil, nil, fmt.Errorf("while generating Ed25519 key: %w", err) + return nil, nil, fmt.Errorf("while generating Ed25519 key: %w", err) } - sig := ed25519.Sign(priv, toBeSigned) - return priv, pub, sig, nil + privKey = priv default: - return nil, nil, nil, fmt.Errorf("unknown key type %q", keyType) + return nil, nil, fmt.Errorf("unknown key type %q", keyType) } + + tmpl := &x509.CertificateRequest{} + pkcs10Req, err := x509.CreateCertificateRequest(rand.Reader, tmpl, privKey) + if err != nil { + return nil, nil, fmt.Errorf("while generating stub PKCS#10 request: %w", err) + } + + return privKey, pkcs10Req, nil } func pemEncodeKey(key crypto.PrivateKey) ([]byte, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go index 554f607cbc..467ba4f297 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go @@ -48,14 +48,14 @@ type prober struct { grpc grpcprobe.Prober runner kubecontainer.CommandRunner - recorder record.EventRecorder + recorder record.EventRecorderLogger } // NewProber creates a Prober, it takes a command runner and // several container info managers. func newProber( runner kubecontainer.CommandRunner, - recorder record.EventRecorder) *prober { + recorder record.EventRecorderLogger) *prober { const followNonLocalRedirects = false return &prober{ @@ -76,7 +76,7 @@ func (pb *prober) recordContainerEvent(ctx context.Context, pod *v1.Pod, contain logger.Error(err, "Can't make a ref to pod and container", "pod", klog.KObj(pod), "containerName", container.Name) return } - pb.recorder.Eventf(ref, eventType, reason, message, args...) + pb.recorder.WithLogger(logger).Eventf(ref, eventType, reason, message, args...) } // probe probes the container. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober_manager.go index 7595c0f7c5..7d07479ca9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober_manager.go @@ -124,7 +124,7 @@ func NewManager( readinessManager results.Manager, startupManager results.Manager, runner kubecontainer.CommandRunner, - recorder record.EventRecorder) Manager { + recorder record.EventRecorderLogger) Manager { prober := newProber(runner, recorder) return &manager{ diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/worker.go b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/worker.go index 2cbda7f20d..4863cf91f7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/worker.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/worker.go @@ -214,7 +214,7 @@ func (w *worker) stop() { // Returns whether the worker should continue. func (w *worker) doProbe(ctx context.Context) (keepGoing bool) { defer func() { recover() }() // Actually eat panics (HandleCrash takes care of logging) - defer runtime.HandleCrash(func(_ interface{}) { keepGoing = true }) + defer runtime.HandleCrashWithContext(ctx, func(ctx context.Context, _ interface{}) { keepGoing = true }) logger := klog.FromContext(ctx) startTime := time.Now() @@ -243,12 +243,17 @@ func (w *worker) doProbe(ctx context.Context) (keepGoing bool) { } } + isRestartableInitContainer := w.isInitContainer() && + w.container.RestartPolicy != nil && + *w.container.RestartPolicy == v1.ContainerRestartPolicyAlways + if w.containerID.String() != c.ContainerID { if !w.containerID.IsEmpty() { w.resultsManager.Remove(w.containerID) } w.containerID = kubecontainer.ParseContainerID(c.ContainerID) + if !utilfeature.DefaultFeatureGate.Enabled(features.ChangeContainerStatusOnKubeletRestart) { // On kubelet restart, we don't want to immediately set the probe result to Failure, // as this could cause a container that was Ready to become NotReady. @@ -259,6 +264,18 @@ func (w *worker) doProbe(ctx context.Context) (keepGoing bool) { isRestart = true } } + + // For restartable init containers (sidecars) with a startup probe, seed the + // startup result with Success if the container had already started before the + // kubelet restarted. This ensures startupManager.Get() returns a valid result, + // allowing computeInitContainerActions to detect pod initialization. + // See https://github.com/kubernetes/kubernetes/issues/136910 + if isRestartableInitContainer && w.probeType == startup { + if c.Started != nil && *c.Started { + w.resultsManager.Set(w.containerID, results.Success, w.pod) + } + } + if !isRestart { w.resultsManager.Set(w.containerID, w.initialValue, w.pod) } @@ -282,9 +299,6 @@ func (w *worker) doProbe(ctx context.Context) (keepGoing bool) { w.resultsManager.Set(w.containerID, results.Failure, w.pod) } - isRestartableInitContainer := w.isInitContainer() && - w.container.RestartPolicy != nil && *w.container.RestartPolicy == v1.ContainerRestartPolicyAlways - // Abort if the container will not be restarted. if utilfeature.DefaultFeatureGate.Enabled(features.ContainerRestartRules) { if c.State.Terminated == nil { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go b/vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go index 7f9da7f7db..4d6c183238 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go @@ -19,6 +19,7 @@ package kubelet import ( "errors" "fmt" + "sort" "sync" "time" @@ -75,7 +76,11 @@ func (s *runtimeState) setRuntimeState(err error) { func (s *runtimeState) setRuntimeHandlers(rtHandlers []kubecontainer.RuntimeHandler) { s.Lock() defer s.Unlock() - s.rtHandlers = rtHandlers + // Copy and sort to ensure deterministic ordering of runtime handlers and avoid spurious Node status updates. + s.rtHandlers = append([]kubecontainer.RuntimeHandler(nil), rtHandlers...) + sort.Slice(s.rtHandlers, func(i, j int) bool { + return s.rtHandlers[i].Name < s.rtHandlers[j].Name + }) } func (s *runtimeState) runtimeHandlers() []kubecontainer.RuntimeHandler { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/auth.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/auth.go index b5d8255d4c..e385a63c11 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/auth.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/auth.go @@ -25,6 +25,7 @@ import ( "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/server/dynamiccertificates" "k8s.io/apiserver/pkg/server/flagz" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/statusz" @@ -42,11 +43,13 @@ type KubeletAuth struct { NodeRequestAttributesGetter // authorizer determines whether a given authorization.Attributes is allowed authorizer.Authorizer + // CAContentProvider returns CA content for client CA authorization + dynamiccertificates.CAContentProvider } // NewKubeletAuth returns a kubelet.AuthInterface composed of the given authenticator, attribute getter, and authorizer -func NewKubeletAuth(authenticator authenticator.Request, authorizerAttributeGetter NodeRequestAttributesGetter, authorizer authorizer.Authorizer) AuthInterface { - return &KubeletAuth{authenticator, authorizerAttributeGetter, authorizer} +func NewKubeletAuth(authenticator authenticator.Request, authorizerAttributeGetter NodeRequestAttributesGetter, authorizer authorizer.Authorizer, clientCAProvider dynamiccertificates.CAContentProvider) AuthInterface { + return &KubeletAuth{authenticator, authorizerAttributeGetter, authorizer, clientCAProvider} } // NewNodeAuthorizerAttributesGetter creates a new authorizer.RequestAttributesGetter for the node. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/metrics/metrics.go index e9a2b5fca7..7f4f9bd69c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/metrics/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/metrics/metrics.go @@ -26,6 +26,9 @@ import ( const ( kubeletSubsystem = "kubelet" + + CAdvisorMetricsProvider MetricsProviderType = "cadvisor" + CRIMetricsProvider MetricsProviderType = "cri" ) var ( @@ -76,6 +79,26 @@ var ( }, []string{"metric_source"}, ) + MetricsProvider = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Subsystem: kubeletSubsystem, + Name: "metrics_provider", + Help: "Metrics provider used by kubelet to collect container stats. Values can be 'cadvisor' and 'cri'", + StabilityLevel: metrics.ALPHA, + }, + []string{"provider"}, + ) + // WebSocketStreamingRequests counts WebSocket streaming requests received by the kubelet, + // labeled by subresource. + WebSocketStreamingRequests = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: kubeletSubsystem, + Name: "websocket_streaming_requests_total", + Help: "Total number of WebSocket streaming requests (exec/attach/portforward) received by the kubelet.", + StabilityLevel: metrics.ALPHA, + }, + []string{"subresource"}, + ) ) var registerMetrics sync.Once @@ -87,9 +110,16 @@ func Register() { legacyregistry.MustRegister(HTTPRequestsDuration) legacyregistry.MustRegister(HTTPInflightRequests) legacyregistry.MustRegister(VolumeStatCalDuration) + legacyregistry.MustRegister(MetricsProvider) + legacyregistry.MustRegister(WebSocketStreamingRequests) }) } +// ResetForTest resets metrics that support reset, for use in unit tests. +func ResetForTest() { + WebSocketStreamingRequests.Reset() +} + // SinceInSeconds gets the time since the specified start in seconds. func SinceInSeconds(start time.Time) float64 { return time.Since(start).Seconds() @@ -99,3 +129,17 @@ func SinceInSeconds(start time.Time) float64 { func CollectVolumeStatCalDuration(metricSource string, start time.Time) { VolumeStatCalDuration.WithLabelValues(metricSource).Observe(SinceInSeconds(start)) } + +type MetricsProviderType string + +// SetMetricsProvider sets the metrics provider. +func SetMetricsProvider(provider MetricsProviderType) { + MetricsProvider.Reset() + MetricsProvider.WithLabelValues(string(provider)).Set(1) +} + +// IncWebSocketStreamingRequest increments the count of WebSocket streaming requests received +// by the kubelet for the given subresource (exec/attach/portforward). +func IncWebSocketStreamingRequest(subresource string) { + WebSocketStreamingRequests.WithLabelValues(subresource).Inc() +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go index 31ecfe6567..fe96a4ab36 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go @@ -19,6 +19,7 @@ package server import ( "context" "crypto/tls" + "errors" "fmt" "io" "net" @@ -50,6 +51,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/httpstream/wsstream" "k8s.io/apimachinery/pkg/util/proxy" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" @@ -59,11 +61,14 @@ import ( "k8s.io/apiserver/pkg/server/flagz" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/httplog" + + "k8s.io/apiserver/pkg/server/dynamiccertificates" "k8s.io/apiserver/pkg/server/routes" "k8s.io/apiserver/pkg/server/statusz" "k8s.io/apiserver/pkg/util/compatibility" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/util/flushwriter" + translator "k8s.io/apiserver/pkg/util/proxy" "k8s.io/component-base/configz" "k8s.io/component-base/logs" compbasemetrics "k8s.io/component-base/metrics" @@ -73,11 +78,12 @@ import ( zpagesfeatures "k8s.io/component-base/zpages/features" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/cri-client/pkg/util" + "k8s.io/cri-streaming/pkg/streaming" + "k8s.io/cri-streaming/pkg/streaming/portforward" + remotecommandserver "k8s.io/cri-streaming/pkg/streaming/remotecommand" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" podresourcesapiv1alpha1 "k8s.io/kubelet/pkg/apis/podresources/v1alpha1" - "k8s.io/kubelet/pkg/cri/streaming" - "k8s.io/kubelet/pkg/cri/streaming/portforward" - remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand" + podsv1alpha1 "k8s.io/kubelet/pkg/apis/pods/v1alpha1" kubelettypes "k8s.io/kubelet/pkg/types" "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" @@ -86,6 +92,8 @@ import ( kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/config" apisgrpc "k8s.io/kubernetes/pkg/kubelet/apis/grpc" "k8s.io/kubernetes/pkg/kubelet/apis/podresources" + "k8s.io/kubernetes/pkg/kubelet/apis/pods" + kubeletcadvisor "k8s.io/kubernetes/pkg/kubelet/cadvisor" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/metrics/collectors" "k8s.io/kubernetes/pkg/kubelet/prober" @@ -130,9 +138,12 @@ type Server struct { // TLSOptions holds the TLS options. type TLSOptions struct { - Config *tls.Config - CertFile string - KeyFile string + MinVersion uint16 + CipherSuites []uint16 + CurvePreferences []tls.CurveID + CertFile string + KeyFile string + ClientCAFile string } // containerInterface defines the restful.Container functions used on the root container @@ -172,7 +183,7 @@ func ListenAndServeKubeletServer( checkers []healthz.HealthChecker, flagz flagz.Reader, kubeCfg *kubeletconfiginternal.KubeletConfiguration, - tlsOptions *TLSOptions, + tlsConfig *tls.Config, auth AuthInterface, tp oteltrace.TracerProvider) { @@ -192,15 +203,14 @@ func ListenAndServeKubeletServer( MaxHeaderBytes: 1 << 20, } - if tlsOptions != nil { - s.TLSConfig = tlsOptions.Config - // Passing empty strings as the cert and key files means no - // cert/keys are specified and GetCertificate in the TLSConfig - // should be called instead. - if err := s.ListenAndServeTLS(tlsOptions.CertFile, tlsOptions.KeyFile); err != nil { + if tlsConfig != nil { + s.TLSConfig = tlsConfig + if err := s.ListenAndServeTLS("", ""); err != nil { logger.Error(err, "Failed to listen and serve") os.Exit(1) } + + // support a hollow node with plain HTTP } else if err := s.ListenAndServe(); err != nil { logger.Error(err, "Failed to listen and serve") os.Exit(1) @@ -258,6 +268,32 @@ func ListenAndServePodResources(ctx context.Context, endpoint string, providers } } +// ListenAndServePodsServer initializes an HTTP server to serve the Pod API. +func ListenAndServePodsServer(ctx context.Context, endpoint string, srv podsv1alpha1.PodsServer) { + logger := klog.FromContext(ctx) + server := grpc.NewServer(apisgrpc.WithRateLimiter(ctx, "pods", pods.DefaultQPS, pods.DefaultBurstTokens)) + + podsv1alpha1.RegisterPodsServer(server, srv) + + l, err := util.CreateListener(endpoint) + if err != nil { + logger.Error(err, "Failed to create listener for pods API endpoint") + os.Exit(1) + } + + logger.Info("Starting to serve the pods API", "endpoint", endpoint) + go func() { + if err := server.Serve(l); err != nil && !errors.Is(err, grpc.ErrServerStopped) { + logger.Error(err, "Failed to serve") + os.Exit(1) + } + }() + + <-ctx.Done() + logger.Info("Shutting down pods API server") + server.GracefulStop() +} + type NodeRequestAttributesGetter interface { GetRequestAttributes(ctx context.Context, u user.Info, r *http.Request) []authorizer.Attributes } @@ -267,6 +303,7 @@ type AuthInterface interface { authenticator.Request NodeRequestAttributesGetter authorizer.Authorizer + dynamiccertificates.CAContentProvider } // HostInterface contains all the kubelet methods required by the server. @@ -315,18 +352,17 @@ func NewServer( server.InstallAuthNotRequiredHandlers(ctx) if kubeCfg != nil && kubeCfg.EnableDebuggingHandlers { logger.Info("Adding debug handlers to kubelet server") - server.InstallAuthRequiredHandlers(ctx) // To maintain backward compatibility serve logs and pprof only when enableDebuggingHandlers is also enabled // see https://github.com/kubernetes/kubernetes/pull/87273 server.InstallSystemLogHandler(kubeCfg.EnableSystemLogHandler, kubeCfg.EnableSystemLogQuery) server.InstallProfilingHandler(kubeCfg.EnableProfilingHandler, kubeCfg.EnableContentionProfiling) server.InstallDebugFlagsHandler(kubeCfg.EnableDebugFlagsHandler) + // must be done last so all paths are included in /statusz + server.InstallAuthRequiredHandlers(ctx) } else { server.InstallDebuggingDisabledHandlers() } - server.installStatusZ() - return server } @@ -390,7 +426,14 @@ func (s *Server) InstallTracingFilter(tp oteltrace.TracerProvider, opts ...otelr s.restfulCont.Filter(otelrestful.OTelFilter("kubelet", append(opts, otelrestful.WithTracerProvider(tp))...)) } -func (s *Server) installStatusZ() { +func (s *Server) InstallZPages() { + if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { + if s.flagz != nil { + s.addMetricsBucketMatcher("flagz") + flagz.Install(s.restfulCont, ComponentKubelet, s.flagz) + } + } + // must be done last so all paths are included in /statusz if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentStatusz) { s.addMetricsBucketMatcher("statusz") statusz.Install(s.restfulCont, ComponentKubelet, statusz.NewRegistry(compatibility.DefaultBuildEffectiveVersion(), statusz.WithListedPaths(s.restfulCont.RegisteredHandlePaths()))) @@ -471,7 +514,9 @@ func (s *Server) InstallAuthNotRequiredHandlers(ctx context.Context) { } if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPSI) { - includedMetrics[cadvisormetrics.PressureMetrics] = struct{}{} + if kubeletcadvisor.IsPsiEnabled(logger) { + includedMetrics[cadvisormetrics.PressureMetrics] = struct{}{} + } } // cAdvisor metrics are exposed under the secured handler as well @@ -479,6 +524,7 @@ func (s *Server) InstallAuthNotRequiredHandlers(ctx context.Context) { r.RawMustRegister(metrics.NewPrometheusMachineCollector(prometheusHostAdapter{s.host}, includedMetrics)) if utilfeature.DefaultFeatureGate.Enabled(features.PodAndContainerStatsFromCRI) { r.CustomRegister(collectors.NewCRIMetricsCollector(context.TODO(), s.host.ListPodSandboxMetrics, s.host.ListMetricDescriptors)) + servermetrics.SetMetricsProvider(servermetrics.CRIMetricsProvider) } else { cadvisorOpts := cadvisorv2.RequestOptions{ IdType: cadvisorv2.TypeName, @@ -486,6 +532,7 @@ func (s *Server) InstallAuthNotRequiredHandlers(ctx context.Context) { Recursive: true, } r.RawMustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host), includedMetrics, clock.RealClock{}, cadvisorOpts)) + servermetrics.SetMetricsProvider(servermetrics.CAdvisorMetricsProvider) } s.restfulCont.Handle(cadvisorMetricsPath, compbasemetrics.HandlerFor(r, compbasemetrics.HandlerOpts{ErrorHandling: compbasemetrics.ContinueOnError}), @@ -599,13 +646,6 @@ func (s *Server) InstallAuthRequiredHandlers(ctx context.Context) { s.addMetricsBucketMatcher("configz") configz.InstallHandler(s.restfulCont) - if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { - if s.flagz != nil { - s.addMetricsBucketMatcher("flagz") - flagz.Install(s.restfulCont, ComponentKubelet, s.flagz) - } - } - // The /runningpods endpoint is used for testing only. s.addMetricsBucketMatcher("runningpods") ws = new(restful.WebService) @@ -627,6 +667,9 @@ func (s *Server) InstallAuthRequiredHandlers(ctx context.Context) { Operation("checkpoint")) s.restfulCont.Add(ws) } + + // must be done last so all paths are included in /statusz + s.InstallZPages() } // InstallDebuggingDisabledHandlers registers the HTTP request patterns that provide better error message @@ -932,13 +975,6 @@ func (r *responder) Error(w http.ResponseWriter, req *http.Request, err error) { http.Error(w, err.Error(), http.StatusInternalServerError) } -// proxyStream proxies stream to url. -func proxyStream(w http.ResponseWriter, r *http.Request, url *url.URL) { - // TODO(random-liu): Set MaxBytesPerSec to throttle the stream. - handler := proxy.NewUpgradeAwareHandler(url, nil /*transport*/, false /*wrapTransport*/, true /*upgradeRequired*/, &responder{}) - handler.ServeHTTP(w, r) -} - // getAttach handles requests to attach to a container. func (s *Server) getAttach(request *restful.Request, response *restful.Response) { params := getExecRequestParams(request) @@ -960,8 +996,20 @@ func (s *Server) getAttach(request *restful.Request, response *restful.Response) streaming.WriteError(err, response.ResponseWriter) return } - - proxyStream(response.ResponseWriter, request.Request, url) + var handler http.Handler = proxy.NewUpgradeAwareHandler(url, nil /*transport*/, false /*wrapTransport*/, true /*upgradeRequired*/, &responder{}) + // If upgrade request is for V5 websockets, wrap with websocket/spdy stream translation. + if utilfeature.DefaultFeatureGate.Enabled(features.ExtendWebSocketsToKubelet) && + wsstream.IsWebSocketRequestWithStreamCloseProtocol(request.Request) { + servermetrics.IncWebSocketStreamingRequest("attach") + streamOptions := translator.Options{ + Stdin: streamOpts.Stdin, + Stdout: streamOpts.Stdout, + Stderr: streamOpts.Stderr, + Tty: streamOpts.TTY, + } + handler = translator.NewStreamTranslatorHandler(url, nil, 0, streamOptions) + } + handler.ServeHTTP(response.ResponseWriter, request.Request) } // getExec handles requests to run a command inside a container. @@ -985,7 +1033,20 @@ func (s *Server) getExec(request *restful.Request, response *restful.Response) { streaming.WriteError(err, response.ResponseWriter) return } - proxyStream(response.ResponseWriter, request.Request, url) + var handler http.Handler = proxy.NewUpgradeAwareHandler(url, nil /*transport*/, false /*wrapTransport*/, true /*upgradeRequired*/, &responder{}) + // If upgrade request is for V5 websockets, wrap with websocket/spdy stream translation. + if utilfeature.DefaultFeatureGate.Enabled(features.ExtendWebSocketsToKubelet) && + wsstream.IsWebSocketRequestWithStreamCloseProtocol(request.Request) { + servermetrics.IncWebSocketStreamingRequest("exec") + streamOptions := translator.Options{ + Stdin: streamOpts.Stdin, + Stdout: streamOpts.Stdout, + Stderr: streamOpts.Stderr, + Tty: streamOpts.TTY, + } + handler = translator.NewStreamTranslatorHandler(url, nil, 0, streamOptions) + } + handler.ServeHTTP(response.ResponseWriter, request.Request) } // getRun handles requests to run a command inside a container. @@ -1026,12 +1087,21 @@ func writeJSONResponse(logger klog.Logger, response *restful.Response, data []by func (s *Server) getPortForward(request *restful.Request, response *restful.Response) { params := getPortForwardRequestParams(request) - portForwardOptions, err := portforward.NewV4Options(request.Request) - if err != nil { - utilruntime.HandleError(err) - response.WriteError(http.StatusBadRequest, err) - return + websocketSPDYTunnel := utilfeature.DefaultFeatureGate.Enabled(features.ExtendWebSocketsToKubelet) && + wsstream.IsWebSocketRequestWithTunnelingProtocol(request.Request) + var portForwardOptions *portforward.V4Options + var err error + if websocketSPDYTunnel { + portForwardOptions = &portforward.V4Options{} + } else { + portForwardOptions, err = portforward.NewV4Options(request.Request) + if err != nil { + utilruntime.HandleError(err) + response.WriteError(http.StatusBadRequest, err) //nolint:errcheck + return + } } + pod, ok := s.host.GetPodByName(params.podNamespace, params.podName) if !ok { response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist")) @@ -1047,7 +1117,13 @@ func (s *Server) getPortForward(request *restful.Request, response *restful.Resp streaming.WriteError(err, response.ResponseWriter) return } - proxyStream(response.ResponseWriter, request.Request, url) + var handler http.Handler = proxy.NewUpgradeAwareHandler(url, nil /*transport*/, false /*wrapTransport*/, true /*upgradeRequired*/, &responder{}) + // If upgrade request is for tunneling websockets, wrap with tunneling handling. + if websocketSPDYTunnel { + servermetrics.IncWebSocketStreamingRequest("portforward") + handler = translator.NewTunnelingHandler(handler) + } + handler.ServeHTTP(response.ResponseWriter, request.Request) } // checkpoint handles the checkpoint API request. It checks if the requested @@ -1193,8 +1269,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { servermetrics.HTTPInflightRequests.WithLabelValues(method, path, serverType, longRunning).Inc() defer servermetrics.HTTPInflightRequests.WithLabelValues(method, path, serverType, longRunning).Dec() - startTime := time.Now() - defer servermetrics.HTTPRequestsDuration.WithLabelValues(method, path, serverType, longRunning).Observe(servermetrics.SinceInSeconds(startTime)) + // Use ObserveSince to ensure the duration is calculated when the defer executes, + // not when it's declared. In Go, arguments to deferred functions are evaluated + // immediately at the defer statement, which would cause the metric to record + // near-zero values (~2 microseconds) instead of actual request handling time. + defer servermetrics.HTTPRequestsDuration.ObserveSince(time.Now(), method, path, serverType, longRunning)() handler.ServeHTTP(w, req) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go index 61b7576c9f..1ac76920c9 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go @@ -79,7 +79,7 @@ type Provider interface { // namespace. GetPodByName(namespace, name string) (*v1.Pod, bool) // GetNode returns the spec of the local node. - GetNode() (*v1.Node, error) + GetNode(context.Context) (*v1.Node, error) // GetNodeConfig returns the configuration of the local node. GetNodeConfig() cm.NodeConfig // ListVolumesForPod returns the stats of the volume used by the pod with diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go index d371b7042c..35b95754fe 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go @@ -72,7 +72,7 @@ func NewSummaryProvider(ctx context.Context, statsProvider Provider) SummaryProv func (sp *summaryProviderImpl) Get(ctx context.Context, updateStats bool) (*statsapi.Summary, error) { // TODO(timstclair): Consider returning a best-effort response if any of // the following errors occur. - node, err := sp.provider.GetNode() + node, err := sp.provider.GetNode(ctx) if err != nil { return nil, fmt.Errorf("failed to get node info: %v", err) } @@ -129,7 +129,7 @@ func (sp *summaryProviderImpl) Get(ctx context.Context, updateStats bool) (*stat func (sp *summaryProviderImpl) GetCPUAndMemoryStats(ctx context.Context) (*statsapi.Summary, error) { // TODO(timstclair): Consider returning a best-effort response if any of // the following errors occur. - node, err := sp.provider.GetNode() + node, err := sp.provider.GetNode(ctx) if err != nil { return nil, fmt.Errorf("failed to get node info: %v", err) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers.go index 8ec6ca1f30..10fe13cd9f 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers_windows.go index ac6fae1f42..ea07f41542 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary_sys_containers_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider.go index a2f2d2fd36..14f2fb3171 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider.go @@ -165,10 +165,7 @@ func (p *criStatsProvider) listPodStats(ctx context.Context, updateCPUNanoCoreUs return nil, err } // CRI implementation doesn't support ListPodSandboxStats, warn and fallback. - logger.V(5).Info( - "CRI implementation must be updated to support ListPodSandboxStats if PodAndContainerStatsFromCRI feature gate is enabled. Falling back to populating with cAdvisor; this call will fail in the future.", - "err", err, - ) + logger.V(5).Info("CRI implementation must be updated to support ListPodSandboxStats if PodAndContainerStatsFromCRI feature gate is enabled. Falling back to populating with cAdvisor; this call will fail in the future.", "err", err) } return p.listPodStatsPartiallyFromCRI(ctx, updateCPUNanoCoreUsage, containerMap, podSandboxMap, &rootFsInfo) } @@ -288,6 +285,7 @@ func (p *criStatsProvider) listPodStatsStrictlyFromCRI(ctx context.Context, upda } func (p *criStatsProvider) PodCPUAndMemoryStats(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus) (*statsapi.PodStats, error) { + logger := klog.FromContext(ctx) if len(podStatus.SandboxStatuses) == 0 { return nil, fmt.Errorf("missing sandbox for pod %s", format.Pod(pod)) } @@ -311,7 +309,7 @@ func (p *criStatsProvider) PodCPUAndMemoryStats(ctx context.Context, pod *v1.Pod return nil, err } // CRI implementation doesn't support PodSandboxStats, warn and fallback. - klog.ErrorS(err, + logger.Error(err, "CRI implementation must be updated to support PodSandboxStats if PodAndContainerStatsFromCRI feature gate is enabled. Falling back to populating with cAdvisor; this call will fail in the future.", ) } else { @@ -332,7 +330,7 @@ func (p *criStatsProvider) PodCPUAndMemoryStats(ctx context.Context, pod *v1.Pod for _, stats := range resp { containerStatus := podStatus.FindContainerStatusByName(stats.Attributes.Metadata.Name) if containerStatus == nil { - klog.V(4).InfoS("Received stats for unknown container", "pod", klog.KObj(pod), "container", stats.Attributes.Metadata) + logger.V(4).Info("Received stats for unknown container", "pod", klog.KObj(pod), "container", stats.Attributes.Metadata) continue } @@ -399,8 +397,12 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats(ctx context.Context) ([]stat continue } ps := buildPodStats(podSandbox) + // Add container-level CPU and memory stats from CRI + p.addCRIPodContainerCPUAndMemoryStats(criSandboxStat, ps, containerMap) addCRIPodCPUStats(ps, criSandboxStat) addCRIPodMemoryStats(ps, criSandboxStat) + // Aggregate pod swap from container swap stats (CRI doesn't have pod-level swap) + aggregatePodSwapStats(ps) result = append(result, *ps) } return result, err @@ -700,6 +702,33 @@ func (p *criStatsProvider) addSwapStats( } } +// aggregatePodSwapStats aggregates pod-level swap stats from container swap stats. +// This is used when CRI doesn't provide pod-level swap stats (e.g., LinuxPodSandboxStats doesn't have a Swap field). +func aggregatePodSwapStats(ps *statsapi.PodStats) { + if len(ps.Containers) == 0 { + return + } + var swapAvailableBytes, swapUsageBytes uint64 + var hasSwapStats bool + var swapTime metav1.Time + for _, cs := range ps.Containers { + if cs.Swap != nil { + hasSwapStats = true + // TODO: Consider picking the newest time across containers instead of just using the last one. + swapTime = cs.Swap.Time + swapAvailableBytes += ptr.Deref(cs.Swap.SwapAvailableBytes, 0) + swapUsageBytes += ptr.Deref(cs.Swap.SwapUsageBytes, 0) + } + } + if hasSwapStats { + ps.Swap = &statsapi.SwapStats{ + Time: swapTime, + SwapAvailableBytes: &swapAvailableBytes, + SwapUsageBytes: &swapUsageBytes, + } + } +} + func (p *criStatsProvider) addIOStats( ps *statsapi.PodStats, podUID types.UID, @@ -783,6 +812,15 @@ func (p *criStatsProvider) makeContainerStats( if stats.Memory.RssBytes != nil { result.Memory.RSSBytes = &stats.Memory.RssBytes.Value } + if stats.Memory.AvailableBytes != nil { + result.Memory.AvailableBytes = &stats.Memory.AvailableBytes.Value + } + if stats.Memory.PageFaults != nil { + result.Memory.PageFaults = &stats.Memory.PageFaults.Value + } + if stats.Memory.MajorPageFaults != nil { + result.Memory.MajorPageFaults = &stats.Memory.MajorPageFaults.Value + } result.Memory.PSI = makePSIStats(stats.Memory.Psi) } else { result.Memory.Time = metav1.NewTime(time.Unix(0, time.Now().UnixNano())) @@ -1157,6 +1195,11 @@ func (p *criStatsProvider) addCadvisorContainerCPUAndMemoryStats( if memory != nil { cs.Memory = memory } + + swap := cadvisorInfoToSwapStats(caPodStats) + if swap != nil { + cs.Swap = swap + } } func getCRICadvisorStats(logger klog.Logger, infos map[string]cadvisorapiv2.ContainerInfo) (map[string]cadvisorapiv2.ContainerInfo, map[string]cadvisorapiv2.ContainerInfo) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_linux.go index 576df556de..81dc9c76cd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2023 The Kubernetes Authors. @@ -57,6 +56,27 @@ func (p *criStatsProvider) addCRIPodContainerStats( return nil } +// addCRIPodContainerCPUAndMemoryStats adds container CPU and memory stats from CRI to the PodStats. +// This is a lighter-weight version of addCRIPodContainerStats that only populates CPU and memory +// stats needed for the resource metrics endpoint. +func (p *criStatsProvider) addCRIPodContainerCPUAndMemoryStats( + criSandboxStat *runtimeapi.PodSandboxStats, + ps *statsapi.PodStats, + containerMap map[string]*runtimeapi.Container) { + if criSandboxStat == nil || criSandboxStat.Linux == nil { + return + } + for _, criContainerStat := range criSandboxStat.Linux.Containers { + container, found := containerMap[criContainerStat.Attributes.Id] + if !found { + continue + } + // Fill available CPU and memory stats for resource metrics + cs := p.makeContainerCPUAndMemoryStats(criContainerStat, time.Unix(0, container.CreatedAt), true) + ps.Containers = append(ps.Containers, *cs) + } +} + func addCRIPodNetworkStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) { if criPodStat == nil || criPodStat.Linux == nil || criPodStat.Linux.Network == nil { return diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_others.go index f8188fb483..4d075114db 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_others.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2019 The Kubernetes Authors. @@ -59,3 +58,9 @@ func addCRIPodProcessStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSand func addCRIPodIOStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) { } + +func (p *criStatsProvider) addCRIPodContainerCPUAndMemoryStats( + *runtimeapi.PodSandboxStats, + *statsapi.PodStats, + map[string]*runtimeapi.Container) { +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_windows.go index 367a46516b..48fad4582a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/cri_stats_provider_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. @@ -146,11 +145,15 @@ func (p *criStatsProvider) makeWinContainerStats( if stats.Memory.PageFaults != nil { result.Memory.PageFaults = &stats.Memory.PageFaults.Value } + if stats.Memory.CommitMemoryBytes != nil { + result.Memory.UsageBytes = &stats.Memory.CommitMemoryBytes.Value + } } else { result.Memory.Time = metav1.NewTime(time.Unix(0, time.Now().UnixNano())) result.Memory.WorkingSetBytes = ptr.To[uint64](0) result.Memory.AvailableBytes = ptr.To[uint64](0) result.Memory.PageFaults = ptr.To[uint64](0) + result.Memory.UsageBytes = ptr.To[uint64](0) } if stats.WritableLayer != nil { result.Rootfs.Time = metav1.NewTime(time.Unix(0, stats.WritableLayer.Timestamp)) @@ -233,6 +236,7 @@ func addCRIPodMemoryStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandb ps.Memory = &statsapi.MemoryStats{ Time: metav1.NewTime(time.Unix(0, criMemory.Timestamp)), AvailableBytes: valueOfUInt64Value(criMemory.AvailableBytes), + UsageBytes: valueOfUInt64Value(criMemory.CommitMemoryBytes), WorkingSetBytes: valueOfUInt64Value(criMemory.WorkingSetBytes), PageFaults: valueOfUInt64Value(criMemory.PageFaults), } @@ -274,6 +278,66 @@ func criInterfaceToWinSummary(criIface *runtimeapi.WindowsNetworkInterfaceUsage) } } +// addCRIPodContainerCPUAndMemoryStats adds container CPU and memory stats from CRI to the PodStats. +func (p *criStatsProvider) addCRIPodContainerCPUAndMemoryStats( + criSandboxStat *runtimeapi.PodSandboxStats, + ps *statsapi.PodStats, + containerMap map[string]*runtimeapi.Container) { + if criSandboxStat == nil || criSandboxStat.Windows == nil { + return + } + for _, criContainerStat := range criSandboxStat.Windows.Containers { + container, found := containerMap[criContainerStat.Attributes.Id] + if !found { + continue + } + // Fill available CPU and memory stats for resource metrics + cs := p.makeWinContainerCPUAndMemoryStats(criContainerStat, time.Unix(0, container.CreatedAt)) + ps.Containers = append(ps.Containers, *cs) + } +} + +// makeWinContainerCPUAndMemoryStats creates container stats with only CPU and memory populated. +// This is a lighter-weight version for the resource metrics endpoint. +func (p *criStatsProvider) makeWinContainerCPUAndMemoryStats( + stats *runtimeapi.WindowsContainerStats, + startTime time.Time, +) *statsapi.ContainerStats { + result := &statsapi.ContainerStats{ + Name: stats.Attributes.Metadata.Name, + StartTime: metav1.NewTime(startTime), + } + if stats.Cpu != nil { + result.CPU = &statsapi.CPUStats{ + Time: metav1.NewTime(time.Unix(0, stats.Cpu.Timestamp)), + UsageCoreNanoSeconds: ptr.To(stats.Cpu.UsageCoreNanoSeconds.GetValue()), + UsageNanoCores: ptr.To(stats.Cpu.UsageNanoCores.GetValue()), + } + } else { + result.CPU = &statsapi.CPUStats{ + Time: metav1.NewTime(time.Unix(0, time.Now().UnixNano())), + UsageCoreNanoSeconds: ptr.To[uint64](0), + UsageNanoCores: ptr.To[uint64](0), + } + } + if stats.Memory != nil { + result.Memory = &statsapi.MemoryStats{ + Time: metav1.NewTime(time.Unix(0, stats.Memory.Timestamp)), + WorkingSetBytes: ptr.To(stats.Memory.WorkingSetBytes.GetValue()), + AvailableBytes: ptr.To(stats.Memory.AvailableBytes.GetValue()), + PageFaults: ptr.To(stats.Memory.PageFaults.GetValue()), + } + } else { + result.Memory = &statsapi.MemoryStats{ + Time: metav1.NewTime(time.Unix(0, time.Now().UnixNano())), + WorkingSetBytes: ptr.To[uint64](0), + AvailableBytes: ptr.To[uint64](0), + PageFaults: ptr.To[uint64](0), + } + } + return result +} + // newNetworkStatsProvider uses the real windows hnslib if not provided otherwise if the interface is provided // by the cristatsprovider in testing scenarios it uses that one func newNetworkStatsProvider(p *criStatsProvider) windowsNetworkStatsProvider { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go index 25e7655203..40fa8b73b2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go index 805c276d99..b195a771d1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go index f4334b59ce..bac491cb7d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go @@ -22,6 +22,7 @@ import ( "fmt" "reflect" "sort" + "strconv" "strings" "sync" "time" @@ -79,6 +80,7 @@ type manager struct { podDeletionSafety PodDeletionSafetyProvider podStartupLatencyHelper PodStartupLatencyStateHelper + notifiers []PodUpdateNotifier } type podResizeConditions struct { @@ -126,6 +128,21 @@ type PodStartupLatencyStateHelper interface { DeletePodStartupState(podUID types.UID) } +// PodUpdateNotifier is an interface for receiving pod status updates. +type PodUpdateNotifier interface { + // OnPodUpdated is called when a pod's status is updated. + OnPodUpdated(pod *v1.Pod, status v1.PodStatus, isAdded bool) + // OnPodRemoved is called when a pod is terminated. + OnPodRemoved(pod *v1.Pod) +} + +type podStatusNotification struct { + pod *v1.Pod + status v1.PodStatus + isAdded bool + podIsFinished bool +} + // Manager is the Source of truth for kubelet pod status, and should be kept up-to-date with // the latest v1.PodStatus. It also syncs updates back to the API server. type Manager interface { @@ -134,8 +151,11 @@ type Manager interface { // Start the API server status sync loop. Start(ctx context.Context) + // AddPodUpdateNotifier adds a subscriber to receive pod status updates. + AddPodUpdateNotifier(notifier PodUpdateNotifier) + // SetPodStatus caches updates the cached status for the given pod, and triggers a status update. - SetPodStatus(logger klog.Logger, pod *v1.Pod, status v1.PodStatus) + SetPodStatus(logger klog.Logger, pod *v1.Pod, status v1.PodStatus) (v1.PodStatus, bool) // SetContainerReadiness updates the cached container status with the given readiness, and // triggers a status update. @@ -202,10 +222,11 @@ func NewManager(kubeClient clientset.Interface, podManager PodManager, podDeleti } } -// isPodStatusByKubeletEqual returns true if the given pod statuses are equal when non-kubelet-owned -// pod conditions are excluded. -// This method normalizes the status before comparing so as to make sure that meaningless -// changes will be ignored. +// isPodStatusByKubeletEqual returns true if the given pod statuses are equal, ignoring +// fields not managed by the kubelet (including non-kubelet-owned pod conditions, +// ResourceClaimStatuses, ExtendedResourceClaimStatus, and +// NodeAllocatableResourceClaimStatuses). Statuses are assumed to be +// normalized before calling this function. func isPodStatusByKubeletEqual(oldStatus, status *v1.PodStatus) bool { oldCopy := oldStatus.DeepCopy() @@ -233,6 +254,13 @@ func isPodStatusByKubeletEqual(oldStatus, status *v1.PodStatus) bool { } oldCopy.Conditions = status.Conditions + // ResourceClaimStatuses is not owned and not modified by kubelet. + oldCopy.ResourceClaimStatuses = status.ResourceClaimStatuses + // ExtendedResourceClaimStatus is not owned and not modified by kubelet. + oldCopy.ExtendedResourceClaimStatus = status.ExtendedResourceClaimStatus + // NodeAllocatableResourceClaimStatuses is not owned and not modified by kubelet. + oldCopy.NodeAllocatableResourceClaimStatuses = status.NodeAllocatableResourceClaimStatuses + return apiequality.Semantic.DeepEqual(oldCopy, status) } @@ -266,6 +294,12 @@ func (m *manager) Start(ctx context.Context) { }, 0) } +func (m *manager) AddPodUpdateNotifier(notifier PodUpdateNotifier) { + m.podStatusesLock.Lock() + defer m.podStatusesLock.Unlock() + m.notifiers = append(m.notifiers, notifier) +} + // GetPodResizeConditions returns the last cached ResizeStatus value. func (m *manager) GetPodResizeConditions(podUID types.UID) []*v1.PodCondition { m.podStatusesLock.RLock() @@ -281,6 +315,11 @@ func (m *manager) SetPodResizePendingCondition(podUID types.UID, reason, message previousCondition := m.podResizeConditions[podUID].PodResizePending + if reason != v1.PodReasonInfeasible { + // For all other "pending" reasons, we set the reason to "Deferred". + reason = v1.PodReasonDeferred + } + m.podResizeConditions[podUID] = podResizeConditions{ PodResizePending: updatedPodResizeCondition(v1.PodResizePending, m.podResizeConditions[podUID].PodResizePending, reason, message, observedGeneration), PodResizeInProgress: m.podResizeConditions[podUID].PodResizeInProgress, @@ -422,7 +461,14 @@ func (m *manager) GetPodStatus(uid types.UID) (v1.PodStatus, bool) { return status.status, ok } -func (m *manager) SetPodStatus(logger klog.Logger, pod *v1.Pod, status v1.PodStatus) { +func (m *manager) SetPodStatus(logger klog.Logger, pod *v1.Pod, status v1.PodStatus) (v1.PodStatus, bool) { + var notification *podStatusNotification + defer func() { + if notification != nil { + m.sendNotification(notification) + } + }() + m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() @@ -435,10 +481,20 @@ func (m *manager) SetPodStatus(logger klog.Logger, pod *v1.Pod, status v1.PodSta // Force a status update if deletion timestamp is set. This is necessary // because if the pod is in the non-running state, the pod worker still // needs to be able to trigger an update and/or deletion. - m.updateStatusInternal(logger, pod, status, pod.DeletionTimestamp != nil, false) + changed, notif := m.updateStatusInternal(logger, pod, status, pod.DeletionTimestamp != nil, false) + notification = notif + + return m.podStatuses[pod.UID].status, changed } func (m *manager) SetContainerReadiness(logger klog.Logger, podUID types.UID, containerID kubecontainer.ContainerID, ready bool) { + var notification *podStatusNotification + defer func() { + if notification != nil { + m.sendNotification(notification) + } + }() + m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() @@ -498,10 +554,17 @@ func (m *manager) SetContainerReadiness(logger klog.Logger, podUID types.UID, co allContainerStatuses := append(status.InitContainerStatuses, status.ContainerStatuses...) updateConditionFunc(v1.PodReady, GeneratePodReadyCondition(pod, &oldStatus.status, status.Conditions, allContainerStatuses, status.Phase)) updateConditionFunc(v1.ContainersReady, GenerateContainersReadyCondition(pod, &oldStatus.status, allContainerStatuses, status.Phase)) - m.updateStatusInternal(logger, pod, status, false, false) + _, notification = m.updateStatusInternal(logger, pod, status, false, false) } func (m *manager) SetContainerStartup(logger klog.Logger, podUID types.UID, containerID kubecontainer.ContainerID, started bool) { + var notification *podStatusNotification + defer func() { + if notification != nil { + m.sendNotification(notification) + } + }() + m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() @@ -540,7 +603,7 @@ func (m *manager) SetContainerStartup(logger klog.Logger, podUID types.UID, cont containerStatus, _, _ = findContainerStatus(&status, containerID.String()) containerStatus.Started = &started - m.updateStatusInternal(logger, pod, status, false, false) + _, notification = m.updateStatusInternal(logger, pod, status, false, false) } func findContainerStatus(status *v1.PodStatus, containerID string) (containerStatus *v1.ContainerStatus, init bool, ok bool) { @@ -572,6 +635,13 @@ func findContainerStatus(status *v1.PodStatus, containerID string) (containerSta // It also makes sure that pods are transitioned to a terminal phase (Failed or Succeeded) before // their deletion. func (m *manager) TerminatePod(logger klog.Logger, pod *v1.Pod) { + var notification *podStatusNotification + defer func() { + if notification != nil { + m.sendNotification(notification) + } + }() + m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() @@ -634,7 +704,7 @@ func (m *manager) TerminatePod(logger klog.Logger, pod *v1.Pod) { } logger.V(5).Info("TerminatePod calling updateStatusInternal", "pod", klog.KObj(pod), "podUID", pod.UID) - m.updateStatusInternal(logger, pod, status, true, true) + _, notification = m.updateStatusInternal(logger, pod, status, true, true) } // hasPodInitialized returns true if the pod has no evidence of ever starting a regular container, which @@ -776,7 +846,7 @@ func checkContainerStateTransition(oldStatuses, newStatuses *v1.PodStatus, podSp // updateStatusInternal updates the internal status cache, and queues an update to the api server if // necessary. // This method IS NOT THREAD SAFE and must be called from a locked function. -func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v1.PodStatus, forceUpdate, podIsFinished bool) { +func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v1.PodStatus, forceUpdate, podIsFinished bool) (bool, *podStatusNotification) { var oldStatus v1.PodStatus cachedStatus, isCached := m.podStatuses[pod.UID] if isCached { @@ -797,7 +867,7 @@ func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v // Check for illegal state transition in containers if err := checkContainerStateTransition(&oldStatus, &status, &pod.Spec); err != nil { logger.Error(err, "Status update on pod aborted", "pod", klog.KObj(pod)) - return + return false, nil } // Set ContainersReadyCondition.LastTransitionTime. @@ -823,7 +893,7 @@ func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v // ensure that the start time does not change across updates. if oldStatus.StartTime != nil && !oldStatus.StartTime.IsZero() { - status.StartTime = oldStatus.StartTime + status.StartTime = oldStatus.StartTime.DeepCopy() } else if status.StartTime.IsZero() { // if the status has no start time, we need to set an initial time now := metav1.Now() @@ -869,11 +939,38 @@ func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v loggerV.Info("updateStatusInternal", "version", cachedStatus.version+1, "podIsFinished", podIsFinished, "pod", klog.KObj(pod), "podUID", pod.UID, "containers", strings.Join(containers, " ")) } + // Increment container termination metric for newly terminated containers. + // We only want to count terminations once per container per pod. + // By comparing the new status to the old status before we apply it to the cache, + // we can detect exactly when a container in this pod transitions to the + // Terminated state and record the metric. + checkAndRecordTerminations := func(oldStatuses, newStatuses []v1.ContainerStatus, containerType string) { + for _, newCStat := range newStatuses { + if newCStat.State.Terminated != nil { + // Find the old status for this container. + var oldCStat *v1.ContainerStatus + for i := range oldStatuses { + if oldStatuses[i].Name == newCStat.Name { + oldCStat = &oldStatuses[i] + break + } + } + // If it wasn't terminated before (or is brand new and already terminated), record it. + if oldCStat == nil || oldCStat.State.Terminated == nil { + metrics.TerminatedContainersTotal.WithLabelValues(containerType, strconv.Itoa(int(newCStat.State.Terminated.ExitCode)), newCStat.State.Terminated.Reason).Inc() + } + } + } + } + checkAndRecordTerminations(oldStatus.InitContainerStatuses, status.InitContainerStatuses, metrics.InitContainer) + checkAndRecordTerminations(oldStatus.ContainerStatuses, status.ContainerStatuses, metrics.Container) + checkAndRecordTerminations(oldStatus.EphemeralContainerStatuses, status.EphemeralContainerStatuses, metrics.EphemeralContainer) + // The intent here is to prevent concurrent updates to a pod's status from // clobbering each other so the phase of a pod progresses monotonically. if isCached && isPodStatusByKubeletEqual(&cachedStatus.status, &status) && !forceUpdate { logger.V(3).Info("Ignoring same status for pod", "pod", klog.KObj(pod), "status", status) - return + return false, nil } newStatus := versionedPodStatus{ @@ -900,6 +997,28 @@ func (m *manager) updateStatusInternal(logger klog.Logger, pod *v1.Pod, status v default: // there's already a status update pending } + + podCopy := *pod + podCopy.Status = status + + notification := &podStatusNotification{ + pod: &podCopy, + status: status, + isAdded: !isCached && pod.DeletionTimestamp == nil, + podIsFinished: podIsFinished, + } + + return true, notification +} + +func (m *manager) sendNotification(n *podStatusNotification) { + for _, notifier := range m.notifiers { + if !n.podIsFinished { + notifier.OnPodUpdated(n.pod, n.status, n.isAdded) + } else { + notifier.OnPodRemoved(n.pod) + } + } } // updateLastTransitionTime updates the LastTransitionTime of a pod condition. @@ -1277,6 +1396,8 @@ func mergePodStatus(pod *v1.Pod, oldPodStatus, newPodStatus v1.PodStatus, couldH newPodStatus.ResourceClaimStatuses = oldPodStatus.ResourceClaimStatuses // ExtendedResourceClaimStatus is not owned and not modified by kubelet. newPodStatus.ExtendedResourceClaimStatus = oldPodStatus.ExtendedResourceClaimStatus + // NodeAllocatableResourceClaimStatuses is not owned and not modified by kubelet. + newPodStatus.NodeAllocatableResourceClaimStatuses = oldPodStatus.NodeAllocatableResourceClaimStatuses // Delay transitioning a pod to a terminal status unless the pod is actually terminal. // The Kubelet should never transition a pod to terminal status that could have running diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go index ee4bd58c7e..281efd20d3 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go @@ -38,10 +38,8 @@ type PodOperation int // These constants identify the PodOperations that can be made on a pod configuration. const ( - // SET is the current pod configuration. - SET PodOperation = iota // ADD signifies pods that are new to this source. - ADD + ADD PodOperation = iota // DELETE signifies pods that are gracefully deleted from this source. DELETE // REMOVE signifies pods that have been removed from this source. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/types.go index e494ca212e..d2c515d700 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/types.go @@ -16,7 +16,10 @@ limitations under the License. package userns -import "k8s.io/apimachinery/pkg/types" +import ( + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog/v2" +) // Here go types that are common for all supported OS (windows, linux). @@ -24,6 +27,6 @@ type userNsPodsManager interface { HandlerSupportsUserNamespaces(runtimeHandler string) (bool, error) GetPodDir(podUID types.UID) string ListPodsFromDisk() ([]types.UID, error) - GetKubeletMappings(idsPerPod uint32) (uint32, uint32, error) + GetKubeletMappings(logger klog.Logger, idsPerPod uint32) (uint32, uint32, error) GetMaxPods() int } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager.go index edd2e4e97d..6a79ac78f4 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2022 The Kubernetes Authors. @@ -141,7 +140,7 @@ func MakeUserNsManager(logger klog.Logger, kl userNsPodsManager, idsPerPod *int6 // cast it. userNsLength = uint32(*idsPerPod) } - kubeletMappingID, kubeletMappingLen, err := kl.GetKubeletMappings(userNsLength) + kubeletMappingID, kubeletMappingLen, err := kl.GetKubeletMappings(logger, userNsLength) if err != nil { return nil, fmt.Errorf("kubelet mappings: %w", err) } @@ -394,8 +393,7 @@ func (m *UsernsManager) createUserNs(logger klog.Logger, pod *v1.Pod) (userNs us } // GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace -func (m *UsernsManager) GetOrCreateUserNamespaceMappings(ctx context.Context, pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { - logger := klog.FromContext(ctx) +func (m *UsernsManager) GetOrCreateUserNamespaceMappings(logger klog.Logger, pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) { featureEnabled := utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesSupport) // TODO: If the default value for hostUsers ever changes, change the default value of diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager_windows.go index 2bd5c8390d..c83403b92d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/userns/userns_manager_windows.go @@ -37,7 +37,7 @@ func (m *UsernsManager) Release(klog.Logger, types.UID) { return } -func (m *UsernsManager) GetOrCreateUserNamespaceMappings(context.Context, *v1.Pod, string) (*runtimeapi.UserNamespace, error) { +func (m *UsernsManager) GetOrCreateUserNamespaceMappings(klog.Logger, *v1.Pod, string) (*runtimeapi.UserNamespace, error) { return nil, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go index b6a1cc38c8..42fb097733 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go @@ -1,5 +1,4 @@ //go:build darwin -// +build darwin /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go index 7d605d7611..b02f9d8d33 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go @@ -1,5 +1,4 @@ //go:build freebsd -// +build freebsd /* Copyright 2020 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go index 67c9b191cf..028b01d3d5 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/manager/cache_based_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/manager/cache_based_manager.go index 5f478cf3f5..65595cb52d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/manager/cache_based_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/manager/cache_based_manager.go @@ -17,6 +17,7 @@ limitations under the License. package manager import ( + "context" "fmt" "strconv" "sync" @@ -129,9 +130,11 @@ func (s *objectStore) DeleteReference(namespace, name string, _ types.UID) { // GetObjectTTLFromNodeFunc returns a function that returns TTL value // from a given Node object. -func GetObjectTTLFromNodeFunc(getNode func() (*v1.Node, error)) GetObjectTTLFunc { +func GetObjectTTLFromNodeFunc(getNode func(context.Context) (*v1.Node, error)) GetObjectTTLFunc { return func() (time.Duration, bool) { - node, err := getNode() + // TODO: Pass context from upper level instead of using context.Background(). + // This requires changing the GetObjectTTLFunc signature to accept a context parameter. + node, err := getNode(context.Background()) if err != nil { return time.Duration(0), false } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go index d972815a78..d083464f4d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go @@ -34,6 +34,8 @@ type PodStartupLatencyTracker interface { ObservedPodOnWatch(pod *v1.Pod, when time.Time) RecordImageStartedPulling(podUID types.UID) RecordImageFinishedPulling(podUID types.UID) + RecordInitContainerStarted(podUID types.UID, startedAt time.Time) + RecordInitContainerFinished(podUID types.UID, finishedAt time.Time) RecordStatusUpdated(pod *v1.Pod) DeletePodStartupState(podUID types.UID) } @@ -42,15 +44,26 @@ type basicPodStartupLatencyTracker struct { // protect against concurrent read and write on pods map lock sync.Mutex pods map[types.UID]*perPodState + // Track pods that were excluded from SLI due to unschedulability + // These pods should never be re-added even if they later become schedulable + excludedPods map[types.UID]bool // metrics for the first network pod only firstNetworkPodSeen bool // For testability clock clock.Clock } +type imagePullSession struct { + start time.Time + end time.Time +} type perPodState struct { - firstStartedPulling time.Time - lastFinishedPulling time.Time + // Session-based image pulling tracking for accurate overlap handling + imagePullSessions []imagePullSession + imagePullSessionsStarts []time.Time // Track multiple concurrent pull starts + // Init container tracking + totalInitContainerRuntime time.Duration + currentInitContainerStart time.Time // first time, when pod status changed into Running observedRunningTime time.Time // log, if pod latency was already Observed @@ -60,8 +73,9 @@ type perPodState struct { // NewPodStartupLatencyTracker creates an instance of PodStartupLatencyTracker func NewPodStartupLatencyTracker() PodStartupLatencyTracker { return &basicPodStartupLatencyTracker{ - pods: map[types.UID]*perPodState{}, - clock: clock.RealClock{}, + pods: map[types.UID]*perPodState{}, + excludedPods: map[types.UID]bool{}, + clock: clock.RealClock{}, } } @@ -77,13 +91,29 @@ func (p *basicPodStartupLatencyTracker) ObservedPodOnWatch(pod *v1.Pod, when tim state := p.pods[pod.UID] if state == nil { - // create a new record for pod, only if it was not yet acknowledged by the Kubelet - // this is required, as we want to log metric only for those pods, that where scheduled - // after Kubelet started + // if pod was previously unschedulable, don't track it again + if p.excludedPods[pod.UID] { + return + } + + // create a new record for pod if pod.Status.StartTime.IsZero() { - p.pods[pod.UID] = &perPodState{} + if isPodUnschedulable(pod) { + p.excludedPods[pod.UID] = true + return + } + + // if pod is schedulable then track it + state = &perPodState{} + p.pods[pod.UID] = state } + return + } + // remove existing pods from tracking (this handles cases where scheduling state becomes known later) + if isPodUnschedulable(pod) { + delete(p.pods, pod.UID) + p.excludedPods[pod.UID] = true return } @@ -102,29 +132,74 @@ func (p *basicPodStartupLatencyTracker) ObservedPodOnWatch(pod *v1.Pod, when tim ctx := context.TODO() logger := klog.FromContext(ctx) podStartingDuration := when.Sub(pod.CreationTimestamp.Time) - imagePullingDuration := state.lastFinishedPulling.Sub(state.firstStartedPulling) - podStartSLOduration := (podStartingDuration - imagePullingDuration).Seconds() + podStartSLOduration := podStartingDuration + + totalImagesPullingTime := calculateImagePullingTime(state.imagePullSessions) + if totalImagesPullingTime > 0 { + podStartSLOduration -= totalImagesPullingTime + } + + if state.totalInitContainerRuntime > 0 { + podStartSLOduration -= state.totalInitContainerRuntime + } + + podIsStateful := isStatefulPod(pod) logger.Info("Observed pod startup duration", "pod", klog.KObj(pod), - "podStartSLOduration", podStartSLOduration, + "podStartSLOduration", podStartSLOduration.Seconds(), "podStartE2EDuration", podStartingDuration, + "totalImagesPullingTime", totalImagesPullingTime, + "totalInitContainerRuntime", state.totalInitContainerRuntime, + "isStatefulPod", podIsStateful, "podCreationTimestamp", pod.CreationTimestamp.Time, - "firstStartedPulling", state.firstStartedPulling, - "lastFinishedPulling", state.lastFinishedPulling, + "imagePullSessionsCount", len(state.imagePullSessions), + "imagePullSessionsStartsCount", len(state.imagePullSessionsStarts), "observedRunningTime", state.observedRunningTime, "watchObservedRunningTime", when) - metrics.PodStartSLIDuration.WithLabelValues().Observe(podStartSLOduration) metrics.PodStartTotalDuration.WithLabelValues().Observe(podStartingDuration.Seconds()) + if !podIsStateful { + metrics.PodStartSLIDuration.WithLabelValues().Observe(podStartSLOduration.Seconds()) + // if is the first Pod with network track the start values + // these metrics will help to identify problems with the CNI plugin + if !pod.Spec.HostNetwork && !p.firstNetworkPodSeen { + metrics.FirstNetworkPodStartSLIDuration.Set(podStartSLOduration.Seconds()) + p.firstNetworkPodSeen = true + } + } state.metricRecorded = true - // if is the first Pod with network track the start values - // these metrics will help to identify problems with the CNI plugin - if !pod.Spec.HostNetwork && !p.firstNetworkPodSeen { - metrics.FirstNetworkPodStartSLIDuration.Set(podStartSLOduration) - p.firstNetworkPodSeen = true + } +} + +// calculateImagePullingTime computes the total time spent pulling images, +// accounting for overlapping pull sessions properly +func calculateImagePullingTime(sessions []imagePullSession) time.Duration { + if len(sessions) == 0 { + return 0 + } + + var totalTime time.Duration + var currentEnd time.Time + + for i, session := range sessions { + if session.end.IsZero() { + continue } + + if i == 0 || session.start.After(currentEnd) { + // First session or no overlap with previous session + totalTime += session.end.Sub(session.start) + currentEnd = session.end + } else if session.end.After(currentEnd) { + // Partial overlap - add only the non-overlapping part + totalTime += session.end.Sub(currentEnd) + currentEnd = session.end + } + // If session.end <= currentEnd, it's completely overlapped } + + return totalTime } func (p *basicPodStartupLatencyTracker) RecordImageStartedPulling(podUID types.UID) { @@ -136,9 +211,8 @@ func (p *basicPodStartupLatencyTracker) RecordImageStartedPulling(podUID types.U return } - if state.firstStartedPulling.IsZero() { - state.firstStartedPulling = p.clock.Now() - } + now := p.clock.Now() + state.imagePullSessionsStarts = append(state.imagePullSessionsStarts, now) } func (p *basicPodStartupLatencyTracker) RecordImageFinishedPulling(podUID types.UID) { @@ -150,8 +224,48 @@ func (p *basicPodStartupLatencyTracker) RecordImageFinishedPulling(podUID types. return } - if !state.firstStartedPulling.IsZero() { - state.lastFinishedPulling = p.clock.Now() // Now is always grater than values from the past. + now := p.clock.Now() + + // Complete the oldest pull session if we have active starts + if len(state.imagePullSessionsStarts) > 0 { + // Take the first (oldest) start and create a session + startTime := state.imagePullSessionsStarts[0] + session := imagePullSession{ + start: startTime, + end: now, + } + state.imagePullSessions = append(state.imagePullSessions, session) + state.imagePullSessionsStarts = state.imagePullSessionsStarts[1:] + } +} + +func (p *basicPodStartupLatencyTracker) RecordInitContainerStarted(podUID types.UID, startedAt time.Time) { + p.lock.Lock() + defer p.lock.Unlock() + + state := p.pods[podUID] + if state == nil { + return + } + + state.currentInitContainerStart = startedAt +} + +func (p *basicPodStartupLatencyTracker) RecordInitContainerFinished(podUID types.UID, finishedAt time.Time) { + p.lock.Lock() + defer p.lock.Unlock() + + state := p.pods[podUID] + if state == nil { + return + } + + if !state.currentInitContainerStart.IsZero() { + initDuration := finishedAt.Sub(state.currentInitContainerStart) + if initDuration > 0 { + state.totalInitContainerRuntime += initDuration + } + state.currentInitContainerStart = time.Time{} } } @@ -197,9 +311,43 @@ func hasPodStartedSLO(pod *v1.Pod) bool { return true } +// isStatefulPod determines if a pod is stateful according to the SLI documentation: +// "A stateful pod is defined as a pod that mounts at least one volume with sources +// other than secrets, config maps, downward API and empty dir." +// We also include Projected volumes since they are a collection of ephemeral types. +// ref: https://github.com/kubernetes/community/blob/master/sig-scalability/slos/pod_startup_latency.md +func isStatefulPod(pod *v1.Pod) bool { + for _, volume := range pod.Spec.Volumes { + // Check if this volume is NOT a stateless/ephemeral type + if volume.Secret == nil && + volume.ConfigMap == nil && + volume.DownwardAPI == nil && + volume.EmptyDir == nil && + volume.Projected == nil { + return true + } + } + return false +} + +// isPodUnschedulable determines if a pod should be excluded from SLI tracking +// according to the SLI definition: "By schedulable pod we mean a pod that has to be +// immediately (without actions from any other components) schedulable in the cluster +// without causing any preemption." +// Any pod with PodScheduled=False is not immediately schedulable and should be excluded. +func isPodUnschedulable(pod *v1.Pod) bool { + for _, condition := range pod.Status.Conditions { + if condition.Type == v1.PodScheduled && condition.Status == v1.ConditionFalse { + return true + } + } + return false +} + func (p *basicPodStartupLatencyTracker) DeletePodStartupState(podUID types.UID) { p.lock.Lock() defer p.lock.Unlock() delete(p.pods, podUID) + delete(p.excludedPods, podUID) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go index 8aa025abe3..9039797b18 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go @@ -84,7 +84,7 @@ func GetLimits(res *ResourceOpts) v1.ResourceList { if containerResources == nil || containerResources.Limits == nil { return v1.ResourceList{} } - return containerResources.Limits + return containerResources.Limits.DeepCopy() } containerLimits := limitsOrEmpty(res.ContainerResources) @@ -99,13 +99,13 @@ func GetLimits(res *ResourceOpts) v1.ResourceList { // When container-level CPU limit is not set, the pod-level // limit CPU is applied at container-level if containerLimits.Cpu().IsZero() && !podLevelLimits.Cpu().IsZero() { - containerLimits[v1.ResourceCPU] = podLevelLimits[v1.ResourceCPU] + containerLimits[v1.ResourceCPU] = podLevelLimits[v1.ResourceCPU].DeepCopy() } // When container-level Memory limit is not set, the pod-level // limit Memory is applied at container-level if containerLimits.Memory().IsZero() && !podLevelLimits.Memory().IsZero() { - containerLimits[v1.ResourceMemory] = podLevelLimits[v1.ResourceMemory] + containerLimits[v1.ResourceMemory] = podLevelLimits[v1.ResourceMemory].DeepCopy() } return containerLimits } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go index 98efbb46fe..12c11cbeff 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go index e2e1c71bac..35541c404b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go index 0664b6a424..e1a310c0a7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go @@ -1,5 +1,4 @@ //go:build freebsd || linux || darwin -// +build freebsd linux darwin /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go index e95a7c583a..983cbf931d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go @@ -1,5 +1,4 @@ //go:build !freebsd && !linux && !windows && !darwin -// +build !freebsd,!linux,!windows,!darwin /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go index c944a7d22f..80d8211326 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go b/vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go index d0648825cb..5dd5694777 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go @@ -219,12 +219,9 @@ func (kvh *kubeletVolumeHost) GetMounter() mount.Interface { return kvh.kubelet.mounter } -func (kvh *kubeletVolumeHost) GetHostName() string { - return kvh.kubelet.hostname -} - func (kvh *kubeletVolumeHost) GetNodeAllocatable() (v1.ResourceList, error) { - node, err := kvh.kubelet.getNodeAnyWay() + // TODO: Pass proper context when VolumeHost interface methods support context parameters + node, err := kvh.kubelet.getNodeAnyWay(context.TODO()) if err != nil { return nil, fmt.Errorf("error retrieving node: %v", err) } @@ -270,7 +267,8 @@ func (kvh *kubeletVolumeHost) GetPodCertificateCredentialBundle(ctx context.Cont } func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) { - node, err := kvh.kubelet.GetNode() + // TODO: Pass proper context when VolumeHost interface methods support context parameters + node, err := kvh.kubelet.GetNode(context.TODO()) if err != nil { return nil, fmt.Errorf("error retrieving node: %v", err) } @@ -278,7 +276,8 @@ func (kvh *kubeletVolumeHost) GetNodeLabels() (map[string]string, error) { } func (kvh *kubeletVolumeHost) GetAttachedVolumesFromNodeStatus() (map[v1.UniqueVolumeName]string, error) { - node, err := kvh.kubelet.GetNode() + // TODO: Pass proper context when VolumeHost interface methods support context parameters + node, err := kvh.kubelet.GetNode(context.TODO()) if err != nil { return nil, fmt.Errorf("error retrieving node: %v", err) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/volume_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/volume_manager.go index f0c58f3bad..16d580ce94 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/volume_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/volume_manager.go @@ -23,7 +23,6 @@ import ( "slices" "strconv" "strings" - "sync" "time" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -208,7 +207,7 @@ func NewVolumeManager( } intreeToCSITranslator := csitrans.New() - csiMigratedPluginManager := csimigration.NewPluginManager(intreeToCSITranslator, utilfeature.DefaultFeatureGate) + csiMigratedPluginManager := csimigration.NewPluginManager(intreeToCSITranslator) vm.intreeToCSITranslator = intreeToCSITranslator vm.csiMigratedPluginManager = csiMigratedPluginManager @@ -298,7 +297,7 @@ func (e *VolumeAttachLimitExceededError) Error() string { func (vm *volumeManager) Run(ctx context.Context, sourcesReady config.SourcesReady) { logger := klog.FromContext(ctx) - defer runtime.HandleCrash() + defer runtime.HandleCrashWithContext(ctx) if vm.kubeClient != nil { // start informer for CSIDriver @@ -511,21 +510,18 @@ func (vm *volumeManager) WaitForUnmount(ctx context.Context, pod *v1.Pod) error } func (vm *volumeManager) WaitForAllPodsUnmount(ctx context.Context, pods []*v1.Pod) error { - var ( - errors []error - wg sync.WaitGroup - ) - wg.Add(len(pods)) + if len(pods) == 0 { + return nil + } + + funcs := make([]func() error, 0, len(pods)) for _, pod := range pods { - go func(pod *v1.Pod) { - defer wg.Done() - if err := vm.WaitForUnmount(ctx, pod); err != nil { - errors = append(errors, err) - } - }(pod) + funcs = append(funcs, func() error { + return vm.WaitForUnmount(ctx, pod) + }) } - wg.Wait() - return utilerrors.NewAggregate(errors) + + return utilerrors.AggregateGoroutines(funcs...) } func (vm *volumeManager) getVolumesNotInDSW(uniquePodName types.UniquePodName, expectedVolumes []string) []string { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_linux.go index 912e7e5ebc..9237950961 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_unsupported.go index 2595549e6e..b0c000acb5 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/watchdog/watchdog_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go index 771e2315ae..bee3f5f60d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2024 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go index 6ce7a730a5..ee23c41bdd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go index 7083aea47e..f3c67052ea 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go index 4b483d41d8..8d37b31bed 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go index 80e9442f8c..fbee466151 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go index 12ee8edfa9..1169c7c80b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/kubemark/hollow_kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubemark/hollow_kubelet.go index ba2f619eb5..a1f07a291c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubemark/hollow_kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubemark/hollow_kubelet.go @@ -52,7 +52,6 @@ import ( "k8s.io/kubernetes/pkg/volume/iscsi" "k8s.io/kubernetes/pkg/volume/local" "k8s.io/kubernetes/pkg/volume/nfs" - "k8s.io/kubernetes/pkg/volume/portworx" "k8s.io/kubernetes/pkg/volume/projected" "k8s.io/kubernetes/pkg/volume/secret" "k8s.io/kubernetes/pkg/volume/util/hostutil" @@ -78,7 +77,6 @@ func volumePlugins() []volume.VolumePlugin { allPlugins = append(allPlugins, fc.ProbeVolumePlugins()...) allPlugins = append(allPlugins, configmap.ProbeVolumePlugins()...) allPlugins = append(allPlugins, projected.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, portworx.ProbeVolumePlugins()...) allPlugins = append(allPlugins, local.ProbeVolumePlugins()...) allPlugins = append(allPlugins, csi.ProbeVolumePlugins()...) return allPlugins diff --git a/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go b/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go index 7b02daff34..63a529a43d 100644 --- a/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go +++ b/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go b/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go index ab0d020478..6bad852237 100644 --- a/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go index b0c94a18ee..9c86ce2647 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go @@ -176,6 +176,12 @@ type Plugins struct { // MultiPoint is a simplified config field for enabling plugins for all valid extension points MultiPoint PluginSet + + // PlacementGenerate is a list of plugins that should be invoked during pod group scheduling cycle when determining placements for a pod group. + PlacementGenerate PluginSet + + // PlacementScore is a list of plugins that should be invoked during workload scheduling cycle when ranking pod group assignments. + PlacementScore PluginSet } // PluginSet specifies enabled and disabled plugins for an extension point. @@ -189,11 +195,11 @@ type PluginSet struct { Disabled []Plugin } -// Plugin specifies a plugin name and its weight when applicable. Weight is used only for Score plugins. +// Plugin specifies a plugin name and its weight when applicable. Weight is used only for Score and PlacementScore plugins. type Plugin struct { // Name defines the name of plugin Name string - // Weight defines the weight of plugin, only used for Score plugins. + // Weight defines the weight of plugin, only used for Score and PlacementScore plugins. Weight int32 } @@ -244,6 +250,8 @@ func (p *Plugins) Names() []string { p.PostBind, p.Permit, p.QueueSort, + p.PlacementGenerate, + p.PlacementScore, } n := sets.New[string]() for _, e := range extensions { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go index 7920ee6f1d..9475cdfd7b 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go @@ -67,6 +67,9 @@ func applyFeatureGates(config *v1.Plugins) { if utilfeature.DefaultFeatureGate.Enabled(features.GangScheduling) { applyGangScheduling(config) } + if utilfeature.DefaultFeatureGate.Enabled(features.TopologyAwareWorkloadScheduling) { + applyTopologyAwareWorkloadScheduling(config) + } } func applyDynamicResources(config *v1.Plugins) { @@ -91,6 +94,11 @@ func applyGangScheduling(config *v1.Plugins) { config.MultiPoint.Enabled = append(config.MultiPoint.Enabled, v1.Plugin{Name: names.GangScheduling}) } +func applyTopologyAwareWorkloadScheduling(config *v1.Plugins) { + config.MultiPoint.Enabled = append(config.MultiPoint.Enabled, v1.Plugin{Name: names.TopologyPlacementGenerator}) + config.MultiPoint.Enabled = append(config.MultiPoint.Enabled, v1.Plugin{Name: names.PodGroupPodsCount, Weight: ptr.To[int32](1)}) +} + // mergePlugins merges the custom set into the given default one, handling disabled sets. func mergePlugins(logger klog.Logger, defaultPlugins, customPlugins *v1.Plugins) *v1.Plugins { if customPlugins == nil { @@ -110,6 +118,8 @@ func mergePlugins(logger klog.Logger, defaultPlugins, customPlugins *v1.Plugins) defaultPlugins.PreBind = mergePluginSet(logger, defaultPlugins.PreBind, customPlugins.PreBind) defaultPlugins.Bind = mergePluginSet(logger, defaultPlugins.Bind, customPlugins.Bind) defaultPlugins.PostBind = mergePluginSet(logger, defaultPlugins.PostBind, customPlugins.PostBind) + defaultPlugins.PlacementGenerate = mergePluginSet(logger, defaultPlugins.PlacementGenerate, customPlugins.PlacementGenerate) + defaultPlugins.PlacementScore = mergePluginSet(logger, defaultPlugins.PlacementScore, customPlugins.PlacementScore) return defaultPlugins } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go index 225ce267d4..5ec3d720cf 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go @@ -57,6 +57,8 @@ func pluginsNames(p *configv1.Plugins) []string { p.Permit, p.PreEnqueue, p.QueueSort, + p.PlacementGenerate, + p.PlacementScore, } n := sets.New[string]() for _, e := range extensions { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go index 63240b7d11..d4cf46a477 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go @@ -785,6 +785,12 @@ func autoConvert_v1_Plugins_To_config_Plugins(in *configv1.Plugins, out *config. if err := Convert_v1_PluginSet_To_config_PluginSet(&in.MultiPoint, &out.MultiPoint, s); err != nil { return err } + if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PlacementGenerate, &out.PlacementGenerate, s); err != nil { + return err + } + if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PlacementScore, &out.PlacementScore, s); err != nil { + return err + } return nil } @@ -833,6 +839,12 @@ func autoConvert_config_Plugins_To_v1_Plugins(in *config.Plugins, out *configv1. if err := Convert_config_PluginSet_To_v1_PluginSet(&in.MultiPoint, &out.MultiPoint, s); err != nil { return err } + if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PlacementGenerate, &out.PlacementGenerate, s); err != nil { + return err + } + if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PlacementScore, &out.PlacementScore, s); err != nil { + return err + } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go index d50881630d..ec19f18806 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go @@ -319,9 +319,17 @@ func ValidateNodeResourcesFitArgs(path *field.Path, args *config.NodeResourcesFi allErrs = append(allErrs, field.NotSupported(strategyPath.Child("type"), args.ScoringStrategy.Type, sets.List(supportedScoringStrategyTypes))) } allErrs = append(allErrs, validateResources(args.ScoringStrategy.Resources, strategyPath.Child("resources"))...) - if args.ScoringStrategy.RequestedToCapacityRatio != nil { - allErrs = append(allErrs, validateFunctionShape(args.ScoringStrategy.RequestedToCapacityRatio.Shape, strategyPath.Child("shape"))...) + if args.ScoringStrategy.Type == config.RequestedToCapacityRatio { + if args.ScoringStrategy.RequestedToCapacityRatio == nil { + allErrs = append(allErrs, field.Required(strategyPath.Child("requestedToCapacityRatio"), "must be specified when type is RequestedToCapacityRatio")) + } else { + allErrs = append(allErrs, validateFunctionShape(args.ScoringStrategy.RequestedToCapacityRatio.Shape, strategyPath.Child("requestedToCapacityRatio").Child("shape"))...) + } + } else if args.ScoringStrategy.RequestedToCapacityRatio != nil { + allErrs = append(allErrs, field.Forbidden(strategyPath.Child("requestedToCapacityRatio"), "must be nil when type is not RequestedToCapacityRatio")) } + } else { + allErrs = append(allErrs, field.Required(strategyPath, "ScoringStrategy field is required")) } if len(allErrs) == 0 { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go index 2d78d58e58..ad5699db2e 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go @@ -443,6 +443,8 @@ func (in *Plugins) DeepCopyInto(out *Plugins) { in.Bind.DeepCopyInto(&out.Bind) in.PostBind.DeepCopyInto(&out.PostBind) in.MultiPoint.DeepCopyInto(&out.MultiPoint) + in.PlacementGenerate.DeepCopyInto(&out.PlacementGenerate) + in.PlacementScore.DeepCopyInto(&out.PlacementScore) return } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go index a55f8440d6..3a6cd16b02 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go @@ -30,22 +30,20 @@ import ( "k8s.io/klog/v2" fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/api_calls" + apicalls "k8s.io/kubernetes/pkg/scheduler/framework/api_calls" "k8s.io/kubernetes/pkg/scheduler/metrics" ) var ( - cleanAssumedPeriod = 1 * time.Second + updateMetricsPeriod = 1 * time.Second ) // New returns a Cache implementation. -// It automatically starts a go routine that manages expiration of assumed pods. -// "ttl" is how long the assumed pod will get expired. +// It automatically starts a go routine that exports cache metrics. // "ctx" is the context that would close the background goroutine. -func New(ctx context.Context, ttl time.Duration, apiDispatcher fwk.APIDispatcher) Cache { - logger := klog.FromContext(ctx) - cache := newCache(ctx, ttl, cleanAssumedPeriod, apiDispatcher) - cache.run(logger) +func New(ctx context.Context, apiDispatcher fwk.APIDispatcher, genericWorkloadEnabled bool) Cache { + cache := newCache(ctx, updateMetricsPeriod, apiDispatcher, genericWorkloadEnabled) + cache.run() return cache } @@ -60,7 +58,6 @@ type nodeInfoListItem struct { type cacheImpl struct { stop <-chan struct{} - ttl time.Duration period time.Duration // This mutex guards all fields within this cache struct. @@ -77,7 +74,10 @@ type cacheImpl struct { nodeTree *nodeTree // A map from image name to its ImageStateSummary. imageStates map[string]*fwk.ImageStateSummary - + // podGroupStates stores the runtime state for each known pod group (only if GenericWorkload feature gate is enabled). + podGroupStates map[podGroupKey]*podGroupState + // genericWorkloadEnabled stores the GenericWorkload feature gate value. + genericWorkloadEnabled bool // apiDispatcher is used for the methods that are expected to send API calls. // It's non-nil only if the SchedulerAsyncAPICalls feature gate is enabled. apiDispatcher fwk.APIDispatcher @@ -85,26 +85,22 @@ type cacheImpl struct { type podState struct { pod *v1.Pod - // Used by assumedPod to determinate expiration. - // If deadline is nil, assumedPod will never expire. - deadline *time.Time - // Used to block cache from expiring assumedPod if binding still runs - bindingFinished bool } -func newCache(ctx context.Context, ttl, period time.Duration, apiDispatcher fwk.APIDispatcher) *cacheImpl { +func newCache(ctx context.Context, period time.Duration, apiDispatcher fwk.APIDispatcher, genericWorkloadEnabled bool) *cacheImpl { logger := klog.FromContext(ctx) return &cacheImpl{ - ttl: ttl, period: period, stop: ctx.Done(), - nodes: make(map[string]*nodeInfoListItem), - nodeTree: newNodeTree(logger, nil), - assumedPods: sets.New[string](), - podStates: make(map[string]*podState), - imageStates: make(map[string]*fwk.ImageStateSummary), - apiDispatcher: apiDispatcher, + nodes: make(map[string]*nodeInfoListItem), + nodeTree: newNodeTree(logger, nil), + assumedPods: sets.New[string](), + podStates: make(map[string]*podState), + imageStates: make(map[string]*fwk.ImageStateSummary), + podGroupStates: make(map[podGroupKey]*podGroupState), + genericWorkloadEnabled: genericWorkloadEnabled, + apiDispatcher: apiDispatcher, } } @@ -195,6 +191,11 @@ func (cache *cacheImpl) UpdateSnapshot(logger klog.Logger, nodeSnapshot *Snapsho cache.mu.Lock() defer cache.mu.Unlock() + if nodeSnapshot.placementNodes != nil { + logger.Error(nil, "UpdateSnapshot called with assumed placement. This is unexpected. Placement will be cleared.") + nodeSnapshot.ForgetPlacement() + } + // Get the last generation of the snapshot. snapshotGeneration := nodeSnapshot.generation @@ -213,6 +214,10 @@ func (cache *cacheImpl) UpdateSnapshot(logger klog.Logger, nodeSnapshot *Snapsho // last snapshot generation. updateUsedPVCSet := false + // Forget all assumed pods from a previous snapshot version. + // This is a safety check in case any pod wasn't forgotten in the previous scheduling cycle. + nodeSnapshot.forgetAllAssumedPods(logger) + // Start from the head of the NodeInfo doubly linked list and update snapshot // of NodeInfos updated after the last snapshot. for node := cache.headNode; node != nil; node = node.next { @@ -284,9 +289,32 @@ func (cache *cacheImpl) UpdateSnapshot(logger klog.Logger, nodeSnapshot *Snapsho return errors.New(errMsg) } + // Take a snapshot of pod group states for this scheduling cycle. + cache.updatePodGroupStateSnapshot(nodeSnapshot) + return nil } +// updatePodGroupStateSnapshot updates the pod group state portion of the given snapshot. +// It assumes that the cache lock is already held. +// It removes entries that no longer exist in the live cache +// and clones entries whose generation has advanced since the last snapshot. +func (cache *cacheImpl) updatePodGroupStateSnapshot(snapshot *Snapshot) { + // Remove pod group states from snapshot that no longer exist in cache. + for key := range snapshot.podGroupStates { + if _, exists := cache.podGroupStates[key]; !exists { + delete(snapshot.podGroupStates, key) + } + } + // Clone only pod group states that changed since the last snapshot. + for key, podGroupState := range cache.podGroupStates { + if existing, ok := snapshot.podGroupStates[key]; ok && existing.generation == podGroupState.generation { + continue + } + snapshot.podGroupStates[key] = podGroupState.snapshot() + } +} + func (cache *cacheImpl) updateNodeInfoSnapshotList(logger klog.Logger, snapshot *Snapshot, updateAll bool) { snapshot.havePodsWithAffinityNodeInfoList = make([]fwk.NodeInfo, 0, cache.nodeTree.numNodes) snapshot.havePodsWithRequiredAntiAffinityNodeInfoList = make([]fwk.NodeInfo, 0, cache.nodeTree.numNodes) @@ -381,34 +409,6 @@ func (cache *cacheImpl) AssumePod(logger klog.Logger, pod *v1.Pod) error { return cache.addPod(logger, pod, true) } -func (cache *cacheImpl) FinishBinding(logger klog.Logger, pod *v1.Pod) error { - return cache.finishBinding(logger, pod, time.Now()) -} - -// finishBinding exists to make tests deterministic by injecting now as an argument -func (cache *cacheImpl) finishBinding(logger klog.Logger, pod *v1.Pod, now time.Time) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.RLock() - defer cache.mu.RUnlock() - - logger.V(5).Info("Finished binding for pod, can be expired", "podKey", key, "pod", klog.KObj(pod)) - currState, ok := cache.podStates[key] - if ok && cache.assumedPods.Has(key) { - if cache.ttl == time.Duration(0) { - currState.deadline = nil - } else { - dl := now.Add(cache.ttl) - currState.deadline = &dl - } - currState.bindingFinished = true - } - return nil -} - func (cache *cacheImpl) ForgetPod(logger klog.Logger, pod *v1.Pod) error { key, err := framework.GetPodKey(pod) if err != nil { @@ -428,7 +428,7 @@ func (cache *cacheImpl) ForgetPod(logger klog.Logger, pod *v1.Pod) error { } // Only assumed pod can be forgotten. if cache.assumedPods.Has(key) { - return cache.removePod(logger, pod) + return cache.removePod(logger, pod, true) } return fmt.Errorf("pod %v(%v) wasn't assumed so cannot be forgotten", key, klog.KObj(pod)) } @@ -453,12 +453,21 @@ func (cache *cacheImpl) addPod(logger klog.Logger, pod *v1.Pod, assumePod bool) if assumePod { cache.assumedPods.Insert(key) } + + if !cache.isPodGroupMember(pod) { + return nil + } + if assumePod { + cache.assumePodGroupMember(pod) + } else { + cache.addPodGroupMember(pod) + } return nil } // Assumes that lock is already acquired. func (cache *cacheImpl) updatePod(logger klog.Logger, oldPod, newPod *v1.Pod) error { - if err := cache.removePod(logger, oldPod); err != nil { + if err := cache.removePod(logger, oldPod, false); err != nil { return err } return cache.addPod(logger, newPod, false) @@ -468,7 +477,7 @@ func (cache *cacheImpl) updatePod(logger klog.Logger, oldPod, newPod *v1.Pod) er // Removes a pod from the cached node info. If the node information was already // removed and there are no more pods left in the node, cleans up the node from // the cache. -func (cache *cacheImpl) removePod(logger klog.Logger, pod *v1.Pod) error { +func (cache *cacheImpl) removePod(logger klog.Logger, pod *v1.Pod, forgetPod bool) error { key, err := framework.GetPodKey(pod) if err != nil { return err @@ -490,6 +499,16 @@ func (cache *cacheImpl) removePod(logger klog.Logger, pod *v1.Pod) error { delete(cache.podStates, key) delete(cache.assumedPods, key) + + if !cache.isPodGroupMember(pod) { + return nil + } + if forgetPod { + cache.forgetPodGroupMember(logger, pod) + } else { + cache.removePodGroupMember(pod) + } + return nil } @@ -516,7 +535,6 @@ func (cache *cacheImpl) AddPod(logger klog.Logger, pod *v1.Pod) error { return nil } case !ok: - // Pod was expired. We should add it back. if err = cache.addPod(logger, pod, false); err != nil { utilruntime.HandleErrorWithLogger(logger, err, "Error occurred while adding pod") } @@ -575,7 +593,7 @@ func (cache *cacheImpl) RemovePod(logger klog.Logger, pod *v1.Pod) error { klog.FlushAndExit(klog.ExitFlushTimeout, 1) } } - return cache.removePod(logger, currState.pod) + return cache.removePod(logger, currState.pod, false) } func (cache *cacheImpl) IsAssumedPod(pod *v1.Pod) (bool, error) { @@ -678,6 +696,19 @@ func (cache *cacheImpl) RemoveNode(logger klog.Logger, node *v1.Node) error { return nil } +// GetNode returns the copy of node stored in the cache. +// DO NOT use outside of tests. +func (cache *cacheImpl) GetNode(name string) (*framework.NodeInfo, error) { + cache.mu.RLock() + defer cache.mu.RUnlock() + + n, ok := cache.nodes[name] + if !ok { + return nil, fmt.Errorf("node %v does not exist in scheduler cache", name) + } + return n.info.SnapshotConcrete(), nil +} + // addNodeImageStates adds states of the images on given node to the given nodeInfo and update the imageStates in // scheduler cache. This function assumes the lock to scheduler cache has been acquired. func (cache *cacheImpl) addNodeImageStates(node *v1.Node, nodeInfo *framework.NodeInfo) { @@ -729,44 +760,142 @@ func (cache *cacheImpl) removeNodeImageStates(node *v1.Node) { } } -func (cache *cacheImpl) run(logger klog.Logger) { - go wait.Until(func() { - cache.cleanupAssumedPods(logger, time.Now()) - }, cache.period, cache.stop) +func (cache *cacheImpl) run() { + go wait.Until(cache.updateMetrics, cache.period, cache.stop) +} + +// updateMetrics updates cache size metric values for pods, assumed pods, and nodes +func (cache *cacheImpl) updateMetrics() { + cache.mu.RLock() + defer cache.mu.RUnlock() + + metrics.CacheSize.WithLabelValues("assumed_pods").Set(float64(len(cache.assumedPods))) + metrics.CacheSize.WithLabelValues("pods").Set(float64(len(cache.podStates))) + metrics.CacheSize.WithLabelValues("nodes").Set(float64(len(cache.nodes))) +} + +// isPodGroupMember returns true if the pod belongs to a pod group, +// provided that GenericWorkload feature gate is enabled. +func (cache *cacheImpl) isPodGroupMember(pod *v1.Pod) bool { + return cache.genericWorkloadEnabled && pod.Spec.SchedulingGroup != nil +} + +// AddPodGroupMember adds not assigned and not assumed pod to its pod group state in the cache. +func (cache *cacheImpl) AddPodGroupMember(pod *v1.Pod) { + if !cache.isPodGroupMember(pod) { + return + } + cache.mu.Lock() + defer cache.mu.Unlock() + + cache.addPodGroupMember(pod) +} + +// UpdatePodGroupMember updates a pod's entry inside its pod group state in the cache. +func (cache *cacheImpl) UpdatePodGroupMember(logger klog.Logger, oldPod, newPod *v1.Pod) { + if !cache.isPodGroupMember(newPod) { + return + } + cache.mu.Lock() + defer cache.mu.Unlock() + + cache.updatePodGroupMember(logger, oldPod, newPod) } -// cleanupAssumedPods exists for making test deterministic by taking time as input argument. -// It also reports metrics on the cache size for nodes, pods, and assumed pods. -func (cache *cacheImpl) cleanupAssumedPods(logger klog.Logger, now time.Time) { +// RemovePodGroupMember removes the pod from its pod group state in the cache. +func (cache *cacheImpl) RemovePodGroupMember(pod *v1.Pod) { + if !cache.isPodGroupMember(pod) { + return + } cache.mu.Lock() defer cache.mu.Unlock() - defer cache.updateMetrics() - // The size of assumedPods should be small - for key := range cache.assumedPods { - ps, ok := cache.podStates[key] - if !ok { - utilruntime.HandleErrorWithLogger(logger, nil, "Key found in assumed set but not in podStates, potentially a logical error") - klog.FlushAndExit(klog.ExitFlushTimeout, 1) - } - if !ps.bindingFinished { - logger.V(5).Info("Could not expire cache for pod as binding is still in progress", "podKey", key, "pod", klog.KObj(ps.pod)) - continue - } - if cache.ttl != 0 && now.After(*ps.deadline) { - logger.Info("Pod expired", "podKey", key, "pod", klog.KObj(ps.pod)) - if err := cache.removePod(logger, ps.pod); err != nil { - utilruntime.HandleErrorWithLogger(logger, err, "ExpirePod failed", "podKey", key, "pod", klog.KObj(ps.pod)) - } - } + cache.removePodGroupMember(pod) +} + +// addPodGroupMember adds the pod to its pod group state, creating the group entry if it doesn't exist yet. +// Assumes that the cache lock is already held. +func (cache *cacheImpl) addPodGroupMember(pod *v1.Pod) { + key := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + podGroupState, exists := cache.podGroupStates[key] + if !exists { + podGroupState = newPodGroupState() + cache.podGroupStates[key] = podGroupState + } + + podGroupState.addPod(pod) +} + +// updatePodGroupMember updates the pod entry inside its pod group state. +// Assumes that the cache lock is already held. +func (cache *cacheImpl) updatePodGroupMember(logger klog.Logger, oldPod, newPod *v1.Pod) { + key := newPodGroupKey(newPod.Namespace, *newPod.Spec.SchedulingGroup.PodGroupName) + podGroupState, exists := cache.podGroupStates[key] + if !exists { + // This should not happen: the pod group state should have been already created by a prior pod add action. + utilruntime.HandleErrorWithLogger(logger, nil, "Pod group state not found for update, this indicates a missed add event", "pod", klog.KObj(newPod), "podGroupKey", key) + return } + + podGroupState.updatePod(oldPod, newPod) } -// updateMetrics updates cache size metric values for pods, assumed pods, and nodes -func (cache *cacheImpl) updateMetrics() { - metrics.CacheSize.WithLabelValues("assumed_pods").Set(float64(len(cache.assumedPods))) - metrics.CacheSize.WithLabelValues("pods").Set(float64(len(cache.podStates))) - metrics.CacheSize.WithLabelValues("nodes").Set(float64(len(cache.nodes))) +// removePodGroupMember removes the pod from its pod group state, deleting the group entry when empty. +// Assumes that the cache lock is already held. +func (cache *cacheImpl) removePodGroupMember(pod *v1.Pod) { + key := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + podGroupState, exists := cache.podGroupStates[key] + if !exists { + return + } + podGroupState.deletePod(pod.UID) + if podGroupState.empty() { + delete(cache.podGroupStates, key) + } +} + +// assumePodGroupMember marks the pod as assumed in its pod group state. +// Assumes that the cache lock is already held. +func (cache *cacheImpl) assumePodGroupMember(pod *v1.Pod) { + key := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + podGroupState, exists := cache.podGroupStates[key] + if !exists { + podGroupState = newPodGroupState() + podGroupState.allPods[pod.UID] = pod + cache.podGroupStates[key] = podGroupState + } + podGroupState.assumePod(pod) +} + +// forgetPodGroupMember moves the pod back from assumed to unscheduled in its pod group state. +// Assumes that the cache lock is already held. +func (cache *cacheImpl) forgetPodGroupMember(logger klog.Logger, pod *v1.Pod) { + key := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + pgs, exists := cache.podGroupStates[key] + if !exists { + // This should not happen: the pod group state should have been already created by a prior pod add or assume action. + utilruntime.HandleErrorWithLogger(logger, nil, "Pod group state not found for forget, this indicates a missed add or assume event", "pod", klog.KObj(pod), "podGroupKey", key) + return + } + pgs.forgetPod(pod.UID) +} + +// PodGroupStates returns the PodGroupStateLister for this cache. +func (cache *cacheImpl) PodGroupStates() fwk.PodGroupStateLister { + return cache +} + +// Get returns the pod group state for the given pod group. +func (cache *cacheImpl) Get(namespace string, podGroupName string) (fwk.PodGroupState, error) { + cache.mu.RLock() + defer cache.mu.RUnlock() + + key := newPodGroupKey(namespace, podGroupName) + podGroupState, exists := cache.podGroupStates[key] + if !exists { + return nil, fmt.Errorf("pod group state not found for pod group %s", key) + } + return podGroupState, nil } // BindPod handles the pod binding by adding a bind API call to the dispatcher. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go index df5c83cea0..78acf3acb4 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go index 74d0bd2279..de44609a49 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go @@ -20,6 +20,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" + fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework" ) @@ -37,26 +38,21 @@ import ( // | | | | Update // + Assume Add v v | // -// Initial +--------> Assumed +------------+---> Added <--+ +// Initial +--------> Assumed +----------- ---> Added <--+ // -// ^ + + | + -// | | | | | -// | | | Add | | Remove -// | | | | | -// | | | + | -// +----------------+ +-----------> Expired +----> Deleted -// Forget Expire +// ^ + + +// | | | +// | | | Remove +// | | | +// | | v +// +--------------------+ Deleted +// Forget // -// Note that an assumed pod can expire, because if we haven't received Add event notifying us -// for a while, there might be some problems and we shouldn't keep the pod in cache anymore. -// -// Note that "Initial", "Expired", and "Deleted" pods do not actually exist in cache. +// Note that "Initial" and "Deleted" pods do not actually exist in cache. // Based on existing use cases, we are making the following assumptions: // - No pod would be assumed twice // - A pod could be added without going through scheduler. In this case, we will see Add but not Assume event. // - If a pod wasn't added, it wouldn't be removed or updated. -// - Both "Expired" and "Deleted" are valid end states. In case of some problems, e.g. network issue, -// a pod might have changed its state (e.g. added and deleted) without delivering notification to the cache. type Cache interface { // NodeCount returns the number of nodes in the cache. // DO NOT use outside of tests. @@ -66,19 +62,17 @@ type Cache interface { // DO NOT use outside of tests. PodCount() (int, error) + // GetNode returns the copy of node stored in the cache. + // DO NOT use outside of tests. + GetNode(name string) (*framework.NodeInfo, error) + // AssumePod assumes a pod scheduled and aggregates the pod's information into its node. - // The implementation also decides the policy to expire pod before being confirmed (receiving Add event). - // After expiration, its information would be subtracted. AssumePod(logger klog.Logger, pod *v1.Pod) error - // FinishBinding signals that cache for assumed pod can be expired - FinishBinding(logger klog.Logger, pod *v1.Pod) error - // ForgetPod removes an assumed pod from cache. ForgetPod(logger klog.Logger, pod *v1.Pod) error - // AddPod either confirms a pod if it's assumed, or adds it back if it's expired. - // If added back, the pod's information would be added again. + // AddPod confirms an assumed pod, or adds a newly assigned pod to the cache. AddPod(logger klog.Logger, pod *v1.Pod) error // UpdatePod removes oldPod's information and adds newPod's information. @@ -91,7 +85,7 @@ type Cache interface { // same name of the specified pod. GetPod(pod *v1.Pod) (*v1.Pod, error) - // IsAssumedPod returns true if the pod is assumed and not expired. + // IsAssumedPod returns true if the pod is assumed. IsAssumedPod(pod *v1.Pod) (bool, error) // AddNode adds overall information about node. @@ -118,6 +112,18 @@ type Cache interface { // BindPod handles the pod binding by adding a bind API call to the dispatcher. // This method should be used only if the SchedulerAsyncAPICalls feature gate is enabled. BindPod(binding *v1.Binding) (<-chan error, error) + + // PodGroupStates returns a PodGroupStateLister. + PodGroupStates() fwk.PodGroupStateLister + + // AddPodGroupMember adds not assigned and not assumed pod to its pod group state. + AddPodGroupMember(pod *v1.Pod) + + // UpdatePodGroupMember updates a pod in its pod group state. + UpdatePodGroupMember(logger klog.Logger, oldPod, newPod *v1.Pod) + + // RemovePodGroupMember removes a pod from its pod group state. + RemovePodGroupMember(pod *v1.Pod) } // Dump is a dump of the cache state. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/podgroupstate.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/podgroupstate.go new file mode 100644 index 0000000000..3c6efb831a --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/podgroupstate.go @@ -0,0 +1,397 @@ +/* +Copyright 2025 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 cache + +import ( + "maps" + "sync" + "sync/atomic" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/klog/v2" +) + +var generation atomic.Int64 + +// nextPodGroupGeneration increments generation numbers monotonically for a pod group state (instead of per-instance increment) +// to prevent generation reset or collision when a pod group is deleted and recreated with the same name. +func nextPodGroupGeneration() int64 { + return generation.Add(1) +} + +// podGroupKey uniquely identifies a specific instance of a PodGroup. +type podGroupKey struct { + name string + namespace string +} + +func (pgk podGroupKey) GetName() string { + return pgk.name +} + +func (pgk podGroupKey) GetNamespace() string { + return pgk.namespace +} + +func (pgk podGroupKey) String() string { + return pgk.namespace + "/" + pgk.GetName() +} + +var _ klog.KMetadata = &podGroupKey{} + +func newPodGroupKey(namespace string, name string) podGroupKey { + return podGroupKey{ + namespace: namespace, + name: name, + } +} + +// podGroupStateData holds data and functionality shared between podGroupState and podGroupStateSnapshot. +type podGroupStateData struct { + // generation gets bumped whenever the data is changed. + // It's used to detect changes and avoid unnecessary cloning when taking a snapshot. + generation int64 + // allPods tracks all pods belonging to the group that are known to the scheduler. + allPods map[types.UID]*v1.Pod + // unscheduledPods tracks all pods that are unscheduled for this group, + // i.e., are neither assumed nor assigned. + unscheduledPods sets.Set[types.UID] + // assumedPods tracks pods that have reached the Reserve stage and are waiting + // for the rest of the gang to arrive before being allowed to bind. + assumedPods map[types.UID]*v1.Pod + // assignedPods tracks all pods belonging to the group that are assigned (bound). + assignedPods sets.Set[types.UID] +} + +func newPodGroupStateData() podGroupStateData { + return podGroupStateData{ + allPods: make(map[types.UID]*v1.Pod), + unscheduledPods: sets.New[types.UID](), + assumedPods: make(map[types.UID]*v1.Pod), + assignedPods: sets.New[types.UID](), + } +} + +// addPod adds the pod to this group. +// Depending on the NodeName, it can insert the pod into either assignedPods or unscheduledPods. +func (d *podGroupStateData) addPod(pod *v1.Pod) { + d.generation = nextPodGroupGeneration() + d.allPods[pod.UID] = pod + if pod.Spec.NodeName != "" { + d.assignedPods.Insert(pod.UID) + } else { + d.unscheduledPods.Insert(pod.UID) + } +} + +// updatePod updates the pod in this group. +// In case of binding, it moves the pod to assignedPods. +func (d *podGroupStateData) updatePod(oldPod, newPod *v1.Pod) { + d.generation = nextPodGroupGeneration() + d.allPods[newPod.UID] = newPod + if oldPod.Spec.NodeName == "" && newPod.Spec.NodeName != "" { + d.assignedPods.Insert(newPod.UID) + // Clear pod from unscheduled and assumed when it is assigned. + d.unscheduledPods.Delete(newPod.UID) + delete(d.assumedPods, newPod.UID) + } +} + +// deletePod removes the pod from this pod group state. +func (d *podGroupStateData) deletePod(podUID types.UID) { + d.generation = nextPodGroupGeneration() + delete(d.allPods, podUID) + d.unscheduledPods.Delete(podUID) + delete(d.assumedPods, podUID) + d.assignedPods.Delete(podUID) +} + +// assumePod marks a pod as assumed within the pod group state. +func (d *podGroupStateData) assumePod(pod *v1.Pod) { + storedPod, ok := d.allPods[pod.UID] + // A scheduling pod may be removed from the cluster. + // In that case, we just ignore it. + if !ok { + return + } + + d.generation = nextPodGroupGeneration() + // If the pod stored in the state is already assigned, put it into assignedPods. + // Otherwise put it to assumedPods. + if storedPod.Spec.NodeName != "" { + d.assignedPods.Insert(pod.UID) + } else { + d.assumedPods[pod.UID] = pod + } + d.unscheduledPods.Delete(pod.UID) +} + +// forgetPod moves a pod back from the assumed state to unscheduled within the pod group state. +func (d *podGroupStateData) forgetPod(podUID types.UID) { + + pod := d.allPods[podUID] + // A scheduling pod may be removed from the cluster. + // In that case, we just ignore it. + if pod == nil { + return + } + + d.generation = nextPodGroupGeneration() + + delete(d.assumedPods, podUID) + + // If the pod is already assigned, put it into assignedPods. + // Otherwise, put it into unscheduledPods. + if pod.Spec.NodeName != "" { + d.assignedPods.Insert(podUID) + } else { + d.unscheduledPods.Insert(podUID) + } +} + +// scheduledPods returns the pods that are either assumed or assigned for this pod group. +func (d *podGroupStateData) scheduledPods() []*v1.Pod { + scheduledPods := make([]*v1.Pod, 0, len(d.assignedPods)+len(d.assumedPods)) + for uid := range d.assignedPods { + scheduledPods = append(scheduledPods, d.allPods[uid]) + } + for _, pod := range d.assumedPods { + scheduledPods = append(scheduledPods, pod) + } + return scheduledPods +} + +// empty returns true when the pod group state contains no pods. +func (d *podGroupStateData) empty() bool { + return len(d.allPods) == 0 +} + +// allPodsCount returns the number of all pods known to the scheduler for this group. +func (d *podGroupStateData) allPodsCount() int { + return len(d.allPods) +} + +// scheduledPodsCount returns the number of pods for this group that are either assumed or assigned. +func (d *podGroupStateData) scheduledPodsCount() int { + return len(d.assumedPods) + len(d.assignedPods) +} + +// deepCopy returns a deep copy of the pod group state data. +func (d *podGroupStateData) deepCopy() podGroupStateData { + return podGroupStateData{ + generation: d.generation, + allPods: maps.Clone(d.allPods), + unscheduledPods: d.unscheduledPods.Clone(), + assumedPods: maps.Clone(d.assumedPods), + assignedPods: d.assignedPods.Clone(), + } +} + +// unscheduledPodsMap returns all unscheduled pods for this pod group. +func (d *podGroupStateData) unscheduledPodsMap() map[string]*v1.Pod { + result := make(map[string]*v1.Pod, len(d.unscheduledPods)) + for podUID := range d.unscheduledPods { + pod := d.allPods[podUID] + result[pod.Name] = pod + } + return result +} + +// podGroupState holds the runtime state of a pod group. +type podGroupState struct { + lock sync.RWMutex + podGroupStateData +} + +func newPodGroupState() *podGroupState { + return &podGroupState{podGroupStateData: newPodGroupStateData()} +} + +// snapshot returns a deep copy of the live pod group state as an immutable snapshot. +// It must be called under the cache lock. +func (pgs *podGroupState) snapshot() *podGroupStateSnapshot { + return &podGroupStateSnapshot{podGroupStateData: pgs.podGroupStateData.deepCopy()} +} + +// empty returns true when the group contains no pods. +// It must be called under the cache lock. +func (pgs *podGroupState) empty() bool { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.empty() +} + +// addPod adds the pod to this group. +// Depending on the NodeName, it can insert the pod into either assignedPods or unscheduledPods. +// It must be called under the cache lock. +func (pgs *podGroupState) addPod(pod *v1.Pod) { + pgs.lock.Lock() + defer pgs.lock.Unlock() + + pgs.podGroupStateData.addPod(pod) +} + +// updatePod updates the pod in this group. +// In case of binding, it moves the pod to assignedPods. +// It must be called under the cache lock. +func (pgs *podGroupState) updatePod(oldPod, newPod *v1.Pod) { + pgs.lock.Lock() + defer pgs.lock.Unlock() + + pgs.podGroupStateData.updatePod(oldPod, newPod) +} + +// deletePod removes the pod from this pod group state. +// It must be called under the cache lock. +func (pgs *podGroupState) deletePod(podUID types.UID) { + pgs.lock.Lock() + defer pgs.lock.Unlock() + + pgs.podGroupStateData.deletePod(podUID) +} + +// assumePod marks a pod as assumed within the pod group state. +// It must be called under the cache lock. +func (pgs *podGroupState) assumePod(pod *v1.Pod) { + pgs.lock.Lock() + defer pgs.lock.Unlock() + + pgs.podGroupStateData.assumePod(pod) +} + +// forgetPod moves a pod back from the assumed state to unscheduled within the pod group state. +// It must be called under the cache lock. +func (pgs *podGroupState) forgetPod(podUID types.UID) { + pgs.lock.Lock() + defer pgs.lock.Unlock() + + pgs.podGroupStateData.forgetPod(podUID) +} + +// AllPods returns the UIDs of all pods known to the scheduler for this group. +func (pgs *podGroupState) AllPods() sets.Set[types.UID] { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return sets.KeySet(pgs.podGroupStateData.allPods) +} + +// AllPodsCount returns the number of all pods known to the scheduler for this group. +func (pgs *podGroupState) AllPodsCount() int { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.allPodsCount() +} + +// UnscheduledPods returns all pods that are unscheduled for this group, +// i.e., are neither assumed nor assigned. +// The returned map type corresponds to the argument of the PodActivator.Activate method. +func (pgs *podGroupState) UnscheduledPods() map[string]*v1.Pod { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.unscheduledPodsMap() +} + +// AssumedPods returns the UIDs of all pods for this group in the assumed state, +// i.e., that have passed the Reserve stage. +func (pgs *podGroupState) AssumedPods() sets.Set[types.UID] { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return sets.KeySet(pgs.podGroupStateData.assumedPods) +} + +// AssignedPods returns the UIDs of all pods already assigned (bound) for this group. +func (pgs *podGroupState) AssignedPods() sets.Set[types.UID] { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.assignedPods.Clone() +} + +// ScheduledPods returns the pods that are either assumed or assigned for this pod group. +func (pgs *podGroupState) ScheduledPods() []*v1.Pod { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.scheduledPods() +} + +// ScheduledPodsCount returns the number of pods for this group that are either assumed or assigned. +func (pgs *podGroupState) ScheduledPodsCount() int { + pgs.lock.RLock() + defer pgs.lock.RUnlock() + + return pgs.podGroupStateData.scheduledPodsCount() +} + +// podGroupStateSnapshot is an immutable, point-in-time copy of a podGroupState. +// It is taken before a pod group scheduling cycle and used to track states of pods +// during the cycle without modifying the live state of pods. +type podGroupStateSnapshot struct { + podGroupStateData +} + +// assumePod marks a pod within the pod group state snapshot as assumed. +func (s *podGroupStateSnapshot) assumePod(pod *v1.Pod) { + s.podGroupStateData.assumePod(pod) +} + +// forgetPod removes a pod from the assumed state within the snapshot. +func (s *podGroupStateSnapshot) forgetPod(podUID types.UID) { + s.podGroupStateData.forgetPod(podUID) +} + +// AllPods returns the UIDs of all pods known to the scheduler for this group. +func (s *podGroupStateSnapshot) AllPods() sets.Set[types.UID] { + return sets.KeySet(s.podGroupStateData.allPods) +} + +// UnscheduledPods returns all pods that are unscheduled for this group. +func (s *podGroupStateSnapshot) UnscheduledPods() map[string]*v1.Pod { + return s.podGroupStateData.unscheduledPodsMap() +} + +// AssumedPods returns the UIDs of all assumed pods for this group. +func (s *podGroupStateSnapshot) AssumedPods() sets.Set[types.UID] { + return sets.KeySet(s.podGroupStateData.assumedPods) +} + +// AssignedPods returns the UIDs of all assigned (bound) pods for this group. +func (s *podGroupStateSnapshot) AssignedPods() sets.Set[types.UID] { + return s.podGroupStateData.assignedPods +} + +// ScheduledPods returns the pods that are either assumed or assigned for this pod group. +func (s *podGroupStateSnapshot) ScheduledPods() []*v1.Pod { + return s.podGroupStateData.scheduledPods() +} + +// AllPodsCount returns the number of all pods known to the scheduler for this group. +func (s *podGroupStateSnapshot) AllPodsCount() int { + return s.podGroupStateData.allPodsCount() +} + +// ScheduledPodsCount returns the number of pods for this group that are either assumed or assigned. +func (s *podGroupStateSnapshot) ScheduledPodsCount() int { + return s.podGroupStateData.scheduledPodsCount() +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go index b8d34da321..d4b2b92fee 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go @@ -20,11 +20,26 @@ import ( "fmt" v1 "k8s.io/api/core/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/klog/v2" fwk "k8s.io/kube-scheduler/framework" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/framework" ) +// placementNodes stores nodes that are present in the current placement. +// Placement is a limited set of nodes that is used in the pod group scheduling cycle. +type placementNodes struct { + // nodeInfoList contains the list of nodes in the placement. + // This is useful for quickly returning the entire list to the caller. + nodeInfoList []fwk.NodeInfo + // nodeInfoSet contains the set of nodes in the placement. + // This is useful for quickly checking if a node belongs the the placement. + nodeInfoSet sets.Set[string] +} + // Snapshot is a snapshot of cache NodeInfo and NodeTree order. The scheduler takes a // snapshot at the beginning of each scheduling cycle and uses it for its operations in that cycle. type Snapshot struct { @@ -41,6 +56,21 @@ type Snapshot struct { // keyed in the format "namespace/name". usedPVCSet sets.Set[string] generation int64 + // assumedPods maps a pod key to an assumed pod object during a single pod group scheduling cycle. + // This map should be emptied before the next cycle starts. + assumedPods map[string]*v1.Pod + // podGroupStates maps a pod group key to a snapshot of its state, used during a pod group scheduling cycle. + podGroupStates map[podGroupKey]*podGroupStateSnapshot + // placementNodes stores nodes that are present in the current placement. + // If placement is not set, this is nil. + // It should only be set in the pod group scheduling cycle, when checking if pod group can be scheduled within the placement. + // This field should be cleared once the pod group has been checked for the placement. + placementNodes *placementNodes + // genericWorkloadEnabled stores the GenericWorkload feature gate value. + genericWorkloadEnabled bool + // hasBackup holds information whether backup was performed and + // restore was not performed yet. + hasBackup bool } var _ fwk.SharedLister = &Snapshot{} @@ -48,8 +78,11 @@ var _ fwk.SharedLister = &Snapshot{} // NewEmptySnapshot initializes a Snapshot struct and returns it. func NewEmptySnapshot() *Snapshot { return &Snapshot{ - nodeInfoMap: make(map[string]*framework.NodeInfo), - usedPVCSet: sets.New[string](), + nodeInfoMap: make(map[string]*framework.NodeInfo), + usedPVCSet: sets.New[string](), + assumedPods: make(map[string]*v1.Pod), + podGroupStates: make(map[podGroupKey]*podGroupStateSnapshot), + genericWorkloadEnabled: utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload), } } @@ -75,10 +108,86 @@ func NewSnapshot(pods []*v1.Pod, nodes []*v1.Node) *Snapshot { s.havePodsWithAffinityNodeInfoList = havePodsWithAffinityNodeInfoList s.havePodsWithRequiredAntiAffinityNodeInfoList = havePodsWithRequiredAntiAffinityNodeInfoList s.usedPVCSet = createUsedPVCSet(pods) + if s.genericWorkloadEnabled { + s.podGroupStates = createPodGroupStates(pods) + } return s } +// createPodGroupStates builds the initial pod group state snapshot map from a list of pods. +func createPodGroupStates(pods []*v1.Pod) map[podGroupKey]*podGroupStateSnapshot { + podGroupStates := make(map[podGroupKey]*podGroupStateSnapshot) + for _, pod := range pods { + if pod.Spec.SchedulingGroup == nil { + continue + } + key := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + pgs, ok := podGroupStates[key] + if !ok { + pgs = &podGroupStateSnapshot{podGroupStateData: newPodGroupStateData()} + podGroupStates[key] = pgs + } + pgs.addPod(pod) + } + return podGroupStates +} + +// RestoreSnapshot is a function that can be used to restore the snapshot to the state +// before the backup was taken. +type RestoreSnapshot func() + +// BackupSnapshot provides a way to temporarily backup the snapshot's state +// and returns a restore function. This is primarily used in workload-aware +// preemption to simulate pod group preemption by mutating deep copies of NodeInfos. +// Backups cannot be stacked, i.e., only one backup can be made without restoring +// the snapshot first. +// Restoring backup when the placement is set is not supported and can lead to +// undefined behavior. +func (s *Snapshot) BackupSnapshot() (RestoreSnapshot, error) { + if s.hasBackup { + return nil, fmt.Errorf("cannot stack backups") + } + origNodeInfoMap := s.nodeInfoMap + origNodeInfoList := s.nodeInfoList + origHavePodsWithAffinityNodeInfoList := s.havePodsWithAffinityNodeInfoList + origHavePodsWithRequiredAntiAffinityNodeInfoList := s.havePodsWithRequiredAntiAffinityNodeInfoList + + clonedNodeInfoMap := make(map[string]*framework.NodeInfo, len(s.nodeInfoMap)) + for k, v := range s.nodeInfoMap { + clonedNodeInfoMap[k] = v.Snapshot().(*framework.NodeInfo) + } + + clonedNodeInfoList := make([]fwk.NodeInfo, 0, len(clonedNodeInfoMap)) + clonedHavePodsWithAffinityNodeInfoList := make([]fwk.NodeInfo, 0, len(clonedNodeInfoMap)) + clonedHavePodsWithRequiredAntiAffinityNodeInfoList := make([]fwk.NodeInfo, 0, len(clonedNodeInfoMap)) + + for _, v := range s.nodeInfoList { + clonedNode := clonedNodeInfoMap[v.Node().Name] + clonedNodeInfoList = append(clonedNodeInfoList, clonedNode) + if len(clonedNode.PodsWithAffinity) > 0 { + clonedHavePodsWithAffinityNodeInfoList = append(clonedHavePodsWithAffinityNodeInfoList, clonedNode) + } + if len(clonedNode.PodsWithRequiredAntiAffinity) > 0 { + clonedHavePodsWithRequiredAntiAffinityNodeInfoList = append(clonedHavePodsWithRequiredAntiAffinityNodeInfoList, clonedNode) + } + } + + s.hasBackup = true + s.nodeInfoMap = clonedNodeInfoMap + s.nodeInfoList = clonedNodeInfoList + s.havePodsWithAffinityNodeInfoList = clonedHavePodsWithAffinityNodeInfoList + s.havePodsWithRequiredAntiAffinityNodeInfoList = clonedHavePodsWithRequiredAntiAffinityNodeInfoList + + return func() { + s.hasBackup = false + s.nodeInfoMap = origNodeInfoMap + s.nodeInfoList = origNodeInfoList + s.havePodsWithAffinityNodeInfoList = origHavePodsWithAffinityNodeInfoList + s.havePodsWithRequiredAntiAffinityNodeInfoList = origHavePodsWithRequiredAntiAffinityNodeInfoList + }, nil +} + // createNodeInfoMap obtains a list of pods and pivots that list into a map // where the keys are node names and the values are the aggregated information // for that node. @@ -165,8 +274,34 @@ func (s *Snapshot) StorageInfos() fwk.StorageInfoLister { return s } -// NumNodes returns the number of nodes in the snapshot. -func (s *Snapshot) NumNodes() int { +// PodGroupStates returns a PodGroupStateLister. +func (s *Snapshot) PodGroupStates() fwk.PodGroupStateLister { + return &podGroupStateSnapshotLister{podGroupStates: s.podGroupStates} +} + +var _ fwk.PodGroupStateLister = &podGroupStateSnapshotLister{} + +type podGroupStateSnapshotLister struct { + podGroupStates map[podGroupKey]*podGroupStateSnapshot +} + +// Get returns the pod group state from the snapshot for the given pod group. +func (l *podGroupStateSnapshotLister) Get(namespace string, podGroupName string) (fwk.PodGroupState, error) { + key := newPodGroupKey(namespace, podGroupName) + state, ok := l.podGroupStates[key] + if !ok { + return nil, fmt.Errorf("pod group state not found for pod group %s", key) + } + return state, nil +} + +// NumNodesInPlacement returns the number of nodes in the snapshot for the current placement. +// If no placement is set, it returns the number of nodes in the snapshot. +// This function is not thread safe so it should be executed when no other routines can write to the snapshot. +func (s *Snapshot) NumNodesInPlacement() int { + if s.placementNodes != nil { + return len(s.placementNodes.nodeInfoList) + } return len(s.nodeInfoList) } @@ -197,3 +332,151 @@ func (s *Snapshot) Get(nodeName string) (fwk.NodeInfo, error) { func (s *Snapshot) IsPVCUsedByPods(key string) bool { return s.usedPVCSet.Has(key) } + +// AssumePod assumes a given pod in the snapshot. +// ForgetPod should be called on the snapshot before syncing it with the cache. +// This function is not thread safe, so it should be executed when no other routines can write/read from the snapshot. +func (s *Snapshot) AssumePod(podInfo *framework.PodInfo) error { + pod := podInfo.Pod + key, err := framework.GetPodKey(pod) + if err != nil { + return err + } + nodeInfo, ok := s.nodeInfoMap[pod.Spec.NodeName] + if !ok { + nodeInfo = framework.NewNodeInfo() + s.nodeInfoMap[pod.Spec.NodeName] = nodeInfo + } + // Calling AddPodInfo increases the Generation number of the nodeInfo. + // Since this operation only affects the snapshot, + // we should keep the old number to remain consistent with the cached value. + oldGeneration := nodeInfo.Generation + nodeInfo.AddPodInfo(podInfo) + nodeInfo.Generation = oldGeneration + s.assumedPods[key] = pod + // Update the pod group state in the snapshot if the pod belongs to a pod group. + if !s.genericWorkloadEnabled || pod.Spec.SchedulingGroup == nil { + return nil + } + pgKey := newPodGroupKey(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + if pgs, ok := s.podGroupStates[pgKey]; ok { + pgs.assumePod(pod) + } + return nil +} + +// ForgetPod forgets a given pod from the snapshot. +// This function is not thread safe, so it should be executed when no other routines can write/read from the snapshot. +func (s *Snapshot) ForgetPod(logger klog.Logger, pod *v1.Pod) error { + key, err := framework.GetPodKey(pod) + if err != nil { + return err + } + assumedPod, ok := s.assumedPods[key] + if !ok { + return fmt.Errorf("assumed pod %q not found in the snapshot", key) + } + delete(s.assumedPods, key) + nodeName := assumedPod.Spec.NodeName + if nodeInfo, ok := s.nodeInfoMap[nodeName]; ok { + // Calling RemovePod increases the Generation number of the nodeInfo. + // Since this operation only affects the snapshot, + // we should keep the old number to remain consistent with the cached value. + oldGeneration := nodeInfo.Generation + err := nodeInfo.RemovePod(logger, pod) + if err != nil { + return err + } + nodeInfo.Generation = oldGeneration + if len(nodeInfo.Pods) == 0 && nodeInfo.Node() == nil { + delete(s.nodeInfoMap, nodeName) + } + } + // Update the pod group state in the snapshot if the pod belongs to a pod group. + if !s.genericWorkloadEnabled || pod.Spec.SchedulingGroup == nil { + return nil + } + pgKey := newPodGroupKey(assumedPod.Namespace, *assumedPod.Spec.SchedulingGroup.PodGroupName) + if pgs, ok := s.podGroupStates[pgKey]; ok { + pgs.forgetPod(assumedPod.UID) + } + return nil +} + +// forgetAllAssumedPods forgets all assumed pods from the snapshot. +// This function is not thread safe, so it should be executed when no other routines can write/read from the snapshot. +func (s *Snapshot) forgetAllAssumedPods(logger klog.Logger) { + if len(s.assumedPods) == 0 { + return + } + for _, pod := range s.assumedPods { + err := s.ForgetPod(logger, pod) + if err != nil { + utilruntime.HandleErrorWithLogger(logger, err, "Failed to forget assumed pod") + } + } + logger.Error(nil, "Found assumed pods in the snapshot that were not forgotten", "assumedPodsCount", len(s.assumedPods)) +} + +// AssumePlacement sets placement context in the snapshot. +// The snapshot should not be updated if a placement is assumed. +// The placement should be unset with ForgetPlacement once it's no longer needed. +// This function should only be used by the scheduler to limit the node candidates for scheduling. +// This function is not thread safe, so it should be executed when no other routines can write/read from the snapshot. +func (s *Snapshot) AssumePlacement(placement *fwk.Placement) error { + if len(placement.Nodes) == len(s.nodeInfoList) { + // All nodes in placement, meaning we can treat it the same as no placement and avoid copying the buffer. + s.ForgetPlacement() + return nil + } + s.placementNodes = &placementNodes{ + nodeInfoList: placement.Nodes, + nodeInfoSet: sets.New[string](), + } + for _, node := range placement.Nodes { + snapshotNode, ok := s.nodeInfoMap[node.Node().Name] + if !ok { + s.ForgetPlacement() + return fmt.Errorf("node %s in placement is not present in snapshot", node.Node().Name) + } + if snapshotNode != node { + s.ForgetPlacement() + return fmt.Errorf("node %s in placement is not the same instance as in the snapshot", node.Node().Name) + } + s.placementNodes.nodeInfoSet.Insert(node.Node().Name) + } + return nil +} + +// ForgetPlacement clears placement. +// This function should only be used by the scheduler once the pods have been considered for that placement. +// This function is not thread safe, so it should be executed when no other routines can write/read from the snapshot. +func (s *Snapshot) ForgetPlacement() { + s.placementNodes = nil +} + +// GetNodeInPlacement returns the NodeInfo of the given node name within the current placement. +// If no placement is set, this is equivalent to Get. +// Placement is typically set in the pod group scheduling cycle. +// This function should only be used by the scheduler to limit the node candidates for scheduling. +// Plugins normally do not need this information. +// This function is not thread safe so it should be executed when no other routines can write to the snapshot. +func (s *Snapshot) GetNodeInPlacement(nodeName string) (fwk.NodeInfo, error) { + if s.placementNodes == nil || s.placementNodes.nodeInfoSet.Has(nodeName) { + return s.Get(nodeName) + } + return nil, fmt.Errorf("node %q not found in placement", nodeName) +} + +// ListNodesInPlacement returns the list of nodes in the snapshot within the current placement. +// If no placement is set, this is equivalent to List. +// Placement is typically set in the pod group scheduling cycle. +// This function should only be used by the scheduler to limit the node candidates for scheduling. +// Plugins normally do not need this information. +// This function is not thread safe so it should be executed when no other routines can write to the snapshot. +func (s *Snapshot) ListNodesInPlacement() ([]fwk.NodeInfo, error) { + if s.placementNodes == nil { + return s.List() + } + return s.placementNodes.nodeInfoList, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go index de722833d4..060ee8c364 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go @@ -43,6 +43,7 @@ type activeQueuer interface { len() int has(pInfo *framework.QueuedPodInfo) bool + movePodToInFlight(pInfo *framework.QueuedPodInfo) error listInFlightEvents() []interface{} listInFlightPods() []*v1.Pod clusterEventsForPod(logger klog.Logger, pInfo *framework.QueuedPodInfo) ([]*clusterEvent, error) @@ -266,6 +267,39 @@ func (aq *activeQueue) delete(pInfo *framework.QueuedPodInfo) error { return aq.queue.Delete(pInfo) } +// movePodToInFlight moves the pod to the in-flight state. +// It assumes the pod is already popped from the queue. +// It updates the metrics and in-flight tracking. +func (aq *activeQueue) movePodToInFlight(pInfo *framework.QueuedPodInfo) error { + aq.lock.Lock() + defer aq.lock.Unlock() + return aq.unlockedMovePodToInFlight(pInfo) +} + +// unlockedMovePodToInFlight moves the pod to the in-flight state. +// This method should be called under the lock. +func (aq *activeQueue) unlockedMovePodToInFlight(pInfo *framework.QueuedPodInfo) error { + pInfo.Attempts++ + // In flight, no concurrent events yet. + if aq.isSchedulingQueueHintEnabled { + // If the pod is already in the map, we shouldn't overwrite the inFlightPods otherwise it'd lead to a memory leak. + // https://github.com/kubernetes/kubernetes/pull/127016 + if _, ok := aq.inFlightPods[pInfo.Pod.UID]; ok { + return fmt.Errorf("the same pod is tracked in multiple places in the scheduler: %s", klog.KObj(pInfo.Pod)) + } + + aq.metricsRecorder.ObserveInFlightEventsAsync(metrics.PodPoppedInFlightEvent, 1, false) + aq.inFlightPods[pInfo.Pod.UID] = aq.inFlightEvents.PushBack(pInfo.Pod) + } + aq.schedCycle++ + + // Update metrics for unschedulable plugins. + for plugin := range pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) { + metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Dec() + } + return nil +} + // pop removes the head of the queue and returns it. // It blocks if the queue is empty and waits until a new item is added to the queue. // It increments scheduling cycle when a pod is popped. @@ -305,32 +339,14 @@ func (aq *activeQueue) unlockedPop(logger klog.Logger) (*framework.QueuedPodInfo } metrics.SchedulerQueueIncomingPods.WithLabelValues("active", framework.PopFromBackoffQ).Inc() } - pInfo.Attempts++ - // In flight, no concurrent events yet. - if aq.isSchedulingQueueHintEnabled { - // If the pod is already in the map, we shouldn't overwrite the inFlightPods otherwise it'd lead to a memory leak. - // https://github.com/kubernetes/kubernetes/pull/127016 - if _, ok := aq.inFlightPods[pInfo.Pod.UID]; ok { - // Just report it as an error, but no need to stop the scheduler - // because it likely doesn't cause any visible issues from the scheduling perspective. - utilruntime.HandleErrorWithLogger(logger, nil, "The same pod is tracked in multiple places in the scheduler, and just discard it", "pod", klog.KObj(pInfo.Pod)) - // Just ignore/discard this duplicated pod and try to pop the next one. - return aq.unlockedPop(logger) - } - - aq.metricsRecorder.ObserveInFlightEventsAsync(metrics.PodPoppedInFlightEvent, 1, false) - aq.inFlightPods[pInfo.Pod.UID] = aq.inFlightEvents.PushBack(pInfo.Pod) - } - aq.schedCycle++ - - // Update metrics and reset the set of unschedulable plugins for the next attempt. - for plugin := range pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) { - metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Dec() + err = aq.unlockedMovePodToInFlight(pInfo) + if err != nil { + // Just report it as an error, but no need to stop the scheduler + // because it likely doesn't cause any visible issues from the scheduling perspective. + utilruntime.HandleErrorWithLogger(logger, err, "Discarding the popped pod") + // Just ignore/discard this duplicated pod and try to pop the next one. + return aq.unlockedPop(logger) } - pInfo.UnschedulablePlugins.Clear() - pInfo.PendingPlugins.Clear() - pInfo.GatingPlugin = "" - pInfo.GatingPluginEvents = nil return pInfo, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go index 717b55656f..81c5488cb4 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go @@ -88,12 +88,17 @@ const ( // by the checking result. type PreEnqueueCheck func(pod *v1.Pod) bool +// PodSigner creates a scheduling signature for a pod that represents its scheduling requirements. +// The signature is used by the opportunistic batching feature (KEP-5598) to reuse scheduling decisions. +// Returns nil if the pod is "unsignable" (some plugins cannot create a stable signature for it). +type PodSigner func(ctx context.Context, pod *v1.Pod) fwk.PodSignature + // SchedulingQueue is an interface for a queue to store pods waiting to be scheduled. // The interface follows a pattern similar to cache.FIFO and cache.Heap and // makes it easy to use those data structures as a SchedulingQueue. type SchedulingQueue interface { fwk.PodNominator - Add(logger klog.Logger, pod *v1.Pod) + Add(ctx context.Context, pod *v1.Pod) // Activate moves the given pods to activeQ. // If a pod isn't found in unschedulablePods or backoffQ and it's in-flight, // the wildcard event is registered so that the pod will be requeued when it comes back. @@ -111,10 +116,14 @@ type SchedulingQueue interface { // Pop removes the head of the queue and returns it. It blocks if the // queue is empty and waits until a new item is added to the queue. Pop(logger klog.Logger) (*framework.QueuedPodInfo, error) + // PopSpecificPod removes the pod from the queue and returns it. + // It behaves like Pop for the popped pod (metrics, in-flight tracking, etc.). + // It returns nil if the pod is not in the queue. + PopSpecificPod(logger klog.Logger, pod *v1.Pod) *framework.QueuedPodInfo // Done must be called for pod returned by Pop. This allows the queue to // keep track of which pods are currently being processed. Done(types.UID) - Update(logger klog.Logger, oldPod, newPod *v1.Pod) + Update(ctx context.Context, oldPod, newPod *v1.Pod) Delete(pod *v1.Pod) // Important Note: preCheck shouldn't include anything that depends on the in-tree plugins' logic. // (e.g., filter Pods based on added/updated Node's capacity, etc.) @@ -202,10 +211,17 @@ type PriorityQueue struct { // It's non-nil only if the SchedulerAsyncAPICalls feature gate is enabled. apiDispatcher fwk.APIDispatcher + // podSigners maps a profile name to a signing function for that profile. + podSigners map[string]PodSigner + // isSchedulingQueueHintEnabled indicates whether the feature gate for the scheduling queue is enabled. isSchedulingQueueHintEnabled bool // isPopFromBackoffQEnabled indicates whether the feature gate SchedulerPopFromBackoffQ is enabled. isPopFromBackoffQEnabled bool + // isGenericWorkloadEnabled indicates whether the feature gate GenericWorkload is enabled. + isGenericWorkloadEnabled bool + // isOpportunisticBatchingEnabled indicates whether the OpportunisticBatching feature gate is enabled. + isOpportunisticBatchingEnabled bool } // QueueingHintFunction is the wrapper of QueueingHintFn that has PluginName. @@ -234,6 +250,7 @@ type priorityQueueOptions struct { preEnqueuePluginMap map[string]map[string]fwk.PreEnqueuePlugin queueingHintMap QueueingHintMapPerProfile apiDispatcher fwk.APIDispatcher + podSigners map[string]PodSigner } // Option configures a PriorityQueue @@ -315,6 +332,16 @@ func WithAPIDispatcher(apiDispatcher fwk.APIDispatcher) Option { } } +// WithPodSigners sets the pod signing functions per scheduler profile. +// Each profile can have its own signing function for computing pod signatures. +// Pod signatures enable opportunistic batching (KEP-5598) by allowing the scheduler +// to cache and reuse filtering/scoring results for identical pods. +func WithPodSigners(signers map[string]PodSigner) Option { + return func(o *priorityQueueOptions) { + o.podSigners = signers + } +} + var defaultPriorityQueueOptions = priorityQueueOptions{ clock: clock.RealClock{}, podInitialBackoffDuration: DefaultPodInitialBackoffDuration, @@ -351,6 +378,8 @@ func NewPriorityQueue( isSchedulingQueueHintEnabled := utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) isPopFromBackoffQEnabled := utilfeature.DefaultFeatureGate.Enabled(features.SchedulerPopFromBackoffQ) + isGenericWorkloadEnabled := utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) + isOpportunisticBatchingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) lessConverted := convertLessFn(lessFn) backoffQ := newBackoffQueue(options.clock, options.podInitialBackoffDuration, options.podMaxBackoffDuration, lessFn, isPopFromBackoffQEnabled) @@ -367,8 +396,11 @@ func NewPriorityQueue( pluginMetricsSamplePercent: options.pluginMetricsSamplePercent, moveRequestCycle: -1, apiDispatcher: options.apiDispatcher, + podSigners: options.podSigners, isSchedulingQueueHintEnabled: isSchedulingQueueHintEnabled, isPopFromBackoffQEnabled: isPopFromBackoffQEnabled, + isGenericWorkloadEnabled: isGenericWorkloadEnabled, + isOpportunisticBatchingEnabled: isOpportunisticBatchingEnabled, } var backoffQPopper backoffQPopper if isPopFromBackoffQEnabled { @@ -572,11 +604,10 @@ func (p *PriorityQueue) runPreEnqueuePlugins(ctx context.Context, pInfo *framewo }() shouldRecordMetric := rand.Intn(100) < p.pluginMetricsSamplePercent - logger := klog.FromContext(ctx) gatingPlugin := pInfo.GatingPlugin if gatingPlugin != "" { // Run the gating plugin first - s := p.runPreEnqueuePlugin(ctx, logger, p.preEnqueuePluginMap[pod.Spec.SchedulerName][gatingPlugin], pInfo, shouldRecordMetric) + s := p.runPreEnqueuePlugin(ctx, p.preEnqueuePluginMap[pod.Spec.SchedulerName][gatingPlugin], pInfo, shouldRecordMetric) if !s.IsSuccess() { // No need to iterate other plugins return @@ -588,7 +619,7 @@ func (p *PriorityQueue) runPreEnqueuePlugins(ctx context.Context, pInfo *framewo // should be run already above. continue } - s := p.runPreEnqueuePlugin(ctx, logger, pl, pInfo, shouldRecordMetric) + s := p.runPreEnqueuePlugin(ctx, pl, pInfo, shouldRecordMetric) if !s.IsSuccess() { // No need to iterate other plugins return @@ -599,7 +630,7 @@ func (p *PriorityQueue) runPreEnqueuePlugins(ctx context.Context, pInfo *framewo } // runPreEnqueuePlugin runs the PreEnqueue plugin and update pInfo's fields accordingly if needed. -func (p *PriorityQueue) runPreEnqueuePlugin(ctx context.Context, logger klog.Logger, pl fwk.PreEnqueuePlugin, pInfo *framework.QueuedPodInfo, shouldRecordMetric bool) *fwk.Status { +func (p *PriorityQueue) runPreEnqueuePlugin(ctx context.Context, pl fwk.PreEnqueuePlugin, pInfo *framework.QueuedPodInfo, shouldRecordMetric bool) *fwk.Status { pod := pInfo.Pod startTime := p.clock.Now() s := pl.PreEnqueue(ctx, pod) @@ -610,14 +641,17 @@ func (p *PriorityQueue) runPreEnqueuePlugin(ctx context.Context, logger klog.Log // No need to change GatingPlugin; it's overwritten by the next PreEnqueue plugin if they gate this pod, or it's overwritten with an empty string if all PreEnqueue plugins pass. return s } + // Only increment metric and insert if not already incremented for this plugin + if !pInfo.UnschedulablePlugins.Has(pl.Name()) && !pInfo.PendingPlugins.Has(pl.Name()) { + metrics.UnschedulableReason(pl.Name(), pod.Spec.SchedulerName).Inc() + } pInfo.UnschedulablePlugins.Insert(pl.Name()) - metrics.UnschedulableReason(pl.Name(), pod.Spec.SchedulerName).Inc() pInfo.GatingPlugin = pl.Name() pInfo.GatingPluginEvents = p.pluginToEventsMap[pInfo.GatingPlugin] if s.Code() == fwk.Error { utilruntime.HandleErrorWithContext(ctx, s.AsError(), "Unexpected error running PreEnqueue plugin", "pod", klog.KObj(pod), "plugin", pl.Name()) } else { - logger.V(4).Info("Status after running PreEnqueue plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", s) + klog.FromContext(ctx).V(4).Info("Status after running PreEnqueue plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", s) } return s @@ -655,11 +689,11 @@ func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.Queue if p.backoffQ.has(pInfo) { return } - if p.unschedulablePods.get(pInfo.Pod) != nil { - return + + if p.unschedulablePods.get(pInfo.Pod) == nil { + logger.V(5).Info("Pod moved to an internal scheduling queue, because the pod is gated", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", unschedulableQ) } - p.unschedulablePods.addOrUpdate(pInfo, event) - logger.V(5).Info("Pod moved to an internal scheduling queue, because the pod is gated", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", unschedulableQ) + p.unschedulablePods.addOrUpdate(pInfo, gatedBefore, event) return } if pInfo.InitialAttemptTimestamp == nil { @@ -690,9 +724,9 @@ func (p *PriorityQueue) moveToBackoffQ(logger klog.Logger, pInfo *framework.Queu p.runPreEnqueuePlugins(context.Background(), pInfo) if pInfo.Gated() { if p.unschedulablePods.get(pInfo.Pod) == nil { - p.unschedulablePods.addOrUpdate(pInfo, event) logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", unschedulableQ) } + p.unschedulablePods.addOrUpdate(pInfo, gatedBefore, event) return false } } @@ -704,11 +738,12 @@ func (p *PriorityQueue) moveToBackoffQ(logger klog.Logger, pInfo *framework.Queu // Add adds a pod to the active queue. It should be called only when a new pod // is added so there is no chance the pod is already in active/unschedulable/backoff queues -func (p *PriorityQueue) Add(logger klog.Logger, pod *v1.Pod) { +func (p *PriorityQueue) Add(ctx context.Context, pod *v1.Pod) { p.lock.Lock() defer p.lock.Unlock() - pInfo := p.newQueuedPodInfo(pod) + pInfo := p.newQueuedPodInfo(ctx, pod) + logger := klog.FromContext(ctx) if added := p.moveToActiveQ(logger, pInfo, framework.EventUnscheduledPodAdd.Label(), false); added { p.activeQ.broadcast() } @@ -787,6 +822,12 @@ func (p *PriorityQueue) determineSchedulingHintForInFlightPod(logger klog.Logger // In this case, we should retry scheduling it because this Pod may not be retried until the next flush. return queueAfterBackoff } + if p.isGenericWorkloadEnabled && pInfo.Pod.Spec.SchedulingGroup != nil { + // When the pod is a member of the pod group, i.e., needs pod group scheduling, + // its retry logic should be based solely on backoff, because event-based requeueing logic + // is not yet implemented for pod group level. + return queueAfterBackoff + } events, err := p.activeQ.clusterEventsForPod(logger, pInfo) if err != nil { @@ -850,7 +891,7 @@ func (p *PriorityQueue) addUnschedulableWithoutQueueingHint(logger klog.Logger, } } } else { - p.unschedulablePods.addOrUpdate(pInfo, framework.ScheduleAttemptFailure) + p.unschedulablePods.addOrUpdate(pInfo, false /* the Pod was absent from all queues */, framework.ScheduleAttemptFailure) logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pod), "event", framework.ScheduleAttemptFailure, "queue", unschedulableQ) } @@ -894,6 +935,8 @@ func (p *PriorityQueue) AddUnschedulableIfNotPresent(logger klog.Logger, pInfo * // We changed ConsecutiveErrorsCount or UnschedulableCount plus Timestamp, and now the calculated backoff time should be different, // removing the cached backoff time. pInfo.BackoffExpiration = time.Time{} + // Clear the flush flag since the pod is returning to the queue after a scheduling attempt. + pInfo.WasFlushedFromUnschedulable = false if !p.isSchedulingQueueHintEnabled { // fall back to the old behavior which doesn't depend on the queueing hint. @@ -948,6 +991,8 @@ func (p *PriorityQueue) flushUnschedulablePodsLeftover(logger klog.Logger) { for _, pInfo := range p.unschedulablePods.podInfoMap { lastScheduleTime := pInfo.Timestamp if currentTime.Sub(lastScheduleTime) > p.podMaxInUnschedulablePodsDuration { + // Mark this pod as flushed so we can detect if it schedules soon after + pInfo.WasFlushedFromUnschedulable = true podsToMove = append(podsToMove, pInfo) } } @@ -966,6 +1011,41 @@ func (p *PriorityQueue) Pop(logger klog.Logger) (*framework.QueuedPodInfo, error return p.activeQ.pop(logger) } +// PopSpecificPod removes the pod from the queue and returns it. +// It behaves like Pop for the popped pod (metrics, in-flight tracking, etc.). +// It returns nil if the pod is not in the queue. +func (p *PriorityQueue) PopSpecificPod(logger klog.Logger, pod *v1.Pod) *framework.QueuedPodInfo { + p.lock.Lock() + defer p.lock.Unlock() + + pInfoLookup := newQueuedPodInfoForLookup(pod) + + // Try to activate the pod, then obtain it from the activeQ. + // This way, the pod behaves almost the same as it would be activated by some event, + // moved to the activeQ and popped from there. + _ = p.activate(logger, pod) + + var pInfo *framework.QueuedPodInfo + p.activeQ.underRLock(func(unlockedActiveQ unlockedActiveQueueReader) { + pInfo, _ = unlockedActiveQ.get(pInfoLookup) + }) + if pInfo == nil { + return nil + } + if err := p.activeQ.delete(pInfo); err != nil { + // Error means that the pod disappeared from the activeQ in the meantime. + // Returning nil is fine. + return nil + } + err := p.activeQ.movePodToInFlight(pInfo) + if err != nil { + utilruntime.HandleErrorWithLogger(logger, err, "Discarding the popped pod") + return nil + } + + return pInfo +} + // Done must be called for pod returned by Pop. This allows the queue to // keep track of which pods are currently being processed. func (p *PriorityQueue) Done(pod types.UID) { @@ -1011,9 +1091,10 @@ func isPodUpdated(oldPod, newPod *v1.Pod) bool { // the item from the unschedulable queue if pod is updated in a way that it may // become schedulable and adds the updated one to the active queue. // If pod is not present in any of the queues, it is added to the active queue. -func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { +func (p *PriorityQueue) Update(ctx context.Context, oldPod, newPod *v1.Pod) { p.lock.Lock() defer p.lock.Unlock() + logger := klog.FromContext(ctx) var events []fwk.ClusterEvent if p.isSchedulingQueueHintEnabled { @@ -1043,6 +1124,7 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { // If the pod is already in the active queue, just update it there. if pInfo := unlockedActiveQ.update(newPod, oldPodInfo); pInfo != nil { p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) + pInfo.PodSignature = p.signPod(ctx, newPod) updated = true return } @@ -1050,6 +1132,7 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { // If the pod is in the backoff queue, update it there. if pInfo := p.backoffQ.update(newPod, oldPodInfo); pInfo != nil { p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) + pInfo.PodSignature = p.signPod(ctx, newPod) updated = true return } @@ -1063,6 +1146,8 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { if pInfo := p.unschedulablePods.get(newPod); pInfo != nil { _ = pInfo.Update(newPod) p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) + pInfo.PodSignature = p.signPod(ctx, newPod) + if p.isSchedulingQueueHintEnabled { // When unscheduled Pods are updated, we check with QueueingHint // whether the update may make the pods schedulable. @@ -1100,11 +1185,12 @@ func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { } // Pod update didn't make it schedulable, keep it in the unschedulable queue. - p.unschedulablePods.addOrUpdate(pInfo, framework.EventUnscheduledPodUpdate.Label()) + // Use pInfo.Gated() to avoid double-counting "Gated" metrics during an in-place update. + p.unschedulablePods.addOrUpdate(pInfo, pInfo.Gated(), framework.EventUnscheduledPodUpdate.Label()) return } // If pod is not in any of the queues, we put it in the active queue. - pInfo := p.newQueuedPodInfo(newPod) + pInfo := p.newQueuedPodInfo(ctx, newPod) if added := p.moveToActiveQ(logger, pInfo, framework.EventUnscheduledPodUpdate.Label(), false); added { p.activeQ.broadcast() } @@ -1125,6 +1211,10 @@ func (p *PriorityQueue) Delete(pod *v1.Pod) { } if pInfo = p.unschedulablePods.get(pod); pInfo != nil { p.unschedulablePods.delete(pod, pInfo.Gated()) + // Drop metric for deleted pod. + for plugin := range pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) { + metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Dec() + } } } @@ -1192,7 +1282,8 @@ func (p *PriorityQueue) MoveAllToActiveOrBackoffQueue(logger klog.Logger, event // NOTE: this function assumes lock has been acquired in caller func (p *PriorityQueue) requeuePodWithQueueingStrategy(logger klog.Logger, pInfo *framework.QueuedPodInfo, strategy queueingStrategy, event string) string { if strategy == queueSkip { - p.unschedulablePods.addOrUpdate(pInfo, event) + // Current Gate status is required for already exisiting pods. For new pods, this parameter is ignored/unused by addOrUpdate. + p.unschedulablePods.addOrUpdate(pInfo, pInfo.Gated(), event) return unschedulableQ } @@ -1296,6 +1387,8 @@ func (p *PriorityQueue) PodsInBackoffQ() []*v1.Pod { // UnschedulablePods returns all the pods in unschedulable state. func (p *PriorityQueue) UnschedulablePods() []*v1.Pod { + p.lock.RLock() + defer p.lock.RUnlock() var result []*v1.Pod for _, pInfo := range p.unschedulablePods.podInfoMap { result = append(result, pInfo.Pod) @@ -1413,8 +1506,28 @@ func (p *PriorityQueue) NominatedPodsForNode(nodeName string) []fwk.PodInfo { return pods } +// signPod computes the scheduling signature for the given pod when OpportunisticBatching is enabled. +// The signature is used to cache and reuse scheduling results for identical pods. +func (p *PriorityQueue) signPod(ctx context.Context, pod *v1.Pod) fwk.PodSignature { + if !p.isOpportunisticBatchingEnabled { + return nil + } + + if p.podSigners == nil { + return nil + } + + signer, ok := p.podSigners[pod.Spec.SchedulerName] + if !ok { + utilruntime.HandleErrorWithContext(ctx, nil, "No signer registered for scheduler profile", "pod", klog.KObj(pod), "schedulerName", pod.Spec.SchedulerName) + return nil + } + + return signer(ctx, pod) +} + // newQueuedPodInfo builds a QueuedPodInfo object. -func (p *PriorityQueue) newQueuedPodInfo(pod *v1.Pod, plugins ...string) *framework.QueuedPodInfo { +func (p *PriorityQueue) newQueuedPodInfo(ctx context.Context, pod *v1.Pod, plugins ...string) *framework.QueuedPodInfo { now := p.clock.Now() // ignore this err since apiserver doesn't properly validate affinity terms // and we can't fix the validation for backwards compatibility. @@ -1423,6 +1536,7 @@ func (p *PriorityQueue) newQueuedPodInfo(pod *v1.Pod, plugins ...string) *framew PodInfo: podInfo, Timestamp: now, InitialAttemptTimestamp: nil, + PodSignature: p.signPod(ctx, pod), UnschedulablePlugins: sets.New(plugins...), } } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/unschedulable_pods.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/unschedulable_pods.go index 4c248bfcd5..2fff92d499 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/unschedulable_pods.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/unschedulable_pods.go @@ -28,8 +28,10 @@ type unschedulablePods struct { // podInfoMap is a map key by a pod's full-name and the value is a pointer to the QueuedPodInfo. podInfoMap map[string]*framework.QueuedPodInfo keyFunc func(*v1.Pod) string - // unschedulableRecorder/gatedRecorder updates the counter when elements of an unschedulablePods - // get added or removed, and it does nothing if it's nil. + // unschedulableRecorder and gatedRecorder track the number of pods in the unschedulable queue. + // unschedulableRecorder tracks standard unschedulable pods, while gatedRecorder tracks pods + // that are specifically blocked by scheduling gates. These recorders handle + // increments, decrements, and transitions (Gated <-> Ungated). unschedulableRecorder, gatedRecorder metrics.MetricRecorder } @@ -43,14 +45,34 @@ func newUnschedulablePods(unschedulableRecorder, gatedRecorder metrics.MetricRec } } +// updateMetricsOnStateChange handles the metric accounting when a pod changes +// between Gated and Unschedulable states. +func (u *unschedulablePods) updateMetricsOnStateChange(gatedBefore, isGated bool) { + if gatedBefore == isGated { + return + } + + if gatedBefore { + // Transition: Gated -> Ungated + u.gatedRecorder.Dec() + u.unschedulableRecorder.Inc() + } else { + // Transition: Ungated -> Gated + u.gatedRecorder.Inc() + u.unschedulableRecorder.Dec() + } +} + // addOrUpdate adds a pod to the unschedulable podInfoMap. // The event should show which event triggered the addition and is used for the metric recording. -func (u *unschedulablePods) addOrUpdate(pInfo *framework.QueuedPodInfo, event string) { +func (u *unschedulablePods) addOrUpdate(pInfo *framework.QueuedPodInfo, gatedBefore bool, event string) { podID := u.keyFunc(pInfo.Pod) - if _, exists := u.podInfoMap[podID]; !exists { - if pInfo.Gated() && u.gatedRecorder != nil { + if _, exists := u.podInfoMap[podID]; exists { + u.updateMetricsOnStateChange(gatedBefore, pInfo.Gated()) + } else { + if pInfo.Gated() { u.gatedRecorder.Inc() - } else if !pInfo.Gated() && u.unschedulableRecorder != nil { + } else { u.unschedulableRecorder.Inc() } metrics.SchedulerQueueIncomingPods.WithLabelValues("unschedulable", event).Inc() @@ -63,9 +85,9 @@ func (u *unschedulablePods) addOrUpdate(pInfo *framework.QueuedPodInfo, event st func (u *unschedulablePods) delete(pod *v1.Pod, gated bool) { podID := u.keyFunc(pod) if _, exists := u.podInfoMap[podID]; exists { - if gated && u.gatedRecorder != nil { + if gated { u.gatedRecorder.Dec() - } else if !gated && u.unschedulableRecorder != nil { + } else { u.unschedulableRecorder.Dec() } } @@ -85,10 +107,6 @@ func (u *unschedulablePods) get(pod *v1.Pod) *framework.QueuedPodInfo { // clear removes all the entries from the unschedulable podInfoMap. func (u *unschedulablePods) clear() { u.podInfoMap = make(map[string]*framework.QueuedPodInfo) - if u.unschedulableRecorder != nil { - u.unschedulableRecorder.Clear() - } - if u.gatedRecorder != nil { - u.gatedRecorder.Clear() - } + u.unschedulableRecorder.Clear() + u.gatedRecorder.Clear() } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/podgroupinfo.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/podgroupinfo.go deleted file mode 100644 index 5d60db349e..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/podgroupinfo.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 2025 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 workloadmanager - -import ( - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/utils/ptr" -) - -// DefaultSchedulingTimeoutDuration defines how long the gang pods should wait at the -// Permit stage for a quorum before being rejected. -// Variable is exported only for testing purposes. -var DefaultSchedulingTimeoutDuration = 5 * time.Minute - -// podGroupKey uniquely identifies a specific instance of a PodGroup. -type podGroupKey struct { - namespace string - workloadName string - podGroupName string - replicaKey string -} - -func newPodGroupKey(namespace string, workloadRef *v1.WorkloadReference) podGroupKey { - return podGroupKey{ - namespace: namespace, - workloadName: workloadRef.Name, - podGroupName: workloadRef.PodGroup, - replicaKey: workloadRef.PodGroupReplicaKey, - } -} - -// podGroupInfo holds the runtime state of a pod group. -type podGroupInfo struct { - lock sync.RWMutex - // allPods tracks all pods belonging to the group that are known to the scheduler. - allPods map[types.UID]*v1.Pod - // unscheduledPods tracks all pods that are unscheduled for this group, - // i.e., are neither assumed nor scheduled. - unscheduledPods sets.Set[types.UID] - // assumedPods tracks pods that have reached the Reserve stage and are waiting - // for the rest of the gang to arrive before being allowed to bind. - assumedPods sets.Set[types.UID] - // assignedPods tracks all pods belonging to the group that are assigned (bound). - assignedPods sets.Set[types.UID] - // schedulingDeadline stores the time at which the gang will time out. - // It is initialized when the first pod from the group enters the Permit stage. - schedulingDeadline *time.Time -} - -func newPodGroupInfo() *podGroupInfo { - return &podGroupInfo{ - allPods: make(map[types.UID]*v1.Pod), - unscheduledPods: sets.New[types.UID](), - assumedPods: sets.New[types.UID](), - assignedPods: sets.New[types.UID](), - } -} - -// addPod adds the pod to this group. -// Depending on the NodeName, it can insert the pod to assignedPods set. -func (pgs *podGroupInfo) addPod(pod *v1.Pod) { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - pgs.allPods[pod.UID] = pod - if pod.Spec.NodeName != "" { - pgs.assignedPods.Insert(pod.UID) - } else { - pgs.unscheduledPods.Insert(pod.UID) - } -} - -// updatePod updates the pod in this group. -// In case of binding, it moves the pod to assignedPods. -func (pgs *podGroupInfo) updatePod(oldPod, newPod *v1.Pod) { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - pgs.allPods[newPod.UID] = newPod - if oldPod.Spec.NodeName == "" && newPod.Spec.NodeName != "" { - pgs.assignedPods.Insert(newPod.UID) - // Clear pod from unscheduled and assumed when it is assigned. - pgs.unscheduledPods.Delete(newPod.UID) - pgs.assumedPods.Delete(newPod.UID) - } -} - -// deletePod completely deletes the pod from this group. -func (pgs *podGroupInfo) deletePod(podUID types.UID) { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - delete(pgs.allPods, podUID) - pgs.unscheduledPods.Delete(podUID) - pgs.assumedPods.Delete(podUID) - pgs.assignedPods.Delete(podUID) -} - -// empty returns true when the group is empty. -func (pgs *podGroupInfo) empty() bool { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - return len(pgs.allPods) == 0 -} - -// AllPods returns the UIDs of all pods known to the scheduler for this group. -func (pgs *podGroupInfo) AllPods() sets.Set[types.UID] { - pgs.lock.RLock() - defer pgs.lock.RUnlock() - - return sets.KeySet(pgs.allPods) -} - -// UnscheduledPods returns all pods that are unscheduled for this group, -// i.e., are neither assumed nor assigned. -// The returned map type corresponds to the argument of the PodActivator.Activate method. -func (pgs *podGroupInfo) UnscheduledPods() map[string]*v1.Pod { - pgs.lock.RLock() - defer pgs.lock.RUnlock() - - unscheduledPods := make(map[string]*v1.Pod, len(pgs.unscheduledPods)) - for podUID := range pgs.unscheduledPods { - pod := pgs.allPods[podUID] - unscheduledPods[pod.Name] = pod - } - return unscheduledPods -} - -// AssumedPods returns the UIDs of all pods for this group in the assumed state, -// i.e., passed the Reserve gate. -func (pgs *podGroupInfo) AssumedPods() sets.Set[types.UID] { - pgs.lock.RLock() - defer pgs.lock.RUnlock() - - return pgs.assumedPods.Clone() -} - -// AssignedPods returns the UIDs of all pods already assigned (bound) for this group. -func (pgs *podGroupInfo) AssignedPods() sets.Set[types.UID] { - pgs.lock.RLock() - defer pgs.lock.RUnlock() - - return pgs.assignedPods.Clone() -} - -// SchedulingTimeout returns the remaining time until the pod group scheduling times out. -// A new deadline is created if one doesn't exist, or if the previous one has expired. -func (pgs *podGroupInfo) SchedulingTimeout() time.Duration { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - now := time.Now() - // A new deadline is set if one doesn't exist, or if the old one has passed. - // This allows a new attempt to form a gang after a previous attempt timed out. - if pgs.schedulingDeadline == nil || pgs.schedulingDeadline.Before(now) { - pgs.schedulingDeadline = ptr.To(now.Add(DefaultSchedulingTimeoutDuration)) - } - return pgs.schedulingDeadline.Sub(now) -} - -// AssumePod marks a pod as having reached the Reserve stage. -func (pgs *podGroupInfo) AssumePod(podUID types.UID) { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - pgs.assumedPods.Insert(podUID) - pgs.unscheduledPods.Delete(podUID) -} - -// ForgetPod removes a pod from the assumed state. -func (pgs *podGroupInfo) ForgetPod(podUID types.UID) { - pgs.lock.Lock() - defer pgs.lock.Unlock() - - pgs.unscheduledPods.Insert(podUID) - pgs.assumedPods.Delete(podUID) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/workloadmanager.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/workloadmanager.go deleted file mode 100644 index 088d852cb2..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager/workloadmanager.go +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright 2025 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 workloadmanager - -import ( - "fmt" - "sync" - - v1 "k8s.io/api/core/v1" - fwk "k8s.io/kube-scheduler/framework" -) - -// WorkloadManager is the central source of truth for the state of pods belonging to Workload objects. -// It is designed to be driven explicitly by the scheduler's event handlers to ensure thread safety -// and avoid race conditions with the main scheduling queue. -// Note: The current implementation assumes that pod.Spec.Workload is immutable. -// Allowing mutability would require changes to the manager, e.g., by properly handling pod updates. -type WorkloadManager interface { - fwk.WorkloadManager - - // AddPod is called by the scheduler when a Pod/Add event is observed. - AddPod(pod *v1.Pod) - // UpdatePod is called by the scheduler when a Pod/Update event is observed. - UpdatePod(oldPod, newPod *v1.Pod) - // DeletePod is called by the scheduler when a Pod/Delete event is observed. - DeletePod(pod *v1.Pod) -} - -// workloadManager is the concrete implementation of the WorkloadManager. -type workloadManager struct { - lock sync.RWMutex - - // podGroupInfos stores the runtime state for each known pod group. - podGroupInfos map[podGroupKey]*podGroupInfo -} - -// New initializes a new workload manager and returns it. -func New() *workloadManager { - return &workloadManager{ - podGroupInfos: make(map[podGroupKey]*podGroupInfo), - } -} - -// AddPod adds a pod to the workload manager if it has a workload reference. -// Pod is added to the available pods set for its corresponding pod group. -func (wm *workloadManager) AddPod(pod *v1.Pod) { - if pod.Spec.WorkloadRef == nil { - return - } - wm.lock.Lock() - defer wm.lock.Unlock() - - key := newPodGroupKey(pod.Namespace, pod.Spec.WorkloadRef) - info, ok := wm.podGroupInfos[key] - if !ok { - info = newPodGroupInfo() - wm.podGroupInfos[key] = info - } - info.addPod(pod) -} - -// UpdatePod updates a pod in the workload manager if it has a workload reference. -// Note: The current implementation assumes that newPod.Spec.Workload is immutable. -func (wm *workloadManager) UpdatePod(oldPod, newPod *v1.Pod) { - if newPod.Spec.WorkloadRef == nil { - return - } - wm.lock.Lock() - defer wm.lock.Unlock() - - key := newPodGroupKey(newPod.Namespace, newPod.Spec.WorkloadRef) - info, ok := wm.podGroupInfos[key] - if !ok { - // Shouldn't happen, but handling this case gracefully. - info = newPodGroupInfo() - wm.podGroupInfos[key] = info - info.addPod(newPod) - return - } - info.updatePod(oldPod, newPod) -} - -// DeletePod removes a pod from the workload manager if it has a workload reference. -// Pod is removed from the pods sets for its corresponding pod group. -func (wm *workloadManager) DeletePod(pod *v1.Pod) { - if pod.Spec.WorkloadRef == nil { - return - } - wm.lock.Lock() - defer wm.lock.Unlock() - - key := newPodGroupKey(pod.Namespace, pod.Spec.WorkloadRef) - info, ok := wm.podGroupInfos[key] - if !ok { - // The pod group may have already been cleaned up, or the pod was never added. - return - } - info.deletePod(pod.UID) - // Clean up the map entry if no pods are left in the group. - if info.empty() { - delete(wm.podGroupInfos, key) - } -} - -// PodGroupInfo returns the state of a pod group. -func (wm *workloadManager) PodGroupInfo(namespace string, workloadRef *v1.WorkloadReference) (fwk.PodGroupInfo, error) { - wm.lock.RLock() - defer wm.lock.RUnlock() - - state, ok := wm.podGroupInfos[newPodGroupKey(namespace, workloadRef)] - if !ok { - return nil, fmt.Errorf("internal pod group state doesn't exist for a pod's workload") - } - return state, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go b/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go index 2febf790f5..232fa4b403 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go @@ -52,8 +52,7 @@ import ( func (sched *Scheduler) addNodeToCache(obj interface{}) { evt := fwk.ClusterEvent{Resource: fwk.Node, ActionType: fwk.Add} - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), evt.Label())() logger := sched.logger node, ok := obj.(*v1.Node) if !ok { @@ -99,8 +98,7 @@ func (sched *Scheduler) updateNodeInCache(oldObj, newObj interface{}) { func (sched *Scheduler) deleteNodeFromCache(obj interface{}) { evt := fwk.ClusterEvent{Resource: fwk.Node, ActionType: fwk.Delete} - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), evt.Label())() logger := sched.logger var node *v1.Node @@ -135,10 +133,6 @@ func (sched *Scheduler) addPod(obj interface{}) { return } - if sched.WorkloadManager != nil { - // Register pod into workload manager before adding to the cache or scheduling queue. - sched.WorkloadManager.AddPod(pod) - } if assignedPod(pod) { sched.addAssignedPodToCache(pod) } else if responsibleForPod(pod, sched.Profiles) { @@ -159,10 +153,6 @@ func (sched *Scheduler) updatePod(oldObj, newObj interface{}) { return } - if sched.WorkloadManager != nil { - // Update pod in workload manager before updating it in the cache or scheduling queue. - sched.WorkloadManager.UpdatePod(oldPod, newPod) - } if assignedPod(oldPod) { sched.updateAssignedPodInCache(oldPod, newPod) } else if assignedPod(newPod) { @@ -187,10 +177,6 @@ func (sched *Scheduler) deletePod(obj interface{}) { switch t := obj.(type) { case *v1.Pod: pod = t - if sched.WorkloadManager != nil { - // Delete pod from workload manager before deleting the pod from cache or scheduling queue. - sched.WorkloadManager.DeletePod(pod) - } if assignedPod(pod) { sched.deleteAssignedPodFromCache(pod) } else if responsibleForPod(pod, sched.Profiles) { @@ -206,10 +192,6 @@ func (sched *Scheduler) deletePod(obj interface{}) { utilruntime.HandleErrorWithLogger(logger, nil, "Cannot convert to *v1.Pod", "obj", t.Obj) return } - if sched.WorkloadManager != nil { - // Delete pod from workload manager before deleting the pod from cache or scheduling queue. - sched.WorkloadManager.DeletePod(pod) - } // The carried object may be stale, so we don't use it to check if // it's assigned or not. Attempting to cleanup anyways. sched.deleteAssignedPodFromCache(pod) @@ -226,12 +208,12 @@ func (sched *Scheduler) deletePod(obj interface{}) { } func (sched *Scheduler) addPodToSchedulingQueue(pod *v1.Pod) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodAdd.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), framework.EventUnscheduledPodAdd.Label())() logger := sched.logger logger.V(3).Info("Add event for unscheduled pod", "pod", klog.KObj(pod)) - sched.SchedulingQueue.Add(logger, pod) + sched.Cache.AddPodGroupMember(pod) + sched.SchedulingQueue.Add(klog.NewContext(context.Background(), logger), pod) if utilfeature.DefaultFeatureGate.Enabled(features.GangScheduling) { sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventUnscheduledPodAdd, nil, pod, nil) } @@ -303,10 +285,10 @@ func (sched *Scheduler) updatePodInSchedulingQueue(oldPod, newPod *v1.Pod) { return } - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodUpdate.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(start, framework.EventUnscheduledPodUpdate.Label())() for _, evt := range framework.PodSchedulingPropertiesChange(newPod, oldPod) { if evt.Label() != framework.EventUnscheduledPodUpdate.Label() { - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(start, evt.Label())() } } @@ -316,6 +298,8 @@ func (sched *Scheduler) updatePodInSchedulingQueue(oldPod, newPod *v1.Pod) { _ = sched.syncPodWithDispatcher(newPod) } + sched.Cache.UpdatePodGroupMember(logger, oldPod, newPod) + isAssumed, err := sched.Cache.IsAssumedPod(newPod) if err != nil { utilruntime.HandleErrorWithLogger(logger, err, "Failed to check whether pod is assumed", "pod", klog.KObj(newPod)) @@ -330,7 +314,7 @@ func (sched *Scheduler) updatePodInSchedulingQueue(oldPod, newPod *v1.Pod) { } logger.V(4).Info("Update event for unscheduled pod", "pod", klog.KObj(newPod)) - sched.SchedulingQueue.Update(logger, oldPod, newPod) + sched.SchedulingQueue.Update(klog.NewContext(context.Background(), logger), oldPod, newPod) if hasNominatedNodeNameChanged(oldPod, newPod) { // Nominated node changed in pod, so we need to treat it as if the pod was deleted from the old nominated node, // because the scheduler treats such a pod as if it was already assigned when scheduling lower or equal priority pods. @@ -344,8 +328,7 @@ func hasNominatedNodeNameChanged(oldPod, newPod *v1.Pod) bool { } func (sched *Scheduler) deletePodFromSchedulingQueue(pod *v1.Pod, inBinding bool) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodDelete.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), framework.EventUnscheduledPodDelete.Label())() logger := sched.logger @@ -358,6 +341,7 @@ func (sched *Scheduler) deletePodFromSchedulingQueue(pod *v1.Pod, inBinding bool // once the https://github.com/kubernetes/kubernetes/issues/134859 is fixed. return } + sched.Cache.RemovePodGroupMember(pod) isAssumed, err := sched.Cache.IsAssumedPod(pod) if err != nil { utilruntime.HandleErrorWithLogger(logger, err, "Failed to check whether pod is assumed", "pod", klog.KObj(pod)) @@ -383,8 +367,7 @@ func getLEPriorityPreCheck(priority int32) queue.PreEnqueueCheck { } func (sched *Scheduler) addAssignedPodToCache(pod *v1.Pod) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodAdd.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), framework.EventAssignedPodAdd.Label())() logger := sched.logger @@ -411,7 +394,7 @@ func (sched *Scheduler) addAssignedPodToCache(pod *v1.Pod) { func (sched *Scheduler) updateAssignedPodInCache(oldPod, newPod *v1.Pod) { start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodUpdate.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(start, framework.EventAssignedPodUpdate.Label())() logger := sched.logger @@ -453,8 +436,7 @@ func (sched *Scheduler) updateAssignedPodInCache(oldPod, newPod *v1.Pod) { } func (sched *Scheduler) deleteAssignedPodFromCache(pod *v1.Pod) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodDelete.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), framework.EventAssignedPodDelete.Label())() logger := sched.logger @@ -538,8 +520,7 @@ func addAllEventHandlers( if at&fwk.Add != 0 { evt := fwk.ClusterEvent{Resource: resource, ActionType: fwk.Add} funcs.AddFunc = func(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) + defer metrics.EventHandlingLatency.ObserveSince(time.Now(), evt.Label())() if resource == fwk.StorageClass && !utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { sc, ok := obj.(*storagev1.StorageClass) if !ok { @@ -683,10 +664,10 @@ func addAllEventHandlers( return err } handlers = append(handlers, handlerRegistration) - case fwk.Workload: + case fwk.PodGroup: if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { - if handlerRegistration, err = informerFactory.Scheduling().V1alpha1().Workloads().Informer().AddEventHandler( - buildEvtResHandler(at, fwk.Workload), + if handlerRegistration, err = informerFactory.Scheduling().V1alpha2().PodGroups().Informer().AddEventHandler( + buildEvtResHandler(at, fwk.PodGroup), ); err != nil { return err } @@ -754,8 +735,9 @@ func preCheckForNode(logger klog.Logger, nodeInfo *framework.NodeInfo) queue.Pre func AdmissionCheck(pod *v1.Pod, nodeInfo *framework.NodeInfo, includeAllFailures bool) []AdmissionResult { var admissionResults []AdmissionResult insufficientResources := noderesources.Fits(pod, nodeInfo, nil, noderesources.ResourceRequestsOptions{ - EnablePodLevelResources: utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), - EnableDRAExtendedResource: utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource), + EnablePodLevelResources: utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), + EnableDRAExtendedResource: utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource), + EnableDRANodeAllocatableResources: utilfeature.DefaultFeatureGate.Enabled(features.DRANodeAllocatableResources), }) if len(insufficientResources) != 0 { for i := range insufficientResources { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go index 690bce50d2..31b7872535 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go @@ -36,6 +36,16 @@ type CycleState struct { skipScorePlugins sets.Set[string] // skipPreBindPlugins are plugins that will be skipped in the PreBind extension point. skipPreBindPlugins sets.Set[string] + // skipAllPostFilterPlugins indicates whether to skip all plugins in the PostFilter extension point. + skipAllPostFilterPlugins bool + // GetParallelPreBindPlugins returns plugins that can be run in parallel with other plugins + // in the PreBind extension point. + parallelPreBindPlugins sets.Set[string] + // podGroupCycleState contains the CycleState for this pod's PodGroup. + // If set to nil, it means that the pod referencing this CycleState either passed the pod group cycle + // or doesn't belong to any pod group. + // This field can only be non-nil when GenericWorkload feature flag is enabled. + podGroupCycleState fwk.PodGroupCycleState } // NewCycleState initializes a new CycleState and returns its pointer. @@ -83,6 +93,34 @@ func (c *CycleState) GetSkipPreBindPlugins() sets.Set[string] { return c.skipPreBindPlugins } +func (c *CycleState) SetParallelPreBindPlugins(plugins sets.Set[string]) { + c.parallelPreBindPlugins = plugins +} + +func (c *CycleState) GetParallelPreBindPlugins() sets.Set[string] { + return c.parallelPreBindPlugins +} + +func (c *CycleState) IsPodGroupSchedulingCycle() bool { + return c.podGroupCycleState != nil +} + +func (c *CycleState) SetPodGroupSchedulingCycle(podGroupCycleState fwk.PodGroupCycleState) { + c.podGroupCycleState = podGroupCycleState +} + +func (c *CycleState) GetPodGroupSchedulingCycle() fwk.PodGroupCycleState { + return c.podGroupCycleState +} + +func (c *CycleState) SetSkipAllPostFilterPlugins(flag bool) { + c.skipAllPostFilterPlugins = flag +} + +func (c *CycleState) ShouldSkipAllPostFilterPlugins() bool { + return c.skipAllPostFilterPlugins +} + // Clone creates a copy of CycleState and returns its pointer. Clone returns // nil if the context being cloned is nil. func (c *CycleState) Clone() fwk.CycleState { @@ -100,6 +138,9 @@ func (c *CycleState) Clone() fwk.CycleState { copy.skipFilterPlugins = c.skipFilterPlugins copy.skipScorePlugins = c.skipScorePlugins copy.skipPreBindPlugins = c.skipPreBindPlugins + copy.parallelPreBindPlugins = c.parallelPreBindPlugins + copy.podGroupCycleState = c.podGroupCycleState + copy.skipAllPostFilterPlugins = c.skipAllPostFilterPlugins return copy } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go index bca3dfab90..bbdfa4890c 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go @@ -21,8 +21,10 @@ package framework import ( "context" "sync" + "time" v1 "k8s.io/api/core/v1" + "k8s.io/api/scheduling/v1alpha2" "k8s.io/apimachinery/pkg/util/sets" fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/apis/config" @@ -159,6 +161,16 @@ type SortedScoredNodes interface { Len() int } +// PodGroupPostFilterPlugin is an interface for plugins that are called +// after a PodGroup cannot be scheduled. +// It should not be used by any other plugin but DefaultPreemption. +type PodGroupPostFilterPlugin interface { + fwk.Plugin + + // PodGroupPostFilter is called after a PodGroup cannot be scheduled. + PodGroupPostFilter(ctx context.Context, pg *v1alpha2.PodGroup, pods []*v1.Pod, pgSchedulingFunc func(ctx context.Context) *fwk.Status) *fwk.Status +} + // Framework manages the set of plugins in use by the scheduling framework. // Configured plugins are called at specified points in a scheduling context. type Framework interface { @@ -173,12 +185,12 @@ type Framework interface { // QueueSortFunc returns the function to sort pods in scheduling queue QueueSortFunc() fwk.LessFunc - // Create a scheduling signature for a given pod, if possible. Two pods with the same signature + // SignPod creates a scheduling signature for a given pod, if possible. Two pods with the same signature // should get the same feasibility and scores for any given set of nodes even after one of them gets assigned. If some plugins // are unable to create a signature, the pod may be "unsignable" which disables results caching // and gang scheduling optimizations. // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/5598-opportunistic-batching - SignPod(ctx context.Context, pod *v1.Pod, recordPluginStats bool) fwk.PodSignature + SignPod(ctx context.Context, pod *v1.Pod) fwk.PodSignature // RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns // *fwk.Status and its code is set to non-success if any of the plugins returns @@ -197,15 +209,19 @@ type Framework interface { // cluster state to make the pod potentially schedulable in a future scheduling cycle. RunPostFilterPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, filteredNodeStatusMap fwk.NodeToStatusReader) (*fwk.PostFilterResult, *fwk.Status) - // Get a "node hint" for a given pod. A node hint is the name of a node provided by the batching code when information + // GetNodeHint returns a "node hint" for a given pod. A node hint is the name of a node provided by the batching code when information // from the previous scheduling cycle can be reused for this cycle. // If the batching code cannot provide a hint, the function returns "". // See git.k8s.io/enhancements/keps/sig-scheduling/5598-opportunistic-batching - GetNodeHint(ctx context.Context, pod *v1.Pod, state fwk.CycleState, cycleCount int64) (hint string, signature fwk.PodSignature) + GetNodeHint(ctx context.Context, pod *v1.Pod, signature fwk.PodSignature, state fwk.CycleState, cycleCount int64) string // StoreScheduleResults stores the results after we have sorted and filtered nodes. StoreScheduleResults(ctx context.Context, signature fwk.PodSignature, hintedNode, chosenNode string, otherNodes SortedScoredNodes, cycleCount int64) + // RunPlacementGeneratePlugins runs the set of configured PlacementGenerate plugins. + // It returns the combined list of generated Placements. + RunPlacementGeneratePlugins(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, nodes []fwk.NodeInfo) ([]*fwk.Placement, *fwk.Status) + // RunPreBindPlugins runs the set of configured PreBind plugins. It returns // *fwk.Status and its code is set to non-success if any of the plugins returns // anything but Success. If the Status code is "Unschedulable", it is @@ -233,10 +249,15 @@ type Framework interface { // RunPermitPlugins runs the set of configured Permit plugins. If any of these // plugins returns a status other than "Success" or "Wait", it does not continue // running the remaining plugins and returns an error. Otherwise, if any of the - // plugins returns "Wait", then this function will create and add waiting pod - // to a map of currently waiting pods and return status with "Wait" code. + // plugins returns "Wait", then this function will construct the pluginsWaitTime and return status with "Wait" code. + // This function itself will NOT create a waiting pod object and the caller should call AddWaitingPod method to do this. + RunPermitPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) (pluginsWaitTime map[string]time.Duration, status *fwk.Status) + + // AddWaitingPod creates a waiting pod instance and adds it to the framework. + // It takes the pluginsWaitTime map returned by the RunPermitPlugins. // Pod will remain waiting pod for the minimum duration returned by the Permit plugins. - RunPermitPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status + // This method should only be called when RunPermitPlugins returns a Wait status and WaitOnPermit is expected to execute soon. + AddWaitingPod(pod *v1.Pod, pluginsWaitTime map[string]time.Duration) // WillWaitOnPermit returns whether this pod will wait on permit by checking if the pod is a waiting pod. WillWaitOnPermit(ctx context.Context, pod *v1.Pod) bool @@ -251,6 +272,12 @@ type Framework interface { // code=5("skip") status. RunBindPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status + // RunPlacementScorePlugins runs the set of configured placement scoring plugins. + // It returns a list that stores scores from each plugin and total score for each Placement. + // It also returns *Status, which is set to non-success if any of the plugins returns + // a non-success status. + RunPlacementScorePlugins(ctx context.Context, state fwk.PodGroupCycleState, podGroupInfo fwk.PodGroupInfo, placements []*fwk.PodGroupAssignments) (ns []fwk.PlacementPluginScores, status *fwk.Status) + // HasFilterPlugins returns true if at least one Filter plugin is defined. HasFilterPlugins() bool @@ -260,6 +287,9 @@ type Framework interface { // HasScorePlugins returns true if at least one Score plugin is defined. HasScorePlugins() bool + // PodGroupPostFilterPlugins returns registered PodGroupPostFilter plugins. + PodGroupPostFilterPlugins() []PodGroupPostFilterPlugin + // ListPlugins returns a map of extension point name to list of configured Plugins. ListPlugins() *config.Plugins diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go deleted file mode 100644 index 2eff825bae..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2019 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 parallelize - -import "context" - -// ErrorChannel supports non-blocking send and receive operation to capture error. -// A maximum of one error is kept in the channel and the rest of the errors sent -// are ignored, unless the existing error is received and the channel becomes empty -// again. -type ErrorChannel struct { - errCh chan error -} - -// SendError sends an error without blocking the sender. -func (e *ErrorChannel) SendError(err error) { - select { - case e.errCh <- err: - default: - } -} - -// SendErrorWithCancel sends an error without blocking the sender and calls -// cancel function. -func (e *ErrorChannel) SendErrorWithCancel(err error, cancel context.CancelFunc) { - e.SendError(err) - cancel() -} - -// ReceiveError receives an error from channel without blocking on the receiver. -func (e *ErrorChannel) ReceiveError() error { - select { - case err := <-e.errCh: - return err - default: - return nil - } -} - -// NewErrorChannel returns a new ErrorChannel. -func NewErrorChannel() *ErrorChannel { - return &ErrorChannel{ - errCh: make(chan error, 1), - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/result_channel.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/result_channel.go new file mode 100644 index 0000000000..fd0981e9be --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/result_channel.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 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 parallelize + +import "context" + +// ResultChannel supports non-blocking send and receive operation to capture result. +// A maximum of one result is kept in the channel and the rest of the results sent +// are ignored, unless the existing result is received and the channel becomes empty +// again. +type ResultChannel[T comparable] struct { + ch chan T +} + +// Send sends a result without blocking the sender. +func (e *ResultChannel[T]) Send(result T) { + select { + case e.ch <- result: + default: + } +} + +// SendWithCancel sends a result without blocking the sender and calls +// cancel function. +func (e *ResultChannel[T]) SendWithCancel(result T, cancel context.CancelFunc) { + e.Send(result) + cancel() +} + +// Receive receives a result from channel without blocking on the receiver. +func (e *ResultChannel[T]) Receive() T { + select { + case result := <-e.ch: + return result + default: + var zeroValue T + return zeroValue + } +} + +// NewResultChannel returns a new ResultChannel. +func NewResultChannel[T comparable]() *ResultChannel[T] { + return &ResultChannel[T]{ + ch: make(chan T, 1), + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go index bc3d55b49e..d35ea3b308 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go @@ -24,9 +24,11 @@ import ( v1 "k8s.io/api/core/v1" policy "k8s.io/api/policy/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/listers/scheduling/v1alpha2" corev1helpers "k8s.io/component-helpers/scheduling/corev1" "k8s.io/klog/v2" extenderv1 "k8s.io/kube-scheduler/extender/v1" @@ -62,10 +64,14 @@ type MoreImportantPodFunc func(pod1, pod2 *v1.Pod) bool // DefaultPreemption is a PostFilter plugin implements the preemption logic. type DefaultPreemption struct { - fh fwk.Handle - fts feature.Features - args config.DefaultPreemptionArgs - Evaluator *preemption.Evaluator + fh fwk.Handle + fts feature.Features + args config.DefaultPreemptionArgs + + Executor *preemption.Executor + Evaluator *preemption.Evaluator + pgLister v1alpha2.PodGroupLister + podGroupEvaluator *preemption.PodGroupEvaluator // IsEligiblePod returns whether a victim pod is allowed to be preempted by a preemptor pod. // This filtering is in addition to the internal requirement that the victim pod have lower @@ -103,7 +109,15 @@ func New(_ context.Context, dpArgs runtime.Object, fh fwk.Handle, fts feature.Fe fts: fts, args: *args, } - pl.Evaluator = preemption.NewEvaluator(Name, fh, &pl, fts.EnableAsyncPreemption) + pl.Executor = preemption.NewExecutor(fh, fts) + pl.Evaluator = preemption.NewEvaluator(Name, fh, &pl, pl.Executor) + + if pl.fts.EnableWorkloadAwarePreemption || pl.fts.EnableTopologyAwareWorkloadScheduling { + pl.pgLister = fh.SharedInformerFactory().Scheduling().V1alpha2().PodGroups().Lister() + } + if pl.fts.EnableWorkloadAwarePreemption { + pl.podGroupEvaluator = preemption.NewPodGroupEvaluator(fh, pl.Executor) + } // Default behavior: No additional filtering, beyond the internal requirement that the victim pod // have lower priority than the preemptor pod. @@ -123,6 +137,23 @@ func (pl *DefaultPreemption) PostFilter(ctx context.Context, state fwk.CycleStat metrics.PreemptionAttempts.Inc() }() + if pod.Spec.SchedulingGroup != nil && pl.fts.EnableTopologyAwareWorkloadScheduling { + pg, err := pl.pgLister.PodGroups(pod.Namespace).Get(*pod.Spec.SchedulingGroup.PodGroupName) + if err != nil { + return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: pod group for pod not found") + } + if pg.Spec.SchedulingConstraints != nil { + // When TAS is enabled, the default preemption logic needs to be disabled to avoid performing preemption multiple times for each topology option. + // The TAS-compatible preemption logic will be implemented in Delayed Preemption KEP 4671 or Workload-aware preemption KEP 5710 features. + return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to placement-based pod group scheduling limitation") + } + } + if pod.Spec.SchedulingGroup != nil && pl.fts.EnableWorkloadAwarePreemption { + // When WAP is enabled, the default preemption logic needs to be disabled for pod group scheduling to avoid performing preemption in pod by pod cycle + // of pod group scheduling. Instead the WAP will be called to perform preemption for the entire pod group. + return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to workload aware preemption enabled") + } + result, status := pl.Evaluator.Preempt(ctx, state, pod, m) msg := status.Message() if len(msg) > 0 { @@ -135,7 +166,20 @@ func (pl *DefaultPreemption) PreEnqueue(ctx context.Context, p *v1.Pod) *fwk.Sta if !pl.fts.EnableAsyncPreemption { return nil } - if pl.Evaluator.IsPodRunningPreemption(p.GetUID()) { + if p.Spec.SchedulingGroup != nil && pl.fts.EnableWorkloadAwarePreemption { + pg, err := pl.pgLister.PodGroups(p.Namespace).Get(*p.Spec.SchedulingGroup.PodGroupName) + // If the pg is not found do not block the pod. It's not a default preemption responsibility + // to block pods from pod group without pg from entering the queue. + if err != nil { + return nil + } + if pl.Executor.IsPodGroupRunningPreemption(pg.GetUID()) { + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "waiting for the preemption for this pod group to be finished") + } + return nil + } + + if pl.Executor.IsPodRunningPreemption(p.GetUID()) { return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "waiting for the preemption for this pod to be finished") } return nil @@ -235,9 +279,11 @@ func (pl *DefaultPreemption) SelectVictimsOnNode( for _, pi := range nodeInfo.GetPods() { if pl.isPreemptionAllowed(nodeInfo, pi, pod) { potentialVictims = append(potentialVictims, pi) - if err := removePod(pi); err != nil { - return nil, 0, fwk.AsStatus(err) - } + } + } + for _, pi := range potentialVictims { + if err := removePod(pi); err != nil { + return nil, 0, fwk.AsStatus(err) } } @@ -417,3 +463,8 @@ func filterPodsWithPDBViolation(podInfos []fwk.PodInfo, pdbs []*policy.PodDisrup } return violatingPodInfos, nonViolatingPodInfos } + +// PodGroupPostFilter runs a default preemption for the pod group. +func (pl *DefaultPreemption) PodGroupPostFilter(ctx context.Context, pg *schedulingapi.PodGroup, pods []*v1.Pod, pgSchedulingFunc func(ctx context.Context) *fwk.Status) *fwk.Status { + return pl.podGroupEvaluator.Preempt(ctx, pg, pods, pgSchedulingFunc) +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go index 21d192ffc8..f74e466a40 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go @@ -120,6 +120,13 @@ func (a *allocatedDevices) Get() (sets.Set[structured.DeviceID], int64) { return a.ids.Clone(), a.revision } +func (a *allocatedDevices) GetSharedDeviceIDs() (sets.Set[structured.SharedDeviceID], int64) { + a.mutex.RLock() + defer a.mutex.RUnlock() + + return a.shareIDs.Clone(), a.revision +} + func (a *allocatedDevices) Capacities() (structured.ConsumedCapacityCollection, int64) { a.mutex.RLock() defer a.mutex.RUnlock() diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/claims.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/claims.go index cb2c15efc9..66968a374d 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/claims.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/claims.go @@ -20,6 +20,7 @@ import ( "fmt" "iter" + v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" "k8s.io/apimachinery/pkg/types" ) @@ -32,6 +33,10 @@ import ( type claimStore struct { // claims contains all user-owned claims, optionally followed by the special ResourceClaim for extended resources. claims []*resourceapi.ResourceClaim + // bindTo lists the objects to which each of the claims should be bound: + // either a Pod or its PodGroup. It is always empty when PodGroup claims are + // disabled. + bindTo []resourceapi.ResourceClaimConsumerReference // numUserOwned is the number of claims without the special ResourceClaim. numUserOwned int // initialExtendedResourceClaimUID is the initial extended resource claim UID from PreFilter phase. @@ -40,9 +45,10 @@ type claimStore struct { } // newClaimStore stores the list of user-owned claims and the optional claim owned by the scheduler. -func newClaimStore(claims []*resourceapi.ResourceClaim, extendedResourceClaim *resourceapi.ResourceClaim) claimStore { +func newClaimStore(claims []*resourceapi.ResourceClaim, extendedResourceClaim *resourceapi.ResourceClaim, claimBindings []resourceapi.ResourceClaimConsumerReference) claimStore { cs := claimStore{ claims: claims, + bindTo: claimBindings, numUserOwned: len(claims), initialExtendedResourceClaimUID: "", } @@ -127,6 +133,21 @@ func (cs claimStore) set(i int, c *resourceapi.ResourceClaim) { cs.claims[i] = c } +// getBinding returns a reference to the object to which the ResourceClaim at +// the given index should be bound: either a Pod or its PodGroup. For extended +// resource claims, it always returns a reference to the Pod. +func (cs claimStore) getBinding(i int, pod *v1.Pod) resourceapi.ResourceClaimConsumerReference { + if i >= len(cs.bindTo) { + return resourceapi.ResourceClaimConsumerReference{ + APIGroup: v1.GroupName, + Resource: "pods", + Name: pod.Name, + UID: pod.UID, + } + } + return cs.bindTo[i] +} + // updateExtendedResourceClaim updates the input claim as extended resource // claim in the internal claims slice. // It returns error when there is no extended resource claim in the internal diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go index 2be14d10ec..a1703319f6 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go @@ -20,18 +20,26 @@ import ( "context" "errors" "fmt" + "iter" + "slices" "sync" + "github.com/go-logr/logr" + resourceapi "k8s.io/api/resource/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" resourcelisters "k8s.io/client-go/listers/resource/v1" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" "k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache" resourceslicetracker "k8s.io/dynamic-resource-allocation/resourceslice/tracker" "k8s.io/dynamic-resource-allocation/structured" + "k8s.io/dynamic-resource-allocation/structured/schedulerapi" "k8s.io/klog/v2" fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/features" @@ -47,6 +55,7 @@ type DefaultDRAManager struct { resourceClaimTracker *claimTracker resourceSliceLister *resourceSliceLister deviceClassLister *deviceClassLister + podGroupLister *podGroupLister extendedResourceCache *extendedresourcecache.ExtendedResourceCache } @@ -55,7 +64,7 @@ func NewDRAManager(ctx context.Context, claimsCache *assumecache.AssumeCache, re manager := &DefaultDRAManager{ resourceClaimTracker: &claimTracker{ cache: claimsCache, - inFlightAllocations: &sync.Map{}, + inFlightAllocations: make(map[types.UID]inFlightAllocation), allocatedDevices: newAllocatedDevices(logger), logger: logger, }, @@ -67,6 +76,12 @@ func NewDRAManager(ctx context.Context, claimsCache *assumecache.AssumeCache, re manager.extendedResourceCache = extendedresourcecache.NewExtendedResourceCache(logger) } + pgLister := &podGroupLister{} + if utilfeature.DefaultFeatureGate.Enabled(features.DRAWorkloadResourceClaims) { + pgLister.podGroupLister = informerFactory.Scheduling().V1alpha2().PodGroups().Lister() + } + manager.podGroupLister = pgLister + // Reacting to events is more efficient than iterating over the list // repeatedly in PreFilter. manager.resourceClaimTracker.cache.AddEventHandler(manager.resourceClaimTracker.allocatedDevices.handlers()) @@ -86,6 +101,10 @@ func (s *DefaultDRAManager) DeviceClasses() fwk.DeviceClassLister { return s.deviceClassLister } +func (s *DefaultDRAManager) PodGroups() fwk.PodGroupLister { + return s.podGroupLister +} + // DeviceClassResolver will always return a valid interface implementation. It // wraps a nil extendedresourcecache.ExtendedResourceCache if the feature is // disabled. @@ -120,6 +139,21 @@ func (l *deviceClassLister) List() ([]*resourceapi.DeviceClass, error) { return l.classLister.List(labels.Everything()) } +var _ fwk.PodGroupLister = &podGroupLister{} + +type podGroupLister struct { + podGroupLister schedulinglisters.PodGroupLister +} + +// Get implements [fwk.PodGroupLister]. When the inner podGroupLister is nil, +// Get always returns a new BadRequest error. +func (l *podGroupLister) Get(namespace, podGroupName string) (*schedulingapi.PodGroup, error) { + if l.podGroupLister == nil { + return nil, apierrors.NewBadRequest("listing podgroups is disabled") + } + return l.podGroupLister.PodGroups(namespace).Get(podGroupName) +} + var _ fwk.ResourceClaimTracker = &claimTracker{} type claimTracker struct { @@ -142,12 +176,16 @@ type claimTracker struct { // - would make integration with cluster autoscaler harder because it would need // to trigger informer callbacks. cache *assumecache.AssumeCache + // inFlightMutex syncs access to inFlightAllocations. + inFlightMutex sync.RWMutex // inFlightAllocations is a map from claim UUIDs to claim objects for those claims // for which allocation was triggered during a scheduling cycle and the // corresponding claim status update call in PreBind has not been done - // yet. If another pod needs the claim, the pod is treated as "not - // schedulable yet". The cluster event for the claim status update will - // make it schedulable. + // yet. It also includes a reference count tracking how many actively + // scheduling Pods in a PodGroup are using that pending allocation. If + // another pod outside the PodGroup needs the claim, the pod is treated as + // "not schedulable yet". For those pods, the cluster event for the + // claim status update will make them schedulable. // // This mechanism avoids the following problem: // - Pod A triggers allocation for claim X. @@ -161,37 +199,92 @@ type claimTracker struct { // problem: // - Pod A and B get scheduled as above. // - PreBind for pod A gets called first, then fails with a temporary API error. - // It removes the updated claim from the assume cache because of that. + // It removes the updated claim from the in-flight claims because of that. // - PreBind for pod B gets called next and succeeds with adding the // allocation and its own reservedFor entry. // - The assume cache is now not reflecting that the claim is allocated, // which could lead to reusing the same resource for some other claim. // + // For pods in a PodGroup, a pending allocation may be shared among several + // pods in the group. In the PreBind phase, the allocation will be written + // for the first pod that succeeds. The scenario above is prevented by + // keeping the pending allocation in-flight as long as it has not been + // unreserved for every pod in the group, as tracked by + // inFlightAllocationSharers. + // // A sync.Map is used because in practice sharing of a claim between // pods is expected to be rare compared to per-pod claim, so we end up // hitting the "multiple goroutines read, write, and overwrite entries // for disjoint sets of keys" case that sync.Map is optimized for. - inFlightAllocations *sync.Map + inFlightAllocations map[types.UID]inFlightAllocation allocatedDevices *allocatedDevices logger klog.Logger } -func (c *claimTracker) ClaimHasPendingAllocation(claimUID types.UID) bool { - _, found := c.inFlightAllocations.Load(claimUID) - return found +type inFlightAllocation struct { + claim *resourceapi.ResourceClaim + sharers int +} + +func (c *claimTracker) GetPendingAllocation(claimUID types.UID) *resourceapi.AllocationResult { + c.inFlightMutex.RLock() + defer c.inFlightMutex.RUnlock() + + inFlight, found := c.inFlightAllocations[claimUID] + if !found || inFlight.claim == nil { + return nil + } + return inFlight.claim.Status.Allocation } func (c *claimTracker) SignalClaimPendingAllocation(claimUID types.UID, allocatedClaim *resourceapi.ResourceClaim) error { - c.inFlightAllocations.Store(claimUID, allocatedClaim) + c.inFlightMutex.Lock() + defer c.inFlightMutex.Unlock() + + inFlight, found := c.inFlightAllocations[claimUID] + if found { + inFlight.sharers++ + c.inFlightAllocations[claimUID] = inFlight + + claim := inFlight.claim + c.logger.V(5).Info("Added share for in-flight claim", "claim", klog.KObj(claim), "uid", claimUID, "version", claim.ResourceVersion, "sharers", inFlight.sharers) + return nil + } + + c.inFlightAllocations[claimUID] = inFlightAllocation{ + claim: allocatedClaim, + sharers: 1, + } + // This is the same verbosity as the corresponding log in the assume cache. + c.logger.V(5).Info("Added in-flight claim", "claim", klog.KObj(allocatedClaim), "uid", claimUID, "version", allocatedClaim.ResourceVersion) // There's no reason to return an error in this implementation, but the error is helpful for other implementations. // For example, implementations that have to deal with fake claims might want to return an error if the allocation // is for an invalid claim. return nil } -func (c *claimTracker) RemoveClaimPendingAllocation(claimUID types.UID) (deleted bool) { - _, found := c.inFlightAllocations.LoadAndDelete(claimUID) - return found +func (c *claimTracker) MaybeRemoveClaimPendingAllocation(claimUID types.UID, forceRemove bool) (deleted bool) { + c.inFlightMutex.Lock() + defer c.inFlightMutex.Unlock() + + inFlight, found := c.inFlightAllocations[claimUID] + // The assume cache doesn't log this, but maybe it should. + if !found { + c.logger.V(5).Info("Redundant remove of in-flight claim, not found", "uid", claimUID) + return false + } + claim := inFlight.claim + + if forceRemove || inFlight.sharers == 1 { + delete(c.inFlightAllocations, claimUID) + c.logger.V(5).Info("Removed in-flight claim", "claim", klog.KObj(claim), "uid", claimUID, "version", claim.ResourceVersion) + return true + } + + inFlight.sharers-- + c.inFlightAllocations[claimUID] = inFlight + c.logger.V(5).Info("Claim is still shared by other pods, not removing in-flight claim", "claim", klog.KObj(claim), "uid", claimUID, "version", claim.ResourceVersion, "sharers", inFlight.sharers) + return false } func (c *claimTracker) Get(namespace, claimName string) (*resourceapi.ResourceClaim, error) { @@ -238,20 +331,24 @@ func (c *claimTracker) List() ([]*resourceapi.ResourceClaim, error) { // so we don't need to re-check the in-flight claims. var errClaimTrackerConcurrentModification = errors.New("conflicting concurrent modification") -func (c *claimTracker) ListAllAllocatedDevices() (sets.Set[structured.DeviceID], error) { +func (c *claimTracker) ListAllAllocatedDevices() (a sets.Set[structured.DeviceID], err error) { + c.logger.V(6).Info("Starting ListAllAllocatedDevices") + defer func() { + c.logger.V(6).Info("Finished ListAllAllocatedDevices", "allocatedDevices", logAllocatedDevices(c.logger, a), "err", err) + }() + // Start with a fresh set that matches the current known state of the // world according to the informers. allocated, revision := c.allocatedDevices.Get() // Whatever is in flight also has to be checked. - c.inFlightAllocations.Range(func(key, value any) bool { - claim := value.(*resourceapi.ResourceClaim) + for _, inFlight := range c.allInFlightAllocationsRLocked() { + claim := inFlight.claim foreachAllocatedDevice(claim, func(deviceID structured.DeviceID) { c.logger.V(6).Info("Device is in flight for allocation", "device", deviceID, "claim", klog.KObj(claim)) allocated.Insert(deviceID) }, false, func(structured.SharedDeviceID) {}, func(structured.DeviceConsumedCapacity) {}) - return true - }) + } if revision == c.allocatedDevices.Revision() { // Our current result is valid, nothing changed in the meantime. @@ -261,38 +358,79 @@ func (c *claimTracker) ListAllAllocatedDevices() (sets.Set[structured.DeviceID], return nil, errClaimTrackerConcurrentModification } -func (c *claimTracker) GatherAllocatedState() (*structured.AllocatedState, error) { +// GatherAllocatedState collects and returns the current allocation state of all devices +// across the cluster. This includes: +// - AllocatedDevices: Set of device IDs that are fully allocated (dedicated mode) +// - AllocatedSharedDeviceIDs: Set of shared device IDs when consumable capacity is enabled +// - AggregatedCapacity: Consumed capacity across all devices when consumable capacity is enabled +// +// The function handles two allocation models: +// 1. Legacy dedicated mode (DRAConsumableCapacity disabled): Devices are allocated exclusively +// to a single claim. Shared devices are converted to their base device IDs. +// 2. Consumable capacity mode (DRAConsumableCapacity enabled): Devices can be shared across +// multiple claims with capacity tracking. +// +// The function ensures consistency by: +// - Reading allocation state from informer-backed cache +// - Including in-flight allocations that haven't been persisted yet +// - Using revision numbers to detect concurrent modifications and retry if needed +// +// Returns errClaimTrackerConcurrentModification if the state changed during collection, +// indicating the caller should retry. +func (c *claimTracker) GatherAllocatedState() (s *structured.AllocatedState, err error) { + c.logger.V(6).Info("Starting GatherAllocatedState") + defer func() { + var a sets.Set[structured.DeviceID] + if s != nil { + a = s.AllocatedDevices + } + c.logger.V(6).Info("Finished GatherAllocatedState", "allocatedDevices", logAllocatedDevices(c.logger, a), "err", err) + }() + // Start with a fresh set that matches the current known state of the // world according to the informers. + enabledConsumableCapacity := utilfeature.DefaultFeatureGate.Enabled(features.DRAConsumableCapacity) + allocated, revision1 := c.allocatedDevices.Get() - allocatedSharedDeviceIDs := sets.New[structured.SharedDeviceID]() - aggregatedCapacity, revision2 := c.allocatedDevices.Capacities() + allocatedSharedDeviceIDs, revision2 := c.allocatedDevices.GetSharedDeviceIDs() + aggregatedCapacity, revision3 := c.allocatedDevices.Capacities() - if revision1 != revision2 { + if revision1 != revision2 || revision2 != revision3 { // Already not consistent. Try again. return nil, errClaimTrackerConcurrentModification } - enabledConsumableCapacity := utilfeature.DefaultFeatureGate.Enabled(features.DRAConsumableCapacity) + if !enabledConsumableCapacity { + // When the DRAConsumableCapacity feature is disabled, we fall back to the legacy + // dedicated device allocation model. + // This ensures backward compatibility with the original DRA behavior where devices + // could only be allocated exclusively to a single claim. + for sharedDeviceID := range allocatedSharedDeviceIDs { + allocated.Insert(sharedDeviceID.GetDeviceID()) + } + // Reset allocatedSharedDeviceIDs and aggregatedCapacity + allocatedSharedDeviceIDs = sets.New[structured.SharedDeviceID]() + aggregatedCapacity = make(schedulerapi.ConsumedCapacityCollection) + } // Whatever is in flight also has to be checked. - c.inFlightAllocations.Range(func(key, value any) bool { - claim := value.(*resourceapi.ResourceClaim) - foreachAllocatedDevice(claim, func(deviceID structured.DeviceID) { - c.logger.V(6).Info("Device is in flight for allocation", "device", deviceID, "claim", klog.KObj(claim)) - allocated.Insert(deviceID) - }, + for _, inFlight := range c.allInFlightAllocationsRLocked() { + claim := inFlight.claim + foreachAllocatedDevice(claim, + func(deviceID structured.DeviceID) { // dedicatedDeviceCallback + c.logger.V(6).Info("Device is in flight for allocation", "device", deviceID, "claim", klog.KObj(claim)) + allocated.Insert(deviceID) + }, enabledConsumableCapacity, - func(sharedDeviceID structured.SharedDeviceID) { + func(sharedDeviceID structured.SharedDeviceID) { // sharedDeviceCallback c.logger.V(6).Info("Device is in flight for allocation", "shared device", sharedDeviceID, "claim", klog.KObj(claim)) allocatedSharedDeviceIDs.Insert(sharedDeviceID) - }, func(capacity structured.DeviceConsumedCapacity) { + }, + func(capacity structured.DeviceConsumedCapacity) { // consumedCapacityCallback c.logger.V(6).Info("Device is in flight for allocation", "consumed capacity", capacity, "claim", klog.KObj(claim)) aggregatedCapacity.Insert(capacity) }) - return true - }) - + } if revision1 == c.allocatedDevices.Revision() { // Our current result is valid, nothing changed in the meantime. return &structured.AllocatedState{ @@ -305,6 +443,18 @@ func (c *claimTracker) GatherAllocatedState() (*structured.AllocatedState, error return nil, errClaimTrackerConcurrentModification } +func (c *claimTracker) allInFlightAllocationsRLocked() iter.Seq2[types.UID, inFlightAllocation] { + return func(yield func(types.UID, inFlightAllocation) bool) { + c.inFlightMutex.RLock() + defer c.inFlightMutex.RUnlock() + for uid, inFlight := range c.inFlightAllocations { + if !yield(uid, inFlight) { + return + } + } + } +} + func (c *claimTracker) AssumeClaimAfterAPICall(claim *resourceapi.ResourceClaim) error { return c.cache.Assume(claim) } @@ -312,3 +462,64 @@ func (c *claimTracker) AssumeClaimAfterAPICall(claim *resourceapi.ResourceClaim) func (c *claimTracker) AssumedClaimRestore(namespace, claimName string) { c.cache.Restore(namespace + "/" + claimName) } + +// At V(6), log only a limited number of devices to avoid blowing up logs. For +// many E2E tests, 10 devices is enough for all devices without having to +// truncate, at least when running the tests sequentially. +const maxDevicesLevel6 = 10 + +// logAllocatedDevices returns a handle for the value in a structured log call which +// includes varying amounts of information about the allocated devices, depending on +// the verbosity of the logger. +func logAllocatedDevices(logger klog.Logger, allocatedDevices sets.Set[structured.DeviceID]) any { + // We need to check verbosity here because our caller's source code + // location may be relevant (-vmodule !). + helper, logger := logger.WithCallStackHelper() + helper() + + // We always produce the same output at V <= 5. 6 adds all IDs. + verbosity := 5 + for i := 7; i > verbosity; i-- { + if loggerV := logger.V(i); loggerV.Enabled() { + verbosity = i + break + } + } + + return &allocatedDevicesLogger{verbosity, allocatedDevices} +} + +type allocatedDevicesLogger struct { + verbosity int + devices sets.Set[structured.DeviceID] +} + +var _ logr.Marshaler = &allocatedDevicesLogger{} + +func (a *allocatedDevicesLogger) MarshalLog() any { + if a.verbosity < 6 { + return nil + } + + info := struct { + Count int `json:"count"` + Devices []string `json:"devices"` + }{ + Count: len(a.devices), + } + ids := make([]string, 0, len(a.devices)) + for id := range a.devices { + ids = append(ids, id.String()) + } + slices.Sort(ids) + if a.verbosity == 6 && len(ids) > maxDevicesLevel6 { + truncated := make([]string, 0, maxDevicesLevel6+1) + truncated = append(truncated, ids[:maxDevicesLevel6/2]...) + truncated = append(truncated, "...") + truncated = append(truncated, ids[len(ids)-maxDevicesLevel6/2:]...) + ids = truncated + } + info.Devices = ids + + return info +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go index 75551dc980..c298b17666 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go @@ -28,6 +28,7 @@ import ( v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" apiequality "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" @@ -50,6 +51,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" + schedmetrics "k8s.io/kubernetes/pkg/scheduler/metrics" schedutil "k8s.io/kubernetes/pkg/scheduler/util" "k8s.io/utils/ptr" ) @@ -113,11 +115,32 @@ func (d *stateData) Clone() fwk.StateData { return d } +// This state is persisted in the PodGroup CycleState. Because we save the +// pointer in fwk.CycleState, in the later phases we don't need to call Write +// method to update the value. +type podGroupStateData struct { + // pendingAllocations stores the UIDs of ResourceClaims that are currently + // pending for *this* PodGroup scheduling cycle. The DRAManager continues to + // track inter-cycle sharing of pending allocations, including the + // allocations themselves and how many Pods are sharing them. + // + // It does not need to be protected by a lock because a PodGroup's + // CycleState is only available during synchronous scheduling phases and is + // cleared before asynchronous phases begin. + pendingAllocations sets.Set[types.UID] +} + +func (d *podGroupStateData) Clone() fwk.StateData { + return d +} + type informationForClaim struct { // Node selector based on the claim status if allocated. availableOnNodes *nodeaffinity.NodeSelector - // Set by Reserved, published by PreBind, empty if nothing had to be allocated. + // Set by Reserve, published by PreBind, empty if nothing had to be allocated. + // May be set by PreFilter if this allocation was made by a previous Pod's + // Reserve but not yet published in PreBind. allocation *resourceapi.AllocationResult } @@ -132,6 +155,9 @@ type nodeAllocation struct { // containerResourceRequestMappings has the container, extended resource, and device request mappings // calculated at the Filter phase, and used at the PreBind phase. containerResourceRequestMappings []v1.ContainerExtendedResourceRequest + // nodeAllocatableResourceClaimStatuses stores the calculated node allocatable resource allocations through DRA. + // This is populated during Filter stage and passed to PreBind. + nodeAllocatableResourceClaimStatuses []v1.NodeAllocatableResourceClaimStatus } // DynamicResources is a plugin that ensures that ResourceClaims are allocated. @@ -146,6 +172,11 @@ type DynamicResources struct { draManager fwk.SharedDRAManager } +var ( + ErrDeviceBindingTimeout = errors.New("device binding timeout") + ErrDeviceBindingFailed = errors.New("device binding failed") +) + // New initializes a new plugin and returns it. func New(ctx context.Context, plArgs runtime.Object, fh fwk.Handle, fts feature.Features) (fwk.Plugin, error) { if !fts.EnableDynamicResourceAllocation { @@ -174,7 +205,10 @@ func New(ctx context.Context, plArgs runtime.Object, fh fwk.Handle, fts feature. // This is a LRU cache for compiled CEL expressions. The most // recent 10 of them get reused across different scheduling // cycles. - celCache: cel.NewCache(10, cel.Features{EnableConsumableCapacity: fts.EnableDRAConsumableCapacity}), + celCache: cel.NewCache(10, cel.Features{ + EnableConsumableCapacity: fts.EnableDRAConsumableCapacity, + EnableListTypeAttributes: fts.EnableDRAListTypeAttributes, + }), draManager: fh.SharedDRAManager(), } @@ -361,6 +395,29 @@ func (pl *DynamicResources) podResourceClaims(pod *v1.Pod) ([]*resourceapi.Resou return claims, nil } +// podResourceClaimBindings returns a list of references to objects to which +// each of the Pod's claims should be bound, as recorded in ResourceClaims' +// Status.ReservedFor. References are either to the Pod itself or its PodGroup. +func (pl *DynamicResources) podResourceClaimBindings(pod *v1.Pod) ([]resourceapi.ResourceClaimConsumerReference, error) { + if !pl.fts.EnableDRAWorkloadResourceClaims { + return nil, nil + } + + bindings := make([]resourceapi.ResourceClaimConsumerReference, 0, len(pod.Spec.ResourceClaims)) + podGroup, err := pl.getPodGroup(pod) + if err != nil { + return nil, err + } + for _, podClaim := range pod.Spec.ResourceClaims { + bindTo, err := resourceclaim.BindTo(pod, podGroup, &podClaim) + if err != nil { + return nil, err + } + bindings = append(bindings, bindTo) + } + return bindings, nil +} + // foreachPodResourceClaim checks that each ResourceClaim for the pod exists. // It calls an optional handler for those claims that it finds. func (pl *DynamicResources) foreachPodResourceClaim(pod *v1.Pod, cb func(podResourceName string, claim *resourceapi.ResourceClaim)) error { @@ -385,7 +442,7 @@ func (pl *DynamicResources) foreachPodResourceClaim(pod *v1.Pod, cb func(podReso } if mustCheckOwner { - if err := resourceclaim.IsForPod(pod, claim); err != nil { + if err := resourceclaim.IsForPod(pod, claim, pl.fts.EnableDRAWorkloadResourceClaims); err != nil { return err } } @@ -412,6 +469,11 @@ func (pl *DynamicResources) PreFilter(ctx context.Context, state fwk.CycleState, s := &stateData{} state.Write(stateKey, s) + podGroupState, err := getPodGroupStateData(state) + if err != nil { + return nil, statusError(logger, err) + } + userClaims, err := pl.podResourceClaims(pod) if err != nil { return nil, statusUnschedulable(logger, err.Error()) @@ -421,7 +483,11 @@ func (pl *DynamicResources) PreFilter(ctx context.Context, state fwk.CycleState, if status != nil { return nil, status } - claims := newClaimStore(userClaims, extendedResourceClaim) + claimBindings, err := pl.podResourceClaimBindings(pod) + if err != nil { + return nil, statusUnschedulable(logger, err.Error()) + } + claims := newClaimStore(userClaims, extendedResourceClaim, claimBindings) // This check covers user and extended ResourceClaim. if claims.empty() { @@ -434,7 +500,7 @@ func (pl *DynamicResources) PreFilter(ctx context.Context, state fwk.CycleState, for index, claim := range claims.all() { if claim.Status.Allocation != nil && !resourceclaim.CanBeReserved(claim) && - !resourceclaim.IsReservedForPod(pod, claim) { + !resourceclaim.IsReservedForPod(pod, claim, pl.fts.EnableDRAWorkloadResourceClaims) { // Resource is in use. The pod has to wait. return nil, statusUnschedulable(logger, "resourceclaim in use", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) } @@ -450,10 +516,38 @@ func (pl *DynamicResources) PreFilter(ctx context.Context, state fwk.CycleState, } else { numClaimsToAllocate++ + // Gang scheduling works by waiting for all Pods in a gang to + // succeed through the Reserve phase, then binding all of the Pods. + // Since a claim's allocation is not recorded in [stateData.claims] + // until PreBind, we look for a pending allocation made in Reserve + // here to avoid blocking this Pod on waiting for the allocation to + // complete. + // + // Claims with pending allocations are considered "unallocated" in + // that the claim's Status.Allocation needs to be populated. Claims + // with pending allocations are not input to the allocator, though + // we numClaimsToAllocate increment to create an allocator anyway to + // signal that some claims need their status updated in PreBind. + // + // Currently, sharing is limited to a single PodGroup scheduling + // cycle. Ungrouped Pods and Pods across different PodGroup + // scheduling cycles cannot share claims with pending allocations + // for now to limit potential impact outside of the alpha + // GenericWorkload feature gate. Sharing claims this way more + // broadly may have benefits: + // https://github.com/kubernetes/kubernetes/issues/137932 + if podGroupState != nil && podGroupState.pendingAllocations.Has(claim.UID) { + if pendingAllocation := pl.draManager.ResourceClaims().GetPendingAllocation(claim.UID); pendingAllocation != nil { + s.informationsForClaim[index].allocation = pendingAllocation + logger.V(5).Info("reusing pending allocation", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim), "uid", claim.UID, "allocation", klog.Format(pendingAllocation)) + continue + } + } + // Allocation in flight? Better wait for that // to finish, see inFlightAllocations // documentation for details. - if pl.draManager.ResourceClaims().ClaimHasPendingAllocation(claim.UID) { + if pl.draManager.ResourceClaims().GetPendingAllocation(claim.UID) != nil { return nil, statusUnschedulable(logger, fmt.Sprintf("resource claim %s is in the process of being allocated", klog.KObj(claim))) } @@ -619,6 +713,29 @@ func getStateData(cs fwk.CycleState) (*stateData, error) { return s, nil } +func getPodGroupStateData(cs fwk.CycleState) (*podGroupStateData, error) { + podGroupCycleState := cs.GetPodGroupSchedulingCycle() + if podGroupCycleState == nil { + return nil, nil + } + state, err := podGroupCycleState.Read(stateKey) + if errors.Is(err, fwk.ErrNotFound) { + podGroupState := &podGroupStateData{ + pendingAllocations: make(sets.Set[types.UID]), + } + podGroupCycleState.Write(stateKey, podGroupState) + return podGroupState, nil + } + if err != nil { + return nil, err + } + s, ok := state.(*podGroupStateData) + if !ok { + return nil, errors.New("state is not podGroupStateData") + } + return s, nil +} + // Filter invoked at the filter extension point. // It evaluates if a pod can fit due to the resources it requests, // for both allocated and unallocated claims. @@ -675,14 +792,26 @@ func (pl *DynamicResources) Filter(ctx context.Context, cs fwk.CycleState, pod * // If the claim is not ready yet (ready false, no error) and binding has timed out // or binding has failed (err non-nil), then the scheduler should consider deallocating this // claim in PostFilter to unblock trying other devices. - if err != nil || !ready && pl.isClaimTimeout(claim) { + if err != nil { + logger.V(5).Info("Claim failed binding conditions check", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim), "err", err) + unavailableClaims = append(unavailableClaims, index) + } else if !ready && pl.isClaimTimeout(claim) { + logger.V(5).Info("Claim timed out waiting for binding conditions", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) unavailableClaims = append(unavailableClaims, index) } } - } + // The claim is allocated, check if its a node-allocatable resource claim that is already allocated. + if pl.fts.EnableDRANodeAllocatableResources { + status := pl.validateNodeAllocatableDRAClaimSharing(pod, nodeInfo, claim) + if status != nil { + return status + } + } + } // Use allocator to check the node and cache the result in case that the node is picked. var allocations []resourceapi.AllocationResult + var nodeAllocatableClaimStatus []v1.NodeAllocatableResourceClaimStatus if state.allocator != nil { allocCtx := ctx if loggerV := logger.V(5); loggerV.Enabled() { @@ -701,17 +830,31 @@ func (pl *DynamicResources) Filter(ctx context.Context, cs fwk.CycleState, pod * // This replaces the special ResourceClaim for extended resources with one // matching the node. claimsToAllocate := make([]*resourceapi.ResourceClaim, 0, state.claims.len()) + // pendingResult holds pending allocations that were made for a previous + // Pod in Reserve, but before that allocation is recorded in the status + // by PreBind. + var pendingResult []resourceapi.AllocationResult extendedResourceClaim := state.claims.extendedResourceClaim() - for _, claim := range state.claims.toAllocate() { + for index, claim := range state.claims.toAllocate() { if claim == extendedResourceClaim && nodeExtendedResourceClaim != nil { claim = nodeExtendedResourceClaim } + if state.informationsForClaim[index].allocation != nil { + pendingResult = append(pendingResult, *state.informationsForClaim[index].allocation) + continue + } claimsToAllocate = append(claimsToAllocate, claim) } - a, err := state.allocator.Allocate(allocCtx, node, claimsToAllocate) + allocationResult, err := state.allocator.Allocate(allocCtx, node, claimsToAllocate) switch { case errors.Is(err, context.DeadlineExceeded): - return statusUnschedulable(logger, "timed out trying to allocate devices", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(claimsToAllocate)) + // Timeouts are potentially transient. Return Error + // so the pod retries via backoff instead of sitting in the + // unschedulable queue waiting for a cluster event. + // + // The timeout might be caused by ResourceSlices for the node, + // so including the node name may help with diagnosing the failure. + return statusError(logger, fmt.Errorf("node %s: timed out trying to allocate devices", node.Name), "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(claimsToAllocate)) case errors.Is(err, structured.ErrFailedAllocationOnNode): // Not a fatal error, allocation on other nodes may proceed. // The error is only surfaced if allocation fails on all nodes. @@ -732,11 +875,27 @@ func (pl *DynamicResources) Filter(ctx context.Context, cs fwk.CycleState, pod * return statusError(logger, err, "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(claimsToAllocate)) } // Check for exact length just to be sure. In practice this is all-or-nothing. - if len(a) != len(claimsToAllocate) { + if len(allocationResult) != len(claimsToAllocate) { return statusUnschedulable(logger, "cannot allocate all claims", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(claimsToAllocate)) } + + if pl.fts.EnableDRANodeAllocatableResources { + allocationsMap := make(map[types.UID]*resourceapi.AllocationResult) + for i, claim := range claimsToAllocate { + allocationsMap[claim.UID] = &allocationResult[i] + } + for i, claim := range state.claims.toAllocate() { + if state.informationsForClaim[i].allocation != nil { + allocationsMap[claim.UID] = state.informationsForClaim[i].allocation + } + } + nodeAllocatableClaimStatus, status = pl.calculateAndCheckNodeAllocatableResources(ctx, state, pod, nodeInfo, allocationsMap) + if status != nil { + return status + } + } // Reserve uses this information. - allocations = a + allocations = append(allocationResult, pendingResult...) } // Store information in state while holding the mutex. @@ -761,9 +920,10 @@ func (pl *DynamicResources) Filter(ctx context.Context, cs fwk.CycleState, pod * if state.allocator != nil { state.nodeAllocations[node.Name] = nodeAllocation{ - allocationResults: allocations, - extendedResourceClaim: nodeExtendedResourceClaim, - containerResourceRequestMappings: containerResourceRequestMappings, + allocationResults: allocations, + extendedResourceClaim: nodeExtendedResourceClaim, + containerResourceRequestMappings: containerResourceRequestMappings, + nodeAllocatableResourceClaimStatuses: nodeAllocatableClaimStatus, } } @@ -821,16 +981,97 @@ func (pl *DynamicResources) PostFilter(ctx context.Context, cs fwk.CycleState, p // If the special resource claim for extended resource backed by DRA // is reserved or allocated at prior scheduling cycle, then it should be deleted. extendedResourceClaim := extendedResourceClaim.DeepCopy() - if err := pl.deleteClaim(ctx, extendedResourceClaim, logger); err != nil { + if err := pl.deleteClaim(ctx, extendedResourceClaim); err != nil { return nil, statusError(logger, err) } return nil, fwk.NewStatus(fwk.Unschedulable, "deletion of ResourceClaim completed") } + + // If we make it here we know that not all pods of the PodGroup could be scheduled. + // To let the scheduler try to find new devices in case binding the current allocation + // failed in some previous cycle, remove the PodGroup from its claims' status.reservedFor. + // Note that more Pods may exist than a PodGroup's minCount, but performing + // a cleanup after a previous cycle is safe as long as there are no assumed + // nor assigned pods yet. + if pl.fts.EnableDRAWorkloadResourceClaims { + status := pl.unreservePodGroupClaims(ctx, pod) + if status != nil { + return nil, status + } + } + return nil, fwk.NewStatus(fwk.Unschedulable, "still not schedulable") } +func (pl *DynamicResources) unreservePodGroupClaims(ctx context.Context, pod *v1.Pod) *fwk.Status { + if pod.Spec.SchedulingGroup == nil || pod.Spec.SchedulingGroup.PodGroupName == nil { + return nil + } + + logger := klog.FromContext(ctx) + + // The podGroupState lister is based on the live cache and does not consider + // pods assumed within the PodGroup scheduling cycle, but the ones that + // happened before or outside the scheduling cycle. We use it to check + // whether there were no assumed or assigned pods that would use the + // ResourceClaim. + podGroupState, err := pl.fh.PodGroupManager().PodGroupStates().Get(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) + if err != nil { + return statusError(logger, err) + } + if podGroupState.ScheduledPodsCount() > 0 { + return nil + } + podGroup, err := pl.getPodGroup(pod) + if err != nil { + return statusError(logger, err) + } + + for _, podGroupClaim := range podGroup.Spec.ResourceClaims { + claimName, mustCheckOwner, err := resourceclaim.NameFromPodGroup(podGroup, &podGroupClaim) + if err != nil { + return statusError(logger, err) + } + if claimName == nil { + continue + } + claim, err := pl.draManager.ResourceClaims().Get(podGroup.Namespace, *claimName) + if err != nil { + return statusError(logger, err) + } + if mustCheckOwner { + if err := resourceclaim.IsForPodGroup(podGroup, claim); err != nil { + continue + } + } + + if claim.Status.Allocation != nil { + if resourceclaim.IsReservedForPod(pod, claim, pl.fts.EnableDRAWorkloadResourceClaims) { + // Remove PodGroup from ReservedFor. A strategic-merge-patch is used + // because that allows removing an individual entry without having + // the latest ResourceClaim. + patch := fmt.Sprintf(`{"metadata": {"uid": %q}, "status": { "reservedFor": [ {"$patch": "delete", "uid": %q} ] }}`, + claim.UID, + podGroup.UID, + ) + logger.V(5).Info("postfilter unreserved claim", "resourceclaim", klog.KObj(claim), "pod", klog.KObj(pod), "podgroup", klog.KObj(podGroup)) + claim, err := pl.clientset.ResourceV1().ResourceClaims(claim.Namespace).Patch(ctx, claim.Name, types.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{}, "status") + if err != nil { + // We will get here again when pod scheduling is retried. + logger.Error(err, "postfilter unreserving claim", "resourceclaim", klog.KObj(claim)) + continue + } else { + return statusUnschedulable(logger, "ResourceClaim unreserved for PodGroup") + } + } + } + } + + return nil +} + func (pl *DynamicResources) Score(ctx context.Context, cs fwk.CycleState, pod *v1.Pod, nodeInfo fwk.NodeInfo) (int64, *fwk.Status) { - if !pl.enabled { + if !pl.enabled || !pl.fts.EnableDRAPrioritizedList { return 0, nil } logger := klog.FromContext(ctx) @@ -859,13 +1100,29 @@ func (pl *DynamicResources) Score(ctx context.Context, cs fwk.CycleState, pod *v func computeScore(iterator iter.Seq2[int, *resourceapi.ResourceClaim], allocations nodeAllocation) (int64, error) { var score int64 - for i, claim := range iterator { + unallocatedIndex := 0 + for _, claim := range iterator { // Collect the names for all allocated subrequests. allocatedSubRequests := sets.New[string]() - if i >= len(allocations.allocationResults) { - return 0, fmt.Errorf("number of allocations %d is smaller than number of claims", len(allocations.allocationResults)) + + var allocation *resourceapi.AllocationResult + // The allocation for a claim can be in two places: + // 1. For claims allocated in a previous cycle (e.g. PodGroup claims), the allocation + // is already in claim.Status.Allocation. + // 2. For claims allocated in this cycle (in Filter), the allocation is in + // allocations.allocationResults. + // Since we iterate over all claims, we must check both and maintain a separate index + // for claims that needed allocation in this cycle. + if claim.Status.Allocation != nil { + allocation = claim.Status.Allocation + } else { + if unallocatedIndex >= len(allocations.allocationResults) { + return 0, fmt.Errorf("number of allocations %d is smaller than number of claims needing allocation", len(allocations.allocationResults)) + } + allocation = &allocations.allocationResults[unallocatedIndex] + unallocatedIndex++ } - allocation := allocations.allocationResults[i] + for _, res := range allocation.Devices.Results { request := res.Request if resourceclaim.IsSubRequestRef(request) { @@ -914,6 +1171,11 @@ func (pl *DynamicResources) Reserve(ctx context.Context, cs fwk.CycleState, pod logger := klog.FromContext(ctx) + podGroupState, err := getPodGroupStateData(cs) + if err != nil { + return statusError(logger, err) + } + numClaimsWithAllocator := 0 for _, claim := range state.claims.all() { if claim.Status.Allocation != nil { @@ -922,6 +1184,7 @@ func (pl *DynamicResources) Reserve(ctx context.Context, cs fwk.CycleState, pod // updating the ResourceClaim status, we assume that reserving // will work and only do it for real during binding. If it fails at // that time, some other pod was faster and we have to try again. + continue } @@ -989,8 +1252,12 @@ func (pl *DynamicResources) Reserve(ctx context.Context, cs fwk.CycleState, pod if err != nil { return statusError(logger, fmt.Errorf("internal error, couldn't signal allocation for claim %s", claim.Name)) } - logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "allocation", klog.Format(allocation)) + logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "uid", claim.UID, "resourceVersion", claim.ResourceVersion, "allocation", klog.Format(allocation)) allocIndex++ + + if podGroupState != nil { + podGroupState.pendingAllocations.Insert(claim.UID) + } } } @@ -1010,19 +1277,41 @@ func (pl *DynamicResources) Unreserve(ctx context.Context, cs fwk.CycleState, po if state.claims.empty() { return } + podGroupState, err := getPodGroupStateData(cs) + if err != nil { + return + } logger := klog.FromContext(ctx) // we process user claims here first, extendedResourceClaim if any is handled below. for _, claim := range state.claims.allUserClaims() { - // If allocation was in-flight, then it's not anymore and we need to revert the - // claim object in the assume cache to what it was before. - if deleted := pl.draManager.ResourceClaims().RemoveClaimPendingAllocation(claim.UID); deleted { + // If allocation was in-flight, then it might not be anymore if no pods + // still need the pending allocation. If the allocation was removed from + // in-flight, we need to revert the claim object in the assume cache to + // what it was before. The allocation is not removed until the last Pod + // sharing it is Bound or Unreserved. + if deleted := pl.draManager.ResourceClaims().MaybeRemoveClaimPendingAllocation(claim.UID, false); deleted { + logger.V(5).Info("Released resource in allocation result", "claim", klog.KObj(claim), "uid", claim.UID, "resourceVersion", claim.ResourceVersion, "allocation", klog.Format(claim.Status.Allocation)) pl.draManager.ResourceClaims().AssumedClaimRestore(claim.Namespace, claim.Name) + + // If we are currently asynchronously Binding Pods in a PodGroup, + // then the pendingAllocations set does not need to be updated. New + // PodGroup scheduling cycles will start with an empty set and not + // share pending allocations started in *this* cycle until Unreserve + // completes for all the Pods sharing that pending allocation and + // they can be Reserved again in another cycle. + if podGroupState != nil { + podGroupState.pendingAllocations.Delete(claim.UID) + } } + // Ignore claims reserved for the PodGroup because other Pods in the + // group may still need this claim. The PodGroup may be unreserved and + // dellocated (in api-server) in the next scheduling cycle if the + // PodGroup is not schedulable (in PostFilter) and not used yet. if claim.Status.Allocation != nil && - resourceclaim.IsReservedForPod(pod, claim) { + resourceclaim.IsReservedForPod(pod, claim, false /* acceptPodGroupReservation */) { // Remove pod from ReservedFor. A strategic-merge-patch is used // because that allows removing an individual entry without having // the latest ResourceClaim. @@ -1038,7 +1327,14 @@ func (pl *DynamicResources) Unreserve(ctx context.Context, cs fwk.CycleState, po } } } - pl.unreserveExtendedResourceClaim(ctx, logger, pod, state) + pl.unreserveExtendedResourceClaim(ctx, pod, state) + + if pl.fts.EnableDRANodeAllocatableResources { + nodeAllocations, ok := state.nodeAllocations[nodeName] + if ok && len(nodeAllocations.nodeAllocatableResourceClaimStatuses) > 0 { + pl.clearNodeAllocatableResourceClaimStatus(ctx, pod) + } + } } // PreBind gets called in a separate goroutine after it has been determined @@ -1063,9 +1359,14 @@ func (pl *DynamicResources) PreBind(ctx context.Context, cs fwk.CycleState, pod logger := klog.FromContext(ctx) + podGroupState, err := getPodGroupStateData(cs) + if err != nil { + return statusError(logger, err) + } + for index, claim := range state.claims.all() { - if !resourceclaim.IsReservedForPod(pod, claim) { - claim, err := pl.bindClaim(ctx, state, index, pod, nodeName) + if !resourceclaim.IsReservedForPod(pod, claim, pl.fts.EnableDRAWorkloadResourceClaims) { + claim, err := pl.bindClaim(ctx, state, podGroupState, index, pod, nodeName) if err != nil { return statusError(logger, err) } @@ -1074,6 +1375,15 @@ func (pl *DynamicResources) PreBind(ctx context.Context, cs fwk.CycleState, pod } } + if pl.fts.EnableDRANodeAllocatableResources { + nodeAllocations, ok := state.nodeAllocations[nodeName] + if ok && len(nodeAllocations.nodeAllocatableResourceClaimStatuses) > 0 { + if status := pl.patchNodeAllocatableResourceClaimStatus(ctx, pod, nodeAllocations.nodeAllocatableResourceClaimStatuses); status != nil { + return status + } + } + } + if !pl.fts.EnableDRADeviceBindingConditions || !pl.fts.EnableDRAResourceClaimDeviceStatus { // If we don't have binding conditions, we can return early. // The claim is now reserved for the pod and the scheduler can proceed with binding. @@ -1089,19 +1399,62 @@ func (pl *DynamicResources) PreBind(ctx context.Context, cs fwk.CycleState, pod } // We need to wait for the device to be attached to the node. - pl.fh.EventRecorder().Eventf(pod, nil, v1.EventTypeNormal, "BindingConditionsPending", "Scheduling", "waiting for binding conditions for device on node %s", nodeName) + pl.fh.EventRecorder().WithLogger(logger).Eventf(pod, nil, v1.EventTypeNormal, "BindingConditionsPending", "Scheduling", "waiting for binding conditions for device on node %s", nodeName) + // START: Record start time for metrics duration calculation + start := time.Now() err = wait.PollUntilContextTimeout(ctx, 5*time.Second, pl.bindingTimeout, true, func(ctx context.Context) (bool, error) { return pl.isPodReadyForBinding(state) }) - if err != nil { - if errors.Is(err, context.DeadlineExceeded) { - err = errors.New("device binding timeout") + // GOAL: Calculate duration since start for metrics recording + duration := time.Since(start) + if errors.Is(err, context.DeadlineExceeded) { + err = fmt.Errorf("%w: %w", ErrDeviceBindingTimeout, err) + } + + // Determine status label based on error + statusLabel := schedmetrics.BindingConditionsStatusSuccess + switch { + case err == nil: + logger.V(5).Info("BindingConditions is met", + "pod", klog.KObj(pod), + "node", nodeName, + "devices", bindingConditionsStatusFormatter{state, statusLabel}, + ) + // keep success + case errors.Is(err, ErrDeviceBindingTimeout): + statusLabel = schedmetrics.BindingConditionsStatusTimeout + case errors.Is(err, ErrDeviceBindingFailed): + statusLabel = schedmetrics.BindingConditionsStatusFailed + default: + statusLabel = schedmetrics.BindingConditionsStatusError + } + + // Record metrics for binding conditions outcome (success/failure/timeout/error) + profileLabel := pl.fh.ProfileName() + for _, claim := range state.claims.all() { + if claim.Status.Allocation == nil { + continue + } + for _, res := range claim.Status.Allocation.Devices.Results { + schedmetrics.DRABindingConditionsPreBindDuration. + WithLabelValues(profileLabel, res.Driver, statusLabel). + Observe(duration.Seconds()) + } + + // Count scheduling attempts that used devices with BindingConditions. + for _, bcStatus := range listBindingConditionsStatus(claim) { + schedmetrics.DRABindingConditionsAllocationsTotal. + WithLabelValues(profileLabel, bcStatus.Driver, statusLabel). + Inc() } + } + + if err != nil { // Returning an error here causes another scheduling attempt. // In that next attempt, PreFilter will detect the timeout or // error and try to recover. - return statusError(logger, err) + return statusError(logger, err, "devices", formatBCStatusOneLine(getBindingConditionsStatusForStatus(state, statusLabel))) } // If we get here, we know that reserving the claim for @@ -1111,26 +1464,28 @@ func (pl *DynamicResources) PreBind(ctx context.Context, cs fwk.CycleState, pod // PreBindPreFlight is called before PreBind, and determines whether PreBind is going to do something for this pod, or not. // It just checks state.claims to determine whether there are any claims and hence the plugin has to handle them at PreBind. -func (pl *DynamicResources) PreBindPreFlight(ctx context.Context, cs fwk.CycleState, p *v1.Pod, nodeName string) *fwk.Status { +func (pl *DynamicResources) PreBindPreFlight(ctx context.Context, cs fwk.CycleState, p *v1.Pod, nodeName string) (*fwk.PreBindPreFlightResult, *fwk.Status) { + result := &fwk.PreBindPreFlightResult{AllowParallel: true} if !pl.enabled { - return fwk.NewStatus(fwk.Skip) + return result, fwk.NewStatus(fwk.Skip) } state, err := getStateData(cs) if err != nil { - return statusError(klog.FromContext(ctx), err) + return result, statusError(klog.FromContext(ctx), err) } if state.claims.empty() { - return fwk.NewStatus(fwk.Skip) + return result, fwk.NewStatus(fwk.Skip) } - return nil + return result, nil } // bindClaim gets called by PreBind for claim which is not reserved for the pod yet. // It might not even be allocated. bindClaim then ensures that the allocation // and reservation are recorded. This finishes the work started in Reserve. -func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, index int, pod *v1.Pod, nodeName string) (*resourceapi.ResourceClaim, error) { +func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, podGroupState *podGroupStateData, index int, pod *v1.Pod, nodeName string) (*resourceapi.ResourceClaim, error) { logger := klog.FromContext(ctx) claim := state.claims.get(index) + binding := state.claims.getBinding(index, pod) allocation := state.informationsForClaim[index].allocation isExtendedResourceClaim := false if claim == state.claims.extendedResourceClaim() { @@ -1143,22 +1498,57 @@ func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, ind claimUIDs := []types.UID{claim.UID} resourceClaimModified := false defer func() { + // Creating the claim may have failed. + resourceVersion := "" + claimUID := types.UID("") + if claim != nil { + resourceVersion = claim.ResourceVersion + claimUID = claim.UID + } + // The scheduler was handling allocation. Now that has // completed, either successfully or with a failure. + + // The claim should remain in-flight in case any more Pods in the + // PodGroup are still using the pending allocation. If binding failed + // (e.g. due to a conflict in writing the allocation), then we signal + // that this Pod no longer needs the pending allocation without removing it. + forceRemovePendingAllocation := false + if resourceClaimModified { if isExtendedResourceClaim { - pl.waitForExtendedClaimInAssumeCache(ctx, logger, claim) + pl.waitForExtendedClaimInAssumeCache(ctx, claim) } else { // This can fail, but only for reasons that are okay (concurrent delete or update). // Shouldn't happen in this case. if err := pl.draManager.ResourceClaims().AssumeClaimAfterAPICall(claim); err != nil { - logger.V(5).Info("Claim not stored in assume cache", "err", err) + logger.V(5).Info("Claim not stored in assume cache", "err", err, "claim", klog.KObj(claim), "uid", claimUID, "resourceVersion", resourceVersion) + } else { + logger.V(5).Info("Claim stored in assume cache", "claim", klog.KObj(claim), "uid", claimUID, "resourceVersion", resourceVersion) + + // Once the pending allocation is recorded in the + // AssumeCache, we no longer need to keep it in-flight. + // Even if it happens to still be shared, the allocation in + // the AssumeCache is authoritative. + forceRemovePendingAllocation = true } } } if allocation != nil { for _, claimUID := range claimUIDs { - pl.draManager.ResourceClaims().RemoveClaimPendingAllocation(claimUID) + if deleted := pl.draManager.ResourceClaims().MaybeRemoveClaimPendingAllocation(claimUID, forceRemovePendingAllocation); deleted { + // If we are currently asynchronously Binding Pods in a + // PodGroup, then the pendingAllocations set does not need + // to be updated. New PodGroup scheduling cycles will start + // with an empty set and not share pending allocations + // started in *this* cycle until Unreserve completes for all + // the Pods sharing that pending allocation and they can be + // Reserved again in another cycle. + if podGroupState != nil { + podGroupState.pendingAllocations.Delete(claim.UID) + } + logger.V(5).Info("Removed claim from in-flight claims", "claim", klog.KObj(claim), "uid", claimUID, "resourceVersion", resourceVersion, "allocation", klog.Format(allocation)) + } } } }() @@ -1166,7 +1556,7 @@ func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, ind // Create the special claim for extended resource backed by DRA if isExtendedResourceClaim && isSpecialClaimName(claim.Name) { var err error - claim, err = pl.createExtendedResourceClaimInAPI(ctx, logger, pod, nodeName, state) + claim, err = pl.createExtendedResourceClaimInAPI(ctx, pod, nodeName, state) if err != nil { return nil, err } @@ -1225,9 +1615,18 @@ func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, ind // We can simply try to add the pod here without checking // preconditions. The apiserver will tell us with a // non-conflict error if this isn't possible. - claim.Status.ReservedFor = append(claim.Status.ReservedFor, resourceapi.ResourceClaimConsumerReference{Resource: "pods", Name: pod.Name, UID: pod.UID}) - if pl.fts.EnableDRADeviceBindingConditions && pl.fts.EnableDRAResourceClaimDeviceStatus && claim.Status.Allocation.AllocationTimestamp == nil { - claim.Status.Allocation.AllocationTimestamp = &metav1.Time{Time: time.Now()} + claim.Status.ReservedFor = append(claim.Status.ReservedFor, binding) + if pl.fts.EnableDRADeviceBindingConditions && + pl.fts.EnableDRAResourceClaimDeviceStatus { + // Once the feature gate checks get removed, this code can be moved into an else branch + // for `if allocation != nil` above. For now it is kept here to avoid changing normal + // behavior. + if claim.Status.Allocation == nil { + return fmt.Errorf("claim %s got deallocated elsewhere in the meantime", klog.KObj(claim)) + } + if claim.Status.Allocation.AllocationTimestamp == nil { + claim.Status.Allocation.AllocationTimestamp = &metav1.Time{Time: time.Now()} + } } updatedClaim, err := pl.clientset.ResourceV1().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) if err != nil { @@ -1280,7 +1679,8 @@ func (pl *DynamicResources) isClaimReadyForBinding(claim *resourceapi.ResourceCl for _, cond := range deviceRequest.BindingFailureConditions { failedCond := apimeta.FindStatusCondition(deviceStatus.Conditions, cond) if failedCond != nil && failedCond.Status == metav1.ConditionTrue { - return false, fmt.Errorf("claim %s binding failed: reason=%s, message=%q", + return false, fmt.Errorf("%w: claim=%s, reason=%s, message=%q", + ErrDeviceBindingFailed, claim.Name, failedCond.Reason, failedCond.Message) @@ -1336,7 +1736,7 @@ func (pl *DynamicResources) isPodReadyForBinding(state *stateData) (bool, error) } if !ready { if pl.isClaimTimeout(claim) { - return false, fmt.Errorf("claim %s binding timeout", claim.Name) + return false, fmt.Errorf("%w: claim=%s", ErrDeviceBindingTimeout, claim.Name) } return false, nil } @@ -1344,6 +1744,14 @@ func (pl *DynamicResources) isPodReadyForBinding(state *stateData) (bool, error) return true, nil } +func (pl *DynamicResources) getPodGroup(pod *v1.Pod) (*schedulingapi.PodGroup, error) { + if !pl.fts.EnableDRAWorkloadResourceClaims || + pod.Spec.SchedulingGroup == nil || pod.Spec.SchedulingGroup.PodGroupName == nil { + return nil, nil + } + return pl.draManager.PodGroups().Get(pod.Namespace, *pod.Spec.SchedulingGroup.PodGroupName) +} + // hasBindingConditions checks whether any of the claims in the state // has binding conditions. // It returns true if at least one claim has binding conditions. @@ -1395,3 +1803,130 @@ func getAllocatedDeviceStatus(claim *resourceapi.ResourceClaim, deviceRequest *r } return nil } + +// bindingConditionsStatusFormatter implements fmt.Stringer for lazy evaluation of device status formatting. +// This avoids expensive processing when logging is disabled. +type bindingConditionsStatusFormatter struct { + state *stateData + statusLabel string +} + +func (d bindingConditionsStatusFormatter) String() string { + return formatBCStatusOneLine(getBindingConditionsStatusForStatus(d.state, d.statusLabel)) +} + +// BindingConditionsStatus is a compact per-device summary for BindingConditions logging. +type BindingConditionsStatus struct { + Driver string `json:"driver"` + Pool string `json:"pool"` + Device string `json:"device"` + Pending []string `json:"pending,omitempty"` + Failed []string `json:"failed,omitempty"` // only failure conditions that are true +} + +// listBindingConditionsStatus inspects ONE claim and returns a summary per allocated device +// that has BindingConditions. +// - Pending: BindingConditions that are not yet true (or all conditions if device status is missing) +// - Failed: BindingFailureConditions that are true +func listBindingConditionsStatus(claim *resourceapi.ResourceClaim) []BindingConditionsStatus { + if claim == nil || claim.Status.Allocation == nil { + return nil + } + + var out []BindingConditionsStatus + for _, res := range claim.Status.Allocation.Devices.Results { + if len(res.BindingConditions) == 0 { + continue + } + + sum := BindingConditionsStatus{ + Driver: res.Driver, + Pool: res.Pool, + Device: res.Device, + } + + ds := getAllocatedDeviceStatus(claim, &res) + if ds == nil { + // No status yet => all BindingConditions are pending. + sum.Pending = append(sum.Pending, res.BindingConditions...) + out = append(out, sum) + continue + } + + // Failed conditions that are true. + for _, c := range res.BindingFailureConditions { + if apimeta.IsStatusConditionTrue(ds.Conditions, c) { + sum.Failed = append(sum.Failed, c) + } + } + + // Pending conditions: those not yet true. + for _, c := range res.BindingConditions { + if !apimeta.IsStatusConditionTrue(ds.Conditions, c) { + sum.Pending = append(sum.Pending, c) + } + } + + out = append(out, sum) + } + + return out +} + +// getBindingConditionsStatusForStatus selects which devices to log across ALL claims in the state. +func getBindingConditionsStatusForStatus(state *stateData, statusLabel string) []BindingConditionsStatus { + var out []BindingConditionsStatus + for _, claim := range state.claims.all() { + for _, s := range listBindingConditionsStatus(claim) { + switch statusLabel { + case schedmetrics.BindingConditionsStatusSuccess: + // success: show all BC devices + if len(s.Failed) == 0 && len(s.Pending) == 0 { + out = append(out, s) + } + case schedmetrics.BindingConditionsStatusFailed: + // failure: only devices that have at least one failure condition true + if len(s.Failed) > 0 { + out = append(out, BindingConditionsStatus{ + Driver: s.Driver, + Pool: s.Pool, + Device: s.Device, + Failed: append([]string(nil), s.Failed...), + }) + } + + case schedmetrics.BindingConditionsStatusTimeout: + // timeout/error: only devices still pending, and not failed + if len(s.Pending) > 0 && len(s.Failed) == 0 { + out = append(out, s) + } + + default: + // Treat unknown like timeout/error + if len(s.Pending) > 0 && len(s.Failed) == 0 { + out = append(out, s) + } + } + } + } + return out +} + +// formatBCStatusOneLine formats the selected devices into a single log-friendly line. +func formatBCStatusOneLine(devs []BindingConditionsStatus) string { + if len(devs) == 0 { + return "" + } + parts := make([]string, 0, len(devs)) + for _, d := range devs { + base := fmt.Sprintf(" %s", d.Driver, d.Pool, d.Device) + if len(d.Failed) > 0 { + base += fmt.Sprintf(" failed=[%s]", strings.Join(d.Failed, ",")) + } + if len(d.Pending) > 0 { + base += fmt.Sprintf(" pending=[%s]", strings.Join(d.Pending, ",")) + } + parts = append(parts, base) + } + return strings.Join(parts, "; ") +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/extendeddynamicresources.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/extendeddynamicresources.go index 1c677e728c..8709dee6e3 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/extendeddynamicresources.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/extendeddynamicresources.go @@ -41,7 +41,6 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" schedutil "k8s.io/kubernetes/pkg/scheduler/util" "k8s.io/kubernetes/pkg/scheduler/util/assumecache" - "k8s.io/kubernetes/pkg/util/slice" "k8s.io/utils/ptr" ) @@ -283,7 +282,7 @@ func isSpecialClaimName(name string) bool { } // deleteClaim deletes the claim after removing the finalizer from the claim, if there is any. -func (pl *DynamicResources) deleteClaim(ctx context.Context, claim *resourceapi.ResourceClaim, logger klog.Logger) error { +func (pl *DynamicResources) deleteClaim(ctx context.Context, claim *resourceapi.ResourceClaim) error { refreshClaim := false retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { if refreshClaim { @@ -311,7 +310,7 @@ func (pl *DynamicResources) deleteClaim(ctx context.Context, claim *resourceapi. return retryErr } - logger.V(5).Info("Delete", "resourceclaim", klog.KObj(claim)) + klog.FromContext(ctx).V(5).Info("Delete", "resourceclaim", klog.KObj(claim)) err := pl.clientset.ResourceV1().ResourceClaims(claim.Namespace).Delete(ctx, claim.Name, metav1.DeleteOptions{}) if err != nil { return err @@ -374,7 +373,7 @@ func createResourceRequestAndMappings(containerIndex int, container *v1.Containe } // resource requests in a container is a map, their names must // be sorted to determine the resource's index order. - slice.SortStrings(keys) + slices.Sort(keys) ridx := 0 for j := range keys { if keys[j] == rName.String() { @@ -419,9 +418,7 @@ func createRequestsAndMappings(pod *v1.Pod, extendedResources map[v1.ResourceNam for resource := range extendedResources { resourceNames = append(resourceNames, resource) } - sort.Slice(resourceNames, func(i, j int) bool { - return resourceNames[i] < resourceNames[j] - }) + slices.Sort(resourceNames) for _, resource := range resourceNames { class := deviceClassMapping.GetDeviceClass(resource) @@ -500,9 +497,9 @@ func createRequestsAndMappings(pod *v1.Pod, extendedResources map[v1.ResourceNam // so we poll with a timeout. func (pl *DynamicResources) waitForExtendedClaimInAssumeCache( ctx context.Context, - logger klog.Logger, claim *resourceapi.ResourceClaim, ) { + logger := klog.FromContext(ctx) pollErr := wait.PollUntilContextTimeout( ctx, 1*time.Second, @@ -529,11 +526,11 @@ func (pl *DynamicResources) waitForExtendedClaimInAssumeCache( // createExtendedResourceClaimInAPI creates an extended resource claim in the API server. func (pl *DynamicResources) createExtendedResourceClaimInAPI( ctx context.Context, - logger klog.Logger, pod *v1.Pod, nodeName string, state *stateData, ) (*resourceapi.ResourceClaim, error) { + logger := klog.FromContext(ctx) logger.V(5).Info("preparing to create claim for extended resources", "pod", klog.KObj(pod), "node", nodeName) // Get the node-specific claim that was prepared during Filter phase nodeAllocation, ok := state.nodeAllocations[nodeName] @@ -591,7 +588,7 @@ func (pl *DynamicResources) patchPodExtendedResourceClaimStatus( // unreserveExtendedResourceClaim cleans up the scheduler-owned extended resource claim // when scheduling fails. It reverts the assume cache, and deletes the claim from the API // server if it was already created. -func (pl *DynamicResources) unreserveExtendedResourceClaim(ctx context.Context, logger klog.Logger, pod *v1.Pod, state *stateData) { +func (pl *DynamicResources) unreserveExtendedResourceClaim(ctx context.Context, pod *v1.Pod, state *stateData) { extendedResourceClaim := state.claims.extendedResourceClaim() if extendedResourceClaim == nil { // there is no extended resource claim @@ -600,7 +597,7 @@ func (pl *DynamicResources) unreserveExtendedResourceClaim(ctx context.Context, // If the claim was marked as pending allocation (in-flight), remove that marker and restore // the assumed claim state to what it was before this scheduling attempt. - if deleted := pl.draManager.ResourceClaims().RemoveClaimPendingAllocation(state.claims.getInitialExtendedResourceClaimUID()); deleted { + if deleted := pl.draManager.ResourceClaims().MaybeRemoveClaimPendingAllocation(state.claims.getInitialExtendedResourceClaimUID(), false); deleted { pl.draManager.ResourceClaims().AssumedClaimRestore(extendedResourceClaim.Namespace, extendedResourceClaim.Name) } if isSpecialClaimName(extendedResourceClaim.Name) { @@ -608,9 +605,10 @@ func (pl *DynamicResources) unreserveExtendedResourceClaim(ctx context.Context, return } // Claim was written to API server, need to delete it to prevent orphaned resources. + logger := klog.FromContext(ctx) logger.V(5).Info("delete extended resource backed by DRA", "resourceclaim", klog.KObj(extendedResourceClaim), "pod", klog.KObj(pod), "claim.UID", extendedResourceClaim.UID) extendedResourceClaim = extendedResourceClaim.DeepCopy() - if err := pl.deleteClaim(ctx, extendedResourceClaim, logger); err != nil { + if err := pl.deleteClaim(ctx, extendedResourceClaim); err != nil { logger.Error(err, "delete", "resourceclaim", klog.KObj(extendedResourceClaim)) } } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/nodeallocatabledynamicresources.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/nodeallocatabledynamicresources.go new file mode 100644 index 0000000000..d509445d7f --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/nodeallocatabledynamicresources.go @@ -0,0 +1,449 @@ +/* +Copyright 2025 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 dynamicresources + +import ( + "context" + "errors" + "fmt" + "sort" + + v1 "k8s.io/api/core/v1" + resourceapi "k8s.io/api/resource/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" + resourcehelper "k8s.io/component-helpers/resource" + "k8s.io/klog/v2" + fwk "k8s.io/kube-scheduler/framework" + v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" + "k8s.io/kubernetes/pkg/scheduler/framework" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" + schedutil "k8s.io/kubernetes/pkg/scheduler/util" +) + +// ExtractPodNodeAllocatableResourceClaimStatus returns the pod nodeAllocatable claim status stored in state +func ExtractPodNodeAllocatableResourceClaimStatus(logger klog.Logger, state fwk.CycleState, nodeName string) []v1.NodeAllocatableResourceClaimStatus { + s, err := state.Read(names.DynamicResources) + if err != nil { + // DynamicResources plugin didn't run or no state + return nil + } + + draState, ok := s.(*stateData) + if !ok { + logger.Error(errors.New("invalid DynamicResources state type"), "Failed to cast CycleState data") + return nil + } + + if nodeAlloc, exists := draState.nodeAllocations[nodeName]; exists { + return nodeAlloc.nodeAllocatableResourceClaimStatuses + } + + return nil +} + +// calculateAndCheckNodeAllocatableResources calculates the total node-allocatable resources (e.g., CPU, memory) +// requested by a pod, considering both its standard container requests and any additional resources +// derived from its DRA claims. It then checks if this aggregated demand fits within the node's remaining allocatable capacity. +func (pl *DynamicResources) calculateAndCheckNodeAllocatableResources(ctx context.Context, state *stateData, pod *v1.Pod, nodeInfo fwk.NodeInfo, allocations map[types.UID]*resourceapi.AllocationResult) ([]v1.NodeAllocatableResourceClaimStatus, *fwk.Status) { + logger := klog.FromContext(ctx) + + nodeAllocatableClaims := []*resourceapi.ResourceClaim{} + nodeAllocatableClaimUIDs := sets.New[types.UID]() + + for _, claim := range state.claims.all() { + if alloc, ok := allocations[claim.UID]; ok { + for _, result := range alloc.Devices.Results { + device, err := getDeviceFromManager(pl.draManager, result.Pool, result.Device) + if err != nil { + logger.Error(err, "Failed to get device from manager", "claim", klog.KObj(claim), "device", result.Device, "pool", result.Pool) + continue + } + if device != nil && len(device.NodeAllocatableResourceMappings) > 0 { + if !nodeAllocatableClaimUIDs.Has(claim.UID) { + nodeAllocatableClaims = append(nodeAllocatableClaims, claim) + nodeAllocatableClaimUIDs.Insert(claim.UID) + } + break + } + } + } + } + + if len(nodeAllocatableClaims) == 0 { + return nil, nil // No nodeAllocatable resources to check + } + + totalPodDemand, nodeAllocatableClaimStatus, status := pl.getPodNodeAllocatableResourceFootprint(logger, nodeInfo, pod, state, allocations, nodeAllocatableClaims) + if status != nil { + logger.V(5).Info("calculateAndCheckNodeAllocatableResources: getPodNodeAllocatableResourceFootprint failed", "status", status) + return nil, status + } + + if status := pl.nodeFitsResources(nodeInfo, totalPodDemand); status != nil { + return nil, status + } + logger.V(5).Info("Pod fits on node ( including DRA Node Allocatable Resources)", "pod", klog.KObj(pod), "node", nodeInfo.Node().Name) + return nodeAllocatableClaimStatus, nil +} + +// getDeviceFromManager retrieves a specific Device object from the DRA manager's cache and +// looks for the device matching the given poolName and deviceName. +func getDeviceFromManager(draManager fwk.SharedDRAManager, poolName, deviceName string) (*resourceapi.Device, error) { + slices, err := draManager.ResourceSlices().ListWithDeviceTaintRules() + if err != nil { + return nil, fmt.Errorf("listing resource slices: %w", err) + } + for _, slice := range slices { + if slice.Spec.Pool.Name == poolName { + for i := range slice.Spec.Devices { + if slice.Spec.Devices[i].Name == deviceName { + return &slice.Spec.Devices[i], nil + } + } + } + } + return nil, fmt.Errorf("device %s not found in pool %s", deviceName, poolName) +} + +// buildNodeAllocatableDRAInfo processes the node allocatable resource allocations for a pod. +// It translates the allocated devices and quantities from DRA claims into a list of v1.NodeAllocatableResourceClaimStatus. +func (pl *DynamicResources) buildNodeAllocatableDRAInfo(pod *v1.Pod, nodeAllocatableClaimAllocations map[v1.ObjectReference]*resourceapi.AllocationResult, claimNametoUID map[string]types.UID) ([]v1.NodeAllocatableResourceClaimStatus, error) { + allContainers := make([]v1.Container, 0, len(pod.Spec.InitContainers)+len(pod.Spec.Containers)) + allContainers = append(allContainers, pod.Spec.InitContainers...) + allContainers = append(allContainers, pod.Spec.Containers...) + claimToStatus := make(map[types.UID]v1.NodeAllocatableResourceClaimStatus) + + for key, alloc := range nodeAllocatableClaimAllocations { + currentClaimStatus := v1.NodeAllocatableResourceClaimStatus{ + ResourceClaimName: key.Name, + Containers: []string{}, + Resources: map[v1.ResourceName]resource.Quantity{}, + } + + hasNodeAllocatableClaims := false + for _, result := range alloc.Devices.Results { + device, err := getDeviceFromManager(pl.draManager, result.Pool, result.Device) + if err != nil { + return nil, fmt.Errorf("claim %s/%s, device %s: %w", key.Namespace, key.Name, result.Device, err) + } + if device == nil || device.NodeAllocatableResourceMappings == nil { + continue + } + + for resourceName, resourceMap := range device.NodeAllocatableResourceMappings { + quantity := resource.Quantity{} + + if resourceMap.CapacityKey != nil && *resourceMap.CapacityKey != "" { + capacityKey := *resourceMap.CapacityKey + if result.ConsumedCapacity == nil { + return nil, fmt.Errorf("claim %s/%s, device %s: ConsumedCapacity is nil, but Capacity key '%s' is set in NodeAllocatableResourceMappings for resource %s", key.Namespace, key.Name, result.Device, capacityKey, resourceName) + } + if consumed, exists := result.ConsumedCapacity[capacityKey]; exists { + quantity = consumed.DeepCopy() + if resourceMap.AllocationMultiplier != nil { + qDec := quantity.AsDec() + multiplier := resourceMap.AllocationMultiplier.DeepCopy() + qDec.Mul(qDec, multiplier.AsDec()) + quantity = *resource.NewDecimalQuantity(*qDec, quantity.Format) + } + } else { + // If the capacityKey is not in ConsumedCapacity, this mapping is not relevant for this allocation + continue + } + } else if resourceMap.AllocationMultiplier != nil { + quantity = resourceMap.AllocationMultiplier.DeepCopy() + } + + if currentClaimStatus.Resources == nil { + currentClaimStatus.Resources = make(map[v1.ResourceName]resource.Quantity) + } + curQuantity, ok := currentClaimStatus.Resources[resourceName] + if !ok { + currentClaimStatus.Resources[resourceName] = quantity + } else { + curQuantity.Add(quantity) + currentClaimStatus.Resources[resourceName] = curQuantity + } + + hasNodeAllocatableClaims = true + + } + } + + if hasNodeAllocatableClaims { + claimToStatus[key.UID] = currentClaimStatus + } + } + + for _, container := range allContainers { + for _, podClaim := range container.Resources.Claims { + if claimUID, ok := claimNametoUID[podClaim.Name]; ok { + if nodeAllocatableClaimStatus, ok := claimToStatus[claimUID]; ok { + nodeAllocatableClaimStatus.Containers = append(nodeAllocatableClaimStatus.Containers, container.Name) + claimToStatus[claimUID] = nodeAllocatableClaimStatus + } + } + } + } + + nodeAllocatableClaimInfoList := make([]v1.NodeAllocatableResourceClaimStatus, 0, len(claimToStatus)) + for _, status := range claimToStatus { + nodeAllocatableClaimInfoList = append(nodeAllocatableClaimInfoList, status) + } + + // Sort the results for consistent output. + sort.Slice(nodeAllocatableClaimInfoList, func(i, j int) bool { + return nodeAllocatableClaimInfoList[i].ResourceClaimName < nodeAllocatableClaimInfoList[j].ResourceClaimName + }) + + return nodeAllocatableClaimInfoList, nil +} + +// validateNodeAllocatableDRAClaimSharing ensures that a node-allocatable DRA claim is not already in use by another pod on this node. +func (pl *DynamicResources) validateNodeAllocatableDRAClaimSharing(pod *v1.Pod, nodeInfo fwk.NodeInfo, claim *resourceapi.ResourceClaim) *fwk.Status { + if claim == nil { + return nil + } + claimKey := types.NamespacedName{Namespace: pod.Namespace, Name: claim.Name} + claimStates := nodeInfo.GetNodeAllocatableDRAClaimState() + if state, ok := claimStates[claimKey]; ok && state != nil { + if state.ConsumerPods.Len() > 1 { + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("node allocatable resource claim %s shared by multiple pods", claimKey.Name)) + } + if state.ConsumerPods.Len() == 1 && !state.ConsumerPods.Has(pod.UID) { + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("node allocatable resource claim %s is already used by another pod", claimKey.Name)) + } + } + return nil +} + +// validatePodLevelRequestsCoverDRA checks if the pod-level requests, if specified, are sufficient to cover +// the container level and DRA claim requests. +func (pl *DynamicResources) validatePodLevelRequestsCoverDRA(logger klog.Logger, pod *v1.Pod, requestWithPodLevel v1.ResourceList) *fwk.Status { + if !pl.fts.EnablePodLevelResources || pod.Spec.Resources == nil || pod.Spec.Resources.Requests == nil { + return nil + } + + // Calculate Sum(Containers) + DRA + overhead resources.. Skip pod level resources for this sum + optsSum := resourcehelper.PodResourcesOptions{ + SkipPodLevelResources: true, + UseDRANodeAllocatableResourceClaimStatus: true, + } + requestWithoutPodLevel := resourcehelper.PodRequests(pod, optsSum) + + // For resources specified at pod level, check if container and DRA aggregates does not exceed pod level budget. + for resName, podLevelReq := range requestWithPodLevel { + val, ok := requestWithoutPodLevel[resName] + if !ok { + continue + } + if val.Cmp(podLevelReq) > 0 { + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("pod level request for %s is insufficient to cover the aggregated container and node-allocatable DRA requests", resName)) + } + } + return nil +} + +// getPodNodeAllocatableResourceFootprint determines the total nodeAllocatable resource demand of a pod. +func (pl *DynamicResources) getPodNodeAllocatableResourceFootprint(logger klog.Logger, nodeInfo fwk.NodeInfo, pod *v1.Pod, state *stateData, allocations map[types.UID]*resourceapi.AllocationResult, nodeAllocatableClaims []*resourceapi.ResourceClaim) (*framework.Resource, []v1.NodeAllocatableResourceClaimStatus, *fwk.Status) { + nodeAllocatableDRAAllocations := make(map[v1.ObjectReference]*resourceapi.AllocationResult) + // Add pre-allocated claims + for _, claim := range nodeAllocatableClaims { + key := v1.ObjectReference{ + Namespace: pod.Namespace, + Name: claim.Name, + UID: claim.UID, + } + if claim.Status.Allocation != nil { + nodeAllocatableDRAAllocations[key] = claim.Status.Allocation + } + if alloc, ok := allocations[claim.UID]; ok { + nodeAllocatableDRAAllocations[key] = alloc + } + } + + claimNametoUID := make(map[string]types.UID) + if err := pl.foreachPodResourceClaim(pod, func(name string, claim *resourceapi.ResourceClaim) { + claimNametoUID[name] = claim.UID + }); err != nil { + return nil, nil, statusError(logger, fmt.Errorf("processing pod resource claims: %w", err)) + } + + nodeAllocatableStatus, err := pl.buildNodeAllocatableDRAInfo(pod, nodeAllocatableDRAAllocations, claimNametoUID) + if err != nil { + return nil, nil, statusError(logger, err) + } + + for _, status := range nodeAllocatableStatus { + // TODO(KEP-5517): Evaluate if its ok to have no containers referencing a node allocatable resource claim. + // This is pending on defining kubelet cgroup enforcement. + if len(status.Containers) == 0 { + return nil, nil, fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("claim %s: node-allocatable resource claim not referenced by any container within the pod", status.ResourceClaimName)) + } + } + + // Calculate the final totalPodDemand to be used for node fitting + optsTotal := resourcehelper.PodResourcesOptions{ + SkipPodLevelResources: !pl.fts.EnablePodLevelResources, + UseDRANodeAllocatableResourceClaimStatus: true, + } + podCopy := pod.DeepCopy() + podCopy.Status.NodeAllocatableResourceClaimStatuses = nodeAllocatableStatus + totalPodDemandRes := resourcehelper.PodRequests(podCopy, optsTotal) + + // Validate that pod-level requests, if specified, cover the aggregated container + DRA requests. + // The API validation in pkg/apis/core/validation/validation.go only checks pod.Spec.Resources against container + // requests within the Spec. It cannot account for DRA-derived resources, which are determined after device allocation. + if status := pl.validatePodLevelRequestsCoverDRA(logger, podCopy, totalPodDemandRes); status != nil { + return nil, nil, status + } + + totalPodDemand := framework.NewResource(totalPodDemandRes) + logger.V(5).Info("Total Pod Demand After DRA", "pod", klog.KObj(pod), "demand", totalPodDemand) + + return totalPodDemand, nodeAllocatableStatus, nil +} + +// insufficientResource describes what kind of resource limit is hit and caused the pod to not fit the node. +type insufficientResource struct { + resourceName v1.ResourceName + // We explicitly have a parameter for reason to avoid formatting a message on the fly + // for common resources, which is expensive for cluster autoscaler simulations. + reason string + requested int64 + used int64 + capacity int64 + // unresolvable indicates whether this node could be schedulable for the pod by the preemption, + // which is determined by comparing the node's size and the pod's request. + unresolvable bool +} + +// nodeFitsResources checks if the node has sufficient capacity to accommodate the pod's nodeAllocatable resource requirements. +// TODO(pravk03): Unify this with the fitsRequest() in pkg/scheduler/framework/plugins/noderesources/fit.go. +func (pl *DynamicResources) nodeFitsResources(nodeInfo fwk.NodeInfo, podRequest *framework.Resource) *fwk.Status { + insufficientResources := make([]insufficientResource, 0, 4) + + if podRequest.MilliCPU > 0 && podRequest.MilliCPU > (nodeInfo.GetAllocatable().GetMilliCPU()-nodeInfo.GetRequested().GetMilliCPU()) { + insufficientResources = append(insufficientResources, insufficientResource{ + resourceName: v1.ResourceCPU, + reason: "Insufficient cpu", + requested: podRequest.MilliCPU, + used: nodeInfo.GetRequested().GetMilliCPU(), + capacity: nodeInfo.GetAllocatable().GetMilliCPU(), + unresolvable: podRequest.MilliCPU > nodeInfo.GetAllocatable().GetMilliCPU(), + }) + } + if podRequest.Memory > 0 && podRequest.Memory > (nodeInfo.GetAllocatable().GetMemory()-nodeInfo.GetRequested().GetMemory()) { + insufficientResources = append(insufficientResources, insufficientResource{ + resourceName: v1.ResourceMemory, + reason: "Insufficient memory", + requested: podRequest.Memory, + used: nodeInfo.GetRequested().GetMemory(), + capacity: nodeInfo.GetAllocatable().GetMemory(), + unresolvable: podRequest.Memory > nodeInfo.GetAllocatable().GetMemory(), + }) + } + if podRequest.EphemeralStorage > 0 && + podRequest.EphemeralStorage > (nodeInfo.GetAllocatable().GetEphemeralStorage()-nodeInfo.GetRequested().GetEphemeralStorage()) { + insufficientResources = append(insufficientResources, insufficientResource{ + resourceName: v1.ResourceEphemeralStorage, + reason: "Insufficient ephemeral-storage", + requested: podRequest.EphemeralStorage, + used: nodeInfo.GetRequested().GetEphemeralStorage(), + capacity: nodeInfo.GetAllocatable().GetEphemeralStorage(), + unresolvable: podRequest.GetEphemeralStorage() > nodeInfo.GetAllocatable().GetEphemeralStorage(), + }) + } + + for resName, reqQuant := range podRequest.ScalarResources { + if v1helper.IsHugePageResourceName(resName) { + nodeCapacity := nodeInfo.GetAllocatable().GetScalarResources()[resName] + nodeRequested := nodeInfo.GetRequested().GetScalarResources()[resName] + available := nodeCapacity - nodeRequested + + if reqQuant > available { + insufficientResources = append(insufficientResources, insufficientResource{ + resourceName: resName, + reason: fmt.Sprintf("Insufficient %s", resName), + requested: reqQuant, + used: nodeRequested, + capacity: nodeCapacity, + unresolvable: reqQuant > nodeCapacity, + }) + } + } + } + + if len(insufficientResources) > 0 { + failureReasons := make([]string, 0, len(insufficientResources)) + statusCode := fwk.Unschedulable + for i := range insufficientResources { + failureReasons = append(failureReasons, insufficientResources[i].reason) + if insufficientResources[i].unresolvable { + statusCode = fwk.UnschedulableAndUnresolvable + } + } + return fwk.NewStatus(statusCode, failureReasons...) + } + return nil +} + +func (pl *DynamicResources) patchNodeAllocatableResourceClaimStatus(ctx context.Context, pod *v1.Pod, nodeAllocatableClaimStatus []v1.NodeAllocatableResourceClaimStatus) *fwk.Status { + + if len(nodeAllocatableClaimStatus) == 0 { + return nil + } + logger := klog.FromContext(ctx) + + // The incoming 'pod' is from the scheduler cache and would have NodeAllocatableResourceClaimStatus + // pre-populated in the assume phase without persisting to the API server. + // schedutil.PatchPodStatus skips patching if the old and new status are identical. + // To ensure the status is persisted to the API server we clear it in the baseStatus, forcing a patch. + baseStatus := pod.Status.DeepCopy() + if !apiequality.Semantic.DeepEqual(baseStatus.NodeAllocatableResourceClaimStatuses, nodeAllocatableClaimStatus) { + logger.V(5).Info("NodeAllocatableResourceClaimStatuses difference: assumed pod status does not match calculated status", "pod", klog.KObj(pod)) + return statusError(logger, errors.New("assumed pod status does not match calculated status to be patched")) + } + baseStatus.NodeAllocatableResourceClaimStatuses = nil + + targetStatus := pod.Status.DeepCopy() + + targetStatus.NodeAllocatableResourceClaimStatuses = nodeAllocatableClaimStatus + if err := schedutil.PatchPodStatus(ctx, pl.clientset, pod.Name, pod.Namespace, baseStatus, targetStatus); err != nil { + return statusError(logger, fmt.Errorf("updating pod %s/%s NodeAllocatableResourceClaimStatuses: %w", pod.Namespace, pod.Name, err)) + } + logger.V(5).Info("Patched pod status with NodeAllocatableResourceClaimStatuses", "pod", klog.KObj(pod), "status", targetStatus.NodeAllocatableResourceClaimStatuses) + + return nil +} + +func (pl *DynamicResources) clearNodeAllocatableResourceClaimStatus(ctx context.Context, pod *v1.Pod) { + logger := klog.FromContext(ctx) + logger.V(5).Info("Clearing NodeAllocatableResourceClaimStatuses on Unreserve", "pod", klog.KObj(pod)) + + targetStatus := pod.Status.DeepCopy() + targetStatus.NodeAllocatableResourceClaimStatuses = nil + + if err := schedutil.PatchPodStatus(ctx, pl.clientset, pod.Name, pod.Namespace, &pod.Status, targetStatus); err != nil { + logger.Error(err, "Failed to clear NodeAllocatableResourceClaimStatuses on Unreserve", "pod", klog.KObj(pod)) + } else { + logger.V(5).Info("Cleared NodeAllocatableResourceClaimStatuses", "pod", klog.KObj(pod)) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go index f15c64edbd..233c20542b 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go @@ -31,12 +31,14 @@ type Features struct { EnableDRAConsumableCapacity bool EnableDRADeviceTaints bool EnableDRADeviceBindingConditions bool + EnableDRAListTypeAttributes bool + EnableDRANodeAllocatableResources bool EnableDRAPartitionableDevices bool EnableDRAResourceClaimDeviceStatus bool EnableDRASchedulerFilterTimeout bool + EnableDRAWorkloadResourceClaims bool EnableDynamicResourceAllocation bool EnableVolumeAttributesClass bool - EnableCSIMigrationPortworx bool EnableVolumeLimitScaling bool EnableNodeInclusionPolicyInPodTopologySpread bool EnableMatchLabelKeysInPodTopologySpread bool @@ -48,8 +50,11 @@ type Features struct { EnableStorageCapacityScoring bool EnableNodeDeclaredFeatures bool EnableGangScheduling bool + EnableGenericWorkload bool EnableTaintTolerationComparisonOperators bool EnableInPlacePodLevelResourcesVerticalScaling bool + EnableTopologyAwareWorkloadScheduling bool + EnableWorkloadAwarePreemption bool } // NewSchedulerFeaturesFromGates copies the current state of the feature gates into the struct. @@ -60,12 +65,13 @@ func NewSchedulerFeaturesFromGates(featureGate featuregate.FeatureGate) Features EnableDRAAdminAccess: featureGate.Enabled(features.DRAAdminAccess), EnableDRAConsumableCapacity: featureGate.Enabled(features.DRAConsumableCapacity), EnableDRADeviceTaints: featureGate.Enabled(features.DRADeviceTaints), + EnableDRAListTypeAttributes: featureGate.Enabled(features.DRAListTypeAttributes), EnableDRASchedulerFilterTimeout: featureGate.Enabled(features.DRASchedulerFilterTimeout), EnableDRAResourceClaimDeviceStatus: featureGate.Enabled(features.DRAResourceClaimDeviceStatus), EnableDRADeviceBindingConditions: featureGate.Enabled(features.DRADeviceBindingConditions), + EnableDRAWorkloadResourceClaims: featureGate.Enabled(features.DRAWorkloadResourceClaims), EnableDynamicResourceAllocation: featureGate.Enabled(features.DynamicResourceAllocation), EnableVolumeAttributesClass: featureGate.Enabled(features.VolumeAttributesClass), - EnableCSIMigrationPortworx: featureGate.Enabled(features.CSIMigrationPortworx), EnableVolumeLimitScaling: featureGate.Enabled(features.VolumeLimitScaling), EnableNodeInclusionPolicyInPodTopologySpread: featureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread), EnableMatchLabelKeysInPodTopologySpread: featureGate.Enabled(features.MatchLabelKeysInPodTopologySpread), @@ -78,7 +84,11 @@ func NewSchedulerFeaturesFromGates(featureGate featuregate.FeatureGate) Features EnableStorageCapacityScoring: featureGate.Enabled(features.StorageCapacityScoring), EnableNodeDeclaredFeatures: featureGate.Enabled(features.NodeDeclaredFeatures), EnableGangScheduling: featureGate.Enabled(features.GangScheduling), + EnableGenericWorkload: featureGate.Enabled(features.GenericWorkload), EnableTaintTolerationComparisonOperators: featureGate.Enabled(features.TaintTolerationComparisonOperators), EnableInPlacePodLevelResourcesVerticalScaling: featureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling), + EnableTopologyAwareWorkloadScheduling: featureGate.Enabled(features.TopologyAwareWorkloadScheduling), + EnableDRANodeAllocatableResources: featureGate.Enabled(features.DRANodeAllocatableResources), + EnableWorkloadAwarePreemption: featureGate.Enabled(features.WorkloadAwarePreemption), } } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling.go index df9f0dd32d..130b379f2e 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling.go @@ -22,14 +22,14 @@ import ( "time" v1 "k8s.io/api/core/v1" - schedulingapi "k8s.io/api/scheduling/v1alpha1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha1" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" "k8s.io/klog/v2" fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" "k8s.io/kubernetes/pkg/scheduler/util" ) @@ -37,25 +37,31 @@ import ( const ( // Name is the name of the plugin used in the plugin registry and configurations. Name = names.GangScheduling + // permitTimeoutDuration defines how long the gang pods should + // wait at the permit stage for a quorum before being rejected. + permitTimeoutDuration = 5 * time.Minute ) // GangScheduling is a plugin that enforces "all-or-nothing" scheduling for pods -// belonging to a Workload with a Gang scheduling policy. +// belonging to a PodGroup with a Gang scheduling policy. type GangScheduling struct { - handle fwk.Handle - workloadLister schedulinglisters.WorkloadLister + handle fwk.Handle + podGroupLister schedulinglisters.PodGroupLister + podGroupManager fwk.PodGroupManager + snapshotLister fwk.SharedLister } var _ fwk.EnqueueExtensions = &GangScheduling{} var _ fwk.PreEnqueuePlugin = &GangScheduling{} -var _ fwk.ReservePlugin = &GangScheduling{} var _ fwk.PermitPlugin = &GangScheduling{} // New initializes a new plugin and returns it. func New(_ context.Context, _ runtime.Object, fh fwk.Handle, fts feature.Features) (fwk.Plugin, error) { return &GangScheduling{ - handle: fh, - workloadLister: fh.SharedInformerFactory().Scheduling().V1alpha1().Workloads().Lister(), + handle: fh, + podGroupLister: fh.SharedInformerFactory().Scheduling().V1alpha2().PodGroups().Lister(), + podGroupManager: fh.PodGroupManager(), + snapshotLister: fh.SnapshotSharedLister(), }, nil } @@ -68,88 +74,80 @@ func (pl *GangScheduling) Name() string { func (pl *GangScheduling) EventsToRegister(_ context.Context) ([]fwk.ClusterEventWithHint, error) { return []fwk.ClusterEventWithHint{ // A new pod being added might be the one that completes a gang, meeting its MinCount requirement. - // Workload reference is immutable, so there is no need to subscribe on Pod/Update event. + // PodSchedulingGroup field is immutable, so there is no need to subscribe on Pod/Update event. {Event: fwk.ClusterEvent{Resource: fwk.Pod, ActionType: fwk.Add}, QueueingHintFn: pl.isSchedulableAfterPodAdded}, - // A Workload being added can be making a waiting gang schedulable. - // Workload's PodGroups are immutable, so there's no need to handle Workload/Update event. - {Event: fwk.ClusterEvent{Resource: fwk.Workload, ActionType: fwk.Add}, QueueingHintFn: pl.isSchedulableAfterWorkloadAdded}, + // A PodGroup being added can be making a waiting gang schedulable. + // PodGroups are immutable, so there's no need to handle PodGroup/Update event. + {Event: fwk.ClusterEvent{Resource: fwk.PodGroup, ActionType: fwk.Add}, QueueingHintFn: pl.isSchedulableAfterPodGroupAdded}, }, nil } -// matchingWorkloadReference returns true if two pods belong to the same workload, including their pod group and replica key. -func matchingWorkloadReference(pod1, pod2 *v1.Pod) bool { - return pod1.Spec.WorkloadRef != nil && pod2.Spec.WorkloadRef != nil && pod1.Namespace == pod2.Namespace && *pod1.Spec.WorkloadRef == *pod2.Spec.WorkloadRef -} - func (pl *GangScheduling) isSchedulableAfterPodAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (fwk.QueueingHint, error) { _, addedPod, err := util.As[*v1.Pod](oldObj, newObj) if err != nil { return fwk.Queue, err } - if !matchingWorkloadReference(pod, addedPod) { - logger.V(5).Info("another pod was added but it doesn't match the target pod's workload", - "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "addedPod", klog.KObj(addedPod), "addedWorkloadRef", pod.Spec.WorkloadRef) + if !helper.MatchingSchedulingGroup(pod, addedPod) { + logger.V(5).Info("another pod was added but it doesn't match the target pod's scheduling group", + "pod", klog.KObj(pod), "schedulingGroup", pod.Spec.SchedulingGroup, "addedPod", klog.KObj(addedPod), "addedPodSchedulingGroup", addedPod.Spec.SchedulingGroup) return fwk.QueueSkip, nil } - logger.V(5).Info("another pod was added and it matches the target pod's workload, which may make the pod schedulable", - "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "addedPod", klog.KObj(addedPod), "addedWorkloadRef", pod.Spec.WorkloadRef) + logger.V(5).Info("another pod was added and it matches the target pod's scheduling group, which may make the pod schedulable", + "pod", klog.KObj(pod), "schedulingGroup", pod.Spec.SchedulingGroup, "addedPod", klog.KObj(addedPod), "addedPodSchedulingGroup", addedPod.Spec.SchedulingGroup) return fwk.Queue, nil } -func (pl *GangScheduling) isSchedulableAfterWorkloadAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (fwk.QueueingHint, error) { - _, addedWorkload, err := util.As[*schedulingapi.Workload](oldObj, newObj) +func (pl *GangScheduling) isSchedulableAfterPodGroupAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (fwk.QueueingHint, error) { + _, addedPodGroup, err := util.As[*schedulingapi.PodGroup](oldObj, newObj) if err != nil { return fwk.Queue, err } - if pod.Spec.WorkloadRef == nil || pod.Namespace != addedWorkload.Namespace || pod.Spec.WorkloadRef.Name != addedWorkload.Name { - logger.V(5).Info("workload was added but it doesn't match the target pod's workloadRef", - "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "addedWorkload", klog.KObj(addedWorkload)) + if pod.Spec.SchedulingGroup == nil || pod.Namespace != addedPodGroup.Namespace || *pod.Spec.SchedulingGroup.PodGroupName != addedPodGroup.Name { + logger.V(5).Info("pod group was added but it doesn't match the target pod's scheduling group", + "pod", klog.KObj(pod), "schedulingGroup", pod.Spec.SchedulingGroup, "addedPodGroup", klog.KObj(addedPodGroup)) return fwk.QueueSkip, nil } - logger.V(5).Info("workload was added and it matches the target pod's workload, which may make the pod schedulable", - "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "addedWorkload", klog.KObj(addedWorkload)) + logger.V(5).Info("pod group was added and it matches the target pod's scheduling group, which may make the pod schedulable", + "pod", klog.KObj(pod), "schedulingGroup", pod.Spec.SchedulingGroup, "addedPodGroup", klog.KObj(addedPodGroup)) return fwk.Queue, nil } // PreEnqueue checks if the pod belongs to a gang and, if so, whether the gang has met its MinCount of available pods. // If not, the pod is rejected until more pods arrive. func (pl *GangScheduling) PreEnqueue(ctx context.Context, pod *v1.Pod) *fwk.Status { - if pod.Spec.WorkloadRef == nil { + if pod.Spec.SchedulingGroup == nil { return nil } namespace := pod.Namespace - workloadRef := pod.Spec.WorkloadRef + schedulingGroup := pod.Spec.SchedulingGroup - workload, err := pl.workloadLister.Workloads(namespace).Get(workloadRef.Name) + podGroup, err := pl.podGroupLister.PodGroups(namespace).Get(*schedulingGroup.PodGroupName) if err != nil { if apierrors.IsNotFound(err) { - // The pod is unschedulable until its Workload object is created. - return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("waiting for pods's workload %q to appear in scheduling queue", workloadRef.Name)) + // The pod is unschedulable until its PodGroup object is created. + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("waiting for pods's pod group %q to appear in scheduling queue", *schedulingGroup.PodGroupName)) } - klog.FromContext(ctx).Error(err, "Failed to get workload", "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef) - return fwk.AsStatus(fmt.Errorf("failed to get workload %s/%s", namespace, workloadRef.Name)) + klog.FromContext(ctx).Error(err, "Failed to get pod group", "pod", klog.KObj(pod), "schedulingGroup", schedulingGroup) + return fwk.AsStatus(fmt.Errorf("failed to get pod group %s/%s", namespace, *schedulingGroup.PodGroupName)) } - policy, ok := podGroupPolicy(workload, workloadRef.PodGroup) - if !ok { - return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("pod group %q doesn't exist for a workload %q", workloadRef.PodGroup, workload.Name)) - } + policy := podGroup.Spec.SchedulingPolicy // This plugin only cares about pods with a Gang scheduling policy. if policy.Gang == nil { return nil } - podGroupInfo, err := pl.handle.WorkloadManager().PodGroupInfo(namespace, workloadRef) + podGroupState, err := pl.podGroupManager.PodGroupStates().Get(namespace, *schedulingGroup.PodGroupName) if err != nil { return fwk.AsStatus(err) } - allPods := podGroupInfo.AllPods() - if len(allPods) < int(policy.Gang.MinCount) { + allPodsCount := podGroupState.AllPodsCount() + if allPodsCount < int(policy.Gang.MinCount) { return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "waiting for minCount pods from a gang to appear in scheduling queue") } @@ -157,87 +155,54 @@ func (pl *GangScheduling) PreEnqueue(ctx context.Context, pod *v1.Pod) *fwk.Stat return nil } -// Reserve is called after a node has been selected for the pod. For gang pods, -// this stage marks the pod as "assumed" in the WorkloadManager, -// contributing to the count of pods ready to be co-scheduled at the Permit stage. -func (pl *GangScheduling) Reserve(ctx context.Context, cs fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status { - if pod.Spec.WorkloadRef == nil { - return nil - } - podGroupInfo, err := pl.handle.WorkloadManager().PodGroupInfo(pod.Namespace, pod.Spec.WorkloadRef) - if err != nil { - return fwk.AsStatus(err) - } - podGroupInfo.AssumePod(pod.UID) - return nil -} - -// Unreserve removes the gang pod from the "assumed" state in the WorkloadManager, -// ensuring it doesn't count towards the Permit quorum. -func (pl *GangScheduling) Unreserve(ctx context.Context, cs fwk.CycleState, pod *v1.Pod, nodeName string) { - if pod.Spec.WorkloadRef == nil { - return - } - podGroupInfo, err := pl.handle.WorkloadManager().PodGroupInfo(pod.Namespace, pod.Spec.WorkloadRef) - if err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Failed to get pod group info", "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef) - return - } - podGroupInfo.ForgetPod(pod.UID) -} - -// podGroupPolicy is a helper to find the policy for a specific pod group name in a workload. -func podGroupPolicy(workload *schedulingapi.Workload, podGroupName string) (schedulingapi.PodGroupPolicy, bool) { - for _, podGroup := range workload.Spec.PodGroups { - if podGroup.Name == podGroupName { - return podGroup.Policy, true - } - } - return schedulingapi.PodGroupPolicy{}, false -} - // Permit forces all pods in a gang to wait at this stage. Once the number of waiting (assumed) pods // reaches the gang's MinCount, all pods in the gang are permitted to proceed to binding simultaneously. func (pl *GangScheduling) Permit(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) (*fwk.Status, time.Duration) { - if pod.Spec.WorkloadRef == nil { + if pod.Spec.SchedulingGroup == nil { return nil, 0 } logger := klog.FromContext(ctx) namespace := pod.Namespace - workloadRef := pod.Spec.WorkloadRef + schedulingGroup := pod.Spec.SchedulingGroup - workload, err := pl.workloadLister.Workloads(namespace).Get(workloadRef.Name) + podGroup, err := pl.podGroupLister.PodGroups(namespace).Get(*schedulingGroup.PodGroupName) if err != nil { - // It's likely that the workload was removed or another error happened. - // Returning error to retry the Pod when the Workload is added again. - return fwk.AsStatus(fmt.Errorf("failed to get workload %s/%s: %w", namespace, workloadRef.Name, err)), 0 + // It's likely that the pod group was removed or another error happened. + // Returning error to retry the Pod when the pod group is added again. + return fwk.AsStatus(fmt.Errorf("failed to get podGroup %s/%s: %w", namespace, *schedulingGroup.PodGroupName, err)), 0 } - policy, ok := podGroupPolicy(workload, workloadRef.PodGroup) - if !ok { - return fwk.AsStatus(fmt.Errorf("pod group %q doesn't exist for a workload %q", workloadRef.PodGroup, workload.Name)), 0 - } + policy := podGroup.Spec.SchedulingPolicy // This plugin only cares about pods with a Gang scheduling policy. if policy.Gang == nil { return nil, 0 } - podGroupInfo, err := pl.handle.WorkloadManager().PodGroupInfo(namespace, workloadRef) + // Select a lister for the pod group state based on the currently executed scheduling phase. + // In the pod group scheduling cycle, it reads from the snapshot. + // Otherwise, it reads the runtime state of the pod group from the cache. + var podGroupStateLister fwk.PodGroupStateLister + if state.IsPodGroupSchedulingCycle() { + podGroupStateLister = pl.snapshotLister.PodGroupStates() + } else { + podGroupStateLister = pl.podGroupManager.PodGroupStates() + } + podGroupState, err := podGroupStateLister.Get(namespace, *schedulingGroup.PodGroupName) if err != nil { return fwk.AsStatus(err), 0 } - assumedPods := podGroupInfo.AssumedPods() - assumedOrAssignedPods := assumedPods.Union(podGroupInfo.AssignedPods()) - if len(assumedOrAssignedPods) < int(policy.Gang.MinCount) { + scheduledPodsCount := podGroupState.ScheduledPodsCount() + if scheduledPodsCount < int(policy.Gang.MinCount) { // Activate unscheduled pods from this pod group in case they were waiting for this pod to be scheduled. - unscheduledPods := podGroupInfo.UnscheduledPods() + unscheduledPods := podGroupState.UnscheduledPods() pl.handle.Activate(klog.FromContext(ctx), unscheduledPods) - logger.V(4).Info("Quorum is not met for a gang. Waiting for another pod to allow", "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "activatedPods", len(unscheduledPods)) - return fwk.NewStatus(fwk.Wait, "waiting for minCount pods from a gang to be waiting on permit"), podGroupInfo.SchedulingTimeout() + logger.V(4).Info("Quorum is not met for a gang. Waiting for another pod to allow", "pod", klog.KObj(pod), "schedulingGroup", schedulingGroup, "activatedPods", len(unscheduledPods)) + return fwk.NewStatus(fwk.Wait, "waiting for minCount pods from a gang to be scheduled"), permitTimeoutDuration } - logger.V(4).Info("Quorum is met for a gang. Allowing other pods from a gang waiting on permit", "pod", klog.KObj(pod), "workloadRef", pod.Spec.WorkloadRef, "allowedPods", len(assumedPods)) + assumedPods := podGroupState.AssumedPods() + logger.V(4).Info("Quorum is met for a gang. Allowing other pods from a gang waiting on permit", "pod", klog.KObj(pod), "schedulingGroup", schedulingGroup, "allowedPods", len(assumedPods)) // The quorum is met. Allow this pod and signal all other waiting pods from the same gang to proceed. for podUID := range assumedPods { diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/podgroup.go similarity index 58% rename from vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go rename to vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/podgroup.go index 95c7022932..5acc4e6f41 100644 --- a/vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/podgroup.go @@ -1,6 +1,3 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release - /* Copyright The Kubernetes Authors. @@ -17,12 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. - -package v1beta1 - -func (*AdmissionRequest) ProtoMessage() {} +package helper -func (*AdmissionResponse) ProtoMessage() {} +import ( + v1 "k8s.io/api/core/v1" +) -func (*AdmissionReview) ProtoMessage() {} +// MatchingSchedulingGroup returns true if two pods belong to the same scheduling group. +func MatchingSchedulingGroup(pod1, pod2 *v1.Pod) bool { + return pod1.Namespace == pod2.Namespace && + pod1.Spec.SchedulingGroup != nil && + pod2.Spec.SchedulingGroup != nil && + *pod1.Spec.SchedulingGroup.PodGroupName == *pod2.Spec.SchedulingGroup.PodGroupName +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go index f23d9d9e7e..6733c09851 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go @@ -103,7 +103,8 @@ func calculatePriority(sumScores int64, numContainers int) int64 { return fwk.MaxNodeScore * (sumScores - minThreshold) / (maxThreshold - minThreshold) } -// sumImageScores returns the sum of image scores of all the containers that are already on the node. +// sumImageScores returns the total image score for all container images in the Pod spec, +// including regular containers, init containers, and image volumes, that already exist on the node. // Each image receives a raw score of its size, scaled by scaledImageScore. The raw scores are later used to calculate // the final score. func sumImageScores(nodeInfo fwk.NodeInfo, pod *v1.Pod, totalNumNodes int) int64 { @@ -118,6 +119,14 @@ func sumImageScores(nodeInfo fwk.NodeInfo, pod *v1.Pod, totalNumNodes int) int64 sum += scaledImageScore(state, totalNumNodes) } } + for _, volume := range pod.Spec.Volumes { + if volume.Image == nil { + continue + } + if state, ok := nodeInfo.GetImageStates()[normalizedImageName(volume.Image.Reference)]; ok { + sum += scaledImageScore(state, totalNumNodes) + } + } return sum } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go index e5d8463c72..7b521680af 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go @@ -173,7 +173,17 @@ func (pl *InterPodAffinity) isSchedulableAfterPodChange(logger klog.Logger, pod if err != nil { return fwk.Queue, err } - if (modifiedPod != nil && modifiedPod.Spec.NodeName == "") || (originalPod != nil && originalPod.Spec.NodeName == "") { + if modifiedPod != nil && originalPod != nil && pod.UID == modifiedPod.UID { + // The only update event we listen on is UpdatePodLabel, so we can assume the labels have changed. + // The pod can become schedulable after update to its labels because e.g. some other pod might have + // anti-affinity on the old labels but not on the new ones. + logger.V(5).Info("the target pod labels have changed and it may be schedulable now", + "pod", klog.KObj(pod)) + return fwk.Queue, nil + } + // We don't need to check cases where NodeName or NominatedNodeName changes on a pod because in those cases Add/Delete event is fired + if (modifiedPod != nil && modifiedPod.Spec.NodeName == "" && modifiedPod.Status.NominatedNodeName == "") || + (originalPod != nil && originalPod.Spec.NodeName == "" && originalPod.Status.NominatedNodeName == "") { logger.V(5).Info("the added/updated/deleted pod is unscheduled, so it doesn't make the target pod schedulable", "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod), "modifiedPod", klog.KObj(modifiedPod)) return fwk.QueueSkip, nil @@ -220,15 +230,27 @@ func (pl *InterPodAffinity) isSchedulableAfterPodChange(logger klog.Logger, pod return fwk.QueueSkip, nil } - // Pod is deleted. Return Queue when the deleted pod matching the target pod's anti-affinity. - if !podMatchesAllAffinityTerms(antiTerms, originalPod) { - logger.V(5).Info("a scheduled pod was deleted but it doesn't match the target pod's anti-affinity", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return fwk.QueueSkip, nil + // Pod is deleted. Return Queue when the deleted pod matches the target pod's anti-affinity or vice versa. + + if podMatchesAllAffinityTerms(antiTerms, originalPod) { + logger.V(5).Info("a scheduled pod was deleted and it matches the target pod's anti-affinity. The pod may be schedulable now", + "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod)) + return fwk.Queue, nil } - logger.V(5).Info("a scheduled pod was deleted and it matches the target pod's anti-affinity. The pod may be schedulable now", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return fwk.Queue, nil + + originalPodAntiTerms, err := fwk.GetAffinityTerms(originalPod, fwk.GetPodAntiAffinityTerms(originalPod.Spec.Affinity)) + if err != nil { + return fwk.Queue, err + } + if podMatchesAllAffinityTerms(originalPodAntiTerms, pod) { + logger.V(5).Info("a scheduled pod was deleted and the target pod matches the deleted pod's anti-affinity. The pod may be schedulable now", + "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod)) + return fwk.Queue, nil + } + + logger.V(5).Info("a scheduled pod was deleted but it doesn't match the target pod's anti-affinity, nor vice versa", + "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod)) + return fwk.QueueSkip, nil } func (pl *InterPodAffinity) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (fwk.QueueingHint, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go index 60915c352a..e63efba701 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go @@ -38,4 +38,6 @@ const ( VolumeBinding = "VolumeBinding" VolumeRestrictions = "VolumeRestrictions" VolumeZone = "VolumeZone" + TopologyPlacementGenerator = "TopologyPlacementGenerator" + PodGroupPodsCount = "PodGroupPodsCount" ) diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodedeclaredfeatures/nodedeclaredfeatures.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodedeclaredfeatures/nodedeclaredfeatures.go index 330f8ed7a3..faceea9b93 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodedeclaredfeatures/nodedeclaredfeatures.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodedeclaredfeatures/nodedeclaredfeatures.go @@ -20,15 +20,12 @@ import ( "context" "fmt" "slices" - "strings" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" versionutil "k8s.io/apimachinery/pkg/util/version" "k8s.io/component-base/version" ndf "k8s.io/component-helpers/nodedeclaredfeatures" - "k8s.io/component-helpers/nodedeclaredfeatures/features" "k8s.io/klog/v2" fwk "k8s.io/kube-scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" @@ -41,6 +38,9 @@ const ( Name = names.NodeDeclaredFeatures // preFilterStateKey is the key in CycleState used to store the pod's feature requirements. preFilterStateKey fwk.StateKey = "PreFilter" + Name + // errReasonUnsatisfiedRequirements is the status reason given when a node's declared features + // doesn't meet the pod's required features. + errReasonUnsatisfiedRequirements = "node(s) didn't match Pod's required features" ) // preFilterState computed at PreFilter and used at Filter. @@ -76,10 +76,7 @@ func New(ctx context.Context, plArgs runtime.Object, fh fwk.Handle, fts feature. // Disabled, won't do anything. return &NodeDeclaredFeatures{}, nil } - ndfFramework, err := ndf.New(features.AllFeatures) - if err != nil { - return nil, fmt.Errorf("failed to create node feature framework: %w", err) - } + ndfFramework := ndf.DefaultFramework ver, err := versionutil.Parse(version.Get().String()) if err != nil { return nil, fmt.Errorf("failed to parse version: %w", err) @@ -98,7 +95,7 @@ func (pl *NodeDeclaredFeatures) PreFilter(ctx context.Context, cycleState fwk.Cy if err != nil { return nil, fwk.AsStatus(err) } - if reqs.Len() == 0 { + if reqs.IsEmpty() { return nil, fwk.NewStatus(fwk.Skip) } cycleState.Write(preFilterStateKey, &preFilterState{reqs: reqs}) @@ -119,12 +116,13 @@ func (pl *NodeDeclaredFeatures) Filter(ctx context.Context, cycleState fwk.Cycle if err != nil { return fwk.AsStatus(err) } - result, err := ndf.MatchNodeFeatureSet(s.reqs, nodeInfo.GetNodeDeclaredFeatures()) + // Don't use ndf.MatchNodeFeatureSet(...) here since we don't want to pay the cost of computing the feature diff. + isMatch, err := s.reqs.IsSubset(nodeInfo.GetNodeDeclaredFeatures()) if err != nil { return fwk.AsStatus(err) } - if !result.IsMatch { - return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, fmt.Sprintf("node declared features check failed - unsatisfied requirements: %s", strings.Join(result.UnsatisfiedRequirements, ", "))) + if !isMatch { + return fwk.NewStatus(fwk.UnschedulableAndUnresolvable, errReasonUnsatisfiedRequirements) } return nil } @@ -135,9 +133,8 @@ func (pl *NodeDeclaredFeatures) SignPod(ctx context.Context, pod *v1.Pod) ([]fwk if err != nil { return nil, fwk.AsStatus(err) } - featuresList := sets.List(fs.Set) return []fwk.SignFragment{ - {Key: fwk.FeaturesSignerName, Value: featuresList}, + {Key: fwk.FeaturesSignerName, Value: fs.String()}, }, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go index 035c77b334..6a87b04226 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go @@ -123,9 +123,18 @@ func (pl *BalancedAllocation) SignPod(ctx context.Context, pod *v1.Pod) ([]fwk.S EnablePodLevelResources: pl.enablePodLevelResources, EnableDRAExtendedResource: pl.enableDRAExtendedResource, } - if pl.enableDRAExtendedResource { - return nil, fwk.NewStatus(fwk.Unschedulable, "signature disabled when dra extended resources enabled") + podRequest := computePodResourceRequest(pod, opts) + for rName, rQuant := range podRequest.ScalarResources { + // Skip in case request quantity is zero + if rQuant == 0 { + continue + } + + if shouldDelegateResourceToDRA(rName, nil, pl.draManager, opts) { + return nil, fwk.NewStatus(fwk.Unschedulable, "signature disabled when dra extended resources are used in the cluster") + } + } } return []fwk.SignFragment{ @@ -187,18 +196,35 @@ func NewBalancedAllocation(_ context.Context, baArgs runtime.Object, h fwk.Handl useRequested: true, resources: args.Resources, enableInPlacePodLevelResourcesVerticalScaling: fts.EnableInPlacePodLevelResourcesVerticalScaling, + draManager: h.SharedDRAManager(), }, }, nil } -func balancedResourceScorer(requested, allocable []int64) int64 { +func balancedResourceScorer(requested, allocated, allocatable []int64) int64 { + // Compute the score for the node with pending pod requests + scoreWithPod := balancedResourceScore(requested, allocatable) + // Compute the score for the node without pending pod requests + scoreWithoutPod := balancedResourceScore(allocated, allocatable) + // Score based on the improvement to the node balance (before vs after adding the pod). + // Scores with/without pod are in range [MaxNodeScore/2, MaxNodeScore]. + // Therefore, their difference will be in range [-MaxNodeScore/2, MaxNodeScore/2]. + // This operation brings the range back to [MaxNodeScore/2, MaxNodeScore] + // to be closer to the original implementation that only considered the score after adding the pod. + // If the difference to the balance is small, the score will be around 75. + // If the balance is improved, the score will move towards 100. + // If the balance is decreased, the score will move towards 50. + return fwk.MaxNodeScore/2 + (fwk.MaxNodeScore/2+scoreWithPod-scoreWithoutPod)/2 +} + +func balancedResourceScore(requested, allocatable []int64) int64 { var resourceToFractions []float64 var totalFraction float64 for i := range requested { - if allocable[i] == 0 { + if allocatable[i] == 0 { continue } - fraction := float64(requested[i]) / float64(allocable[i]) + fraction := float64(requested[i]) / float64(allocatable[i]) if fraction > 1 { fraction = 1 } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go index a423986d5c..5c2bcc4497 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go @@ -47,6 +47,7 @@ var _ fwk.EnqueueExtensions = &Fit{} var _ fwk.PreScorePlugin = &Fit{} var _ fwk.ScorePlugin = &Fit{} var _ fwk.SignPlugin = &Fit{} +var _ fwk.PlacementScorePlugin = &Fit{} const ( // Name is the name of the plugin used in the plugin registry and configurations. @@ -62,27 +63,27 @@ const ( // nodeResourceStrategyTypeMap maps strategy to scorer implementation var nodeResourceStrategyTypeMap = map[config.ScoringStrategyType]scorer{ - config.LeastAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources + config.LeastAllocated: func(strategy *config.ScoringStrategy) *resourceAllocationScorer { + resources := strategy.Resources return &resourceAllocationScorer{ Name: string(config.LeastAllocated), scorer: leastResourceScorer(resources), resources: resources, } }, - config.MostAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources + config.MostAllocated: func(strategy *config.ScoringStrategy) *resourceAllocationScorer { + resources := strategy.Resources return &resourceAllocationScorer{ Name: string(config.MostAllocated), scorer: mostResourceScorer(resources), resources: resources, } }, - config.RequestedToCapacityRatio: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources + config.RequestedToCapacityRatio: func(strategy *config.ScoringStrategy) *resourceAllocationScorer { + resources := strategy.Resources return &resourceAllocationScorer{ Name: string(config.RequestedToCapacityRatio), - scorer: requestedToCapacityRatioScorer(resources, args.ScoringStrategy.RequestedToCapacityRatio.Shape), + scorer: requestedToCapacityRatioScorer(resources, strategy.RequestedToCapacityRatio.Shape), resources: resources, } }, @@ -100,6 +101,7 @@ type Fit struct { enableInPlacePodLevelResourcesVerticalScaling bool handle fwk.Handle *resourceAllocationScorer + placementScorer *resourceAllocationScorer } // ScoreExtensions of the Score plugin. @@ -177,13 +179,34 @@ func (pl *Fit) SignPod(ctx context.Context, pod *v1.Pod) ([]fwk.SignFragment, *f EnableDRAExtendedResource: pl.enableDRAExtendedResource, } if pl.enableDRAExtendedResource { - return nil, fwk.NewStatus(fwk.Unschedulable, "signature disabled when dra extended resources enabled") + podRequest := computePodResourceRequest(pod, opts) + for rName, rQuant := range podRequest.ScalarResources { + // Skip in case request quantity is zero + if rQuant == 0 { + continue + } + if shouldDelegateResourceToDRA(rName, nil, pl.draManager, opts) { + return nil, fwk.NewStatus(fwk.Unschedulable, "signature disabled when dra extended resources are used in the cluster") + } + } } + return []fwk.SignFragment{ {Key: fwk.ResourcesSignerName, Value: computePodResourceRequest(pod, opts)}, }, nil } +func getScorer(strategy *config.ScoringStrategy) (*resourceAllocationScorer, error) { + if strategy == nil { + return nil, fmt.Errorf("scoring strategy not specified") + } + scorerFactory, exists := nodeResourceStrategyTypeMap[strategy.Type] + if !exists { + return nil, fmt.Errorf("scoring strategy %s is not supported", strategy.Type) + } + return scorerFactory(strategy), nil +} + // NewFit initializes a new plugin and returns it. func NewFit(_ context.Context, plArgs runtime.Object, h fwk.Handle, fts feature.Features) (fwk.Plugin, error) { args, ok := plArgs.(*config.NodeResourcesFitArgs) @@ -194,27 +217,23 @@ func NewFit(_ context.Context, plArgs runtime.Object, h fwk.Handle, fts feature. return nil, err } - if args.ScoringStrategy == nil { - return nil, fmt.Errorf("scoring strategy not specified") - } - - strategy := args.ScoringStrategy.Type - scorePlugin, exists := nodeResourceStrategyTypeMap[strategy] - if !exists { - return nil, fmt.Errorf("scoring strategy %s is not supported", strategy) + scorer, err := getScorer(args.ScoringStrategy) + if err != nil { + return nil, err } - - scorer := scorePlugin(args) if fts.EnableDRAExtendedResource { scorer.enableDRAExtendedResource = true scorer.draManager = h.SharedDRAManager() scorer.draFeatures = dynamicresources.AllocatorFeatures(fts) // Create a CEL cache for device class selector compilation // This cache improves performance by avoiding recompilation of the same CEL expressions - scorer.DRACaches.celCache = cel.NewCache(10, cel.Features{EnableConsumableCapacity: fts.EnableDRAConsumableCapacity}) + scorer.DRACaches.celCache = cel.NewCache(10, cel.Features{ + EnableConsumableCapacity: fts.EnableDRAConsumableCapacity, + EnableListTypeAttributes: fts.EnableDRAListTypeAttributes, + }) } - return &Fit{ + pl := &Fit{ ignoredResources: sets.New(args.IgnoredResources...), ignoredResourceGroups: sets.New(args.IgnoredResourceGroups...), enableInPlacePodVerticalScaling: fts.EnableInPlacePodVerticalScaling, @@ -225,42 +244,51 @@ func NewFit(_ context.Context, plArgs runtime.Object, h fwk.Handle, fts feature. enableDRAExtendedResource: fts.EnableDRAExtendedResource, enableInPlacePodLevelResourcesVerticalScaling: fts.EnableInPlacePodLevelResourcesVerticalScaling, resourceAllocationScorer: scorer, - }, nil + } + + if fts.EnableTopologyAwareWorkloadScheduling { + placementScorer, err := getScorer(&config.ScoringStrategy{ + Type: config.MostAllocated, + Resources: args.ScoringStrategy.Resources, + }) + if err != nil { + return nil, err + } + pl.placementScorer = placementScorer + } + + return pl, nil } // ResourceRequestsOptions contains feature gate flags for resource request computation. type ResourceRequestsOptions struct { - EnablePodLevelResources bool - EnableDRAExtendedResource bool + EnablePodLevelResources bool + EnableDRAExtendedResource bool + EnableDRANodeAllocatableResources bool } // shouldDelegateResourceToDRA checks if the given resource should be delegated to the DRA plugin. // It returns true if: // 1. The resource is not a scalar resource in the node's allocatable (not provided by device plugin) -// 2. Either: -// a. A device class mapping exists for the resource in the cache (when draManager is available), OR -// b. draManager is nil (e.g., kubelet admission check) and the resource name suggests it's a DRA resource +// 2. A device class mapping exists for the resource in the cache (when draManager is available) func shouldDelegateResourceToDRA(rName v1.ResourceName, nodeInfo fwk.NodeInfo, draManager fwk.SharedDRAManager, opts ResourceRequestsOptions) bool { if !opts.EnableDRAExtendedResource { return false } - if allocatable := nodeInfo.GetAllocatable().GetScalarResources()[rName]; allocatable > 0 { - return false + if nodeInfo != nil { + if allocatable := nodeInfo.GetAllocatable().GetScalarResources()[rName]; allocatable > 0 { + return false + } } - // If draManager is available, check the cache for a mapping - if draManager != nil { - cache := draManager.DeviceClassResolver() - return cache.GetDeviceClass(rName) != nil + if draManager == nil { + return false } - // If draManager is nil (e.g., kubelet admission check), delegate resources that are not in - // the node's allocatable. This allows pod to be admitted even when the kubelet - // doesn't have access to the device class cache. - // This can be removed once we have the fix for kubelet to admit pods with - // implicit extended resources or node's allocatable for the extended resource is zero. - return true + // If draManager is available, check the cache for a mapping + cache := draManager.DeviceClassResolver() + return cache.GetDeviceClass(rName) != nil } // computePodResourceRequest returns a framework.Resource that covers the largest @@ -294,7 +322,8 @@ func computePodResourceRequest(pod *v1.Pod, opts ResourceRequestsOptions) *preFi // pod hasn't scheduled yet so we don't need to worry about InPlacePodVerticalScalingEnabled reqs := resource.PodRequests(pod, resource.PodResourcesOptions{ // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !opts.EnablePodLevelResources, + SkipPodLevelResources: !opts.EnablePodLevelResources, + UseDRANodeAllocatableResourceClaimStatus: opts.EnableDRANodeAllocatableResources, }) result := &preFilterState{} result.SetMaxResource(reqs) @@ -755,3 +784,13 @@ func (f *Fit) Score(ctx context.Context, state fwk.CycleState, pod *v1.Pod, node return f.score(ctx, pod, nodeInfo, s.podRequests, s.draPreScoreState) } + +// PlacementScoreExtensions is not used by this plugin. +func (f *Fit) PlacementScoreExtensions() fwk.PlacementScoreExtensions { + return nil +} + +// ScorePlacement scores capacity ratio on all nodes in the placement including all assigned pod group pods' resource requests. +func (f *Fit) ScorePlacement(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, placement *fwk.PodGroupAssignments) (int64, *fwk.Status) { + return f.placementScorer.scorePlacement(ctx, podGroup, placement) +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go index 20a456d963..19fa2761d3 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go @@ -27,8 +27,8 @@ import ( // // Details: // (cpu((capacity-requested)*MaxNodeScore*cpuWeight/capacity) + memory((capacity-requested)*MaxNodeScore*memoryWeight/capacity) + ...)/weightSum -func leastResourceScorer(resources []config.ResourceSpec) func([]int64, []int64) int64 { - return func(requested, allocable []int64) int64 { +func leastResourceScorer(resources []config.ResourceSpec) func([]int64, []int64, []int64) int64 { + return func(requested, _, allocable []int64) int64 { var nodeScore, weightSum int64 for i := range requested { if allocable[i] == 0 { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go index 3e694d1b22..2d514c0540 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go @@ -27,8 +27,8 @@ import ( // // Details: // (cpu(MaxNodeScore * requested * cpuWeight / capacity) + memory(MaxNodeScore * requested * memoryWeight / capacity) + ...) / weightSum -func mostResourceScorer(resources []config.ResourceSpec) func(requested, allocable []int64) int64 { - return func(requested, allocable []int64) int64 { +func mostResourceScorer(resources []config.ResourceSpec) func(requested, _, allocable []int64) int64 { + return func(requested, _, allocable []int64) int64 { var nodeScore, weightSum int64 for i := range requested { if allocable[i] == 0 { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go index f6c7838be3..a15500d4bc 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go @@ -28,7 +28,7 @@ const maxUtilization = 100 // buildRequestedToCapacityRatioScorerFunction allows users to apply bin packing // on core resources like CPU, Memory as well as extended resources like accelerators. -func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.FunctionShape, resources []config.ResourceSpec) func([]int64, []int64) int64 { +func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.FunctionShape, resources []config.ResourceSpec) func([]int64, []int64, []int64) int64 { rawScoringFunction := helper.BuildBrokenLinearFunction(scoringFunctionShape) resourceScoringFunction := func(requested, capacity int64) int64 { if capacity == 0 || requested > capacity { @@ -37,7 +37,7 @@ func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.Fun return rawScoringFunction(requested * maxUtilization / capacity) } - return func(requested, allocable []int64) int64 { + return func(requested, _, allocable []int64) int64 { var nodeScore, weightSum int64 for i := range requested { if allocable[i] == 0 { @@ -57,7 +57,7 @@ func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.Fun } } -func requestedToCapacityRatioScorer(resources []config.ResourceSpec, shape []config.UtilizationShapePoint) func([]int64, []int64) int64 { +func requestedToCapacityRatioScorer(resources []config.ResourceSpec, shape []config.UtilizationShapePoint) func([]int64, []int64, []int64) int64 { shapes := make([]helper.FunctionShapePoint, 0, len(shape)) for _, point := range shape { shapes = append(shapes, helper.FunctionShapePoint{ diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go index b4f6f16b4b..ab694a4441 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go @@ -36,7 +36,7 @@ import ( ) // scorer is decorator for resourceAllocationScorer -type scorer func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer +type scorer func(strategy *config.ScoringStrategy) *resourceAllocationScorer // DRACaches holds various caches used for DRA-related computations type DRACaches struct { @@ -58,7 +58,7 @@ type resourceAllocationScorer struct { // used to decide whether to use Requested or NonZeroRequested for // cpu and memory. useRequested bool - scorer func(requested, allocable []int64) int64 + scorer func(requested, allocated, allocatable []int64) int64 resources []config.ResourceSpec draFeatures structured.Features draManager fwk.SharedDRAManager @@ -150,19 +150,9 @@ func (r *resourceAllocationScorer) score( return 0, fwk.NewStatus(fwk.Error, "resources not found") } - requested := make([]int64, len(r.resources)) - allocatable := make([]int64, len(r.resources)) - for i := range r.resources { - alloc, req := r.calculateResourceAllocatableRequest(ctx, nodeInfo, v1.ResourceName(r.resources[i].Name), podRequests[i], draPreScoreState) - // Only fill the extended resource entry when it's non-zero. - if alloc == 0 { - continue - } - allocatable[i] = alloc - requested[i] = req - } + requested, allocated, allocatable := r.calculateNodeAllocatableRequest(ctx, nodeInfo, podRequests, draPreScoreState) - score := r.scorer(requested, allocatable) + score := r.scorer(requested, allocated, allocatable) if loggerV := logger.V(10); loggerV.Enabled() { // Serializing these maps is costly. loggerV.Info("Listed internal info for allocatable resources, requested resources and score", "pod", @@ -174,34 +164,55 @@ func (r *resourceAllocationScorer) score( return score, nil } +func (r *resourceAllocationScorer) calculateNodeAllocatableRequest( + ctx context.Context, + nodeInfo fwk.NodeInfo, + podRequests []int64, + draPreScoreState *draPreScoreState, +) (requested []int64, allocated []int64, allocatable []int64) { + requested = make([]int64, len(r.resources)) + allocated = make([]int64, len(r.resources)) + allocatable = make([]int64, len(r.resources)) + for i := range r.resources { + resource := v1.ResourceName(r.resources[i].Name) + // If it's an extended resource, and the pod doesn't request it. + // We don't fill the resource entry as an implication to bypass scoring on it. + if podRequests[i] == 0 && schedutil.IsScalarResourceName(resource) { + continue + } + nodeAllocatable, nodeAllocated := r.calculateResourceAllocatableRequest(ctx, nodeInfo, resource, draPreScoreState) + // Only fill the extended resource entry when it's non-zero. + if nodeAllocatable == 0 { + continue + } + allocatable[i] = nodeAllocatable + allocated[i] = nodeAllocated + requested[i] = allocated[i] + podRequests[i] + } + return requested, allocated, allocatable +} + // calculateResourceAllocatableRequest returns 2 parameters: // - 1st param: quantity of allocatable resource on the node. // - 2nd param: aggregated quantity of requested resource on the node. -// Note: if it's an extended resource, and the pod doesn't request it, (0, 0) is returned. func (r *resourceAllocationScorer) calculateResourceAllocatableRequest( ctx context.Context, nodeInfo fwk.NodeInfo, resource v1.ResourceName, - podRequest int64, draPreScoreState *draPreScoreState, -) (int64, int64) { +) (allocatable int64, allocated int64) { requested := nodeInfo.GetNonZeroRequested() if r.useRequested { requested = nodeInfo.GetRequested() } - // If it's an extended resource, and the pod doesn't request it. We return (0, 0) - // as an implication to bypass scoring on this resource. - if podRequest == 0 && schedutil.IsScalarResourceName(resource) { - return 0, 0 - } switch resource { case v1.ResourceCPU: - return nodeInfo.GetAllocatable().GetMilliCPU(), (requested.GetMilliCPU() + podRequest) + return nodeInfo.GetAllocatable().GetMilliCPU(), requested.GetMilliCPU() case v1.ResourceMemory: - return nodeInfo.GetAllocatable().GetMemory(), (requested.GetMemory() + podRequest) + return nodeInfo.GetAllocatable().GetMemory(), requested.GetMemory() case v1.ResourceEphemeralStorage: - return nodeInfo.GetAllocatable().GetEphemeralStorage(), (nodeInfo.GetRequested().GetEphemeralStorage() + podRequest) + return nodeInfo.GetAllocatable().GetEphemeralStorage(), nodeInfo.GetRequested().GetEphemeralStorage() default: allocatable, exists := nodeInfo.GetAllocatable().GetScalarResources()[resource] if allocatable == 0 && r.enableDRAExtendedResource && draPreScoreState != nil { @@ -209,11 +220,11 @@ func (r *resourceAllocationScorer) calculateResourceAllocatableRequest( // Calculate allocatable and requested for resources backed by DRA. allocatable, allocated := r.calculateDRAExtendedResourceAllocatableRequest(ctx, nodeInfo.Node(), resource, draPreScoreState) if allocatable > 0 { - return allocatable, allocated + podRequest + return allocatable, allocated } } if exists { - return allocatable, (nodeInfo.GetRequested().GetScalarResources()[resource] + podRequest) + return allocatable, nodeInfo.GetRequested().GetScalarResources()[resource] } } klog.FromContext(ctx).V(10).Info("Requested resource is omitted for node score calculation", "resourceName", resource) @@ -490,3 +501,44 @@ func (r *resourceAllocationScorer) deviceMatchesClass(ctx context.Context, devic return true, nil } + +func (r *resourceAllocationScorer) scorePlacement( + ctx context.Context, + podGroupInfo fwk.PodGroupInfo, + podGroupAssignments *fwk.PodGroupAssignments, +) (int64, *fwk.Status) { + requested := make([]int64, len(r.resources)) + // Calculate requests for the pod group pods scheduled for this placement + for _, assignment := range podGroupAssignments.ProposedAssignments { + pod := assignment.GetPod() + podRequests := r.calculatePodResourceRequestList(pod, r.resources) + for i := range len(r.resources) { + requested[i] += podRequests[i] + } + } + allocatable := make([]int64, len(r.resources)) + allocated := make([]int64, len(r.resources)) + // Calculate resources on all nodes in this placement + for _, node := range podGroupAssignments.Nodes { + _, nodeAllocated, nodeAllocatable := r.calculateNodeAllocatableRequest(ctx, node, requested, nil) + for i := range r.resources { + allocatable[i] += nodeAllocatable[i] + allocated[i] += nodeAllocated[i] + // requested includes both the already existing pods + // and the pod group pods that are being scheduled for this placement + requested[i] += nodeAllocated[i] + } + } + + score := r.scorer(requested, allocated, allocatable) + + logger := klog.FromContext(ctx) + if loggerV := logger.V(10); loggerV.Enabled() { // Serializing these maps is costly. + loggerV.Info("Listed internal info for placement's allocatable resources, requested resources and placement score", "podGroup", + klog.KRef(podGroupInfo.GetNamespace(), podGroupInfo.GetName()), "placement", podGroupAssignments.Name, "resourceAllocationScorer", r.Name, + "allocatableResource", allocatable, "requestedResource", requested, "resourceScore", score, + ) + } + + return score, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go deleted file mode 100644 index fd4345117b..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2019 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 noderesources - -import ( - "github.com/google/go-cmp/cmp/cmpopts" //nolint:depguard - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -var ( - ignoreBadValueDetail = cmpopts.IgnoreFields(field.Error{}, "BadValue", "Detail") - defaultResources = []config.ResourceSpec{ - {Name: string(v1.ResourceCPU), Weight: 1}, - {Name: string(v1.ResourceMemory), Weight: 1}, - } - extendedRes = "abc.com/xyz" - extendedResourceSet = []config.ResourceSpec{ - {Name: string(v1.ResourceCPU), Weight: 1}, - {Name: string(v1.ResourceMemory), Weight: 1}, - {Name: extendedRes, Weight: 1}, - } -) - -func makeNode(node string, milliCPU, memory int64, extendedResource map[string]int64) *v1.Node { - resourceList := make(map[v1.ResourceName]resource.Quantity) - for res, quantity := range extendedResource { - resourceList[v1.ResourceName(res)] = *resource.NewQuantity(quantity, resource.DecimalSI) - } - resourceList[v1.ResourceCPU] = *resource.NewMilliQuantity(milliCPU, resource.DecimalSI) - resourceList[v1.ResourceMemory] = *resource.NewQuantity(memory, resource.BinarySI) - return &v1.Node{ - ObjectMeta: metav1.ObjectMeta{Name: node}, - Status: v1.NodeStatus{ - Capacity: resourceList, - Allocatable: resourceList, - }, - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go index 07be0e040b..7ba415589b 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go @@ -23,11 +23,12 @@ import ( v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/rand" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" corelisters "k8s.io/client-go/listers/core/v1" storagelisters "k8s.io/client-go/listers/storage/v1" + "k8s.io/client-go/tools/cache" ephemeral "k8s.io/component-helpers/storage/ephemeral" storagehelpers "k8s.io/component-helpers/storage/volume" csitrans "k8s.io/csi-translation-lib" @@ -63,11 +64,11 @@ type CSILimits struct { scLister storagelisters.StorageClassLister vaLister storagelisters.VolumeAttachmentLister csiDriverLister storagelisters.CSIDriverLister + vaIndexer cache.Indexer - enableCSIMigrationPortworx bool - randomVolumeIDPrefix string - enableVolumeLimitScaling bool - translator InTreeToCSITranslator + randomVolumeIDPrefix string + enableVolumeLimitScaling bool + translator InTreeToCSITranslator } var _ fwk.PreFilterPlugin = &CSILimits{} @@ -356,7 +357,7 @@ func (pl *CSILimits) Filter(ctx context.Context, _ fwk.CycleState, pod *v1.Pod, func (pl *CSILimits) checkCSIDriverOnNode(pluginName string, csiNode *storagev1.CSINode) (bool, error) { // the registered driver must be a CSI driver to enforce this limit, if we can't find the driver, // we assume the driver may not be a CSI driver and allow the pod to be scheduled. - _, err := pl.csiDriverLister.Get(pluginName) + csiDriver, err := pl.csiDriverLister.Get(pluginName) if err != nil { if apierrors.IsNotFound(err) { return true, nil @@ -364,6 +365,12 @@ func (pl *CSILimits) checkCSIDriverOnNode(pluginName string, csiNode *storagev1. return false, fmt.Errorf("error getting CSIDriver for provider %s: %w", pluginName, err) } + driverOptin := csiDriver.Spec.PreventPodSchedulingIfMissing + + if driverOptin == nil || !*driverOptin { + return true, nil + } + if csiNode == nil { return false, nil } @@ -458,7 +465,7 @@ func (pl *CSILimits) checkAttachableInlineVolume(logger klog.Logger, vol *v1.Vol if err != nil { return fmt.Errorf("looking up provisioner name for volume %s: %w", vol.Name, err) } - if !isCSIMigrationOn(csiNode, inTreeProvisionerName, pl.enableCSIMigrationPortworx) { + if !isCSIMigrationOn(csiNode, inTreeProvisionerName) { csiNodeName := "" if csiNode != nil { csiNodeName = csiNode.Name @@ -519,7 +526,7 @@ func (pl *CSILimits) getCSIDriverInfo(logger klog.Logger, csiNode *storagev1.CSI return "", "" } - if !isCSIMigrationOn(csiNode, pluginName, pl.enableCSIMigrationPortworx) { + if !isCSIMigrationOn(csiNode, pluginName) { logger.V(5).Info("CSI Migration of plugin is not enabled", "plugin", pluginName) return "", "" } @@ -567,7 +574,7 @@ func (pl *CSILimits) getCSIDriverInfoFromSC(logger klog.Logger, csiNode *storage provisioner := storageClass.Provisioner if pl.translator.IsMigratableIntreePluginByName(provisioner) { - if !isCSIMigrationOn(csiNode, provisioner, pl.enableCSIMigrationPortworx) { + if !isCSIMigrationOn(csiNode, provisioner) { logger.V(5).Info("CSI Migration of provisioner is not enabled", "provisioner", provisioner) return "", "" } @@ -583,6 +590,14 @@ func (pl *CSILimits) getCSIDriverInfoFromSC(logger klog.Logger, csiNode *storage return provisioner, volumeHandle } +func volumeAttachmentIndexer(obj interface{}) ([]string, error) { + va, ok := obj.(*storagev1.VolumeAttachment) + if !ok { + return []string{}, nil + } + return []string{va.Spec.NodeName}, nil +} + // NewCSI initializes a new plugin and returns it. func NewCSI(_ context.Context, _ runtime.Object, handle fwk.Handle, fts feature.Features) (fwk.Plugin, error) { informerFactory := handle.SharedInformerFactory() @@ -591,19 +606,25 @@ func NewCSI(_ context.Context, _ runtime.Object, handle fwk.Handle, fts feature. scLister := informerFactory.Storage().V1().StorageClasses().Lister() vaLister := informerFactory.Storage().V1().VolumeAttachments().Lister() csiDriverLister := informerFactory.Storage().V1().CSIDrivers().Lister() + vaInformer := informerFactory.Storage().V1().VolumeAttachments().Informer() + if err := vaInformer.AddIndexers(cache.Indexers{vaIndexKey: volumeAttachmentIndexer}); err != nil { + if vaInformer.GetIndexer().GetIndexers()[vaIndexKey] == nil { + return nil, fmt.Errorf("failed to add index to VA informer: %w", err) + } + } csiTranslator := csitrans.New() return &CSILimits{ - csiManager: handle.SharedCSIManager(), - pvLister: pvLister, - pvcLister: pvcLister, - scLister: scLister, - vaLister: vaLister, - csiDriverLister: csiDriverLister, - enableCSIMigrationPortworx: fts.EnableCSIMigrationPortworx, - enableVolumeLimitScaling: fts.EnableVolumeLimitScaling, - randomVolumeIDPrefix: rand.String(32), - translator: csiTranslator, + csiManager: handle.SharedCSIManager(), + pvLister: pvLister, + pvcLister: pvcLister, + scLister: scLister, + vaLister: vaLister, + csiDriverLister: csiDriverLister, + enableVolumeLimitScaling: fts.EnableVolumeLimitScaling, + randomVolumeIDPrefix: rand.String(32), + translator: csiTranslator, + vaIndexer: vaInformer.GetIndexer(), }, nil } @@ -623,14 +644,22 @@ func getVolumeLimits(csiNode *storagev1.CSINode) map[string]int64 { return nodeVolumeLimits } +const vaIndexKey = "va.spec.nodename" + // getNodeVolumeAttachmentInfo returns a map of volumeID to driver name for the given node. func (pl *CSILimits) getNodeVolumeAttachmentInfo(logger klog.Logger, nodeName string) (map[string]string, error) { volumeAttachments := make(map[string]string) - vas, err := pl.vaLister.List(labels.Everything()) + vas, err := pl.vaIndexer.ByIndex(vaIndexKey, nodeName) if err != nil { return nil, err } - for _, va := range vas { + for _, vao := range vas { + va, ok := vao.(*storagev1.VolumeAttachment) + if !ok { + utilruntime.HandleErrorWithLogger(logger, fmt.Errorf("unexpected object type in volume attachment indexer: %v", vao), + "volume indexer not available") + continue + } if va.Spec.NodeName == nodeName { if va.Spec.Attacher == "" { logger.V(5).Info("VolumeAttachment has no attacher", "VolumeAttachment", klog.KObj(va)) diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go index 7cb761379d..a672895b2e 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go @@ -17,17 +17,13 @@ limitations under the License. package nodevolumelimits import ( - "strings" - - v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" - "k8s.io/apimachinery/pkg/util/sets" csilibplugins "k8s.io/csi-translation-lib/plugins" ) // isCSIMigrationOn returns a boolean value indicating whether // the CSI migration has been enabled for a particular storage plugin. -func isCSIMigrationOn(csiNode *storagev1.CSINode, pluginName string, enableCSIMigrationPortworx bool) bool { +func isCSIMigrationOn(csiNode *storagev1.CSINode, pluginName string) bool { if csiNode == nil || len(pluginName) == 0 { return false } @@ -38,9 +34,7 @@ func isCSIMigrationOn(csiNode *storagev1.CSINode, pluginName string, enableCSIMi case csilibplugins.AWSEBSInTreePluginName: return true case csilibplugins.PortworxVolumePluginName: - if !enableCSIMigrationPortworx { - return false - } + return true case csilibplugins.GCEPDInTreePluginName: return true case csilibplugins.AzureDiskInTreePluginName: @@ -50,22 +44,4 @@ func isCSIMigrationOn(csiNode *storagev1.CSINode, pluginName string, enableCSIMi default: return false } - - // The plugin name should be listed in the CSINode object annotation. - // This indicates that the plugin has been migrated to a CSI driver in the node. - csiNodeAnn := csiNode.GetAnnotations() - if csiNodeAnn == nil { - return false - } - - var mpaSet sets.Set[string] - mpa := csiNodeAnn[v1.MigratedPluginsAnnotationKey] - if len(mpa) == 0 { - mpaSet = sets.New[string]() - } else { - tok := strings.Split(mpa, ",") - mpaSet = sets.New(tok...) - } - - return mpaSet.Has(pluginName) } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount/podgroup_pods_count.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount/podgroup_pods_count.go new file mode 100644 index 0000000000..143e66d763 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount/podgroup_pods_count.go @@ -0,0 +1,87 @@ +/* +Copyright 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 podgrouppodscount + +import ( + "context" + "errors" + + "k8s.io/apimachinery/pkg/runtime" + fwk "k8s.io/kube-scheduler/framework" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" +) + +// PodGroupPodsCount is a placement score plugin that favors placements that can accommodate more pods from the considered PodGroup. +type PodGroupPodsCount struct { + handle fwk.Handle +} + +var _ fwk.PlacementScorePlugin = &PodGroupPodsCount{} + +const Name = names.PodGroupPodsCount + +// New initializes a new plugin and returns it. +func New(_ context.Context, _ runtime.Object, h fwk.Handle, _ feature.Features) (fwk.Plugin, error) { + return &PodGroupPodsCount{handle: h}, nil +} + +// Name returns name of the plugin. It is used in logs, etc. +func (pl *PodGroupPodsCount) Name() string { + return Name +} + +// ScorePlacement calculates a score for a given Placement. +// Both scheduled (assumed/assigned) pods and the proposed assignments are taken into consideration +// when computing the score. This ensures that the relative difference between choices is reduced, +// and small changes to the total count result in small changes to the score. +func (pl *PodGroupPodsCount) ScorePlacement(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, placement *fwk.PodGroupAssignments) (int64, *fwk.Status) { + pgState, err := pl.handle.SnapshotSharedLister().PodGroupStates().Get(podGroup.GetNamespace(), podGroup.GetName()) + if err != nil { + return 0, fwk.AsStatus(err) + } + + return int64(pgState.ScheduledPodsCount() + len(placement.ProposedAssignments)), nil +} + +// PlacementScoreExtensions returns a PlacementScoreExtensions interface if it implements one, or nil if does not. +// PodGroupPodsCount implements this interface. +func (pl *PodGroupPodsCount) PlacementScoreExtensions() fwk.PlacementScoreExtensions { + return pl +} + +// NormalizePlacementScore normalizes the scores to a range of [MinScore, MaxScore]. +// The normalization is based on the maximum count among all candidate placements. +// We purposely do not consider MinCount (the minimum pods required for the group) during normalization +// to avoid large gaps in scores when there are minimal differences in pod counts. +func (pl *PodGroupPodsCount) NormalizePlacementScore(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, scores []fwk.PlacementScore) *fwk.Status { + maxCount := int64(0) + + for _, score := range scores { + maxCount = max(maxCount, score.Score) + } + + if maxCount == 0 { + return fwk.AsStatus(errors.New("no pods from pod group are assigned to any of the candidate placements")) + } + + for i := range scores { + scores[i].Score = fwk.MinScore + scores[i].Score*(fwk.MaxScore-fwk.MinScore)/maxCount + } + + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go index 18e7be733d..af93f64c68 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go @@ -184,8 +184,13 @@ func (pl *PodTopologySpread) EventsToRegister(_ context.Context) ([]fwk.ClusterE // involvedInTopologySpreading returns true if the incomingPod is involved in the topology spreading of podWithSpreading. func involvedInTopologySpreading(incomingPod, podWithSpreading *v1.Pod) bool { - return incomingPod.UID == podWithSpreading.UID || - (incomingPod.Spec.NodeName != "" && incomingPod.Namespace == podWithSpreading.Namespace) + if incomingPod.UID == podWithSpreading.UID { + return true + } + if incomingPod.Spec.NodeName == "" && incomingPod.Status.NominatedNodeName == "" { + return false + } + return incomingPod.Namespace == podWithSpreading.Namespace } // hasConstraintWithNodeTaintsPolicyHonor returns true if any constraint has `NodeTaintsPolicy: Honor`. diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go index 8d945f6319..c09c34919c 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go @@ -32,10 +32,12 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone" @@ -69,6 +71,8 @@ func NewInTreeRegistry() runtime.Registry { defaultpreemption.Name: runtime.FactoryAdapter(fts, defaultpreemption.New), schedulinggates.Name: runtime.FactoryAdapter(fts, schedulinggates.New), gangscheduling.Name: runtime.FactoryAdapter(fts, gangscheduling.New), + topologyaware.Name: runtime.FactoryAdapter(fts, topologyaware.New), + podgrouppodscount.Name: runtime.FactoryAdapter(fts, podgrouppodscount.New), } return registry diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware/topology_placement.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware/topology_placement.go new file mode 100644 index 0000000000..ccf7978748 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware/topology_placement.go @@ -0,0 +1,142 @@ +/* +Copyright 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 topologyaware + +import ( + "context" + "fmt" + + v1 "k8s.io/api/core/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" + "k8s.io/apimachinery/pkg/runtime" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" + "k8s.io/klog/v2" + fwk "k8s.io/kube-scheduler/framework" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" +) + +const ( + // Name is the name of the plugin used in the plugin registry and configurations. + Name = names.TopologyPlacementGenerator +) + +// TopologyPlacement is a plugin that generates placements for a pod group based on its topology constraints. +type TopologyPlacement struct { + handle fwk.Handle + podGroupLister schedulinglisters.PodGroupLister +} + +var _ fwk.PlacementGeneratePlugin = &TopologyPlacement{} + +// New initializes a new plugin and returns it. +func New(_ context.Context, _ runtime.Object, fh fwk.Handle, fts feature.Features) (*TopologyPlacement, error) { + return &TopologyPlacement{ + handle: fh, + podGroupLister: fh.SharedInformerFactory().Scheduling().V1alpha2().PodGroups().Lister(), + }, nil +} + +// Name returns name of the plugin. +func (pl *TopologyPlacement) Name() string { + return Name +} + +// GeneratePlacements generates placements for a pod group based on the topology constraints in the pod group spec. +// It uses the parent placement to find the nodes that are available for placement. +func (pl *TopologyPlacement) GeneratePlacements(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, parentPlacement *fwk.Placement) (*fwk.GeneratePlacementsResult, *fwk.Status) { + podGroupResource, err := pl.podGroupLister.PodGroups(podGroup.GetNamespace()).Get(podGroup.GetName()) + if err != nil { + return nil, fwk.AsStatus(err) + } + topologyKey, ok := pl.getTopologyKey(podGroupResource) + if !ok { + // No topology constraints, return a single placement with no constraints. + return &fwk.GeneratePlacementsResult{Placements: []*fwk.Placement{parentPlacement}}, nil + } + + var requiredDomain *string + scheduledPods, err := pl.getScheduledPods(podGroup) + if err != nil { + return nil, fwk.AsStatus(err) + } + if len(scheduledPods) > 0 { + scheduledDomain, err := pl.getScheduledPodsTopologyDomain(topologyKey, scheduledPods) + if err != nil { + return nil, fwk.AsStatus(fmt.Errorf("cannot determine domain for already scheduled pods: %w", err)) + } + requiredDomain = &scheduledDomain + } + + nodesPerTopologyDomain := make(map[string][]fwk.NodeInfo) + for _, node := range parentPlacement.Nodes { + if domain, ok := node.Node().Labels[topologyKey]; ok { + if requiredDomain == nil || *requiredDomain == domain { + nodesPerTopologyDomain[domain] = append(nodesPerTopologyDomain[domain], node) + } + } + } + + placements := make([]*fwk.Placement, 0, len(nodesPerTopologyDomain)) + for topologyDomain, nodes := range nodesPerTopologyDomain { + if len(nodes) > 0 { + placements = append(placements, &fwk.Placement{ + Name: topologyDomain, + Nodes: nodes, + }) + } + } + + return &fwk.GeneratePlacementsResult{Placements: placements}, nil +} + +func (pl *TopologyPlacement) getScheduledPodsTopologyDomain(topologyKey string, scheduledPods []*v1.Pod) (string, error) { + topologyDomain := "" + for _, pod := range scheduledPods { + node, err := pl.handle.SnapshotSharedLister().NodeInfos().Get(pod.Spec.NodeName) + if err != nil { + return "", fmt.Errorf("getting node for pod %v: %w", klog.KObj(pod), err) + } + domain, ok := node.Node().Labels[topologyKey] + if !ok { + return "", fmt.Errorf("no topology domain found for pod %v", klog.KObj(pod)) + } + if topologyDomain != "" && topologyDomain != domain { + return "", fmt.Errorf("more than 1 domain found for pod group: %v, %v", topologyDomain, domain) + } + topologyDomain = domain + } + return topologyDomain, nil +} + +// getTopologyKey returns the topology key for the pod group if there's any specified. +func (pl *TopologyPlacement) getTopologyKey(podGroupResource *schedulingapi.PodGroup) (string, bool) { + if schedulingConstraints := podGroupResource.Spec.SchedulingConstraints; schedulingConstraints != nil && len(schedulingConstraints.Topology) > 0 { + // Right now, we only support a single topology constraint on the API level. + return schedulingConstraints.Topology[0].Key, true + } + return "", false +} + +func (pl *TopologyPlacement) getScheduledPods(podGroup fwk.PodGroupInfo) ([]*v1.Pod, error) { + name := podGroup.GetName() + podGroupState, err := pl.handle.SnapshotSharedLister().PodGroupStates().Get(podGroup.GetNamespace(), name) + if err != nil { + return nil, err + } + return podGroupState.ScheduledPods(), nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go index f4c9a22fc1..3efccb1f82 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go @@ -209,7 +209,6 @@ type PodVolumeClaims struct { type volumeBinder struct { kubeClient clientset.Interface enableVolumeAttributesClass bool - enableCSIMigrationPortworx bool classLister storagelisters.StorageClassLister podLister corelisters.PodLister @@ -262,7 +261,6 @@ func NewVolumeBinder( b := &volumeBinder{ kubeClient: kubeClient, enableVolumeAttributesClass: fts.EnableVolumeAttributesClass, - enableCSIMigrationPortworx: fts.EnableCSIMigrationPortworx, podLister: podInformer.Lister(), classLister: storageClassInformer.Lister(), nodeLister: nodeInformer.Lister(), @@ -1066,7 +1064,7 @@ func (a byPVCSize) Less(i, j int) bool { } // isCSIMigrationOnForPlugin checks if CSI migration is enabled for a given plugin. -func isCSIMigrationOnForPlugin(pluginName string, enableCSIMigrationPortworx bool) bool { +func isCSIMigrationOnForPlugin(pluginName string) bool { switch pluginName { case csiplugins.AWSEBSInTreePluginName: return true @@ -1077,7 +1075,7 @@ func isCSIMigrationOnForPlugin(pluginName string, enableCSIMigrationPortworx boo case csiplugins.CinderInTreePluginName: return true case csiplugins.PortworxVolumePluginName: - return enableCSIMigrationPortworx + return true } return false } @@ -1116,7 +1114,7 @@ func (b *volumeBinder) tryTranslatePVToCSI(logger klog.Logger, pv *v1.Persistent return nil, fmt.Errorf("could not get plugin name from pv: %v", err) } - if !isCSIMigrationOnForPlugin(pluginName, b.enableCSIMigrationPortworx) { + if !isCSIMigrationOnForPlugin(pluginName) { return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go index 0774ea7810..83111927c2 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go @@ -552,20 +552,21 @@ var errNoPodVolumeForNode = fmt.Errorf("no pod volume found for node") // PreBindPreFlight is called before PreBind, and determines whether PreBind is going to do something for this pod, or not. // It checks state.podVolumesByNode to determine whether there are any pod volumes for the node and hence the plugin has to handle them at PreBind. -func (pl *VolumeBinding) PreBindPreFlight(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status { +func (pl *VolumeBinding) PreBindPreFlight(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) (*fwk.PreBindPreFlightResult, *fwk.Status) { + result := &fwk.PreBindPreFlightResult{AllowParallel: true} s, err := getStateData(state) if err != nil { - return fwk.AsStatus(err) + return result, fwk.AsStatus(err) } if s.allBound { // no need to bind volumes - return fwk.NewStatus(fwk.Skip) + return result, fwk.NewStatus(fwk.Skip) } if _, ok := s.podVolumesByNode[nodeName]; !ok { - return fwk.AsStatus(fmt.Errorf("%w %q", errNoPodVolumeForNode, nodeName)) + return result, fwk.AsStatus(fmt.Errorf("%w %q", errNoPodVolumeForNode, nodeName)) } - return nil + return result, nil } // PreBind will make the API update with the assumed bindings and wait until diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/executor.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/executor.go new file mode 100644 index 0000000000..319e9a9027 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/executor.go @@ -0,0 +1,512 @@ +/* +Copyright 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 preemption + +import ( + "context" + "fmt" + "sync" + "time" + + v1 "k8s.io/api/core/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + clientset "k8s.io/client-go/kubernetes" + corelisters "k8s.io/client-go/listers/core/v1" + corev1helpers "k8s.io/component-helpers/scheduling/corev1" + "k8s.io/klog/v2" + extenderv1 "k8s.io/kube-scheduler/extender/v1" + fwk "k8s.io/kube-scheduler/framework" + apipod "k8s.io/kubernetes/pkg/api/v1/pod" + "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" + "k8s.io/kubernetes/pkg/scheduler/metrics" + "k8s.io/kubernetes/pkg/scheduler/util" +) + +type pendingVictim struct { + namespace string + name string +} + +// ExecutorPreemptor is an interface that represents a preemptor. +// It's mainly used to abstract away fields needed for logging +// purposes during preemption calls done by Executor. +type ExecutorPreemptor interface { + klog.KMetadata + // UID returns the UID of the object that is triggering preemption. + UID() types.UID + // SchedulerName returns the scheduler name assigned to the object that is triggering preemption. + SchedulerName() string + // Obj returns the object that is triggering preemption. + Obj() runtime.Object + // Pods returns a map of pod name to pods that form a preemptor. + Pods() map[string]*v1.Pod + // Priority returns the priority of the preemptor. + Priority() int32 + // Type returns the type of the preemptor. + Type() string +} + +// Executor is responsible for actuating the preemption process based on the provided candidate. +// It supports both synchronous as well as asynchronous preemption. +type Executor struct { + mu sync.RWMutex + fh fwk.Handle + + podLister corelisters.PodLister + + fts feature.Features + + // preempting is a set that records the pods/podgroups that are currently triggering preemption asynchronously, + // which is used to prevent the pods and pods from podgroups from entering the scheduling cycle meanwhile. + preempting sets.Set[types.UID] + // lastVictimsPendingPreemption is a map that records the victim pods that are currently being preempted for a given preemptor pod/podgroup, + // with a condition that the preemptor is waiting for one last victim to be preempted. This is used together with `preempting` + // to prevent the pods/podgroups from entering the scheduling cycle while waiting for preemption to complete. + lastVictimsPendingPreemption map[types.UID]pendingVictim + + // PreemptPod is a function that actually makes API calls to preempt a specific Pod. + // This is exposed to be replaced during tests. + PreemptPod func(ctx context.Context, c Candidate, preemptor ExecutorPreemptor, victim *v1.Pod, pluginName string) error +} + +// NewExecutor creates a new preemption executor. +func NewExecutor(fh fwk.Handle, fts feature.Features) *Executor { + e := &Executor{ + fh: fh, + podLister: fh.SharedInformerFactory().Core().V1().Pods().Lister(), + preempting: sets.New[types.UID](), + lastVictimsPendingPreemption: make(map[types.UID]pendingVictim), + fts: fts, + } + + e.PreemptPod = func(ctx context.Context, c Candidate, preemptor ExecutorPreemptor, victim *v1.Pod, pluginName string) error { + logger := klog.FromContext(ctx) + + skipAPICall := false + eventMessage := fmt.Sprintf("Preempted by %s %v on node %v", preemptor.Type(), preemptor.UID(), c.Name()) + // If the victim is a WaitingPod, try to preempt it without a delete call (victim will go back to backoff queue). + // Otherwise we should delete the victim. + if waitingPod := e.fh.GetWaitingPod(victim.UID); waitingPod != nil { + if waitingPod.Preempt(pluginName, "preempted") { + logger.V(2).Info("Preemptor preempted a waiting pod", "preemptorType", preemptor.Type(), "preemptor", klog.KObj(preemptor), "waitingPod", klog.KObj(victim), "node", c.Name()) + skipAPICall = true + } + } else if podInPreBind := e.fh.GetPodInPreBind(victim.UID); podInPreBind != nil { + // If the victim is in the preBind cancel the binding process. + if podInPreBind.CancelPod(fmt.Sprintf("preempted by %s", pluginName)) { + logger.V(2).Info("Preemptor rejected a pod in preBind", "preemptorType", preemptor.Type(), "preemptor", klog.KObj(preemptor), "podInPreBind", klog.KObj(victim), "node", c.Name()) + skipAPICall = true + } else { + logger.V(5).Info("Failed to reject a pod in preBind, falling back to deletion via api call", "preemptor", klog.KObj(preemptor), "podInPreBind", klog.KObj(victim), "node", c.Name()) + } + } + if !skipAPICall { + condition := &v1.PodCondition{ + Type: v1.DisruptionTarget, + ObservedGeneration: apipod.CalculatePodConditionObservedGeneration(&victim.Status, victim.Generation, v1.DisruptionTarget), + Status: v1.ConditionTrue, + Reason: v1.PodReasonPreemptionByScheduler, + Message: fmt.Sprintf("%s: preempting to accommodate a higher priority %s", preemptor.SchedulerName(), preemptor.Type()), + } + newStatus := victim.Status.DeepCopy() + updated := apipod.UpdatePodCondition(newStatus, condition) + if updated { + if err := util.PatchPodStatus(ctx, fh.ClientSet(), victim.Name, victim.Namespace, &victim.Status, newStatus); err != nil { + if !apierrors.IsNotFound(err) { + logger.Error(err, "Could not add DisruptionTarget condition due to preemption", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim)) + return err + } + logger.V(2).Info("Victim Pod is already deleted", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) + return nil + } + } + if err := util.DeletePod(ctx, fh.ClientSet(), victim); err != nil { + if !apierrors.IsNotFound(err) { + logger.Error(err, "Tried to preempted pod", "pod", klog.KObj(victim), "preemptor", klog.KObj(preemptor)) + return err + } + logger.V(2).Info("Victim Pod is already deleted", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) + return nil + } + logger.V(2).Info("Preemptor Pod preempted victim Pod", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) + } else { + eventMessage += " (in kube-scheduler memory)." + } + + fh.EventRecorder().WithLogger(logger).Eventf(victim, preemptor.Obj(), v1.EventTypeNormal, "Preempted", "Preempting", eventMessage) + + return nil + } + + return e +} + +// actuatePodPreemption actuates the preemption given preemptorPod to be scheduled on targetNode and a list of +// victims to be evicted. +func (e *Executor) actuatePodPreemption(ctx context.Context, targetNode string, victims *extenderv1.Victims, preemptorPod *v1.Pod, pluginName string) *fwk.Status { + candidate := &candidate{ + victims: victims, + name: targetNode, + } + + podPreemptor := &podExecutorPreemptor{Pod: preemptorPod} + if e.fts.EnableAsyncPreemption { + e.prepareCandidateAsync(candidate, podPreemptor, pluginName) + return nil + } + return e.prepareCandidate(ctx, candidate, podPreemptor, pluginName) +} + +// actuatePodGroupPreemption actuates the preemption given preemptor pods, pod group and a list of victims to be evicted. +func (e *Executor) actuatePodGroupPreemption(ctx context.Context, victims *extenderv1.Victims, preemptorPods []*v1.Pod, preemptor *schedulingapi.PodGroup, pluginName string) *fwk.Status { + candidate := &candidate{ + victims: victims, + name: "cluster", + } + + podGroupPreemptor := &podGroupExecutorPreemptor{pg: preemptor, pods: preemptorPods} + if e.fts.EnableAsyncPreemption { + e.prepareCandidateAsync(candidate, podGroupPreemptor, pluginName) + return nil + } + return e.prepareCandidate(ctx, candidate, podGroupPreemptor, pluginName) +} + +// prepareCandidateAsync triggers a goroutine for some preparation work: +// - Evict the victim pods +// - Reject the victim pods if they are in waitingPod map +// - Clear the low-priority pods' nominatedNodeName status if needed +// The Pod won't be retried until the goroutine triggered here completes. +// +// See http://kep.k8s.io/4832 for how the async preemption works. +func (e *Executor) prepareCandidateAsync(c Candidate, preemptor ExecutorPreemptor, pluginName string) { + // Intentionally create a new context, not using a ctx from the scheduling cycle, to create ctx, + // because this process could continue even after this scheduling cycle finishes. + ctx, cancel := context.WithCancel(context.Background()) + logger := klog.FromContext(ctx) + + victimPods := make([]*v1.Pod, 0, len(c.Victims().Pods)) + for _, victim := range c.Victims().Pods { + if victim.DeletionTimestamp != nil { + // Graceful pod deletion has already started. Sending another API call is unnecessary. + logger.V(2).Info("Victim Pod is already being deleted, skipping the API call for it", "preemptor", klog.KObj(preemptor), "node", c.Name(), "victim", klog.KObj(victim)) + continue + } + victimPods = append(victimPods, victim) + } + if len(victimPods) == 0 { + cancel() + return + } + + metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) + + errCh := parallelize.NewResultChannel[error]() + preemptPod := func(index int) { + victim := victimPods[index] + if err := e.PreemptPod(ctx, c, preemptor, victim, pluginName); err != nil { + errCh.SendWithCancel(err, cancel) + } + } + + e.mu.Lock() + e.preempting.Insert(preemptor.UID()) + e.mu.Unlock() + + go func() { + logger := klog.FromContext(ctx) + startTime := time.Now() + result := metrics.GoroutineResultSuccess + defer metrics.PreemptionGoroutinesDuration.WithLabelValues(result).Observe(metrics.SinceInSeconds(startTime)) + defer metrics.PreemptionGoroutinesExecutionTotal.WithLabelValues(result).Inc() + defer func() { + if result == metrics.GoroutineResultError { + // When API call isn't successful, the preemptor's Pods may get stuck in the unschedulable pod pool in the worst case. + // So, we should move the preemptor's Pods to the activeQ. + e.fh.Activate(logger, preemptor.Pods()) + } + }() + defer cancel() + logger.V(2).Info("Start the preemption asynchronously", "preemptor", klog.KObj(preemptor), "node", c.Name(), "numVictims", len(c.Victims().Pods), "numVictimsToDelete", len(victimPods)) + + // Lower priority pods nominated to run on this node, may no longer fit on + // this node. So, we should remove their nomination. Removing their + // nomination updates these pods and moves them to the active queue. It + // lets scheduler find another place for them sooner than after waiting for preemption completion. + nominatedPods := getLowerPriorityNominatedPods(e.fh, preemptor.Priority(), c.Name()) + if err := clearNominatedNodeName(ctx, e.fh.ClientSet(), e.fh.APICacher(), nominatedPods...); err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "Cannot clear 'NominatedNodeName' field from lower priority pods on the same target node", "node", c.Name()) + result = metrics.GoroutineResultError + // We do not return as this error is not critical. + } + + preemptLastVictim := true + if len(victimPods) > 1 { + // In order to prevent requesting preemption of the same pod multiple times for the same preemptor, + // preemptor is marked as "waiting for preemption of a victim" (by adding it to preempting map). + // We can evict all victims in parallel, but the last one. + // While deleting the last victim, we want the PreEnqueue check to be able to verify if the eviction + // is in fact ongoing, or if it has already completed, but the function has not returned yet. + // In the latter case, PreEnqueue (in `IsPodRunningPreemption`) reads the state of the last victim in + // `lastVictimsPendingPreemption` and does not block the pod. + // This helps us avoid the situation where pod removal might be notified to the scheduling queue before + // the preemptor completes the deletion API calls and is removed from the `preempting` map - that way + // the preemptor could end up stuck in the unschedulable pool, with all pod removal events being ignored. + e.fh.Parallelizer().Until(ctx, len(victimPods)-1, preemptPod, pluginName) + if err := errCh.Receive(); err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "Error occurred during async preemption") + result = metrics.GoroutineResultError + preemptLastVictim = false + } + } + + // If any of the previous victims failed to be preempted, then we can skip + // the preemption attempt for the last victim Pod to expedite the preemptor's + // re-entry to the scheduling cycle. + if preemptLastVictim { + lastVictim := victimPods[len(victimPods)-1] + e.mu.Lock() + e.lastVictimsPendingPreemption[preemptor.UID()] = pendingVictim{namespace: lastVictim.Namespace, name: lastVictim.Name} + e.mu.Unlock() + + if err := e.PreemptPod(ctx, c, preemptor, lastVictim, pluginName); err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "Error occurred during async preemption of the last victim") + result = metrics.GoroutineResultError + } + } + e.mu.Lock() + e.preempting.Delete(preemptor.UID()) + delete(e.lastVictimsPendingPreemption, preemptor.UID()) + e.mu.Unlock() + + logger.V(2).Info("Async Preemption finished completely", "preemptor", klog.KObj(preemptor), "node", c.Name(), "result", result) + }() +} + +// prepareCandidate does some preparation work before nominating the selected candidate: +// - Evict the victim pods +// - Reject the victim pods if they are in waitingPod map +// - Clear the low-priority pods' nominatedNodeName status if needed +func (e *Executor) prepareCandidate(ctx context.Context, c Candidate, preemptor ExecutorPreemptor, pluginName string) *fwk.Status { + metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) + + fh := e.fh + cs := e.fh.ClientSet() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + logger := klog.FromContext(ctx) + errCh := parallelize.NewResultChannel[error]() + fh.Parallelizer().Until(ctx, len(c.Victims().Pods), func(index int) { + victim := c.Victims().Pods[index] + if victim.DeletionTimestamp != nil { + // Graceful pod deletion has already started. Sending another API call is unnecessary. + logger.V(2).Info("Victim Pod is already being deleted, skipping the API call for it", "preemptor", klog.KObj(preemptor), "node", c.Name(), "victim", klog.KObj(victim)) + return + } + if err := e.PreemptPod(ctx, c, preemptor, victim, pluginName); err != nil { + errCh.SendWithCancel(err, cancel) + } + }, pluginName) + if err := errCh.Receive(); err != nil { + return fwk.AsStatus(err) + } + + // Lower priority pods nominated to run on this node, may no longer fit on + // this node. So, we should remove their nomination. Removing their + // nomination updates these pods and moves them to the active queue. It + // lets scheduler find another place for them sooner than after waiting for preemption completion. + nominatedPods := getLowerPriorityNominatedPods(fh, preemptor.Priority(), c.Name()) + if err := clearNominatedNodeName(ctx, cs, fh.APICacher(), nominatedPods...); err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "Cannot clear 'NominatedNodeName' field") + // We do not return as this error is not critical. + } + + return nil +} + +// IsPodRunningPreemption returns true if the pod is currently triggering preemption asynchronously. +func (e *Executor) IsPodRunningPreemption(podUID types.UID) bool { + return e.isRunningPreemption(podUID) +} + +// IsPodGroupRunningPreemption returns true if the pod group is currently triggering preemption asynchronously. +func (e *Executor) IsPodGroupRunningPreemption(podGroupUID types.UID) bool { + return e.isRunningPreemption(podGroupUID) +} + +func (e *Executor) isRunningPreemption(uid types.UID) bool { + e.mu.RLock() + defer e.mu.RUnlock() + + if !e.preempting.Has(uid) { + return false + } + + victim, ok := e.lastVictimsPendingPreemption[uid] + if !ok { + // Since preemptor is in `preempting` but last victim is not registered yet, the async preemption is pending. + return true + } + // Preemptor is waiting for preemption of one last victim. We can check if the victim has already been deleted. + victimPod, err := e.podLister.Pods(victim.namespace).Get(victim.name) + if err != nil { + // Victim already deleted, preemption is done. + return false + } + if victimPod.DeletionTimestamp != nil { + // Victim deletion has started, preemption is done. + return false + } + // Preemption of the last pod is still ongoing. + return true +} + +// clearNominatedNodeName internally submit a patch request to API server +// to set each pods[*].Status.NominatedNodeName> to "". +func clearNominatedNodeName(ctx context.Context, cs clientset.Interface, apiCacher fwk.APICacher, pods ...*v1.Pod) utilerrors.Aggregate { + var errs []error + for _, p := range pods { + if apiCacher != nil { + // When API cacher is available, use it to clear the NominatedNodeName. + _, err := apiCacher.PatchPodStatus(p, nil, &fwk.NominatingInfo{NominatedNodeName: "", NominatingMode: fwk.ModeOverride}) + if err != nil { + errs = append(errs, err) + } + } else { + if len(p.Status.NominatedNodeName) == 0 { + continue + } + podStatusCopy := p.Status.DeepCopy() + podStatusCopy.NominatedNodeName = "" + if err := util.PatchPodStatus(ctx, cs, p.Name, p.Namespace, &p.Status, podStatusCopy); err != nil { + errs = append(errs, err) + } + } + } + return utilerrors.NewAggregate(errs) +} + +// getLowerPriorityNominatedPods returns pods whose priority is smaller than the +// priority of the given "pod" and are nominated to run on the given node. +// Note: We could possibly check if the nominated lower priority pods still fit +// and return those that no longer fit, but that would require lots of +// manipulation of NodeInfo and PreFilter state per nominated pod. It may not be +// worth the complexity, especially because we generally expect to have a very +// small number of nominated pods per node. +func getLowerPriorityNominatedPods(pn fwk.PodNominator, priority int32, nodeName string) []*v1.Pod { + podInfos := pn.NominatedPodsForNode(nodeName) + + if len(podInfos) == 0 { + return nil + } + + var lowerPriorityPods []*v1.Pod + for _, pi := range podInfos { + if corev1helpers.PodPriority(pi.GetPod()) < priority { + lowerPriorityPods = append(lowerPriorityPods, pi.GetPod()) + } + } + return lowerPriorityPods +} + +// podExecutorPreemptor is a wrapper around single pod used by preemption execution. +type podExecutorPreemptor struct { + *v1.Pod +} + +func (p *podExecutorPreemptor) UID() types.UID { + return p.Pod.UID +} + +func (p *podExecutorPreemptor) SchedulerName() string { + return p.Spec.SchedulerName +} + +func (p *podExecutorPreemptor) GetName() string { + return p.Name +} + +func (p *podExecutorPreemptor) GetNamespace() string { + return p.Namespace +} + +func (p *podExecutorPreemptor) Obj() runtime.Object { + return p +} + +func (p *podExecutorPreemptor) Pods() map[string]*v1.Pod { + return map[string]*v1.Pod{p.Name: p.Pod} +} + +func (p *podExecutorPreemptor) Priority() int32 { + return corev1helpers.PodPriority(p.Pod) +} + +func (p *podExecutorPreemptor) Type() string { + return "pod" +} + +// podGroupExecutorPreemptor is a wrapper around pod group used by preemption execution. +type podGroupExecutorPreemptor struct { + pg *schedulingapi.PodGroup + pods []*v1.Pod +} + +func (p *podGroupExecutorPreemptor) UID() types.UID { + return p.pg.UID +} + +func (p *podGroupExecutorPreemptor) SchedulerName() string { + // All pods in a pod group should use the same scheduler name. + return p.pods[0].Spec.SchedulerName +} + +func (p *podGroupExecutorPreemptor) GetName() string { + return p.pg.Name +} + +func (p *podGroupExecutorPreemptor) GetNamespace() string { + return p.pg.Namespace +} + +func (p *podGroupExecutorPreemptor) Obj() runtime.Object { + return p.pg +} + +func (p *podGroupExecutorPreemptor) Priority() int32 { + return util.PodGroupPriority(p.pg) +} + +func (p *podGroupExecutorPreemptor) Pods() map[string]*v1.Pod { + m := make(map[string]*v1.Pod, len(p.pods)) + for _, pod := range p.pods { + m[pod.Name] = pod + } + return m +} + +func (p *podGroupExecutorPreemptor) Type() string { + return "podgroup" +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/podgrouppreemption.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/podgrouppreemption.go new file mode 100644 index 0000000000..65d41a37a2 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/podgrouppreemption.go @@ -0,0 +1,289 @@ +/* +Copyright 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 preemption + +import ( + "context" + "fmt" + "sort" + "strings" + + v1 "k8s.io/api/core/v1" + policy "k8s.io/api/policy/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" + policylisters "k8s.io/client-go/listers/policy/v1" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" + + "k8s.io/klog/v2" + extenderv1 "k8s.io/kube-scheduler/extender/v1" + fwk "k8s.io/kube-scheduler/framework" +) + +// PodGroupEvaluator is a preemption evaluator that knows how to run +// preemption where a preemptor is a pod group and the domain is the whole cluster. +type PodGroupEvaluator struct { + Handle fwk.Handle + pdbLister policylisters.PodDisruptionBudgetLister + podGroupLister schedulinglisters.PodGroupLister + + Executor *Executor +} + +// NewPodGroupEvaluator creates a new PodGroupEvaluator. +func NewPodGroupEvaluator(fh fwk.Handle, executor *Executor) *PodGroupEvaluator { + return &PodGroupEvaluator{ + Handle: fh, + pdbLister: fh.SharedInformerFactory().Policy().V1().PodDisruptionBudgets().Lister(), + podGroupLister: fh.SharedInformerFactory().Scheduling().V1alpha2().PodGroups().Lister(), + Executor: executor, + } +} + +// Preempt implements the preemption logic where the preemptor is a pod group +// and the domain is the whole cluster. It preempts pod from the cluster +// in order to make enough room for the pod group to be scheduled. +// It returns a status of the whole preemption process. +// The preemption logic modifies the NodeInfo provided by a Handle +// podGroupSchedulingFunc is a function that will be run to check feasibility of a pod group +// scheduling after modifying the node state. +// The caller is expected to backup the NodeInfo before calling this function +// And rollback the state to the backup after function is finished. +func (ev *PodGroupEvaluator) Preempt(ctx context.Context, pg *schedulingapi.PodGroup, pods []*v1.Pod, podGroupSchedulingFunc func(context.Context) *fwk.Status) *fwk.Status { + // In case of workload-aware preemption, the domain is whole cluster. + // We do not make a snapshot of node info. Those nodes will be shared + // with the PodGroup scheduling algorithm passed as podGroupSchedulingFunc. + allNodes, err := ev.Handle.SnapshotSharedLister().NodeInfos().List() + if err != nil { + return fwk.AsStatus(fmt.Errorf("failed to list node infos: %w", err)) + } + domain := newDomainForWorkloadPreemption(allNodes, ev.podGroupLister, "cluster-domain") + preemptor := newPodGroupPreemptor(pg, pods) + pdbs, err := getPodDisruptionBudgets(ev.pdbLister) + if err != nil { + return fwk.AsStatus(fmt.Errorf("failed to get pod disruption budgets: %w", err)) + } + + victims, status := ev.selectVictimsOnDomain(ctx, preemptor, domain, pdbs, podGroupSchedulingFunc) + if !status.IsSuccess() { + return status + } + return ev.Executor.actuatePodGroupPreemption(ctx, victims, preemptor.pods, preemptor.podGroup, names.DefaultPreemption) +} + +// selectVictimsOnDomain selects a set of victims that can be removed from the +// domain in order to make enough room for the preemptor to be scheduled. +// It prioritizes victims that are not protected by a PDB. +func (ev *PodGroupEvaluator) selectVictimsOnDomain( + ctx context.Context, + preemptor *podGroupPreemptor, + domain *domain, + pdbs []*policy.PodDisruptionBudget, + podGroupSchedulingFunc func(context.Context) *fwk.Status) (*extenderv1.Victims, *fwk.Status) { + logger := klog.FromContext(ctx) + + // Ensure the preemptor is eligible to preempt other pods. + if ok, msg := ev.preemptorEligibleToPreemptOthers(ctx, preemptor); !ok { + logger.V(5).Info("Preemptor is not eligible for preemption", "preemptor", klog.KObj(preemptor.podGroup), "reason", msg) + return nil, fwk.NewStatus(fwk.Unschedulable, msg) + } + + nameToNode := make(map[string]fwk.NodeInfo) + for _, nodeInfo := range domain.Nodes() { + nameToNode[nodeInfo.Node().Name] = nodeInfo + } + + // Compared to the default preemption algorithm do not run the runPreFilterExtensionRemovePod + // or runPreFilterExtensionAddPod as pod group scheduling does prefilter anyway. + removePods := func(v *victim) error { + for _, pi := range v.Pods() { + nodeInfo := nameToNode[pi.GetPod().Spec.NodeName] + if err := nodeInfo.RemovePod(logger, pi.GetPod()); err != nil { + return err + } + } + + return nil + } + addPods := func(v *victim) error { + for _, pi := range v.Pods() { + nodeInfo := nameToNode[pi.GetPod().Spec.NodeName] + nodeInfo.AddPodInfo(pi) + } + + return nil + } + + var potentialVictims []*victim + allPossiblyAffectedVictims := domain.GetAllPossibleVictims() + for _, victim := range allPossiblyAffectedVictims { + if ev.isPreemptionAllowed(victim, preemptor) { + potentialVictims = append(potentialVictims, victim) + } + } + + // No preemption victims found for incoming preemptor. + if len(potentialVictims) == 0 { + return nil, fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "No preemption victims found for incoming preemptor") + } + + // PodGroup being a victim can have pods spread between current domain and other domains + // We need to pull data about nodes from outside of the current domain + // if a pod group has a pod on it. + for _, victim := range potentialVictims { + for name, nodeInfo := range victim.AffectedNodes() { + _, ok := nameToNode[name] + if !ok { + nameToNode[name] = nodeInfo + } + } + + if err := removePods(victim); err != nil { + return nil, fwk.AsStatus(err) + } + } + + // If the scheduling failed after removing all potential victims, return the status. + if status := podGroupSchedulingFunc(ctx); !status.IsSuccess() { + return nil, status + } + + sort.Slice(potentialVictims, func(i, j int) bool { + return moreImportantVictim(potentialVictims[i], potentialVictims[j]) + }) + + violatingVictims, nonViolatingVictims := filterVictimsWithPDBViolation(potentialVictims, pdbs) + numViolatingVictim := 0 + + reprieveVictim := func(v *victim) (bool, error) { + if err := addPods(v); err != nil { + return false, err + } + + status := podGroupSchedulingFunc(ctx) + fits := status.IsSuccess() + if !fits { + if err := removePods(v); err != nil { + return false, err + } + var names []string + for _, p := range v.Pods() { + names = append(names, p.GetPod().Name) + } + pods := strings.Join(names, ",") + logger.V(6).Info("Pods are potential preemption victims on domain", "pods", pods, "domain", domain.GetName()) + } + + return fits, nil + } + + // Try to reprieve as many pods as possible. We first try to reprieve the PDB + // violating victims and then other non-violating ones. In both cases, we start + // from the highest importance victims. + var victimsToPreempt []*victim + for _, v := range violatingVictims { + if fits, err := reprieveVictim(v); err != nil { + return nil, fwk.AsStatus(err) + } else if !fits { + victimsToPreempt = append(victimsToPreempt, v) + numViolatingVictim++ + } + } + + for _, v := range nonViolatingVictims { + if fits, err := reprieveVictim(v); err != nil { + return nil, fwk.AsStatus(err) + } else if !fits { + victimsToPreempt = append(victimsToPreempt, v) + } + } + + sort.Slice(victimsToPreempt, func(i, j int) bool { + return moreImportantVictim(victimsToPreempt[i], victimsToPreempt[j]) + }) + var podsToPreempt []*v1.Pod + for _, v := range victimsToPreempt { + for _, pi := range v.Pods() { + podsToPreempt = append(podsToPreempt, pi.GetPod()) + } + } + + v := &extenderv1.Victims{ + Pods: podsToPreempt, + } + return v, nil +} + +// isPreemptionAllowed returns whether the victim residing on nodeInfo can be preempted by the preemptor +func (ev *PodGroupEvaluator) isPreemptionAllowed(victim *victim, preemptor *podGroupPreemptor) bool { + // The victim must have lower priority than the preemptor. + return victim.Priority() < preemptor.Priority() +} + +// preemptorEligibleToPreemptOthers returns one bool and one string. The bool +// indicates whether this preemptor should be considered for preempting other pods or +// not. The string includes the reason if this preemptor isn't eligible. +func (ev *PodGroupEvaluator) preemptorEligibleToPreemptOthers(_ context.Context, preemptor *podGroupPreemptor) (bool, string) { + if preemptor.PreemptionPolicy() == v1.PreemptNever { + return false, "not eligible due to preemptionPolicy=Never." + } + return true, "" +} + +// moreImportantVictim decides which of two preemption units is considered more critical. +// This function is dedidcated only for PodGroup preemption. +// +// The comparison logic follows this strict hierarchy: +// +// 1. Priority: Higher priority units are always more important. +// +// 2. Workload Type (if WorkloadAwarePreemption is enabled): +// Atomic workloads (PodGroups) are considered more important than individual Pods +// of the same priority. +// +// 3. Start Time (for Single Pods): +// If both units are single Pods, the one with the older StartTime is more important. +// This honors "first-come, first-served". +// +// 4. Group Size (for PodGroups): +// If both units are PodGroups, the one with more members (larger size) is considered +// more important. This avoids the high cost of rescheduling massive jobs. +// +// 5. Start Time (Tie-breaker for PodGroups): +// If sizes are equal, the group that started earlier (has the oldest pod) +// is more important. +func moreImportantVictim(vi1, vi2 *victim) bool { + if vi1.Priority() != vi2.Priority() { + return vi1.Priority() > vi2.Priority() + } + + if vi1.IsPodGroup() != vi2.IsPodGroup() { + return vi1.IsPodGroup() + } + + if !vi1.IsPodGroup() { + return vi1.EarliestStartTime().Before(vi2.EarliestStartTime()) + } + + if len(vi1.Pods()) != len(vi2.Pods()) { + return len(vi1.Pods()) > len(vi2.Pods()) + } + + t1 := vi1.EarliestStartTime() + t2 := vi2.EarliestStartTime() + return t1.Before(t2) +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go index 05918dd778..50106f53a2 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go @@ -22,89 +22,23 @@ import ( "fmt" "math" "sync" - "sync/atomic" - "time" v1 "k8s.io/api/core/v1" policy "k8s.io/api/policy/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/sets" - clientset "k8s.io/client-go/kubernetes" corelisters "k8s.io/client-go/listers/core/v1" policylisters "k8s.io/client-go/listers/policy/v1" corev1helpers "k8s.io/component-helpers/scheduling/corev1" "k8s.io/klog/v2" extenderv1 "k8s.io/kube-scheduler/extender/v1" fwk "k8s.io/kube-scheduler/framework" - apipod "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/metrics" "k8s.io/kubernetes/pkg/scheduler/util" ) -// Candidate represents a nominated node on which the preemptor can be scheduled, -// along with the list of victims that should be evicted for the preemptor to fit the node. -type Candidate interface { - // Victims wraps a list of to-be-preempted Pods and the number of PDB violation. - Victims() *extenderv1.Victims - // Name returns the target node name where the preemptor gets nominated to run. - Name() string -} - -type candidate struct { - victims *extenderv1.Victims - name string -} - -// Victims returns s.victims. -func (s *candidate) Victims() *extenderv1.Victims { - return s.victims -} - -// Name returns s.name. -func (s *candidate) Name() string { - return s.name -} - -type candidateList struct { - idx int32 - items []Candidate -} - -func newCandidateList(size int32) *candidateList { - return &candidateList{idx: -1, items: make([]Candidate, size)} -} - -// add adds a new candidate to the internal array atomically. -func (cl *candidateList) add(c *candidate) { - if idx := atomic.AddInt32(&cl.idx, 1); idx < int32(len(cl.items)) { - cl.items[idx] = c - } -} - -// size returns the number of candidate stored. Note that some add() operations -// might still be executing when this is called, so care must be taken to -// ensure that all add() operations complete before accessing the elements of -// the list. -func (cl *candidateList) size() int32 { - n := atomic.LoadInt32(&cl.idx) + 1 - if n >= int32(len(cl.items)) { - n = int32(len(cl.items)) - } - return n -} - -// get returns the internal candidate array. This function is NOT atomic and -// assumes that all add() operations have been completed. -func (cl *candidateList) get() []Candidate { - return cl.items[:cl.size()] -} - // Interface is expected to be implemented by different preemption plugins as all those member // methods might have different behavior compared with the default preemption. type Interface interface { @@ -127,126 +61,27 @@ type Interface interface { OrderedScoreFuncs(ctx context.Context, nodesToVictims map[string]*extenderv1.Victims) []func(node string) int64 } +// Evaluator is a preemption evaluator. It runs preemption logic with a given Interface. type Evaluator struct { PluginName string Handler fwk.Handle PodLister corelisters.PodLister PdbLister policylisters.PodDisruptionBudgetLister - enableAsyncPreemption bool - mu sync.RWMutex - // preempting is a set that records the pods that are currently triggering preemption asynchronously, - // which is used to prevent the pods from entering the scheduling cycle meanwhile. - preempting sets.Set[types.UID] - // lastVictimsPendingPreemption is a map that records the victim pods that are currently being preempted for a given preemptor pod, - // with a condition that the preemptor is waiting for one last victim to be preempted. This is used together with `preempting` - // to prevent the pods from entering the scheduling cycle while waiting for preemption to complete. - lastVictimsPendingPreemption map[types.UID]pendingVictim - - // PreemptPod is a function that actually makes API calls to preempt a specific Pod. - // This is exposed to be replaced during tests. - PreemptPod func(ctx context.Context, c Candidate, preemptor, victim *v1.Pod, pluginName string) error - Interface + executor *Executor } -type pendingVictim struct { - namespace string - name string -} - -func NewEvaluator(pluginName string, fh fwk.Handle, i Interface, enableAsyncPreemption bool) *Evaluator { - podLister := fh.SharedInformerFactory().Core().V1().Pods().Lister() - pdbLister := fh.SharedInformerFactory().Policy().V1().PodDisruptionBudgets().Lister() - - ev := &Evaluator{ - PluginName: pluginName, - Handler: fh, - PodLister: podLister, - PdbLister: pdbLister, - Interface: i, - enableAsyncPreemption: enableAsyncPreemption, - preempting: sets.New[types.UID](), - lastVictimsPendingPreemption: make(map[types.UID]pendingVictim), +// NewEvaluator creates a new Evaluator. +func NewEvaluator(pluginName string, fh fwk.Handle, i Interface, executor *Executor) *Evaluator { + return &Evaluator{ + PluginName: pluginName, + Handler: fh, + PodLister: fh.SharedInformerFactory().Core().V1().Pods().Lister(), + PdbLister: fh.SharedInformerFactory().Policy().V1().PodDisruptionBudgets().Lister(), + Interface: i, + executor: executor, } - - // PreemptPod actually makes API calls to preempt a specific Pod. - // - // We implement it here directly, rather than creating a separate method like ev.preemptPod(...) - // to prevent the misuse of the PreemptPod function. - ev.PreemptPod = func(ctx context.Context, c Candidate, preemptor, victim *v1.Pod, pluginName string) error { - logger := klog.FromContext(ctx) - - // If the victim is a WaitingPod, send a reject message to the PermitPlugin. - // Otherwise we should delete the victim. - if waitingPod := ev.Handler.GetWaitingPod(victim.UID); waitingPod != nil { - waitingPod.Reject(pluginName, "preempted") - logger.V(2).Info("Preemptor pod rejected a waiting pod", "preemptor", klog.KObj(preemptor), "waitingPod", klog.KObj(victim), "node", c.Name()) - } else { - condition := &v1.PodCondition{ - Type: v1.DisruptionTarget, - ObservedGeneration: apipod.CalculatePodConditionObservedGeneration(&victim.Status, victim.Generation, v1.DisruptionTarget), - Status: v1.ConditionTrue, - Reason: v1.PodReasonPreemptionByScheduler, - Message: fmt.Sprintf("%s: preempting to accommodate a higher priority pod", preemptor.Spec.SchedulerName), - } - newStatus := victim.Status.DeepCopy() - updated := apipod.UpdatePodCondition(newStatus, condition) - if updated { - if err := util.PatchPodStatus(ctx, ev.Handler.ClientSet(), victim.Name, victim.Namespace, &victim.Status, newStatus); err != nil { - if !apierrors.IsNotFound(err) { - logger.Error(err, "Could not add DisruptionTarget condition due to preemption", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim)) - return err - } - logger.V(2).Info("Victim Pod is already deleted", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) - return nil - } - } - if err := util.DeletePod(ctx, ev.Handler.ClientSet(), victim); err != nil { - if !apierrors.IsNotFound(err) { - logger.Error(err, "Tried to preempted pod", "pod", klog.KObj(victim), "preemptor", klog.KObj(preemptor)) - return err - } - logger.V(2).Info("Victim Pod is already deleted", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) - return nil - } - logger.V(2).Info("Preemptor Pod preempted victim Pod", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) - } - - ev.Handler.EventRecorder().Eventf(victim, preemptor, v1.EventTypeNormal, "Preempted", "Preempting", "Preempted by pod %v on node %v", preemptor.UID, c.Name()) - - return nil - } - - return ev -} - -// IsPodRunningPreemption returns true if the pod is currently triggering preemption asynchronously. -func (ev *Evaluator) IsPodRunningPreemption(podUID types.UID) bool { - ev.mu.RLock() - defer ev.mu.RUnlock() - - if !ev.preempting.Has(podUID) { - return false - } - - victim, ok := ev.lastVictimsPendingPreemption[podUID] - if !ok { - // Since pod is in `preempting` but last victim is not registered yet, the async preemption is pending. - return true - } - // Pod is waiting for preemption of one last victim. We can check if the victim has already been deleted. - victimPod, err := ev.PodLister.Pods(victim.namespace).Get(victim.name) - if err != nil { - // Victim already deleted, preemption is done. - return false - } - if victimPod.DeletionTimestamp != nil { - // Victim deletion has started, preemption is done. - return false - } - // Preemption of the last pod is still ongoing. - return true } // Preempt returns a PostFilterResult carrying suggested nominatedNodeName, along with a Status. @@ -326,13 +161,9 @@ func (ev *Evaluator) Preempt(ctx context.Context, state fwk.CycleState, pod *v1. logger.V(2).Info("the target node for the preemption is determined", "node", bestCandidate.Name(), "pod", klog.KObj(pod)) - // 5) Perform preparation work before nominating the selected candidate. - if ev.enableAsyncPreemption { - ev.prepareCandidateAsync(bestCandidate, pod, ev.PluginName) - } else { - if status := ev.prepareCandidate(ctx, bestCandidate, pod, ev.PluginName); !status.IsSuccess() { - return nil, status - } + // 5) Actuate the preemption. + if status := ev.executor.actuatePodPreemption(ctx, bestCandidate.Name(), bestCandidate.Victims(), pod, ev.PluginName); !status.IsSuccess() { + return nil, status } return framework.NewPostFilterResultWithNominatedNode(bestCandidate.Name()), fwk.NewStatus(fwk.Success) @@ -457,177 +288,6 @@ func (ev *Evaluator) SelectCandidate(ctx context.Context, candidates []Candidate return candidates[0] } -// prepareCandidate does some preparation work before nominating the selected candidate: -// - Evict the victim pods -// - Reject the victim pods if they are in waitingPod map -// - Clear the low-priority pods' nominatedNodeName status if needed -func (ev *Evaluator) prepareCandidate(ctx context.Context, c Candidate, pod *v1.Pod, pluginName string) *fwk.Status { - fh := ev.Handler - cs := ev.Handler.ClientSet() - - ctx, cancel := context.WithCancel(ctx) - defer cancel() - logger := klog.FromContext(ctx) - errCh := parallelize.NewErrorChannel() - fh.Parallelizer().Until(ctx, len(c.Victims().Pods), func(index int) { - victim := c.Victims().Pods[index] - if victim.DeletionTimestamp != nil { - // Graceful pod deletion has already started. Sending another API call is unnecessary. - logger.V(2).Info("Victim Pod is already being deleted, skipping the API call for it", "preemptor", klog.KObj(pod), "node", c.Name(), "victim", klog.KObj(victim)) - return - } - if err := ev.PreemptPod(ctx, c, pod, victim, pluginName); err != nil { - errCh.SendErrorWithCancel(err, cancel) - } - }, ev.PluginName) - if err := errCh.ReceiveError(); err != nil { - return fwk.AsStatus(err) - } - - metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) - - // Lower priority pods nominated to run on this node, may no longer fit on - // this node. So, we should remove their nomination. Removing their - // nomination updates these pods and moves them to the active queue. It - // lets scheduler find another place for them sooner than after waiting for preemption completion. - nominatedPods := getLowerPriorityNominatedPods(logger, fh, pod, c.Name()) - if err := clearNominatedNodeName(ctx, cs, ev.Handler.APICacher(), nominatedPods...); err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Cannot clear 'NominatedNodeName' field") - // We do not return as this error is not critical. - } - - return nil -} - -// clearNominatedNodeName internally submit a patch request to API server -// to set each pods[*].Status.NominatedNodeName> to "". -func clearNominatedNodeName(ctx context.Context, cs clientset.Interface, apiCacher fwk.APICacher, pods ...*v1.Pod) utilerrors.Aggregate { - var errs []error - for _, p := range pods { - if apiCacher != nil { - // When API cacher is available, use it to clear the NominatedNodeName. - _, err := apiCacher.PatchPodStatus(p, nil, &fwk.NominatingInfo{NominatedNodeName: "", NominatingMode: fwk.ModeOverride}) - if err != nil { - errs = append(errs, err) - } - } else { - if len(p.Status.NominatedNodeName) == 0 { - continue - } - podStatusCopy := p.Status.DeepCopy() - podStatusCopy.NominatedNodeName = "" - if err := util.PatchPodStatus(ctx, cs, p.Name, p.Namespace, &p.Status, podStatusCopy); err != nil { - errs = append(errs, err) - } - } - } - return utilerrors.NewAggregate(errs) -} - -// prepareCandidateAsync triggers a goroutine for some preparation work: -// - Evict the victim pods -// - Reject the victim pods if they are in waitingPod map -// - Clear the low-priority pods' nominatedNodeName status if needed -// The Pod won't be retried until the goroutine triggered here completes. -// -// See http://kep.k8s.io/4832 for how the async preemption works. -func (ev *Evaluator) prepareCandidateAsync(c Candidate, pod *v1.Pod, pluginName string) { - metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) - - // Intentionally create a new context, not using a ctx from the scheduling cycle, to create ctx, - // because this process could continue even after this scheduling cycle finishes. - ctx, cancel := context.WithCancel(context.Background()) - logger := klog.FromContext(ctx) - - victimPods := make([]*v1.Pod, 0, len(c.Victims().Pods)) - for _, victim := range c.Victims().Pods { - if victim.DeletionTimestamp != nil { - // Graceful pod deletion has already started. Sending another API call is unnecessary. - logger.V(2).Info("Victim Pod is already being deleted, skipping the API call for it", "preemptor", klog.KObj(pod), "node", c.Name(), "victim", klog.KObj(victim)) - continue - } - victimPods = append(victimPods, victim) - } - if len(victimPods) == 0 { - cancel() - return - } - - errCh := parallelize.NewErrorChannel() - preemptPod := func(index int) { - victim := victimPods[index] - if err := ev.PreemptPod(ctx, c, pod, victim, pluginName); err != nil { - errCh.SendErrorWithCancel(err, cancel) - } - } - - ev.mu.Lock() - ev.preempting.Insert(pod.UID) - ev.mu.Unlock() - - go func() { - logger := klog.FromContext(ctx) - startTime := time.Now() - result := metrics.GoroutineResultSuccess - defer metrics.PreemptionGoroutinesDuration.WithLabelValues(result).Observe(metrics.SinceInSeconds(startTime)) - defer metrics.PreemptionGoroutinesExecutionTotal.WithLabelValues(result).Inc() - defer func() { - if result == metrics.GoroutineResultError { - // When API call isn't successful, the Pod may get stuck in the unschedulable pod pool in the worst case. - // So, we should move the Pod to the activeQ. - ev.Handler.Activate(logger, map[string]*v1.Pod{pod.Name: pod}) - } - }() - defer cancel() - logger.V(2).Info("Start the preemption asynchronously", "preemptor", klog.KObj(pod), "node", c.Name(), "numVictims", len(c.Victims().Pods), "numVictimsToDelete", len(victimPods)) - - // Lower priority pods nominated to run on this node, may no longer fit on - // this node. So, we should remove their nomination. Removing their - // nomination updates these pods and moves them to the active queue. It - // lets scheduler find another place for them sooner than after waiting for preemption completion. - nominatedPods := getLowerPriorityNominatedPods(logger, ev.Handler, pod, c.Name()) - if err := clearNominatedNodeName(ctx, ev.Handler.ClientSet(), ev.Handler.APICacher(), nominatedPods...); err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Cannot clear 'NominatedNodeName' field from lower priority pods on the same target node", "node", c.Name()) - result = metrics.GoroutineResultError - // We do not return as this error is not critical. - } - - if len(victimPods) > 1 { - // We can evict all victims in parallel, but the last one. - // We have to remove the pod from the preempting map before the last one is evicted - // because, otherwise, the pod removal might be notified to the scheduling queue before - // we remove this pod from the preempting map, - // and the pod could end up stucking at the unschedulable pod pool - // by all the pod removal events being ignored. - // In order to prevent requesting preemption of the same pod multiple times for the same preemptor, - // preemptor is marked as "waiting for preemption of a victim" (by adding it to preempting map). - // For optimization purposes the last victim is recorded in lastVictimsPendingPreemption. - ev.Handler.Parallelizer().Until(ctx, len(victimPods)-1, preemptPod, ev.PluginName) - if err := errCh.ReceiveError(); err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Error occurred during async preemption") - result = metrics.GoroutineResultError - } - } - - lastVictim := victimPods[len(victimPods)-1] - ev.mu.Lock() - ev.lastVictimsPendingPreemption[pod.UID] = pendingVictim{namespace: lastVictim.Namespace, name: lastVictim.Name} - ev.mu.Unlock() - - if err := ev.PreemptPod(ctx, c, pod, lastVictim, pluginName); err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Error occurred during async preemption") - result = metrics.GoroutineResultError - } - - ev.mu.Lock() - ev.preempting.Delete(pod.UID) - delete(ev.lastVictimsPendingPreemption, pod.UID) - ev.mu.Unlock() - - logger.V(2).Info("Async Preemption finished completely", "preemptor", klog.KObj(pod), "node", c.Name(), "result", result) - }() -} - func getPodDisruptionBudgets(pdbLister policylisters.PodDisruptionBudgetLister) ([]*policy.PodDisruptionBudget, error) { if pdbLister != nil { return pdbLister.List(labels.Everything()) @@ -736,30 +396,6 @@ func pickOneNodeForPreemption(logger klog.Logger, nodesToVictims map[string]*ext return allCandidates[0] } -// getLowerPriorityNominatedPods returns pods whose priority is smaller than the -// priority of the given "pod" and are nominated to run on the given node. -// Note: We could possibly check if the nominated lower priority pods still fit -// and return those that no longer fit, but that would require lots of -// manipulation of NodeInfo and PreFilter state per nominated pod. It may not be -// worth the complexity, especially because we generally expect to have a very -// small number of nominated pods per node. -func getLowerPriorityNominatedPods(logger klog.Logger, pn fwk.PodNominator, pod *v1.Pod, nodeName string) []*v1.Pod { - podInfos := pn.NominatedPodsForNode(nodeName) - - if len(podInfos) == 0 { - return nil - } - - var lowerPriorityPods []*v1.Pod - podPriority := corev1helpers.PodPriority(pod) - for _, pi := range podInfos { - if corev1helpers.PodPriority(pi.GetPod()) < podPriority { - lowerPriorityPods = append(lowerPriorityPods, pi.GetPod()) - } - } - return lowerPriorityPods -} - // DryRunPreemption simulates Preemption logic on in parallel, // returns preemption candidates and a map indicating filtered nodes statuses. // The number of candidates depends on the constraints defined in the plugin's args. In the returned list of @@ -819,3 +455,64 @@ func (ev *Evaluator) DryRunPreemption(ctx context.Context, state fwk.CycleState, fh.Parallelizer().Until(ctx, len(potentialNodes), checkNode, ev.PluginName) return append(nonViolatingCandidates.get(), violatingCandidates.get()...), nodeStatuses, utilerrors.NewAggregate(errs) } + +func filterVictimsWithPDBViolation(victims []*victim, pdbs []*policy.PodDisruptionBudget) (violatingVictims, nonViolatingVictims []*victim) { + pdbsAllowed := make([]int32, len(pdbs)) + podIsViolating := func(pod *v1.Pod) bool { + if len(pod.Labels) == 0 { + return false + } + + for i, pdb := range pdbs { + if pdb.Namespace != pod.Namespace { + continue + } + selector, err := metav1.LabelSelectorAsSelector(pdb.Spec.Selector) + if err != nil { + // This object has an invalid selector, it does not match the pod + continue + } + // A PDB with a nil or empty selector matches nothing. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + + // Existing in DisruptedPods means it has been processed in API server, + // we don't treat it as a violating case. + if _, exist := pdb.Status.DisruptedPods[pod.Name]; exist { + continue + } + // Only decrement the matched pdb when it's not in its ; + // otherwise we may over-decrement the budget number. + pdbsAllowed[i]-- + // We have found a matching PDB. + if pdbsAllowed[i] < 0 { + return true + } + } + + return false + } + + for i, pdb := range pdbs { + pdbsAllowed[i] = pdb.Status.DisruptionsAllowed + } + + for _, victim := range victims { + isUnitViolating := false + + for _, pi := range victim.Pods() { + if podIsViolating(pi.GetPod()) { + isUnitViolating = true + break + } + } + if isUnitViolating { + violatingVictims = append(violatingVictims, victim) + } else { + nonViolatingVictims = append(nonViolatingVictims, victim) + } + } + + return violatingVictims, nonViolatingVictims +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/types.go new file mode 100644 index 0000000000..f8034e03c1 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/types.go @@ -0,0 +1,276 @@ +/* +Copyright 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 preemption + +import ( + "maps" + "slices" + "sync/atomic" + + v1 "k8s.io/api/core/v1" + schedulingapi "k8s.io/api/scheduling/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" + corev1helpers "k8s.io/component-helpers/scheduling/corev1" + extenderv1 "k8s.io/kube-scheduler/extender/v1" + fwk "k8s.io/kube-scheduler/framework" + + "k8s.io/kubernetes/pkg/scheduler/util" +) + +type podGroupPreemptor struct { + priority int32 + pods []*v1.Pod + podGroup *schedulingapi.PodGroup + preemptionPolicy v1.PreemptionPolicy +} + +func newPodGroupPreemptor(pg *schedulingapi.PodGroup, pods []*v1.Pod) *podGroupPreemptor { + preemptionPolicy := v1.PreemptLowerPriority + for _, pod := range pods { + if p := pod.Spec.PreemptionPolicy; p != nil && *p == v1.PreemptNever { + preemptionPolicy = *p + } + } + return &podGroupPreemptor{ + priority: util.PodGroupPriority(pg), + pods: pods, + podGroup: pg, + preemptionPolicy: preemptionPolicy, + } +} + +// Priority returns the scheduling priority of the preemptor. +// This value is used to identify potential victims (which must have lower priority). +func (p *podGroupPreemptor) Priority() int32 { + return p.priority +} + +// Members returns the list of Pods that belong to this preemptor. +func (p *podGroupPreemptor) Members() []*v1.Pod { + return p.pods +} + +// PodGroup returns a pod group connected with this preemptor. +func (p *podGroupPreemptor) PodGroup() *schedulingapi.PodGroup { + return p.podGroup +} + +// PreemptionPolicy returns a preemption policy of this preemptor. +func (p *podGroupPreemptor) PreemptionPolicy() v1.PreemptionPolicy { + return p.preemptionPolicy +} + +// domain represents the boundary or scope within which the preemption logic is evaluated. +type domain struct { + nodes []fwk.NodeInfo + name string + allPossibleVictims []*victim +} + +// isPodGroupPreemptiblePod checks if a pod is a part of a pod group that should +// be treated as a single unit for preemption purposes. +// If the pod is a part of such a pod group, it returns the pod group and true. +// In all other cases, it returns nil and false. +func isPodGroupPreemptiblePod(p *v1.Pod, pgLister schedulinglisters.PodGroupLister) (*schedulingapi.PodGroup, bool) { + if p.Spec.SchedulingGroup == nil { + return nil, false + } + pgName := p.Spec.SchedulingGroup.PodGroupName + pg, err := pgLister.PodGroups(p.Namespace).Get(*pgName) + if err != nil { + return nil, false + } + if mode := pg.Spec.DisruptionMode; mode == nil || *mode != schedulingapi.DisruptionModePodGroup { + return nil, false + } + return pg, true +} + +// newDomainForWorkloadPreemption creates a new domain for workload preemption. +// The domain is the whole cluster and it contains victims that are computed based +// on the pods and their scheduling groups. +// Pods that are part of a pod group with the PodGroup disruption mode are grouped +// together into a single victim. Otherwise, they are treated as individual victims. +func newDomainForWorkloadPreemption(nodes []fwk.NodeInfo, pgLister schedulinglisters.PodGroupLister, name string) *domain { + victimMap := map[types.UID]*victim{} + for _, node := range nodes { + for _, p := range node.GetPods() { + // TODO: Calling the lister here is not ideal given we do this + // for every pod in the cluster. Instead, we should be getting + // this information from the snapshot. + pg, ok := isPodGroupPreemptiblePod(p.GetPod(), pgLister) + if !ok { + victimMap[p.GetPod().UID] = newVictim([]fwk.PodInfo{p}, corev1helpers.PodPriority(p.GetPod()), []fwk.NodeInfo{node}) + continue + } + victim, ok := victimMap[pg.UID] + if ok { + victim.pods = append(victim.pods, p) + victim.affectedNodes[node.Node().Name] = node + continue + } + victimMap[pg.UID] = newVictim([]fwk.PodInfo{p}, util.PodGroupPriority(pg), []fwk.NodeInfo{node}) + } + } + + allPossibleVictims := slices.Collect(maps.Values(victimMap)) + return &domain{ + nodes: nodes, + allPossibleVictims: allPossibleVictims, + name: name, + } +} + +// Nodes returns a list of NodeInfo objects that belong to this domain. +func (d *domain) Nodes() []fwk.NodeInfo { + return d.nodes +} + +// // GetAllPossibleVictims returns all potential victims running within this domain. +func (d *domain) GetAllPossibleVictims() []*victim { + return d.allPossibleVictims +} + +// GetName returns a unique identifier for the domain. +// This is primarily used for logging and debugging purposes. +func (d *domain) GetName() string { + return d.name +} + +// victim represents an atomic entity that can be preempted (a victim). +// It abstracts individual Pods and PodGroup, ensuring that +// atomic entities are treated as a single unit during eviction. +type victim struct { + pods []fwk.PodInfo + priority int32 + affectedNodes map[string]fwk.NodeInfo + earliestStartTime *metav1.Time +} + +// newVictim creates a new Victim representing a set of Pods (or a PodGroup) that can be preempted together. +// It calculates the earliest start time among all provided Pods and identifies all nodes +// affected by the potential eviction of these Pods. +func newVictim(pods []fwk.PodInfo, priority int32, nodeInfos []fwk.NodeInfo) *victim { + nodes := make(map[string]fwk.NodeInfo) + for _, node := range nodeInfos { + nodes[node.Node().Name] = node + } + + var earliest *metav1.Time + for _, pInfo := range pods { + t := util.GetPodStartTime(pInfo.GetPod()) + if earliest == nil || (t != nil && t.Before(earliest)) { + earliest = t + } + } + + return &victim{ + affectedNodes: nodes, + priority: priority, + pods: pods, + earliestStartTime: earliest, + } +} + +// Pods returns the list of all Pods that belong to this preemption unit. +// Evicting this unit implies evicting all Pods in this list. +func (v *victim) Pods() []fwk.PodInfo { + return v.pods +} + +// Priority returns the priority of the preemption unit. +// For a single Pod, this is the Pod's priority. +// For a PodGroup, this is the priority of the PodGroup. +func (v *victim) Priority() int32 { + return v.priority +} + +// AffectedNodes returns a map of Node names to NodeInfo for all nodes +// where members of this preemption unit are currently running. +// This allows the preemption logic to identify the blast radius of evicting this unit. +func (v *victim) AffectedNodes() map[string]fwk.NodeInfo { + return v.affectedNodes +} + +// EarliestStartTime returns the earliest start time of all Pods in this victim. +func (v *victim) EarliestStartTime() *metav1.Time { + return v.earliestStartTime +} + +// IsPodGroup returns true if the preemption unit represents a PodGroup. +func (v *victim) IsPodGroup() bool { + return v.pods[0].GetPod().Spec.SchedulingGroup != nil +} + +// Candidate represents a nominated node on which the preemptor can be scheduled, +// along with the list of victims that should be evicted for the preemptor to fit the node. +type Candidate interface { + // Victims wraps a list of to-be-preempted Pods and the number of PDB violation. + Victims() *extenderv1.Victims + // Name returns the target domain(for pod group)/node name where the preemptor gets nominated to run. + Name() string +} + +type candidate struct { + victims *extenderv1.Victims + name string +} + +// Victims returns s.victims. +func (s *candidate) Victims() *extenderv1.Victims { + return s.victims +} + +// Name returns s.name. +func (s *candidate) Name() string { + return s.name +} + +type candidateList struct { + idx int32 + items []Candidate +} + +// newCandidateList creates a new candidate list with the given capacity. +func newCandidateList(capacity int32) *candidateList { + return &candidateList{idx: -1, items: make([]Candidate, capacity)} +} + +// add adds a new candidate to the internal array atomically. +// Note: in case the list has reached its capacity, the candidate is disregarded +// and not added to the internal array. +func (cl *candidateList) add(c *candidate) { + if idx := atomic.AddInt32(&cl.idx, 1); idx < int32(len(cl.items)) { + cl.items[idx] = c + } +} + +// size returns the number of candidate stored. Note that some add() operations +// might still be executing when this is called, so care must be taken to +// ensure that all add() operations complete before accessing the elements of +// the list. +func (cl *candidateList) size() int32 { + return min(atomic.LoadInt32(&cl.idx)+1, int32(len(cl.items))) +} + +// get returns the internal candidate array. This function is NOT atomic and +// assumes that all add() operations have been completed. +func (cl *candidateList) get() []Candidate { + return cl.items[:cl.size()] +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/batch.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/batch.go index ad296f8a01..67c9fc5051 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/batch.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/batch.go @@ -31,10 +31,9 @@ import ( // OpportunisticBatching caches results from filtering and scoring when possible to optimize // scheduling of common pods. type OpportunisticBatch struct { - state *batchState - lastCycle schedulingCycle - signatureFunc SignatureFunc - handle fwk.Handle + state *batchState + lastCycle schedulingCycle + handle fwk.Handle // Used primarily for tests, count the total pods we // have successfully batched. @@ -57,17 +56,11 @@ const ( maxBatchAge = 500 * time.Millisecond ) -type SignatureFunc func(h fwk.Handle, ctx context.Context, p *v1.Pod, recordPluginStats bool) fwk.PodSignature - -func signUsingFramework(h fwk.Handle, ctx context.Context, p *v1.Pod, recordPluginStats bool) fwk.PodSignature { - return h.SignPod(ctx, p, recordPluginStats) -} - -// Provide a hint for the pod based on filtering an scoring results of previous cycles. Caching works only for consecutive pods +// GetNodeHint provides a hint for the pod based on filtering a scoring results of previous cycles. Caching works only for consecutive pods // with the same signature that are scheduled in 1-pod-per-node manner (otherwise previous scores could not be reused). -// It's assured by checking the top rated node is no longer feasible (meaning the previous pod was successfully scheduled and the +// It's assured by checking the top-rated node is no longer feasible (meaning the previous pod was successfully scheduled and the // current one does not fit). -func (b *OpportunisticBatch) GetNodeHint(ctx context.Context, pod *v1.Pod, state fwk.CycleState, cycleCount int64) (string, fwk.PodSignature) { +func (b *OpportunisticBatch) GetNodeHint(ctx context.Context, pod *v1.Pod, signature fwk.PodSignature, state fwk.CycleState, cycleCount int64) string { logger := klog.FromContext(ctx) var hint string @@ -80,16 +73,14 @@ func (b *OpportunisticBatch) GetNodeHint(ctx context.Context, pod *v1.Pod, state metrics.GetNodeHintDuration.WithLabelValues(hinted, b.handle.ProfileName()).Observe(metrics.SinceInSeconds(startTime)) }() - signature := b.signatureFunc(b.handle, ctx, pod, state.ShouldRecordPluginMetrics()) - nodeInfos := b.handle.SnapshotSharedLister().NodeInfos() // If we don't have state that we can use, then return an empty hint. - if !b.batchStateCompatible(ctx, logger, pod, signature, cycleCount, state, nodeInfos) { + if !b.batchStateCompatible(ctx, pod, signature, cycleCount, state, nodeInfos) { metrics.BatchAttemptStats.WithLabelValues(b.handle.ProfileName(), metrics.BatchAttemptNoHint).Inc() logger.V(4).Info("OpportunisticBatch no node hint available for pod", "profile", b.handle.ProfileName(), "pod", klog.KObj(pod), "cycleCount", cycleCount) - return "", signature + return "" } // Otherwise, pop the head of the list in our state and return it as @@ -99,16 +90,14 @@ func (b *OpportunisticBatch) GetNodeHint(ctx context.Context, pod *v1.Pod, state "profile", b.handle.ProfileName(), "pod", klog.KObj(pod), "cycleCount", cycleCount, "hint", hint, "remainingNodes", b.state.sortedNodes.Len()) - return hint, signature + return hint } -// Store results from scheduling for use as a batch later. +// StoreScheduleResults stores results from scheduling for use as a batch later. func (b *OpportunisticBatch) StoreScheduleResults(ctx context.Context, signature fwk.PodSignature, hintedNode, chosenNode string, otherNodes framework.SortedScoredNodes, cycleCount int64) { logger := klog.FromContext(ctx) - startTime := time.Now() - defer metrics.StoreScheduleResultsDuration.WithLabelValues(b.handle.ProfileName()).Observe(metrics.SinceInSeconds(startTime)) - + defer metrics.StoreScheduleResultsDuration.ObserveSince(time.Now(), b.handle.ProfileName())() // Set our cycle information for next time. b.lastCycle = schedulingCycle{ cycleCount: cycleCount, @@ -170,11 +159,12 @@ func (b *OpportunisticBatch) logUnusableState(logger klog.Logger, cycleCount int } // Update the batch state based on a the arrival of a new pod and the chosen node from the last pod. -func (b *OpportunisticBatch) batchStateCompatible(ctx context.Context, logger klog.Logger, pod *v1.Pod, signature fwk.PodSignature, cycleCount int64, state fwk.CycleState, nodeInfos fwk.NodeInfoLister) bool { +func (b *OpportunisticBatch) batchStateCompatible(ctx context.Context, pod *v1.Pod, signature fwk.PodSignature, cycleCount int64, state fwk.CycleState, nodeInfos fwk.NodeInfoLister) bool { // Just return if we don't have any state to use. if b.stateEmpty() { return false } + logger := klog.FromContext(ctx) // In this case, a previous pod was scheduled by another profile, meaning we can't use the state anymore. if cycleCount != b.lastCycle.cycleCount+1 { @@ -232,9 +222,8 @@ func (b *OpportunisticBatch) stateEmpty() bool { return b.state == nil || b.state.sortedNodes == nil || b.state.sortedNodes.Len() == 0 } -func newOpportunisticBatch(h fwk.Handle, signatureFunc SignatureFunc) *OpportunisticBatch { +func newOpportunisticBatch(h fwk.Handle) *OpportunisticBatch { return &OpportunisticBatch{ - signatureFunc: signatureFunc, - handle: h, + handle: h, } } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go index 350c8e0c7f..aafdce0e27 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go @@ -23,6 +23,7 @@ import ( "fmt" "io" "reflect" + "slices" "sort" "time" @@ -43,8 +44,8 @@ import ( apidispatcher "k8s.io/kubernetes/pkg/scheduler/backend/api_dispatcher" "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/util/slice" ) const ( @@ -55,34 +56,40 @@ const ( // frameworkImpl is the component responsible for initializing and running scheduler // plugins. type frameworkImpl struct { - registry Registry - snapshotSharedLister fwk.SharedLister - waitingPods *waitingPodsMap - scorePluginWeight map[string]int - preEnqueuePlugins []fwk.PreEnqueuePlugin - enqueueExtensions []fwk.EnqueueExtensions - queueSortPlugins []fwk.QueueSortPlugin - preFilterPlugins []fwk.PreFilterPlugin - filterPlugins []fwk.FilterPlugin - postFilterPlugins []fwk.PostFilterPlugin - preScorePlugins []fwk.PreScorePlugin - scorePlugins []fwk.ScorePlugin - reservePlugins []fwk.ReservePlugin - preBindPlugins []fwk.PreBindPlugin - bindPlugins []fwk.BindPlugin - postBindPlugins []fwk.PostBindPlugin - permitPlugins []fwk.PermitPlugin - batchablePlugins []fwk.SignPlugin + registry Registry + snapshotSharedLister fwk.SharedLister + waitingPods *waitingPodsMap + podsInPreBind *podsInPreBindMap + scorePluginWeight map[string]int + preEnqueuePlugins []fwk.PreEnqueuePlugin + enqueueExtensions []fwk.EnqueueExtensions + queueSortPlugins []fwk.QueueSortPlugin + preFilterPlugins []fwk.PreFilterPlugin + filterPlugins []fwk.FilterPlugin + postFilterPlugins []fwk.PostFilterPlugin + preScorePlugins []fwk.PreScorePlugin + scorePlugins []fwk.ScorePlugin + reservePlugins []fwk.ReservePlugin + preBindPlugins []fwk.PreBindPlugin + bindPlugins []fwk.BindPlugin + postBindPlugins []fwk.PostBindPlugin + permitPlugins []fwk.PermitPlugin + batchablePlugins []fwk.SignPlugin + podGroupPostFilterPlugins []framework.PodGroupPostFilterPlugin + + placementGeneratePlugins []fwk.PlacementGeneratePlugin + placementScorePlugins []fwk.PlacementScorePlugin + placementScorePluginWeight map[string]int // pluginsMap contains all plugins, by name. pluginsMap map[string]fwk.Plugin clientSet clientset.Interface kubeConfig *restclient.Config - eventRecorder events.EventRecorder + eventRecorder events.EventRecorderLogger informerFactory informers.SharedInformerFactory sharedDRAManager fwk.SharedDRAManager - workloadManager fwk.WorkloadManager + podGroupManager fwk.PodGroupManager logger klog.Logger sharedCSIManager fwk.CSIManager @@ -129,6 +136,8 @@ func (f *frameworkImpl) getExtensionPoints(plugins *config.Plugins) []extensionP {&plugins.Permit, &f.permitPlugins}, {&plugins.PreEnqueue, &f.preEnqueuePlugins}, {&plugins.QueueSort, &f.queueSortPlugins}, + {&plugins.PlacementGenerate, &f.placementGeneratePlugins}, + {&plugins.PlacementScore, &f.placementScorePlugins}, } } @@ -141,7 +150,7 @@ type frameworkOptions struct { componentConfigVersion string clientSet clientset.Interface kubeConfig *restclient.Config - eventRecorder events.EventRecorder + eventRecorder events.EventRecorderLogger informerFactory informers.SharedInformerFactory sharedDRAManager fwk.SharedDRAManager sharedCSIManager fwk.CSIManager @@ -153,8 +162,9 @@ type frameworkOptions struct { captureProfile CaptureProfile parallelizer parallelize.Parallelizer waitingPods *waitingPodsMap + podsInPreBind *podsInPreBindMap apiDispatcher *apidispatcher.APIDispatcher - workloadManager fwk.WorkloadManager + podGroupManager fwk.PodGroupManager logger *klog.Logger } @@ -186,7 +196,7 @@ func WithKubeConfig(kubeConfig *restclient.Config) Option { } // WithEventRecorder sets clientSet for the scheduling frameworkImpl. -func WithEventRecorder(recorder events.EventRecorder) Option { +func WithEventRecorder(recorder events.EventRecorderLogger) Option { return func(o *frameworkOptions) { o.eventRecorder = recorder } @@ -254,10 +264,10 @@ func WithAPIDispatcher(apiDispatcher *apidispatcher.APIDispatcher) Option { } } -// WithWorkloadManager sets Workload manager for the scheduling frameworkImpl. -func WithWorkloadManager(workloadManager fwk.WorkloadManager) Option { +// WithPodGroupManager sets the PodGroupManager for the scheduling frameworkImpl. +func WithPodGroupManager(podGroupManager fwk.PodGroupManager) Option { return func(o *frameworkOptions) { - o.workloadManager = workloadManager + o.podGroupManager = podGroupManager } } @@ -285,6 +295,13 @@ func WithWaitingPods(wp *waitingPodsMap) Option { } } +// WithPodsInPreBind sets podsInPreBind for the scheduling frameworkImpl. +func WithPodsInPreBind(bp *podsInPreBindMap) Option { + return func(o *frameworkOptions) { + o.podsInPreBind = bp + } +} + // WithLogger overrides the default logger from k8s.io/klog. func WithLogger(logger klog.Logger) Option { return func(o *frameworkOptions) { @@ -303,6 +320,10 @@ func defaultFrameworkOptions(stopCh <-chan struct{}) frameworkOptions { var _ framework.Framework = &frameworkImpl{} // NewFramework initializes plugins given the configuration and the registry. +// +// It creates background goroutines (for example, via defaultFrameworkOptions -> metrics.NewMetricsAsyncRecorder) +// which continue running until the context gets canceled. WaitForShutdown can be used to block +// until they have terminated. func NewFramework(ctx context.Context, r Registry, profile *config.KubeSchedulerProfile, opts ...Option) (framework.Framework, error) { options := defaultFrameworkOptions(ctx.Done()) for _, opt := range opts { @@ -317,8 +338,8 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler registry: r, snapshotSharedLister: options.snapshotSharedLister, sharedCSIManager: options.sharedCSIManager, - scorePluginWeight: make(map[string]int), waitingPods: options.waitingPods, + podsInPreBind: options.podsInPreBind, clientSet: options.clientSet, kubeConfig: options.kubeConfig, eventRecorder: options.eventRecorder, @@ -329,13 +350,13 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler PodNominator: options.podNominator, PodActivator: options.podActivator, apiDispatcher: options.apiDispatcher, - workloadManager: options.workloadManager, + podGroupManager: options.podGroupManager, parallelizer: options.parallelizer, logger: logger, } if utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) { - f.batch = newOpportunisticBatch(f, signUsingFramework) + f.batch = newOpportunisticBatch(f) } if len(f.extenders) > 0 { @@ -417,10 +438,15 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler if len(f.bindPlugins) == 0 { return nil, fmt.Errorf("at least one bind plugin is needed for profile with scheduler name %q", profile.SchedulerName) } + if len(f.placementGeneratePlugins) > 1 { + return nil, fmt.Errorf("at most one placement generate plugin is allowed for profile with scheduler name %q", profile.SchedulerName) + } - if err := getScoreWeights(f, append(profile.Plugins.Score.Enabled, profile.Plugins.MultiPoint.Enabled...)); err != nil { - return nil, err + podScoreWeights, err := getValidScoreWeights(f, reflect.TypeFor[fwk.ScorePlugin](), append(profile.Plugins.Score.Enabled, profile.Plugins.MultiPoint.Enabled...)) + if err != nil { + return nil, fmt.Errorf("score plugins: %w", err) } + f.scorePluginWeight = podScoreWeights // Verifying the score weights again since Plugin.Name() could return a different // value from the one used in the configuration. @@ -430,10 +456,37 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler } } + placementScoreWeights, err := getValidScoreWeights(f, reflect.TypeFor[fwk.PlacementScorePlugin](), append(profile.Plugins.PlacementScore.Enabled, profile.Plugins.MultiPoint.Enabled...)) + if err != nil { + return nil, fmt.Errorf("placement score plugins: %w", err) + } + f.placementScorePluginWeight = placementScoreWeights + + // Verifying the placement score weights again since Plugin.Name() could return a different + // value from the one used in the configuration. + for _, placementScorePlugin := range f.placementScorePlugins { + if f.placementScorePluginWeight[placementScorePlugin.Name()] == 0 { + return nil, fmt.Errorf("placement score plugin %q is not configured with weight", placementScorePlugin.Name()) + } + } + if utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) { f.computeBatchablePlugins() } + // Put default preemption as the only PodGroupPostFilterPlugin + if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) { + if dp, ok := f.pluginsMap[names.DefaultPreemption]; ok { + if _, ok := dp.(framework.PodGroupPostFilterPlugin); ok { + f.podGroupPostFilterPlugins = append(f.podGroupPostFilterPlugins, dp.(framework.PodGroupPostFilterPlugin)) + } else { + logger.V(2).Info("Workload Aware Preemption is enabled, but default preemption plugin does not fulfill PodGroupPostFilterPlugin interface. Workload Aware Preemption will not be used.") + } + } else { + logger.V(2).Info("Workload Aware Preemption is enabled, but default preemption plugin is not set. Workload Aware Preemption will not be used.") + } + } + if options.captureProfile != nil { if len(outputProfile.PluginConfig) != 0 { sort.Slice(outputProfile.PluginConfig, func(i, j int) bool { @@ -451,6 +504,15 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler return f, nil } +// WaitForShutdown waits for completion of all background goroutines of a framework +// instance created by NewFramework. The context given to NewFramework must be canceled +// to stop those background goroutines. +func WaitForShutdown(f framework.Framework) { + if f.(*frameworkImpl).metricsRecorder != nil { + <-f.(*frameworkImpl).metricsRecorder.IsStoppedCh + } +} + // setInstrumentedPlugins initializes instrumented plugins from current plugins that frameworkImpl has. func (f *frameworkImpl) setInstrumentedPlugins() { // Cache metric streams for prefilter and filter plugins. @@ -509,12 +571,12 @@ func (f *frameworkImpl) Close() error { return errors.Join(errs...) } -// getScoreWeights makes sure that, between MultiPoint-Score plugin weights and individual Score +// getValidScoreWeights makes sure that, between MultiPoint-Score plugin weights and individual Score // plugin weights there is not an overflow of MaxTotalScore. -func getScoreWeights(f *frameworkImpl, plugins []config.Plugin) error { +// pluginType is the type of the plugin for which it's valid to define weight, such as Score or PlacementScore. +func getValidScoreWeights(f *frameworkImpl, pluginType reflect.Type, plugins []config.Plugin) (map[string]int, error) { + weights := make(map[string]int) var totalPriority int64 - scorePlugins := reflect.ValueOf(&f.scorePlugins).Elem() - pluginType := scorePlugins.Type().Elem() for _, e := range plugins { pg := f.pluginsMap[e.Name] if !reflect.TypeOf(pg).Implements(pluginType) { @@ -523,23 +585,23 @@ func getScoreWeights(f *frameworkImpl, plugins []config.Plugin) error { // We append MultiPoint plugins to the list of Score plugins. So if this plugin has already been // encountered, let the individual Score weight take precedence. - if _, ok := f.scorePluginWeight[e.Name]; ok { + if _, ok := weights[e.Name]; ok { continue } // a weight of zero is not permitted, plugins can be disabled explicitly // when configured. - f.scorePluginWeight[e.Name] = int(e.Weight) - if f.scorePluginWeight[e.Name] == 0 { - f.scorePluginWeight[e.Name] = 1 + weights[e.Name] = int(e.Weight) + if weights[e.Name] == 0 { + weights[e.Name] = 1 } // Checks totalPriority against MaxTotalScore to avoid overflow - if int64(f.scorePluginWeight[e.Name])*fwk.MaxNodeScore > fwk.MaxTotalScore-totalPriority { - return fmt.Errorf("total score of Score plugins could overflow") + if int64(weights[e.Name])*fwk.MaxScore > fwk.MaxTotalScore-totalPriority { + return nil, fmt.Errorf("total score of Score plugins could overflow") } - totalPriority += int64(f.scorePluginWeight[e.Name]) * fwk.MaxNodeScore + totalPriority += int64(weights[e.Name]) * fwk.MaxScore } - return nil + return weights, nil } type orderedSet struct { @@ -641,7 +703,7 @@ func (f *frameworkImpl) expandMultiPointPlugins(logger klog.Logger, profile *con // - part 3: other plugins (excluded by part 1 & 2) in regular extension point. newPlugins := reflect.New(reflect.TypeOf(e.slicePtr).Elem()).Elem() // part 1 - for _, name := range slice.CopyStrings(enabledSet.list) { + for _, name := range slices.Clone(enabledSet.list) { if overridePlugins.has(name) { newPlugins = reflect.Append(newPlugins, reflect.ValueOf(f.pluginsMap[name])) enabledSet.delete(name) @@ -807,16 +869,14 @@ func (f *frameworkImpl) computeBatchablePlugins() { // is unable to construct a signature for the pod, the result will be nil, which means // there is no way to compare this pod against others, and will turn off a number of optimizations // for this pod. -func (f *frameworkImpl) SignPod(ctx context.Context, pod *v1.Pod, recordPluginStats bool) fwk.PodSignature { +func (f *frameworkImpl) SignPod(ctx context.Context, pod *v1.Pod) fwk.PodSignature { logger := klog.FromContext(ctx) var status *fwk.Status - if recordPluginStats { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Sign, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - } + startTime := time.Now() + defer func() { + f.metricsRecorder.ObserveFrameworkExtensionPointDurationAsync(metrics.Sign, status.Code().String(), f.profileName, metrics.SinceInSeconds(startTime)) + }() if !f.enableSignatures { return nil @@ -1083,6 +1143,10 @@ func (f *frameworkImpl) RunPostFilterPlugins(ctx context.Context, state fwk.Cycl metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PostFilter, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) }() + if state.ShouldSkipAllPostFilterPlugins() { + return nil, fwk.NewStatus(fwk.Unschedulable, "All PostFilter plugins are skipped") + } + logger := klog.FromContext(ctx) verboseLogs := logger.V(4).Enabled() if verboseLogs { @@ -1270,6 +1334,8 @@ func (f *frameworkImpl) runPreScorePlugin(ctx context.Context, pl fwk.PreScorePl // It returns a list that stores scores from each plugin and total score for each Node. // It also returns *Status, which is set to non-success if any of the plugins returns // a non-success status. +// +// This function mostly duplicates RunPlacementScorePlugins. Any changes to it should likely be reflected in both places. func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodes []fwk.NodeInfo) (ns []fwk.NodePluginScores, status *fwk.Status) { startTime := time.Now() defer func() { @@ -1288,7 +1354,7 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat } ctx, cancel := context.WithCancel(ctx) defer cancel() - errCh := parallelize.NewErrorChannel() + errCh := parallelize.NewResultChannel[error]() if len(plugins) > 0 { logger := klog.FromContext(ctx) @@ -1313,7 +1379,7 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat s, status := f.runScorePlugin(ctx, pl, state, pod, nodeInfo) if !status.IsSuccess() { err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) - errCh.SendErrorWithCancel(err, cancel) + errCh.SendWithCancel(err, cancel) return } pluginToNodeScores[pl.Name()][index] = fwk.NodeScore{ @@ -1322,7 +1388,7 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat } } }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { + if err := errCh.Receive(); err != nil { return nil, fwk.AsStatus(fmt.Errorf("running Score plugins: %w", err)) } } @@ -1337,11 +1403,11 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat status := f.runScoreExtension(ctx, pl, state, pod, nodeScoreList) if !status.IsSuccess() { err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) - errCh.SendErrorWithCancel(err, cancel) + errCh.SendWithCancel(err, cancel) return } }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { + if err := errCh.Receive(); err != nil { return nil, fwk.AsStatus(fmt.Errorf("running Normalize on Score plugins: %w", err)) } @@ -1360,7 +1426,7 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat if score > fwk.MaxNodeScore || score < fwk.MinNodeScore { err := fmt.Errorf("plugin %q returns an invalid score %v, it should in the range of [%v, %v] after normalizing", pl.Name(), score, fwk.MinNodeScore, fwk.MaxNodeScore) - errCh.SendErrorWithCancel(err, cancel) + errCh.SendWithCancel(err, cancel) return } weightedScore := score * int64(weight) @@ -1372,7 +1438,7 @@ func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state fwk.CycleStat } allNodePluginScores[index] = nodePluginScores }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { + if err := errCh.Receive(); err != nil { return nil, fwk.AsStatus(fmt.Errorf("applying score defaultWeights on Score plugins: %w", err)) } @@ -1399,8 +1465,140 @@ func (f *frameworkImpl) runScoreExtension(ctx context.Context, pl fwk.ScorePlugi return status } -func (f *frameworkImpl) GetNodeHint(ctx context.Context, pod *v1.Pod, state fwk.CycleState, cycleCount int64) (hint string, signature fwk.PodSignature) { - return f.batch.GetNodeHint(ctx, pod, state, cycleCount) +// RunPlacementScorePlugins runs the set of configured scoring plugins. +// It returns a list that stores scores from each plugin and total score for each Placement. +// It also returns *Status, which is set to non-success if any of the plugins returns +// a non-success status. +// +// This function mostly duplicates RunScorePlugins. Any changes to it should likely be reflected in both places. +func (f *frameworkImpl) RunPlacementScorePlugins(ctx context.Context, state fwk.PodGroupCycleState, podGroupInfo fwk.PodGroupInfo, podGroupAssignments []*fwk.PodGroupAssignments) (ps []fwk.PlacementPluginScores, status *fwk.Status) { + startTime := time.Now() + defer func() { + metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PlacementScore, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) + }() + + allPlacementPluginScores := make([]fwk.PlacementPluginScores, len(podGroupAssignments)) + numPlugins := len(f.placementScorePlugins) + plugins := make([]fwk.PlacementScorePlugin, 0, numPlugins) + pluginToPlacementScores := make(map[string][]fwk.PlacementScore, numPlugins) + for _, pl := range f.placementScorePlugins { + plugins = append(plugins, pl) + pluginToPlacementScores[pl.Name()] = make([]fwk.PlacementScore, len(podGroupAssignments)) + } + ctx, cancel := context.WithCancel(ctx) + defer cancel() + errCh := parallelize.NewResultChannel[error]() + + if len(plugins) > 0 { + logger := klog.FromContext(ctx) + verboseLogs := logger.V(4).Enabled() + if verboseLogs { + logger = klog.LoggerWithName(logger, "PlacementScore") + } + // Run ScorePlacement method for each placement in parallel. + f.Parallelizer().Until(ctx, len(podGroupAssignments), func(index int) { + pga := podGroupAssignments[index] + logger := logger + if verboseLogs { + logger = klog.LoggerWithValues(logger, "placement", pga.Placement.Name) + } + for _, pl := range plugins { + ctx := ctx + if verboseLogs { + logger := klog.LoggerWithName(logger, pl.Name()) + ctx = klog.NewContext(ctx, logger) + } + s, status := f.runPlacementScorePlugin(ctx, pl, state, podGroupInfo, pga) + if !status.IsSuccess() { + err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) + errCh.SendWithCancel(err, cancel) + return + } + pluginToPlacementScores[pl.Name()][index] = fwk.PlacementScore{ + Placement: pga.Placement, + Score: s, + } + } + }, metrics.PlacementScore) + if err := errCh.Receive(); err != nil { + return nil, fwk.AsStatus(fmt.Errorf("running PlacementScore plugins: %w", err)) + } + } + + // Run NormalizePlacementScore method for each PlacementScorePlugin in parallel. + f.Parallelizer().Until(ctx, len(plugins), func(index int) { + pl := plugins[index] + if pl.PlacementScoreExtensions() == nil { + return + } + placementScoreList := pluginToPlacementScores[pl.Name()] + status := f.runPlacementScoreExtension(ctx, pl, state, podGroupInfo, placementScoreList) + if !status.IsSuccess() { + err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) + errCh.SendWithCancel(err, cancel) + return + } + }, metrics.PlacementScore) + if err := errCh.Receive(); err != nil { + return nil, fwk.AsStatus(fmt.Errorf("running NormalizePlacementScore on PlacementScore plugins: %w", err)) + } + + // Apply score weight for each PlacementScorePlugin in parallel, + // and then, build allPlacementPluginScores. + f.Parallelizer().Until(ctx, len(podGroupAssignments), func(index int) { + placementPluginScores := fwk.PlacementPluginScores{ + Placement: podGroupAssignments[index].Placement, + Scores: make([]fwk.PluginScore, len(plugins)), + } + + for i, pl := range plugins { + weight := f.placementScorePluginWeight[pl.Name()] + placementScoreList := pluginToPlacementScores[pl.Name()] + score := placementScoreList[index].Score + + if score > fwk.MaxScore || score < fwk.MinScore { + err := fmt.Errorf("plugin %q returns an invalid score %v, it should in the range of [%v, %v] after normalizing", pl.Name(), score, fwk.MinScore, fwk.MaxScore) + errCh.SendWithCancel(err, cancel) + return + } + weightedScore := score * int64(weight) + placementPluginScores.Scores[i] = fwk.PluginScore{ + Name: pl.Name(), + Score: weightedScore, + } + placementPluginScores.TotalScore += weightedScore + } + allPlacementPluginScores[index] = placementPluginScores + }, metrics.PlacementScore) + if err := errCh.Receive(); err != nil { + return nil, fwk.AsStatus(fmt.Errorf("applying score defaultWeights on PlacementScore plugins: %w", err)) + } + + return allPlacementPluginScores, nil +} + +func (f *frameworkImpl) runPlacementScorePlugin(ctx context.Context, pl fwk.PlacementScorePlugin, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, placement *fwk.PodGroupAssignments) (int64, *fwk.Status) { + if !state.ShouldRecordPluginMetrics() { + return pl.ScorePlacement(ctx, state, podGroup, placement) + } + startTime := time.Now() + s, status := pl.ScorePlacement(ctx, state, podGroup, placement) + f.metricsRecorder.ObservePluginDurationAsync(metrics.PlacementScore, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) + return s, status +} + +func (f *frameworkImpl) runPlacementScoreExtension(ctx context.Context, pl fwk.PlacementScorePlugin, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, placementScoreList []fwk.PlacementScore) *fwk.Status { + if !state.ShouldRecordPluginMetrics() { + return pl.PlacementScoreExtensions().NormalizePlacementScore(ctx, state, podGroup, placementScoreList) + } + startTime := time.Now() + status := pl.PlacementScoreExtensions().NormalizePlacementScore(ctx, state, podGroup, placementScoreList) + f.metricsRecorder.ObservePluginDurationAsync(metrics.PlacementScoreExtensionNormalize, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) + return status +} + +func (f *frameworkImpl) GetNodeHint(ctx context.Context, pod *v1.Pod, signature fwk.PodSignature, state fwk.CycleState, cycleCount int64) string { + return f.batch.GetNodeHint(ctx, pod, signature, state, cycleCount) } func (f *frameworkImpl) StoreScheduleResults(ctx context.Context, signature fwk.PodSignature, hintedNode, chosenNode string, otherNodes framework.SortedScoredNodes, cycleCount int64) { @@ -1421,31 +1619,89 @@ func (f *frameworkImpl) RunPreBindPlugins(ctx context.Context, state fwk.CycleSt logger = klog.LoggerWithName(logger, "PreBind") logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) } - for _, pl := range f.preBindPlugins { - if state.GetSkipPreBindPlugins().Has(pl.Name()) { - continue - } + ctx, cancel := context.WithCancelCause(ctx) + defer cancel(errors.New("RunPreBindPlugins has completed")) + statusCh := parallelize.NewResultChannel[*fwk.Status]() + skippedPlugins := state.GetSkipPreBindPlugins() + parallelPlugins := state.GetParallelPreBindPlugins() + + // run operates directly on the plugin. + run := func(pl fwk.PreBindPlugin) *fwk.Status { ctx := ctx if verboseLogs { logger := klog.LoggerWithName(logger, pl.Name()) ctx = klog.NewContext(ctx, logger) } - status = f.runPreBindPlugin(ctx, pl, state, pod, nodeName) - if !status.IsSuccess() { - if status.IsRejected() { - logger.V(4).Info("Pod rejected by PreBind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", status.Message()) - status.SetPlugin(pl.Name()) - return status + plStatus := f.runPreBindPlugin(ctx, pl, state, pod, nodeName) + if !plStatus.IsSuccess() { + if plStatus.IsRejected() { + logger.V(4).Info("Pod rejected by PreBind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", plStatus.Message()) + plStatus.SetPlugin(pl.Name()) + return plStatus } - err := status.AsError() + err := plStatus.AsError() + if errors.Is(err, context.Canceled) { + err = context.Cause(ctx) + } + logger.Error(err, "Plugin failed", "plugin", pl.Name(), "pod", klog.KObj(pod), "node", nodeName) return fwk.AsStatus(fmt.Errorf("running PreBind plugin %q: %w", pl.Name(), err)) } + return nil + } + + pluginGroups := f.getPreBindPluginGroups(state, skippedPlugins, parallelPlugins) + for _, plugins := range pluginGroups { + // If there is just a single plugin in the group, running it in a separate goroutine + // does not provide any benefit. + if len(plugins) == 1 { + if status := run(plugins[0]); status != nil { + return status + } + continue + } + f.Parallelizer().Until(ctx, len(plugins), func(index int) { + if status := run(plugins[index]); !status.IsSuccess() { + statusCh.SendWithCancel(status, func() { + cancel(errors.New("some other PreBind operation failed")) + }) + } + }, metrics.PreBind) + if status := statusCh.Receive(); !status.IsSuccess() { + return status + } } return nil } +// getPreBindPluginGroups chunks the plugins implementing the PreBind extension point +// into groups of plugins that can be run in parallel. +// The returned value consists of non-skipped plugins only. +func (f *frameworkImpl) getPreBindPluginGroups(state fwk.CycleState, skippedPlugins, parallelPlugins sets.Set[string]) [][]fwk.PreBindPlugin { + var groups [][]fwk.PreBindPlugin + var group []fwk.PreBindPlugin + for _, pl := range f.preBindPlugins { + if parallelPlugins.Has(pl.Name()) { + if !skippedPlugins.Has(pl.Name()) { + group = append(group, pl) + } + continue + } + if len(group) > 0 { + groups = append(groups, group) + group = nil + } + if !skippedPlugins.Has(pl.Name()) { + groups = append(groups, []fwk.PreBindPlugin{pl}) + } + } + if len(group) > 0 { + groups = append(groups, group) + } + return groups +} + func (f *frameworkImpl) runPreBindPlugin(ctx context.Context, pl fwk.PreBindPlugin, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status { if !state.ShouldRecordPluginMetrics() { return pl.PreBind(ctx, state, pod, nodeName) @@ -1473,6 +1729,7 @@ func (f *frameworkImpl) RunPreBindPreFlights(ctx context.Context, state fwk.Cycl logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) } skipPlugins := sets.New[string]() + parallelPlugins := sets.New[string]() returningStatus := fwk.NewStatus(fwk.Skip) for _, pl := range f.preBindPlugins { ctx := ctx @@ -1480,7 +1737,10 @@ func (f *frameworkImpl) RunPreBindPreFlights(ctx context.Context, state fwk.Cycl logger := klog.LoggerWithName(logger, pl.Name()) ctx = klog.NewContext(ctx, logger) } - status = f.runPreBindPreFlight(ctx, pl, state, pod, nodeName) + result, status := f.runPreBindPreFlight(ctx, pl, state, pod, nodeName) + if result != nil && result.AllowParallel { + parallelPlugins.Insert(pl.Name()) + } switch { case status.Code() == fwk.Error: err := status.AsError() @@ -1497,17 +1757,18 @@ func (f *frameworkImpl) RunPreBindPreFlights(ctx context.Context, state fwk.Cycl } } state.SetSkipPreBindPlugins(skipPlugins) + state.SetParallelPreBindPlugins(parallelPlugins) return returningStatus } -func (f *frameworkImpl) runPreBindPreFlight(ctx context.Context, pl fwk.PreBindPlugin, state fwk.CycleState, pod *v1.Pod, nodeName string) *fwk.Status { +func (f *frameworkImpl) runPreBindPreFlight(ctx context.Context, pl fwk.PreBindPlugin, state fwk.CycleState, pod *v1.Pod, nodeName string) (*fwk.PreBindPreFlightResult, *fwk.Status) { if !state.ShouldRecordPluginMetrics() { return pl.PreBindPreFlight(ctx, state, pod, nodeName) } startTime := time.Now() - status := pl.PreBindPreFlight(ctx, state, pod, nodeName) + result, status := pl.PreBindPreFlight(ctx, state, pod, nodeName) f.metricsRecorder.ObservePluginDurationAsync(metrics.PreBindPreFlight, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status + return result, status } // RunBindPlugins runs the set of configured bind plugins until one returns a non `Skip` status. @@ -1673,19 +1934,18 @@ func (f *frameworkImpl) runReservePluginUnreserve(ctx context.Context, pl fwk.Re f.metricsRecorder.ObservePluginDurationAsync(metrics.Unreserve, pl.Name(), fwk.Success.String(), metrics.SinceInSeconds(startTime)) } -// RunPermitPlugins runs the set of configured permit plugins. If any of these +// RunPermitPlugins runs the set of configured Permit plugins. If any of these // plugins returns a status other than "Success" or "Wait", it does not continue // running the remaining plugins and returns an error. Otherwise, if any of the -// plugins returns "Wait", then this function will create and add waiting pod -// to a map of currently waiting pods and return status with "Wait" code. -// Pod will remain waiting pod for the minimum duration returned by the permit plugins. -func (f *frameworkImpl) RunPermitPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) (status *fwk.Status) { +// plugins returns "Wait", then this function will construct the pluginsWaitTime and return status with "Wait" code. +// This function itself will NOT create a waiting pod object and the caller should call AddWaitingPod method to do this. +func (f *frameworkImpl) RunPermitPlugins(ctx context.Context, state fwk.CycleState, pod *v1.Pod, nodeName string) (pluginsWaitTime map[string]time.Duration, status *fwk.Status) { startTime := time.Now() defer func() { metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Permit, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) }() - pluginsWaitTime := make(map[string]time.Duration) - statusCode := fwk.Success + var waitStatus *fwk.Status + pluginsWaitTime = make(map[string]time.Duration) logger := klog.FromContext(ctx) verboseLogs := logger.V(4).Enabled() if verboseLogs { @@ -1702,7 +1962,7 @@ func (f *frameworkImpl) RunPermitPlugins(ctx context.Context, state fwk.CycleSta if !status.IsSuccess() { if status.IsRejected() { logger.V(4).Info("Pod rejected by plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", status.Message()) - return status.WithPlugin(pl.Name()) + return nil, status.WithPlugin(pl.Name()) } if status.IsWait() { // Not allowed to be greater than maxTimeout. @@ -1710,22 +1970,20 @@ func (f *frameworkImpl) RunPermitPlugins(ctx context.Context, state fwk.CycleSta timeout = maxTimeout } pluginsWaitTime[pl.Name()] = timeout - statusCode = fwk.Wait + waitStatus = status } else { err := status.AsError() logger.Error(err, "Plugin failed", "plugin", pl.Name(), "pod", klog.KObj(pod)) - return fwk.AsStatus(fmt.Errorf("running Permit plugin %q: %w", pl.Name(), err)).WithPlugin(pl.Name()) + return nil, fwk.AsStatus(fmt.Errorf("running Permit plugin %q: %w", pl.Name(), err)).WithPlugin(pl.Name()) } } } - if statusCode == fwk.Wait { - waitingPod := newWaitingPod(pod, pluginsWaitTime) - f.waitingPods.add(waitingPod) - msg := fmt.Sprintf("one or more plugins asked to wait and no plugin rejected pod %q", pod.Name) + if waitStatus.IsWait() { logger.V(4).Info("One or more plugins asked to wait and no plugin rejected pod", "pod", klog.KObj(pod)) - return fwk.NewStatus(fwk.Wait, msg) + waitStatus.AppendReason("one or more plugins asked to wait and no plugin rejected pod") + return pluginsWaitTime, waitStatus } - return nil + return nil, nil } func (f *frameworkImpl) runPermitPlugin(ctx context.Context, pl fwk.PermitPlugin, state fwk.CycleState, pod *v1.Pod, nodeName string) (*fwk.Status, time.Duration) { @@ -1738,6 +1996,55 @@ func (f *frameworkImpl) runPermitPlugin(ctx context.Context, pl fwk.PermitPlugin return status, timeout } +// AddWaitingPod creates a waiting pod instance and adds it to the framework. +// It takes the pluginsWaitTime map returned by the RunPermitPlugins. +// Pod will remain waiting pod for the minimum duration returned by the Permit plugins. +// This method should only be called when RunPermitPlugins returns a Wait status and WaitOnPermit is expected to execute soon. +func (f *frameworkImpl) AddWaitingPod(pod *v1.Pod, pluginsWaitTime map[string]time.Duration) { + waitingPod := newWaitingPod(pod, pluginsWaitTime) + f.waitingPods.add(waitingPod) +} + +// RunPlacementGeneratePlugins runs the set of configured PlacementGeneratePlugins and returns the generated placements. +// If no plugins are defined, the input placement is returned instead. +func (f *frameworkImpl) RunPlacementGeneratePlugins(ctx context.Context, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, nodes []fwk.NodeInfo) (placements []*fwk.Placement, status *fwk.Status) { + startTime := time.Now() + defer func() { + metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PlacementGenerate, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) + }() + + placement := &fwk.Placement{ + Nodes: nodes, + } + + if len(f.placementGeneratePlugins) == 0 { + return []*fwk.Placement{placement}, nil + } + + plugin := f.placementGeneratePlugins[0] + + result, status := f.runPlacementGeneratePlugin(ctx, plugin, state, podGroup, placement) + if !status.IsSuccess() { + return nil, status.WithPlugin(plugin.Name()) + } + + if len(result.Placements) == 0 { + return nil, fwk.NewStatus(fwk.Unschedulable, "no feasible placements found").WithPlugin(plugin.Name()) + } + + return result.Placements, nil +} + +func (f *frameworkImpl) runPlacementGeneratePlugin(ctx context.Context, pl fwk.PlacementGeneratePlugin, state fwk.PodGroupCycleState, podGroup fwk.PodGroupInfo, parentPlacement *fwk.Placement) (*fwk.GeneratePlacementsResult, *fwk.Status) { + if !state.ShouldRecordPluginMetrics() { + return pl.GeneratePlacements(ctx, state, podGroup, parentPlacement) + } + startTime := time.Now() + placements, status := pl.GeneratePlacements(ctx, state, podGroup, parentPlacement) + f.metricsRecorder.ObservePluginDurationAsync(metrics.PlacementGenerate, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) + return placements, status +} + func (f *frameworkImpl) WillWaitOnPermit(ctx context.Context, pod *v1.Pod) bool { return f.waitingPods.get(pod.UID) != nil } @@ -1791,15 +2098,32 @@ func (f *frameworkImpl) GetWaitingPod(uid types.UID) fwk.WaitingPod { } // RejectWaitingPod rejects a WaitingPod given its UID. -// The returned value indicates if the given pod is waiting or not. +// The returned value indicates if the rejection was successful. func (f *frameworkImpl) RejectWaitingPod(uid types.UID) bool { if waitingPod := f.waitingPods.get(uid); waitingPod != nil { - waitingPod.Reject("", "removed") - return true + return waitingPod.Reject("", "removed") } return false } +// AddPodInPreBind adds a pod to the pods in preBind list. +func (f *frameworkImpl) AddPodInPreBind(uid types.UID, cancel context.CancelCauseFunc) { + f.podsInPreBind.add(uid, cancel) +} + +// GetPodInPreBind returns a pod that is in the binding cycle but before it is bound given its UID. +func (f *frameworkImpl) GetPodInPreBind(uid types.UID) fwk.PodInPreBind { + if bp := f.podsInPreBind.get(uid); bp != nil { + return bp + } + return nil +} + +// RemovePodInPreBind removes a pod from the pods in preBind list. +func (f *frameworkImpl) RemovePodInPreBind(uid types.UID) { + f.podsInPreBind.remove(uid) +} + // HasFilterPlugins returns true if at least one filter plugin is defined. func (f *frameworkImpl) HasFilterPlugins() bool { return len(f.filterPlugins) > 0 @@ -1815,6 +2139,11 @@ func (f *frameworkImpl) HasScorePlugins() bool { return len(f.scorePlugins) > 0 } +// PodGroupPostFilterPlugins returns registered PodGroup PostFilter plugins. +func (f *frameworkImpl) PodGroupPostFilterPlugins() []framework.PodGroupPostFilterPlugin { + return f.podGroupPostFilterPlugins +} + // ListPlugins returns a map of extension point name to plugin names configured at each extension // point. Returns nil if no plugins where configured. func (f *frameworkImpl) ListPlugins() *config.Plugins { @@ -1827,10 +2156,13 @@ func (f *frameworkImpl) ListPlugins() *config.Plugins { for i := 0; i < plugins.Len(); i++ { name := plugins.Index(i).Interface().(fwk.Plugin).Name() p := config.Plugin{Name: name} + // Weights apply only to score and placement score plugins. if extName == "ScorePlugin" { - // Weights apply only to score plugins. p.Weight = int32(f.scorePluginWeight[name]) } + if extName == "PlacementScorePlugin" { + p.Weight = int32(f.placementScorePluginWeight[name]) + } cfgs = append(cfgs, p) } if len(cfgs) > 0 { @@ -1851,7 +2183,7 @@ func (f *frameworkImpl) KubeConfig() *restclient.Config { } // EventRecorder returns an event recorder. -func (f *frameworkImpl) EventRecorder() events.EventRecorder { +func (f *frameworkImpl) EventRecorder() events.EventRecorderLogger { return f.eventRecorder } @@ -1870,9 +2202,9 @@ func (f *frameworkImpl) SharedCSIManager() fwk.CSIManager { return f.sharedCSIManager } -// WorkloadManager returns the WorkloadManager of the framework. -func (f *frameworkImpl) WorkloadManager() fwk.WorkloadManager { - return f.workloadManager +// PodGroupManager returns the PodGroupManager of the framework. +func (f *frameworkImpl) PodGroupManager() fwk.PodGroupManager { + return f.podGroupManager } func (f *frameworkImpl) pluginsNeeded(plugins *config.Plugins) sets.Set[string] { @@ -1931,7 +2263,7 @@ func (f *frameworkImpl) APICacher() fwk.APICacher { return f.apiCacher } -// Used only for tests +// TotalBatchedPods returns the total number of batched pods. Used only for tests func (f *frameworkImpl) TotalBatchedPods() int64 { return f.batch.batchedPods } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/pods_in_prebind_map.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/pods_in_prebind_map.go new file mode 100644 index 0000000000..41f369e51d --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/pods_in_prebind_map.go @@ -0,0 +1,98 @@ +/* +Copyright 2025 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 runtime + +import ( + "context" + "errors" + "sync" + + "k8s.io/apimachinery/pkg/types" + fwk "k8s.io/kube-scheduler/framework" +) + +// podsInPreBindMap is a thread-safe map of pods currently in the preBind phase. +type podsInPreBindMap struct { + pods map[types.UID]*podInPreBind + mu sync.RWMutex +} + +// NewPodsInPreBindMap creates an empty podsInPreBindMap. +func NewPodsInPreBindMap() *podsInPreBindMap { + return &podsInPreBindMap{ + pods: make(map[types.UID]*podInPreBind), + } +} + +// get returns a pod from the map if it exists. +func (pbm *podsInPreBindMap) get(uid types.UID) *podInPreBind { + pbm.mu.RLock() + defer pbm.mu.RUnlock() + return pbm.pods[uid] +} + +// add adds a pod to map, overwriting existing one. +func (pbm *podsInPreBindMap) add(uid types.UID, cancel context.CancelCauseFunc) { + pbm.mu.Lock() + defer pbm.mu.Unlock() + pbm.pods[uid] = &podInPreBind{cancel: cancel} +} + +// remove removes a pod from the map. +func (pbm *podsInPreBindMap) remove(uid types.UID) { + pbm.mu.Lock() + defer pbm.mu.Unlock() + delete(pbm.pods, uid) +} + +var _ fwk.PodInPreBind = &podInPreBind{} + +// podInPreBind describes a pod in the preBind phase, before the bind was called for a pod. +type podInPreBind struct { + finished bool + canceled bool + cancel context.CancelCauseFunc + mu sync.Mutex +} + +// CancelPod cancels the context running the preBind phase +// for a given pod. +func (bp *podInPreBind) CancelPod(message string) bool { + bp.mu.Lock() + defer bp.mu.Unlock() + if bp.finished { + return false + } + if !bp.canceled { + bp.cancel(errors.New(message)) + } + bp.canceled = true + return true +} + +// MarkPrebound marks the pod as finished with preBind phase +// of binding cycle, making it impossible to cancel +// the binding cycle for it. +func (bp *podInPreBind) MarkPrebound() bool { + bp.mu.Lock() + defer bp.mu.Unlock() + if bp.canceled { + return false + } + bp.finished = true + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go index dc054ee7f5..4bc2bbeb9f 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go @@ -75,6 +75,7 @@ type waitingPod struct { pendingPlugins map[string]*time.Timer s chan *fwk.Status mu sync.RWMutex + done bool } var _ fwk.WaitingPod = &waitingPod{} @@ -141,15 +142,26 @@ func (w *waitingPod) Allow(pluginName string) { } // The select clause works as a non-blocking send. - // If there is no receiver, it's a no-op (default case). + // If there is no place in the buffer, it's a no-op (default case). select { case w.s <- fwk.NewStatus(fwk.Success, ""): default: } + w.done = true } // Reject declares the waiting pod unschedulable. -func (w *waitingPod) Reject(pluginName, msg string) { +func (w *waitingPod) Reject(pluginName, msg string) bool { + return w.stopWithStatus(fwk.Unschedulable, pluginName, msg) +} + +// Preempt declares the waiting pod is preempted. Compared to reject it does not mark the pod as unschedulable, +// allowing it to be rescheduled. +func (w *waitingPod) Preempt(pluginName, msg string) bool { + return w.stopWithStatus(fwk.Error, pluginName, msg) +} + +func (w *waitingPod) stopWithStatus(status fwk.Code, pluginName, msg string) bool { w.mu.RLock() defer w.mu.RUnlock() for _, timer := range w.pendingPlugins { @@ -157,9 +169,14 @@ func (w *waitingPod) Reject(pluginName, msg string) { } // The select clause works as a non-blocking send. - // If there is no receiver, it's a no-op (default case). + // If there is no place in the buffer, it's a no-op (default case). select { - case w.s <- fwk.NewStatus(fwk.Unschedulable, msg).WithPlugin(pluginName): + case w.s <- fwk.NewStatus(status, msg).WithPlugin(pluginName): default: } + if w.done { + return false + } + w.done = true + return true } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go index 9e92527be1..30a72742ed 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go @@ -26,6 +26,7 @@ import ( "time" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" @@ -76,7 +77,7 @@ var ( fwk.ResourceClaim, fwk.ResourceSlice, fwk.DeviceClass, - fwk.Workload, + fwk.PodGroup, } ) @@ -156,7 +157,7 @@ func UnrollWildCardResource() []fwk.ClusterEventWithHint { {Event: fwk.ClusterEvent{Resource: fwk.DeviceClass, ActionType: fwk.All}}, } if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { - events = append(events, fwk.ClusterEventWithHint{Event: fwk.ClusterEvent{Resource: fwk.Workload, ActionType: fwk.All}}) + events = append(events, fwk.ClusterEventWithHint{Event: fwk.ClusterEvent{Resource: fwk.PodGroup, ActionType: fwk.All}}) } return events } @@ -205,6 +206,11 @@ type NodeInfo struct { // DeclaredFeatures is a set of features published by the node DeclaredFeatures ndf.FeatureSet + + // NodeAllocatableDRAClaimStates tracks the state of claims requesting node-allocatable resources + // (resources published in Node.Status.Allocatable like cpu, memory. etc.). + // This is used to enforce sharing policies for these claims on the node. + NodeAllocatableDRAClaimStates map[types.NamespacedName]*fwk.NodeAllocatableDRAClaimState } func (n *NodeInfo) GetPods() []fwk.PodInfo { @@ -252,6 +258,10 @@ func (n *NodeInfo) GetNodeDeclaredFeatures() ndf.FeatureSet { return n.DeclaredFeatures } +func (n *NodeInfo) GetNodeAllocatableDRAClaimState() map[types.NamespacedName]*fwk.NodeAllocatableDRAClaimState { + return n.NodeAllocatableDRAClaimStates +} + // NodeInfo implements KMetadata, so for example klog.KObjSlice(nodes) works // when nodes is a []*NodeInfo. var _ klog.KMetadata = &NodeInfo{} @@ -290,15 +300,16 @@ func (n *NodeInfo) Snapshot() fwk.NodeInfo { // SnapshotConcrete returns a copy of this node, Except that ImageStates is copied without the Nodes field. func (n *NodeInfo) SnapshotConcrete() *NodeInfo { clone := &NodeInfo{ - node: n.node, - Requested: n.Requested.Clone(), - NonZeroRequested: n.NonZeroRequested.Clone(), - Allocatable: n.Allocatable.Clone(), - UsedPorts: make(fwk.HostPortInfo), - ImageStates: make(map[string]*fwk.ImageStateSummary), - PVCRefCounts: make(map[string]int), - Generation: n.Generation, - DeclaredFeatures: n.DeclaredFeatures.Clone(), + node: n.node, + Requested: n.Requested.Clone(), + NonZeroRequested: n.NonZeroRequested.Clone(), + Allocatable: n.Allocatable.Clone(), + UsedPorts: make(fwk.HostPortInfo), + ImageStates: make(map[string]*fwk.ImageStateSummary), + PVCRefCounts: make(map[string]int), + Generation: n.Generation, + DeclaredFeatures: n.DeclaredFeatures.Clone(), + NodeAllocatableDRAClaimStates: make(map[types.NamespacedName]*fwk.NodeAllocatableDRAClaimState), } if len(n.Pods) > 0 { clone.Pods = append([]fwk.PodInfo(nil), n.Pods...) @@ -329,6 +340,9 @@ func (n *NodeInfo) SnapshotConcrete() *NodeInfo { for key, value := range n.PVCRefCounts { clone.PVCRefCounts[key] = value } + for key, value := range n.NodeAllocatableDRAClaimStates { + clone.NodeAllocatableDRAClaimStates[key] = value.Snapshot() + } return clone } @@ -386,6 +400,8 @@ func removeFromSlice(logger klog.Logger, s []fwk.PodInfo, k string) ([]fwk.PodIn removedPod = s[i] // delete the element s[i] = s[len(s)-1] + // clear the reference to prevent potential memory leak + s[len(s)-1] = nil s = s[:len(s)-1] break } @@ -439,6 +455,42 @@ func (n *NodeInfo) update(podInfo fwk.PodInfo, sign int64) { n.updatePVCRefCounts(podInfo.GetPod(), sign > 0) n.Generation = nextGeneration() + + if utilfeature.DefaultFeatureGate.Enabled(features.DRANodeAllocatableResources) { + n.updateNodeAllocatableDRAClaimState(podInfo, sign) + } +} + +// updateNodeAllocatableDRAClaimState updates the NodeInfo based on DRA node allocatable resource claims in the pod. +func (n *NodeInfo) updateNodeAllocatableDRAClaimState(podInfo fwk.PodInfo, sign int64) { + pod := podInfo.GetPod() + + if n.NodeAllocatableDRAClaimStates == nil && len(pod.Status.NodeAllocatableResourceClaimStatuses) > 0 { + n.NodeAllocatableDRAClaimStates = make(map[types.NamespacedName]*fwk.NodeAllocatableDRAClaimState, len(pod.Status.NodeAllocatableResourceClaimStatuses)) + } + + for _, claimStatus := range pod.Status.NodeAllocatableResourceClaimStatuses { + resourceClaimNamespacedName := types.NamespacedName{ + Namespace: pod.Namespace, + Name: claimStatus.ResourceClaimName, + } + + if _, exists := n.NodeAllocatableDRAClaimStates[resourceClaimNamespacedName]; !exists { + n.NodeAllocatableDRAClaimStates[resourceClaimNamespacedName] = &fwk.NodeAllocatableDRAClaimState{ + ConsumerPods: sets.New[types.UID](), + } + } + state := n.NodeAllocatableDRAClaimStates[resourceClaimNamespacedName] + + if sign > 0 { + state.ConsumerPods.Insert(pod.UID) + } else { + state.ConsumerPods.Delete(pod.UID) + if state.ConsumerPods.Len() == 0 { + delete(n.NodeAllocatableDRAClaimStates, resourceClaimNamespacedName) + } + } + } } // updateUsedPorts updates the UsedPorts of NodeInfo. @@ -476,7 +528,10 @@ func (n *NodeInfo) SetNode(node *v1.Node) { n.node = node n.Allocatable = NewResource(node.Status.Allocatable) if utilfeature.DefaultFeatureGate.Enabled(features.NodeDeclaredFeatures) { - n.DeclaredFeatures = ndf.NewFeatureSet(node.Status.DeclaredFeatures...) + // Use TryMap rather than Map here in case the node has unknown features. Since we're only + // concerned with matching known features to the node, there is no risk to discarding + // unknown features. + n.DeclaredFeatures = ndf.DefaultFramework.TryMap(node.Status.DeclaredFeatures) } n.Generation = nextGeneration() } @@ -526,6 +581,12 @@ type QueuedPodInfo struct { // That's why we need to distinguish ConsecutiveErrorsCount for the error status and UnschedulableCount for the unschedulable status. // See https://github.com/kubernetes/kubernetes/issues/128744 for the discussion. ConsecutiveErrorsCount int + // WasFlushedFromUnschedulable tracks whether this pod was most recently moved to activeQ + // by the periodic flush from unschedulablePods due to timeout (rather than by an event). + // This is used to detect if the pod becomes schedulable soon after flush, which may + // indicate queueing hint misconfigurations or event handling bugs. + // This flag is cleared when the pod returns to the queue for any reason. + WasFlushedFromUnschedulable bool // The time when the pod is added to the queue for the first time. The pod may be added // back to the queue multiple times before it's successfully scheduled. // It shouldn't be updated once initialized. It's used to record the e2e scheduling @@ -545,6 +606,8 @@ type QueuedPodInfo struct { // GatingPluginEvents records the events registered by the plugin that gated the Pod at PreEnqueue. // We have it as a cache purpose to avoid re-computing which event(s) might ungate the Pod. GatingPluginEvents []fwk.ClusterEvent + // PodSignature for opportunistic batching + PodSignature fwk.PodSignature } func (pqi *QueuedPodInfo) GetPodInfo() fwk.PodInfo { @@ -610,9 +673,61 @@ func (pqi *QueuedPodInfo) DeepCopy() *QueuedPodInfo { GatingPluginEvents: slices.Clone(pqi.GatingPluginEvents), PendingPlugins: pqi.PendingPlugins.Clone(), ConsecutiveErrorsCount: pqi.ConsecutiveErrorsCount, + PodSignature: pqi.PodSignature, } } +// Update updates the pod in QueuedPodInfo and clears the cached PodSignature, +// since the updated pod may no longer match the signature computed for the previous version. +func (pqi *QueuedPodInfo) Update(pod *v1.Pod) error { + pqi.PodSignature = nil + return pqi.PodInfo.Update(pod) +} + +// ClearRejectorPlugins clears the plugin-related fields that track why a pod +// was rejected in a previous scheduling attempt. +func (pqi *QueuedPodInfo) ClearRejectorPlugins() { + pqi.UnschedulablePlugins.Clear() + pqi.PendingPlugins.Clear() + pqi.GatingPlugin = "" + pqi.GatingPluginEvents = nil +} + +// QueuedPodGroupInfo is a PodGroupInfo wrapper with additional information related to +// the pod group's status in the scheduling queue and stores all queued pods from that pod group. +type QueuedPodGroupInfo struct { + *PodGroupInfo + // QueuedPodInfos are the pod group's pods that are currently queued. + // The order of the pods is deterministic and based on the priority and InitialAttemptTimestamp. + QueuedPodInfos []*QueuedPodInfo +} + +// PodGroupInfo is a wrapper around the PodGroup API object together with a list of pods that belong to the pod group. +// Typically used as an input to pod group scheduling cycle plugins. +type PodGroupInfo struct { + // Namespace is a namespace of this pod group. + Namespace string + // Name is a name of this pod group. + Name string + // UnscheduledPods are pods that are currently being considered for scheduling. + // It can be useful to also retrieve the scheduled (assumed or assigned) pods. + // PodGroupManager.PodGroupState can be used for that. + // The order of the pods is deterministic and based on signature, priority and timestamp. + UnscheduledPods []*v1.Pod +} + +func (pgi *PodGroupInfo) GetName() string { + return pgi.Name +} + +func (pgi *PodGroupInfo) GetNamespace() string { + return pgi.Namespace +} + +func (pgi *PodGroupInfo) GetUnscheduledPods() []*v1.Pod { + return pgi.UnscheduledPods +} + // PodInfo is a wrapper to a Pod with additional pre-computed information to // accelerate processing. This information is typically immutable (e.g., pre-processed // inter-pod affinity selectors). @@ -721,11 +836,14 @@ func (pi *PodInfo) CalculateResource() fwk.PodResource { inPlacePodVerticalScalingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) podLevelResourcesEnabled := utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) inPlacePodLevelResourcesVerticalScalingEnabled := utilfeature.DefaultMutableFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) + nodeAllocatableResourcesDRAEnabled := utilfeature.DefaultFeatureGate.Enabled(features.DRANodeAllocatableResources) + requests := resourcehelper.PodRequests(pi.Pod, resourcehelper.PodResourcesOptions{ UseStatusResources: inPlacePodVerticalScalingEnabled, InPlacePodLevelResourcesVerticalScalingEnabled: inPlacePodLevelResourcesVerticalScalingEnabled, // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, + SkipPodLevelResources: !podLevelResourcesEnabled, + UseDRANodeAllocatableResourceClaimStatus: nodeAllocatableResourcesDRAEnabled, }) isPodLevelResourcesSet := podLevelResourcesEnabled && resourcehelper.IsPodLevelRequestsSet(pi.Pod) nonMissingContainerRequests := getNonMissingContainerRequests(requests, isPodLevelResourcesSet) @@ -735,8 +853,9 @@ func (pi *PodInfo) CalculateResource() fwk.PodResource { UseStatusResources: inPlacePodVerticalScalingEnabled, InPlacePodLevelResourcesVerticalScalingEnabled: inPlacePodLevelResourcesVerticalScalingEnabled, // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, - NonMissingContainerRequests: nonMissingContainerRequests, + SkipPodLevelResources: !podLevelResourcesEnabled, + NonMissingContainerRequests: nonMissingContainerRequests, + UseDRANodeAllocatableResourceClaimStatus: nodeAllocatableResourcesDRAEnabled, }) } non0CPU := non0Requests[v1.ResourceCPU] @@ -987,13 +1106,14 @@ func (r *Resource) SetMaxResource(rl v1.ResourceList) { // the returned object. func NewNodeInfo(pods ...*v1.Pod) *NodeInfo { ni := &NodeInfo{ - Requested: &Resource{}, - NonZeroRequested: &Resource{}, - Allocatable: &Resource{}, - Generation: nextGeneration(), - UsedPorts: make(fwk.HostPortInfo), - ImageStates: make(map[string]*fwk.ImageStateSummary), - PVCRefCounts: make(map[string]int), + Requested: &Resource{}, + NonZeroRequested: &Resource{}, + Allocatable: &Resource{}, + Generation: nextGeneration(), + UsedPorts: make(fwk.HostPortInfo), + ImageStates: make(map[string]*fwk.ImageStateSummary), + PVCRefCounts: make(map[string]int), + NodeAllocatableDRAClaimStates: make(map[types.NamespacedName]*fwk.NodeAllocatableDRAClaimState), } for _, pod := range pods { ni.AddPod(pod) diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go index f59ea1e96f..8377ce3c15 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go @@ -138,6 +138,12 @@ func NewMetricsAsyncRecorder(bufferSize int, interval time.Duration, stopCh <-ch return recorder } +// ObserveFrameworkExtensionPointDurationAsync observes the framework_extension_point_duration_seconds metric. +// The metric will be flushed to Prometheus asynchronously. +func (r *MetricAsyncRecorder) ObserveFrameworkExtensionPointDurationAsync(extensionPoint, status, profileName string, value float64) { + r.observeMetricAsync(FrameworkExtensionPointDuration, value, extensionPoint, status, profileName) +} + // ObservePluginDurationAsync observes the plugin_execution_duration_seconds metric. // The metric will be flushed to Prometheus asynchronously. func (r *MetricAsyncRecorder) ObservePluginDurationAsync(extensionPoint, pluginName, status string, value float64) { diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go index 8fbdc0d98a..46b8d51302 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go @@ -63,25 +63,29 @@ var ExtensionPoints = []string{ Unreserve, Permit, Sign, + PlacementGenerate, } const ( - PreFilter = "PreFilter" - Filter = "Filter" - PreFilterExtensionAddPod = "PreFilterExtensionAddPod" - PreFilterExtensionRemovePod = "PreFilterExtensionRemovePod" - PostFilter = "PostFilter" - PreScore = "PreScore" - Score = "Score" - ScoreExtensionNormalize = "ScoreExtensionNormalize" - PreBind = "PreBind" - PreBindPreFlight = "PreBindPreFlight" - Bind = "Bind" - PostBind = "PostBind" - Reserve = "Reserve" - Unreserve = "Unreserve" - Permit = "Permit" - Sign = "Sign" + PreFilter = "PreFilter" + Filter = "Filter" + PreFilterExtensionAddPod = "PreFilterExtensionAddPod" + PreFilterExtensionRemovePod = "PreFilterExtensionRemovePod" + PostFilter = "PostFilter" + PreScore = "PreScore" + Score = "Score" + ScoreExtensionNormalize = "ScoreExtensionNormalize" + PreBind = "PreBind" + PreBindPreFlight = "PreBindPreFlight" + Bind = "Bind" + PostBind = "PostBind" + Reserve = "Reserve" + Unreserve = "Unreserve" + Permit = "Permit" + Sign = "Sign" + PlacementGenerate = "PlacementGenerate" + PlacementScore = "PlacementScore" + PlacementScoreExtensionNormalize = "PlacementScoreExtensionNormalize" ) const ( @@ -113,6 +117,14 @@ const ( BatchFlushPodNotBatchable = "pod_not_batchable" ) +// DRADeviceBindingConditions status labels +const ( + BindingConditionsStatusSuccess = "success" + BindingConditionsStatusFailed = "failure" + BindingConditionsStatusTimeout = "timeout" + BindingConditionsStatusError = "error" +) + // All the histogram based metrics have 1ms as size for the smallest bucket. var ( scheduleAttempts *metrics.CounterVec @@ -131,6 +143,7 @@ var ( PodSchedulingSLIDuration *metrics.HistogramVec PodSchedulingAttempts *metrics.Histogram + PodScheduledAfterFlush *metrics.Counter FrameworkExtensionPointDuration *metrics.HistogramVec PluginExecutionDuration *metrics.HistogramVec @@ -155,6 +168,13 @@ var ( // The below is only available when the DRAExtendedResource feature gate is enabled. ResourceClaimCreatesTotal *metrics.CounterVec + podGroupScheduleAttempts *metrics.CounterVec + podGroupSchedulingLatency *metrics.HistogramVec + PodGroupSchedulingAlgorithmLatency *metrics.Histogram + // The below are only available when the DRADeviceBindingConditions feature gate is enabled. + DRABindingConditionsAllocationsTotal *metrics.CounterVec + DRABindingConditionsPreBindDuration *metrics.HistogramVec + // metricsList is a list of all metrics that should be registered always, regardless of any feature gate's value. metricsList []metrics.Registerable ) @@ -185,6 +205,19 @@ func Register() { if utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource) { RegisterMetrics(ResourceClaimCreatesTotal) } + if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { + RegisterMetrics( + podGroupScheduleAttempts, + podGroupSchedulingLatency, + PodGroupSchedulingAlgorithmLatency, + ) + } + if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceBindingConditions) { + RegisterMetrics( + DRABindingConditionsAllocationsTotal, + DRABindingConditionsPreBindDuration, + ) + } }) } @@ -259,7 +292,7 @@ func InitMetrics() { Subsystem: SchedulerSubsystem, Name: "goroutines", Help: "Number of running goroutines split by the work they do such as binding.", - StabilityLevel: metrics.ALPHA, + StabilityLevel: metrics.BETA, }, []string{"operation"}) BatchAttemptStats = metrics.NewCounterVec( &metrics.CounterOpts{ @@ -296,6 +329,14 @@ func InitMetrics() { StabilityLevel: metrics.STABLE, }) + PodScheduledAfterFlush = metrics.NewCounter( + &metrics.CounterOpts{ + Subsystem: SchedulerSubsystem, + Name: "pod_scheduled_after_flush_total", + Help: "Number of pods that were successfully scheduled after being flushed from unschedulablePods due to timeout. This metric helps detect potential queueing hint misconfigurations or event handling issues.", + StabilityLevel: metrics.ALPHA, + }) + FrameworkExtensionPointDuration = metrics.NewHistogramVec( &metrics.HistogramOpts{ Subsystem: SchedulerSubsystem, @@ -346,7 +387,7 @@ func InitMetrics() { Name: "permit_wait_duration_seconds", Help: "Duration of waiting on permit.", Buckets: metrics.ExponentialBuckets(0.001, 2, 15), - StabilityLevel: metrics.ALPHA, + StabilityLevel: metrics.BETA, }, []string{"result"}) @@ -363,7 +404,7 @@ func InitMetrics() { Subsystem: SchedulerSubsystem, Name: "unschedulable_pods", Help: "The number of unschedulable pods broken down by plugin name. A pod will increment the gauge for all plugins that caused it to not schedule and so this metric have meaning only when broken down by plugin.", - StabilityLevel: metrics.ALPHA, + StabilityLevel: metrics.BETA, }, []string{"plugin", "profile"}) PluginEvaluationTotal = metrics.NewCounterVec( @@ -371,7 +412,7 @@ func InitMetrics() { Subsystem: SchedulerSubsystem, Name: "plugin_evaluation_total", Help: "Number of attempts to schedule pods by each plugin and the extension point (available only in PreFilter, Filter, PreScore, and Score).", - StabilityLevel: metrics.ALPHA, + StabilityLevel: metrics.BETA, }, []string{"plugin", "extension_point", "profile"}) PreemptionGoroutinesDuration = metrics.NewHistogramVec( @@ -431,6 +472,27 @@ func InitMetrics() { }, []string{"status"}) + DRABindingConditionsAllocationsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: SchedulerSubsystem, + Name: "dra_bindingconditions_allocations_total", + Help: "Number of allocations using devices with BindingConditions, counted per driver per scheduling attempt", + StabilityLevel: metrics.ALPHA, + }, + []string{"profile", "driver", "status"}, + ) + + DRABindingConditionsPreBindDuration = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Subsystem: SchedulerSubsystem, + Name: "dra_bindingconditions_wait_duration_seconds", + Help: "Time in seconds spent waiting for BindingConditions to be satisfied during PreBind.", + Buckets: metrics.ExponentialBuckets(0.1, 2, 14), + StabilityLevel: metrics.ALPHA, + }, + []string{"profile", "driver", "status"}, + ) + GetNodeHintDuration = metrics.NewHistogramVec( &metrics.HistogramOpts{ Subsystem: SchedulerSubsystem, @@ -453,6 +515,31 @@ func InitMetrics() { }, []string{"profile"}) + // The below (podGroupScheduleAttempts, podGroupSchedulingLatency and PodGroupSchedulingAlgorithmLatency) are only available when the GenericWorkload feature gate is enabled. + podGroupScheduleAttempts = metrics.NewCounterVec( + &metrics.CounterOpts{ + Subsystem: SchedulerSubsystem, + Name: "podgroup_schedule_attempts_total", + Help: "Number of attempts to schedule pod group, by the result. 'unschedulable' means a pod group could not be scheduled, while 'error' means an internal scheduler problem.", + StabilityLevel: metrics.ALPHA, + }, []string{"result", "profile"}) + podGroupSchedulingLatency = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Subsystem: SchedulerSubsystem, + Name: "podgroup_scheduling_attempt_duration_seconds", + Help: "Pod group scheduling attempt latency in seconds (scheduling algorithm + binding)", + Buckets: metrics.ExponentialBuckets(0.001, 2, 15), // TBD: Correct buckets + StabilityLevel: metrics.ALPHA, + }, []string{"result", "profile"}) + PodGroupSchedulingAlgorithmLatency = metrics.NewHistogram( + &metrics.HistogramOpts{ + Subsystem: SchedulerSubsystem, + Name: "podgroup_scheduling_algorithm_duration_seconds", + Help: "Pod group scheduling algorithm latency in seconds", + Buckets: metrics.ExponentialBuckets(0.001, 2, 15), // TBD: Correct buckets + StabilityLevel: metrics.ALPHA, + }) + metricsList = []metrics.Registerable{ scheduleAttempts, schedulingLatency, @@ -463,6 +550,7 @@ func InitMetrics() { pendingPods, PodSchedulingSLIDuration, PodSchedulingAttempts, + PodScheduledAfterFlush, FrameworkExtensionPointDuration, PluginExecutionDuration, SchedulerQueueIncomingPods, diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go index d8e36e9df0..16db37c9e6 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go @@ -19,9 +19,10 @@ package metrics // This file contains helpers for metrics that are associated to a profile. var ( - ScheduledResult = "scheduled" - UnschedulableResult = "unschedulable" - ErrorResult = "error" + ScheduledResult = "scheduled" + UnschedulableResult = "unschedulable" + WaitingOnPreemptionResult = "waiting_on_preemption" + ErrorResult = "error" ) // PodScheduled can records a successful scheduling attempt and the duration @@ -46,3 +47,32 @@ func observeScheduleAttemptAndLatency(result, profile string, duration float64) schedulingLatency.WithLabelValues(result, profile).Observe(duration) scheduleAttempts.WithLabelValues(result, profile).Inc() } + +// PodGroupScheduled can records a successful pod group scheduling attempt and the duration +// since `start`. +func PodGroupScheduled(profile string, duration float64) { + observePodGroupScheduleAttemptAndLatency(ScheduledResult, profile, duration) +} + +// PodGroupUnschedulable can records a pod group scheduling attempt for an unschedulable pod group +// and the duration since `start`. +func PodGroupUnschedulable(profile string, duration float64) { + observePodGroupScheduleAttemptAndLatency(UnschedulableResult, profile, duration) +} + +// PodGroupWaitingOnPreemption can records a pod group scheduling attempt for an unschedulable pod group +// waiting on preemption, and the duration since `start`. +func PodGroupWaitingOnPreemption(profile string, duration float64) { + observePodGroupScheduleAttemptAndLatency(WaitingOnPreemptionResult, profile, duration) +} + +// PodGroupScheduleError records a pod group scheduling attempt that had an error, and the +// duration since `start`. +func PodGroupScheduleError(profile string, duration float64) { + observePodGroupScheduleAttemptAndLatency(ErrorResult, profile, duration) +} + +func observePodGroupScheduleAttemptAndLatency(result, profile string, duration float64) { + podGroupSchedulingLatency.WithLabelValues(result, profile).Observe(duration) + podGroupScheduleAttempts.WithLabelValues(result, profile).Inc() +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go b/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go index 3ac39035ee..3fc38492bc 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go @@ -32,7 +32,7 @@ import ( ) // RecorderFactory builds an EventRecorder for a given scheduler name. -type RecorderFactory func(string) events.EventRecorder +type RecorderFactory func(string) events.EventRecorderLogger // newProfile builds a Profile for the given configuration. func newProfile(ctx context.Context, cfg config.KubeSchedulerProfile, r frameworkruntime.Registry, recorderFact RecorderFactory, @@ -84,7 +84,7 @@ func (m Map) Close() error { // NewRecorderFactory returns a RecorderFactory for the broadcaster. func NewRecorderFactory(b events.EventBroadcaster) RecorderFactory { - return func(name string) events.EventRecorder { + return func(name string) events.EventRecorderLogger { return b.NewRecorder(scheme.Scheme, name) } } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go b/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go index 683bfaed69..164eb41f3d 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go @@ -41,6 +41,7 @@ import ( "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources" "k8s.io/kubernetes/pkg/scheduler/metrics" "k8s.io/kubernetes/pkg/scheduler/util" utiltrace "k8s.io/utils/trace" @@ -61,19 +62,42 @@ const ( minFeasibleNodesPercentageToFind = 5 ) -// ScheduleOne does the entire scheduling workflow for a single pod. It is serialized on the scheduling algorithm's host fitting. +// ScheduleOne does the entire scheduling workflow for a single scheduling entity (either a pod or a pod group). +// It is serialized on the scheduling algorithm's host fitting. func (sched *Scheduler) ScheduleOne(ctx context.Context) { logger := klog.FromContext(ctx) podInfo, err := sched.NextPod(logger) if err != nil { - utilruntime.HandleErrorWithContext(ctx, err, "Error while retrieving next pod from scheduling queue") + utilruntime.HandleErrorWithLogger(logger, err, "Error while retrieving next pod from scheduling queue") return } // pod could be nil when schedulerQueue is closed if podInfo == nil || podInfo.Pod == nil { return } + if sched.genericWorkloadEnabled && podInfo.Pod.Spec.SchedulingGroup != nil { + podGroupInfo, err := sched.podGroupInfoForPod(ctx, podInfo) + if err != nil { + podFwk, err := sched.frameworkForPod(podInfo.Pod) + if err != nil { + // This shouldn't happen, because we only accept for scheduling the pods + // which specify a scheduler name that matches one of the profiles. + klog.FromContext(ctx).Error(err, "Error occurred") + sched.SchedulingQueue.Done(podInfo.Pod.UID) + return + } + sched.FailureHandler(ctx, podFwk, podInfo, fwk.AsStatus(err), nil, time.Now()) + return + } + sched.scheduleOnePodGroup(ctx, podGroupInfo) + } else { + sched.scheduleOnePod(ctx, podInfo) + } +} +// scheduleOnePod does the entire scheduling workflow for a single pod. +func (sched *Scheduler) scheduleOnePod(ctx context.Context, podInfo *framework.QueuedPodInfo) { + logger := klog.FromContext(ctx) pod := podInfo.Pod // TODO(knelasevero): Remove duplicated keys from log entry calls // When contextualized logging hits GA @@ -120,19 +144,29 @@ func (sched *Scheduler) ScheduleOne(ctx context.Context) { } // bind the pod to its host asynchronously (we can do this b/c of the assumption step above). - go func() { - bindingCycleCtx, cancel := context.WithCancel(ctx) - defer cancel() + go sched.runBindingCycle(ctx, state, fwk, scheduleResult, assumedPodInfo, start, podsToActivate) +} - metrics.Goroutines.WithLabelValues(metrics.Binding).Inc() - defer metrics.Goroutines.WithLabelValues(metrics.Binding).Dec() +// runBindingCycle runs a binding cycle algorithm. +func (sched *Scheduler) runBindingCycle( + ctx context.Context, + state fwk.CycleState, + schedFramework framework.Framework, + scheduleResult ScheduleResult, + assumedPodInfo *framework.QueuedPodInfo, + start time.Time, + podsToActivate *framework.PodsToActivate) { + bindingCycleCtx, cancel := context.WithCancel(ctx) + defer cancel() - status := sched.bindingCycle(bindingCycleCtx, state, fwk, scheduleResult, assumedPodInfo, start, podsToActivate) - if !status.IsSuccess() { - sched.handleBindingCycleError(bindingCycleCtx, state, fwk, assumedPodInfo, start, scheduleResult, status) - return - } - }() + metrics.Goroutines.WithLabelValues(metrics.Binding).Inc() + defer metrics.Goroutines.WithLabelValues(metrics.Binding).Dec() + + status := sched.bindingCycle(bindingCycleCtx, state, schedFramework, scheduleResult, assumedPodInfo, start, podsToActivate) + if !status.IsSuccess() { + sched.handleBindingCycleError(bindingCycleCtx, state, schedFramework, assumedPodInfo, start, scheduleResult, status) + return + } } var clearNominatedNode = &fwk.NominatingInfo{NominatingMode: fwk.ModeOverride, NominatedNodeName: ""} @@ -146,22 +180,104 @@ func (sched *Scheduler) schedulingCycle( start time.Time, podsToActivate *framework.PodsToActivate, ) (ScheduleResult, *framework.QueuedPodInfo, *fwk.Status) { - logger := klog.FromContext(ctx) + if err := sched.Cache.UpdateSnapshot(klog.FromContext(ctx), sched.nodeInfoSnapshot); err != nil { + return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, fwk.AsStatus(err) + } + + scheduleResult, status := sched.schedulingAlgorithm(ctx, state, schedFramework, podInfo, start) + if !status.IsSuccess() { + return scheduleResult, podInfo, status + } + + assumedPodInfo, status := sched.prepareForBindingCycle(ctx, state, schedFramework, podInfo, podsToActivate, scheduleResult) + if !status.IsSuccess() { + return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, status + } + + return scheduleResult, assumedPodInfo, nil +} + +// prepareForBindingCycle applies the schedule result, generated by the scheduling algorithm, in memory, +// preparing for a binding cycle. +func (sched *Scheduler) prepareForBindingCycle( + ctx context.Context, + state fwk.CycleState, + schedFramework framework.Framework, + podInfo *framework.QueuedPodInfo, + podsToActivate *framework.PodsToActivate, + scheduleResult ScheduleResult, +) (*framework.QueuedPodInfo, *fwk.Status) { + assumedPodInfo, status := sched.assumeAndReserve(ctx, state, schedFramework, podInfo, scheduleResult) + if !status.IsSuccess() { + return assumedPodInfo, status + } + assumedPod := assumedPodInfo.Pod + + // Run "permit" plugins. + pluginsWaitTime, runPermitStatus := schedFramework.RunPermitPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) + if runPermitStatus.IsWait() { + schedFramework.AddWaitingPod(assumedPod, pluginsWaitTime) + } else if !runPermitStatus.IsSuccess() { + // trigger un-reserve plugins to clean up state associated with the reserved Pod + err := sched.unreserveAndForget(ctx, state, schedFramework, assumedPodInfo, scheduleResult.SuggestedHost) + if err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "ForgetPod failed") + } + + if runPermitStatus.IsRejected() { + fitErr := &framework.FitError{ + NumAllNodes: 1, + Pod: podInfo.Pod, + Diagnosis: framework.Diagnosis{ + NodeToStatus: framework.NewDefaultNodeToStatus(), + }, + } + fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, runPermitStatus) + fitErr.Diagnosis.AddPluginStatus(runPermitStatus) + return assumedPodInfo, fwk.NewStatus(runPermitStatus.Code()).WithError(fitErr) + } + + return assumedPodInfo, runPermitStatus + } + + // At the end of a successful scheduling cycle, pop and move up Pods if needed. + if len(podsToActivate.Map) != 0 { + logger := klog.FromContext(ctx) + sched.SchedulingQueue.Activate(logger, podsToActivate.Map) + // Clear the entries after activation. + podsToActivate.Map = make(map[string]*v1.Pod) + } + + return assumedPodInfo, nil +} + +// schedulingAlgorithm runs fitering and scoring phases for a single pod, +// together with post filter when the pod is unschedulable. +func (sched *Scheduler) schedulingAlgorithm( + ctx context.Context, + state fwk.CycleState, + schedFramework framework.Framework, + podInfo *framework.QueuedPodInfo, + start time.Time, +) (ScheduleResult, *fwk.Status) { + defer func() { + metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) + }() + pod := podInfo.Pod - scheduleResult, err := sched.SchedulePod(ctx, schedFramework, state, pod) + + logger := klog.FromContext(ctx) + scheduleResult, err := sched.SchedulePod(ctx, schedFramework, state, podInfo) if err != nil { - defer func() { - metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) - }() if err == ErrNoNodesAvailable { status := fwk.NewStatus(fwk.UnschedulableAndUnresolvable).WithError(err) - return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, status + return ScheduleResult{nominatingInfo: clearNominatedNode}, status } fitError, ok := err.(*framework.FitError) if !ok { logger.Error(err, "Error selecting node for pod", "pod", klog.KObj(pod)) - return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, fwk.AsStatus(err) + return ScheduleResult{nominatingInfo: clearNominatedNode}, fwk.AsStatus(err) } // SchedulePod() may have failed because the pod would not fit on any host, so we try to @@ -171,7 +287,7 @@ func (sched *Scheduler) schedulingCycle( if !schedFramework.HasPostFilterPlugins() { logger.V(3).Info("No PostFilter plugins are registered, so no preemption will be performed") - return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, fwk.NewStatus(fwk.Unschedulable).WithError(err) + return ScheduleResult{nominatingInfo: clearNominatedNode}, fwk.NewStatus(fwk.Unschedulable).WithError(err) } // Run PostFilter plugins to attempt to make the pod schedulable in a future scheduling cycle. @@ -188,81 +304,93 @@ func (sched *Scheduler) schedulingCycle( if result != nil { nominatingInfo = result.NominatingInfo } - return ScheduleResult{nominatingInfo: nominatingInfo}, podInfo, fwk.NewStatus(fwk.Unschedulable).WithError(err) + return ScheduleResult{nominatingInfo: nominatingInfo}, fwk.NewStatus(fwk.Unschedulable).WithError(err) } + return scheduleResult, nil +} - metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) +// assumeAndReserve assumes and reserves the pod in scheduler's memory. +func (sched *Scheduler) assumeAndReserve( + ctx context.Context, + state fwk.CycleState, + schedFramework framework.Framework, + podInfo *framework.QueuedPodInfo, + scheduleResult ScheduleResult, +) (*framework.QueuedPodInfo, *fwk.Status) { + logger := klog.FromContext(ctx) // Tell the cache to assume that a pod now is running on a given node, even though it hasn't been bound yet. // This allows us to keep scheduling without waiting on binding to occur. assumedPodInfo := podInfo.DeepCopy() assumedPod := assumedPodInfo.Pod // assume modifies `assumedPod` by setting NodeName=scheduleResult.SuggestedHost - err = sched.assume(logger, assumedPod, scheduleResult.SuggestedHost) + err := sched.assume(logger, state, assumedPodInfo, scheduleResult.SuggestedHost) if err != nil { // This is most probably result of a BUG in retrying logic. // We report an error here so that pod scheduling can be retried. // This relies on the fact that Error will check if the pod has been bound // to a node and if so will not add it back to the unscheduled pods queue // (otherwise this would cause an infinite loop). - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, fwk.AsStatus(err) + return assumedPodInfo, fwk.AsStatus(err) } // Run the Reserve method of reserve plugins. if sts := schedFramework.RunReservePluginsReserve(ctx, state, assumedPod, scheduleResult.SuggestedHost); !sts.IsSuccess() { // trigger un-reserve to clean up state associated with the reserved Pod - schedFramework.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - utilruntime.HandleErrorWithContext(ctx, forgetErr, "Scheduler cache ForgetPod failed") + err := sched.unreserveAndForget(ctx, state, schedFramework, assumedPodInfo, scheduleResult.SuggestedHost) + if err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "ForgetPod failed") } if sts.IsRejected() { fitErr := &framework.FitError{ NumAllNodes: 1, - Pod: pod, + Pod: podInfo.Pod, Diagnosis: framework.Diagnosis{ NodeToStatus: framework.NewDefaultNodeToStatus(), }, } fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, sts) fitErr.Diagnosis.AddPluginStatus(sts) - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, fwk.NewStatus(sts.Code()).WithError(fitErr) + return assumedPodInfo, fwk.NewStatus(sts.Code()).WithError(fitErr) } - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, sts + return assumedPodInfo, sts } + return assumedPodInfo, nil +} - // Run "permit" plugins. - runPermitStatus := schedFramework.RunPermitPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if !runPermitStatus.IsWait() && !runPermitStatus.IsSuccess() { - // trigger un-reserve to clean up state associated with the reserved Pod - schedFramework.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - utilruntime.HandleErrorWithContext(ctx, forgetErr, "Scheduler cache ForgetPod failed") - } +// unreserveAndForget unreserves and forgets the pod from scheduler's memory. +// This function shouldn't be called during binding cycle with a state, where IsPodGroupSchedulingCycle is set to true, +// but this shouldn't happen, because such pods with such state cannot reach binding. +func (sched *Scheduler) unreserveAndForget( + ctx context.Context, + state fwk.CycleState, + schedFramework framework.Framework, + assumedPodInfo *framework.QueuedPodInfo, + nodeName string, +) error { + logger := klog.FromContext(ctx) - if runPermitStatus.IsRejected() { - fitErr := &framework.FitError{ - NumAllNodes: 1, - Pod: pod, - Diagnosis: framework.Diagnosis{ - NodeToStatus: framework.NewDefaultNodeToStatus(), - }, + schedFramework.RunReservePluginsUnreserve(ctx, state, assumedPodInfo.Pod, nodeName) + if state.IsPodGroupSchedulingCycle() { + err := sched.nodeInfoSnapshot.ForgetPod(logger, assumedPodInfo.Pod) + if err != nil { + return err + } + if assumedPodInfo.Pod.Status.NominatedNodeName != "" { + // Assume method removed the nomination, but since we are reverting that stage for pod groups, + // we need to revert that operation as well. + if sched.SchedulingQueue != nil { + nominatingInfo := &fwk.NominatingInfo{ + NominatedNodeName: assumedPodInfo.Pod.Status.NominatedNodeName, + NominatingMode: fwk.ModeOverride, + } + // AssumedPodInfo can be used here, because the whole pod object is not stored in the nominator. + sched.SchedulingQueue.AddNominatedPod(logger, assumedPodInfo.PodInfo, nominatingInfo) } - fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, runPermitStatus) - fitErr.Diagnosis.AddPluginStatus(runPermitStatus) - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, fwk.NewStatus(runPermitStatus.Code()).WithError(fitErr) } - - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, runPermitStatus - } - - // At the end of a successful scheduling cycle, pop and move up Pods if needed. - if len(podsToActivate.Map) != 0 { - sched.SchedulingQueue.Activate(logger, podsToActivate.Map) - // Clear the entries after activation. - podsToActivate.Map = make(map[string]*v1.Pod) + return nil } - - return scheduleResult, assumedPodInfo, nil + return sched.Cache.ForgetPod(logger, assumedPodInfo.Pod) } // bindingCycle tries to bind an assumed Pod. @@ -278,8 +406,9 @@ func (sched *Scheduler) bindingCycle( assumedPod := assumedPodInfo.Pod + var preFlightStatus *fwk.Status if sched.nominatedNodeNameForExpectationEnabled { - preFlightStatus := schedFramework.RunPreBindPreFlights(ctx, state, assumedPod, scheduleResult.SuggestedHost) + preFlightStatus = schedFramework.RunPreBindPreFlights(ctx, state, assumedPod, scheduleResult.SuggestedHost) if preFlightStatus.Code() == fwk.Error || // Unschedulable status is not supported in PreBindPreFlight and hence we regard it as an error. preFlightStatus.IsRejected() { @@ -323,11 +452,26 @@ func (sched *Scheduler) bindingCycle( // we can free the cluster events stored in the scheduling queue sooner, which is worth for busy clusters memory consumption wise. sched.SchedulingQueue.Done(assumedPod.UID) + // If we are going to run prebind plugins we put the pod in binding map to optimize preemption. + if preFlightStatus.IsSuccess() { + var podInPreBindCancel context.CancelCauseFunc + ctx, podInPreBindCancel = context.WithCancelCause(ctx) + defer podInPreBindCancel(nil) + defer schedFramework.RemovePodInPreBind(assumedPod.UID) + schedFramework.AddPodInPreBind(assumedPod.UID, podInPreBindCancel) + } // Run "prebind" plugins. if status := schedFramework.RunPreBindPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost); !status.IsSuccess() { return status } + // Verify that pod was not preempted during prebinding. + bindingPod := schedFramework.GetPodInPreBind(assumedPod.UID) + if bindingPod != nil && !bindingPod.MarkPrebound() { + err := context.Cause(ctx) + return fwk.AsStatus(err) + } + // Run "bind" plugins. if status := sched.bind(ctx, schedFramework, assumedPod, scheduleResult.SuggestedHost, state); !status.IsSuccess() { return status @@ -340,6 +484,11 @@ func (sched *Scheduler) bindingCycle( if assumedPodInfo.InitialAttemptTimestamp != nil { metrics.PodSchedulingSLIDuration.WithLabelValues(getAttemptsLabel(assumedPodInfo)).Observe(metrics.SinceInSeconds(*assumedPodInfo.InitialAttemptTimestamp)) } + // Count pods scheduled after being flushed from unschedulablePods + if assumedPodInfo.WasFlushedFromUnschedulable { + logger.V(4).Info("Pod scheduled after flush from unschedulablePods", "pod", klog.KObj(assumedPodInfo.Pod), "unschedulablePlugins", assumedPodInfo.UnschedulablePlugins, "pendingPlugins", assumedPodInfo.PendingPlugins) + metrics.PodScheduledAfterFlush.Inc() + } // Run "postbind" plugins. schedFramework.RunPostBindPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) @@ -365,9 +514,8 @@ func (sched *Scheduler) handleBindingCycleError( assumedPod := podInfo.Pod // trigger un-reserve plugins to clean up state associated with the reserved Pod - fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - utilruntime.HandleErrorWithContext(ctx, forgetErr, "scheduler cache ForgetPod failed") + if forgetErr := sched.unreserveAndForget(ctx, state, fwk, podInfo, scheduleResult.SuggestedHost); forgetErr != nil { + utilruntime.HandleErrorWithContext(ctx, forgetErr, "ForgetPod failed") } else { // "Forget"ing an assumed Pod in binding cycle should be treated as a PodDelete event, // as the assumed Pod had occupied a certain amount of resources in scheduler cache. @@ -399,8 +547,9 @@ func (sched *Scheduler) frameworkForPod(pod *v1.Pod) (framework.Framework, error func (sched *Scheduler) skipPodSchedule(ctx context.Context, fwk framework.Framework, pod *v1.Pod) bool { // Case 1: pod is being deleted. if pod.DeletionTimestamp != nil { - fwk.EventRecorder().Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", "skip schedule deleting pod: %v/%v", pod.Namespace, pod.Name) - klog.FromContext(ctx).V(3).Info("Skip schedule deleting pod", "pod", klog.KObj(pod)) + logger := klog.FromContext(ctx) + fwk.EventRecorder().WithLogger(logger).Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", "skip schedule deleting pod: %v/%v", pod.Namespace, pod.Name) + logger.V(3).Info("Skip schedule deleting pod", "pod", klog.KObj(pod)) return true } @@ -418,19 +567,16 @@ func (sched *Scheduler) skipPodSchedule(ctx context.Context, fwk framework.Frame // schedulePod tries to schedule the given pod to one of the nodes in the node list. // If it succeeds, it will return the name of the node. // If it fails, it will return a FitError with reasons. -func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework, state fwk.CycleState, pod *v1.Pod) (result ScheduleResult, err error) { +func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework, state fwk.CycleState, podInfo *framework.QueuedPodInfo) (result ScheduleResult, err error) { + pod := podInfo.Pod trace := utiltrace.New("Scheduling", utiltrace.Field{Key: "namespace", Value: pod.Namespace}, utiltrace.Field{Key: "name", Value: pod.Name}) defer trace.LogIfLong(100 * time.Millisecond) - if err := sched.Cache.UpdateSnapshot(klog.FromContext(ctx), sched.nodeInfoSnapshot); err != nil { - return result, err - } - trace.Step("Snapshotting scheduler cache and node infos done") - if sched.nodeInfoSnapshot.NumNodes() == 0 { + if sched.nodeInfoSnapshot.NumNodesInPlacement() == 0 { return result, ErrNoNodesAvailable } - feasibleNodes, diagnosis, nodeHint, signature, err := sched.findNodesThatFitPod(ctx, fwk, state, pod) + feasibleNodes, diagnosis, nodeHint, err := sched.findNodesThatFitPod(ctx, fwk, state, podInfo) if err != nil { return result, err } @@ -439,7 +585,7 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework if len(feasibleNodes) == 0 { return result, &framework.FitError{ Pod: pod, - NumAllNodes: sched.nodeInfoSnapshot.NumNodes(), + NumAllNodes: sched.nodeInfoSnapshot.NumNodesInPlacement(), Diagnosis: diagnosis, } } @@ -448,7 +594,7 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework if len(feasibleNodes) == 1 { node := feasibleNodes[0].Node().Name if utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) { - fwk.StoreScheduleResults(ctx, signature, nodeHint, node, nil, sched.CurrentCycle()) + fwk.StoreScheduleResults(ctx, podInfo.PodSignature, nodeHint, node, nil, sched.CurrentCycle()) } return ScheduleResult{ SuggestedHost: node, @@ -467,7 +613,7 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework trace.Step("Prioritizing done") if utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) { - fwk.StoreScheduleResults(ctx, signature, nodeHint, node, sortedPrioritizedNodes, sched.CurrentCycle()) + fwk.StoreScheduleResults(ctx, podInfo.PodSignature, nodeHint, node, sortedPrioritizedNodes, sched.CurrentCycle()) } return ScheduleResult{ @@ -479,22 +625,22 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework // Filters the nodes to find the ones that fit the pod based on the framework // filter plugins and filter extenders. -func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework framework.Framework, state fwk.CycleState, pod *v1.Pod) ([]fwk.NodeInfo, framework.Diagnosis, string, fwk.PodSignature, error) { +func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework framework.Framework, state fwk.CycleState, podInfo *framework.QueuedPodInfo) ([]fwk.NodeInfo, framework.Diagnosis, string, error) { logger := klog.FromContext(ctx) diagnosis := framework.Diagnosis{ NodeToStatus: framework.NewDefaultNodeToStatus(), } - - allNodes, err := sched.nodeInfoSnapshot.NodeInfos().List() + allNodes, err := sched.nodeInfoSnapshot.ListNodesInPlacement() if err != nil { - return nil, diagnosis, "", nil, err + return nil, diagnosis, "", err } // Run "prefilter" plugins. + pod := podInfo.Pod preRes, s, unscheduledPlugins := schedFramework.RunPreFilterPlugins(ctx, state, pod) diagnosis.UnschedulablePlugins = unscheduledPlugins if !s.IsSuccess() { if !s.IsRejected() { - return nil, diagnosis, "", nil, s.AsError() + return nil, diagnosis, "", s.AsError() } // All nodes in NodeToStatus will have the same status so that they can be handled in the preemption. diagnosis.NodeToStatus.SetAbsentNodesStatus(s) @@ -504,15 +650,14 @@ func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework diagnosis.PreFilterMsg = msg logger.V(5).Info("Status after running PreFilter plugins for pod", "pod", klog.KObj(pod), "status", msg) diagnosis.AddPluginStatus(s) - return nil, diagnosis, "", nil, nil + return nil, diagnosis, "", nil } var nodeHint string - var signature fwk.PodSignature if utilfeature.DefaultFeatureGate.Enabled(features.OpportunisticBatching) { // We get the node hint even if we have a nominated name for simplicity, but we could potentially avoid it // in this scenario in the future. - nodeHint, signature = schedFramework.GetNodeHint(ctx, pod, state, sched.CurrentCycle()) + nodeHint = schedFramework.GetNodeHint(ctx, pod, podInfo.PodSignature, state, sched.CurrentCycle()) } // "NominatedNodeName" can potentially be set in a previous scheduling cycle as a result of preemption. @@ -525,7 +670,7 @@ func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework } // Nominated node passes all the filters, scheduler is good to assign this node to the pod. if len(feasibleNodes) != 0 { - return feasibleNodes, diagnosis, nodeHint, signature, nil + return feasibleNodes, diagnosis, nodeHint, nil } } @@ -534,8 +679,8 @@ func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework nodes = make([]fwk.NodeInfo, 0, len(preRes.NodeNames)) for nodeName := range preRes.NodeNames { // PreRes may return nodeName(s) which do not exist; we verify - // node exists in the Snapshot. - if nodeInfo, err := sched.nodeInfoSnapshot.Get(nodeName); err == nil { + // node exists in the Snapshot within the selected placement. + if nodeInfo, err := sched.nodeInfoSnapshot.GetNodeInPlacement(nodeName); err == nil { nodes = append(nodes, nodeInfo) } } @@ -547,12 +692,12 @@ func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework processedNodes := len(feasibleNodes) + diagnosis.NodeToStatus.Len() sched.nextStartNodeIndex = (sched.nextStartNodeIndex + processedNodes) % len(allNodes) if err != nil { - return nil, diagnosis, nodeHint, signature, err + return nil, diagnosis, nodeHint, err } feasibleNodesAfterExtender, err := findNodesThatPassExtenders(ctx, sched.Extenders, pod, feasibleNodes, diagnosis.NodeToStatus) if err != nil { - return nil, diagnosis, nodeHint, signature, err + return nil, diagnosis, nodeHint, err } if len(feasibleNodesAfterExtender) != len(feasibleNodes) { // Extenders filtered out some nodes. @@ -569,7 +714,7 @@ func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, schedFramework diagnosis.UnschedulablePlugins.Insert(framework.ExtenderName) } - return feasibleNodesAfterExtender, diagnosis, nodeHint, signature, nil + return feasibleNodesAfterExtender, diagnosis, nodeHint, nil } func (sched *Scheduler) evaluateNominatedNode(ctx context.Context, pod *v1.Pod, schedFramework framework.Framework, state fwk.CycleState, nodeHint string, diagnosis framework.Diagnosis) ([]fwk.NodeInfo, error) { @@ -580,9 +725,16 @@ func (sched *Scheduler) evaluateNominatedNode(ctx context.Context, pod *v1.Pod, nnn = nodeHint } - nodeInfo, err := sched.nodeInfoSnapshot.Get(nnn) + nodeInfo, err := sched.nodeInfoSnapshot.GetNodeInPlacement(nnn) if err != nil { - return nil, err + if _, err := sched.nodeInfoSnapshot.Get(nnn); err != nil { + return nil, err + } + // It's not an error if NNN is in the cluster but not in the placement. + // This can happen during the pod group placement scheduling cycle, where we simulate multiple potential placements. + logger := klog.FromContext(ctx) + logger.V(4).Info("Pod's nominated node is present in the cluster but not available in the current placement", "pod", klog.KObj(pod), "node", pod.Status.NominatedNodeName) + return nil, nil } node := []fwk.NodeInfo{nodeInfo} feasibleNodes, err := sched.findNodesThatPassFilters(ctx, schedFramework, state, pod, &diagnosis, node) @@ -646,7 +798,7 @@ func (sched *Scheduler) findNodesThatPassFilters( return feasibleNodes, nil } - errCh := parallelize.NewErrorChannel() + errCh := parallelize.NewResultChannel[error]() var feasibleNodesLen int32 ctx, cancel := context.WithCancelCause(ctx) defer cancel(errors.New("findNodesThatPassFilters has completed")) @@ -662,7 +814,7 @@ func (sched *Scheduler) findNodesThatPassFilters( nodeInfo := nodes[(sched.nextStartNodeIndex+i)%numAllNodes] status := schedFramework.RunFilterPluginsWithNominatedPods(ctx, state, pod, nodeInfo) if status.Code() == fwk.Error { - errCh.SendErrorWithCancel(status.AsError(), func() { + errCh.SendWithCancel(status.AsError(), func() { cancel(errors.New("some other Filter operation failed")) }) return @@ -700,7 +852,7 @@ func (sched *Scheduler) findNodesThatPassFilters( diagnosis.NodeToStatus.Set(item.node, item.status) diagnosis.AddPluginStatus(item.status) } - if err := errCh.ReceiveError(); err != nil { + if err := errCh.Receive(); err != nil { statusCode = fwk.Error return feasibleNodes, err } @@ -952,21 +1104,39 @@ func (h *nodeScoreHeap) Pop() interface{} { } // assume signals to the cache that a pod is already in the cache, so that binding can be asynchronous. -// assume modifies `assumed`. -func (sched *Scheduler) assume(logger klog.Logger, assumed *v1.Pod, host string) error { +// When called during pod group scheduling cycle, pod is assumed in the snapshot instead. +func (sched *Scheduler) assume(logger klog.Logger, state fwk.CycleState, assumedPodInfo *framework.QueuedPodInfo, host string) error { // Optimistically assume that the binding will succeed and send it to apiserver // in the background. // If the binding fails, scheduler will release resources allocated to assumed pod // immediately. - assumed.Spec.NodeName = host - - if err := sched.Cache.AssumePod(logger, assumed); err != nil { - logger.Error(err, "Scheduler cache AssumePod failed") - return err + assumedPodInfo.Pod.Spec.NodeName = host + if utilfeature.DefaultFeatureGate.Enabled(features.DRANodeAllocatableResources) { + // If DRANodeAllocatableResources is enabled, copy the calculated node allocatable resource claim status + // from the cycle state to the assumed pod's status. This ensures that the scheduler's + // cached version of the pod reflects the node allocatable resources allocated by the DRA plugin + // for this scheduling cycle, making this information available for NodeInfo cache update. + // Any potential NodeAllocatableResourceClaimStatuses from a previously failed scheduling attempt is overwritten. + // This field is not explicitly cleared as the Pod object is reconstructed in handleSchedulingFailure() + // before re-queueing. + assumedPodInfo.Pod.Status.NodeAllocatableResourceClaimStatuses = dynamicresources.ExtractPodNodeAllocatableResourceClaimStatus(logger, state, host) + } + + if state.IsPodGroupSchedulingCycle() { + err := sched.nodeInfoSnapshot.AssumePod(assumedPodInfo.PodInfo) + if err != nil { + logger.Error(err, "Scheduler snapshot AssumePod failed") + return err + } + } else { + if err := sched.Cache.AssumePod(logger, assumedPodInfo.Pod); err != nil { + logger.Error(err, "Scheduler cache AssumePod failed") + return err + } } // if "assumed" is a nominated pod, we should remove it from internal cache if sched.SchedulingQueue != nil { - sched.SchedulingQueue.DeleteNominatedPodIfExists(assumed) + sched.SchedulingQueue.DeleteNominatedPodIfExists(assumedPodInfo.Pod) } return nil @@ -1008,15 +1178,12 @@ func (sched *Scheduler) extendersBinding(logger klog.Logger, pod *v1.Pod, node s } func (sched *Scheduler) finishBinding(logger klog.Logger, fwk framework.Framework, assumed *v1.Pod, targetNode string, status *fwk.Status) { - if finErr := sched.Cache.FinishBinding(logger, assumed); finErr != nil { - utilruntime.HandleErrorWithLogger(logger, finErr, "Scheduler cache FinishBinding failed") - } if !status.IsSuccess() { logger.V(1).Info("Failed to bind pod", "pod", klog.KObj(assumed)) return } - fwk.EventRecorder().Eventf(assumed, nil, v1.EventTypeNormal, "Scheduled", "Binding", "Successfully assigned %v/%v to %v", assumed.Namespace, assumed.Name, targetNode) + fwk.EventRecorder().WithLogger(logger).Eventf(assumed, nil, v1.EventTypeNormal, "Scheduled", "Binding", "Successfully assigned %v/%v to %v", assumed.Namespace, assumed.Name, targetNode) } func getAttemptsLabel(p *framework.QueuedPodInfo) string { @@ -1030,7 +1197,7 @@ func getAttemptsLabel(p *framework.QueuedPodInfo) string { // handleSchedulingFailure records an event for the pod that indicates the // pod has failed to schedule. Also, update the pod condition and nominated node name if set. -func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk framework.Framework, podInfo *framework.QueuedPodInfo, status *fwk.Status, nominatingInfo *fwk.NominatingInfo, start time.Time) { +func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, podFwk framework.Framework, podInfo *framework.QueuedPodInfo, status *fwk.Status, nominatingInfo *fwk.NominatingInfo, start time.Time) { calledDone := false defer func() { if !calledDone { @@ -1049,27 +1216,35 @@ func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk framewo switch reason { case v1.PodReasonUnschedulable: - metrics.PodUnschedulable(fwk.ProfileName(), metrics.SinceInSeconds(start)) + metrics.PodUnschedulable(podFwk.ProfileName(), metrics.SinceInSeconds(start)) case v1.PodReasonSchedulerError: - metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) + metrics.PodScheduleError(podFwk.ProfileName(), metrics.SinceInSeconds(start)) } pod := podInfo.Pod err := status.AsError() errMsg := status.Message() + // Clear plugin-related fields to avoid stale data from previous scheduling attempts. + // These fields will be repopulated below for FitError cases. + // We clear them here (rather than at Pop) because we sometimes want to use them + // for logging when a pod schedules successfully (e.g., after being flushed). + podInfo.ClearRejectorPlugins() + if err == ErrNoNodesAvailable { logger.V(2).Info("Unable to schedule pod; no nodes are registered to the cluster; waiting", "pod", klog.KObj(pod)) } else if fitError, ok := err.(*framework.FitError); ok { // Inject UnschedulablePlugins to PodInfo, which will be used later for moving Pods between queues efficiently. podInfo.UnschedulablePlugins = fitError.Diagnosis.UnschedulablePlugins podInfo.PendingPlugins = fitError.Diagnosis.PendingPlugins logger.V(2).Info("Unable to schedule pod; no fit; waiting", "pod", klog.KObj(pod), "err", errMsg) + } else if errors.Is(err, errPodGroupUnschedulable) { + logger.V(2).Info("Unable to schedule pod belonging to a pod group; waiting", "pod", klog.KObj(pod), "err", errMsg) } else { utilruntime.HandleErrorWithContext(ctx, err, "Error scheduling pod; retrying", "pod", klog.KObj(pod)) } // Check if the Pod exists in informer cache. - podLister := fwk.SharedInformerFactory().Core().V1().Pods().Lister() + podLister := podFwk.SharedInformerFactory().Core().V1().Pods().Lister() cachedPod, e := podLister.Pods(pod.Namespace).Get(pod.Name) if e != nil { logger.Info("Pod doesn't exist in informer cache", "pod", klog.KObj(pod), "err", e) @@ -1081,10 +1256,15 @@ func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk framewo logger.Info("Pod has been assigned to node. Abort adding it back to queue.", "pod", klog.KObj(pod), "node", cachedPod.Spec.NodeName) // We need to call DonePod here because we don't call AddUnschedulableIfNotPresent in this case. } else { + if cachedPod.UID != podInfo.Pod.UID { + logger.V(2).Info("Pod was recreated while handling scheduling failure. Skip requeueing and status updates.", "pod", klog.KObj(pod), "oldUID", podInfo.Pod.UID, "newUID", cachedPod.UID) + return + } // As is from SharedInformer, we need to do a DeepCopy() here. // ignore this err since apiserver doesn't properly validate affinity terms // and we can't fix the validation for backwards compatibility. podInfo.PodInfo, _ = framework.NewPodInfo(cachedPod.DeepCopy()) + pod = podInfo.Pod if err := sched.SchedulingQueue.AddUnschedulableIfNotPresent(logger, podInfo, sched.SchedulingQueue.SchedulingCycle()); err != nil { utilruntime.HandleErrorWithContext(ctx, err, "Error occurred") } @@ -1106,8 +1286,8 @@ func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk framewo } msg := truncateMessage(errMsg) - fwk.EventRecorder().Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", msg) - if err := updatePod(ctx, sched.client, fwk.APICacher(), pod, &v1.PodCondition{ + podFwk.EventRecorder().WithLogger(logger).Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", msg) + if err := updatePod(ctx, sched.client, podFwk.APICacher(), pod, &v1.PodCondition{ Type: v1.PodScheduled, ObservedGeneration: podutil.CalculatePodConditionObservedGeneration(&pod.Status, pod.Generation, v1.PodScheduled), Status: v1.ConditionFalse, diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one_podgroup.go b/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one_podgroup.go new file mode 100644 index 0000000000..0954d06736 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one_podgroup.go @@ -0,0 +1,779 @@ +/* +Copyright 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 scheduler + +import ( + "context" + "fmt" + "math/rand" + "sort" + "time" + + v1 "k8s.io/api/core/v1" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + utilfeature "k8s.io/apiserver/pkg/util/feature" + corev1helpers "k8s.io/component-helpers/scheduling/corev1" + "k8s.io/klog/v2" + fwk "k8s.io/kube-scheduler/framework" + schedulingapi "k8s.io/kubernetes/pkg/apis/scheduling" + "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/pkg/scheduler/framework" + "k8s.io/kubernetes/pkg/scheduler/metrics" + "k8s.io/kubernetes/pkg/scheduler/util" + "k8s.io/utils/ptr" +) + +// errPodGroupUnschedulable is used to describe that the pod group is unschedulable. +var errPodGroupUnschedulable = fmt.Errorf("pod group is unschedulable") + +// scheduleOnePodGroup does the entire workload-aware scheduling workflow for a single pod group. +func (sched *Scheduler) scheduleOnePodGroup(ctx context.Context, podGroupInfo *framework.QueuedPodGroupInfo) { + logger := klog.FromContext(ctx) + // TODO(knelasevero): Remove duplicated keys from log entry calls + // When contextualized logging hits GA + // https://github.com/kubernetes/kubernetes/issues/111672 + logger = klog.LoggerWithValues(logger, "podGroup", klog.KObj(podGroupInfo)) + ctx = klog.NewContext(ctx, logger) + + schedFwk, err := sched.frameworkForPodGroup(podGroupInfo) + if err != nil { + for _, podInfo := range podGroupInfo.QueuedPodInfos { + podFwk, podFwkErr := sched.frameworkForPod(podInfo.Pod) + if podFwkErr != nil { + // This shouldn't happen, because we only accept for scheduling the pods + // which specify a scheduler name that matches one of the profiles. + logger.Error(podFwkErr, "Error occurred") + sched.SchedulingQueue.Done(podInfo.Pod.UID) + return + } + sched.FailureHandler(ctx, podFwk, podInfo, fwk.AsStatus(err), clearNominatedNode, time.Now()) + } + return + } + sched.skipPodGroupPodSchedule(ctx, schedFwk, podGroupInfo) + // skipPodGroupPodSchedule could remove some pods from the pod group. + // Pod group constraints will be re-evaluated on a Permit phase. + // Now, verify if it has any pods left. + if len(podGroupInfo.QueuedPodInfos) == 0 { + return + } + + logger.V(3).Info("Attempting to schedule pod group", "podGroup", klog.KObj(podGroupInfo)) + + sched.podGroupCycle(ctx, schedFwk, framework.NewCycleState(), podGroupInfo) +} + +// frameworkForPodGroup obtains the concrete scheduler framework for the entire pod group. +func (sched *Scheduler) frameworkForPodGroup(podGroupInfo *framework.QueuedPodGroupInfo) (framework.Framework, error) { + schedulerName := "" + for _, pInfo := range podGroupInfo.QueuedPodInfos { + if schedulerName == "" { + schedulerName = pInfo.Pod.Spec.SchedulerName + } else if pInfo.Pod.Spec.SchedulerName != schedulerName { + return nil, fmt.Errorf("all pods in a single pod group should have the same .spec.schedulerName set, got: %q and %q", pInfo.Pod.Spec.SchedulerName, schedulerName) + } + } + fwk, ok := sched.Profiles[schedulerName] + if !ok { + return nil, fmt.Errorf("profile not found for scheduler name %q", schedulerName) + } + return fwk, nil +} + +// skipPodGroupPodSchedule skips the scheduling of particular pods from the group when they should no longer be considered. +// This can happen when the pod is already being deleted (i.e., when its deletionTimestamp is set) +// or when the pod has already been assumed. +func (sched *Scheduler) skipPodGroupPodSchedule(ctx context.Context, schedFwk framework.Framework, podGroupInfo *framework.QueuedPodGroupInfo) { + filteredQueuedPodInfos := make([]*framework.QueuedPodInfo, 0, len(podGroupInfo.QueuedPodInfos)) + for _, podInfo := range podGroupInfo.QueuedPodInfos { + if sched.skipPodSchedule(ctx, schedFwk, podInfo.Pod) { + // We don't put this Pod back to the queue, but we have to cleanup the in-flight pods/events. + sched.SchedulingQueue.Done(podInfo.Pod.UID) + continue + } + filteredQueuedPodInfos = append(filteredQueuedPodInfos, podInfo) + } + if len(filteredQueuedPodInfos) != len(podGroupInfo.QueuedPodInfos) { + podGroupInfo.QueuedPodInfos = filteredQueuedPodInfos + podGroupInfo.UnscheduledPods = make([]*v1.Pod, 0, len(podGroupInfo.QueuedPodInfos)) + for _, pInfo := range podGroupInfo.QueuedPodInfos { + podGroupInfo.UnscheduledPods = append(podGroupInfo.UnscheduledPods, pInfo.Pod) + } + } +} + +// podGroupInfoForPod is a temporary function that obtains the QueuedPodGroupInfo based on the pod that got popped from the scheduling queue. +// Ultimately, scheduling queue, adjusted with workload-awareness will return such QueuedPodGroupInfo directly. +func (sched *Scheduler) podGroupInfoForPod(ctx context.Context, pInfo *framework.QueuedPodInfo) (*framework.QueuedPodGroupInfo, error) { + logger := klog.FromContext(ctx) + + // Get the actual pod group state + podGroupState, err := sched.Cache.PodGroupStates().Get(pInfo.Pod.Namespace, *pInfo.Pod.Spec.SchedulingGroup.PodGroupName) + if err != nil { + return nil, fmt.Errorf("error while retrieving pod group state: %w", err) + } + unscheduledPods := podGroupState.UnscheduledPods() + + podGroupInfo := &framework.QueuedPodGroupInfo{ + PodGroupInfo: &framework.PodGroupInfo{ + Namespace: pInfo.Pod.Namespace, + Name: *pInfo.Pod.Spec.SchedulingGroup.PodGroupName, + }, + QueuedPodInfos: make([]*framework.QueuedPodInfo, 0, len(unscheduledPods)+1), + } + podGroupInfo.QueuedPodInfos = append(podGroupInfo.QueuedPodInfos, pInfo) + + // Pop all unscheduled pods from the scheduling queue + for _, pod := range unscheduledPods { + if pod.Name == pInfo.Pod.Name { + continue + } + unscheduledPodInfo := sched.SchedulingQueue.PopSpecificPod(logger, pod) + if unscheduledPodInfo == nil { + logger.V(5).Info("Pod available in pod group state not available in scheduling queue", "podGroup", klog.KObj(podGroupInfo), "pod", klog.KObj(pod)) + continue + } + podGroupInfo.QueuedPodInfos = append(podGroupInfo.QueuedPodInfos, unscheduledPodInfo) + } + // Sort the pods in deterministic order. First by priority, then by their InitialAttemptTimestamp. + sort.Slice(podGroupInfo.QueuedPodInfos, func(i, j int) bool { + pInfo1 := podGroupInfo.QueuedPodInfos[i] + pInfo2 := podGroupInfo.QueuedPodInfos[j] + p1 := corev1helpers.PodPriority(pInfo1.GetPodInfo().GetPod()) + p2 := corev1helpers.PodPriority(pInfo2.GetPodInfo().GetPod()) + // Timestamps should be set, but dereferencing them for safety. + p1Timestamp := ptr.Deref(pInfo1.InitialAttemptTimestamp, time.Time{}) + p2Timestamp := ptr.Deref(pInfo2.InitialAttemptTimestamp, time.Time{}) + return (p1 > p2) || (p1 == p2 && p1Timestamp.Before(p2Timestamp)) + }) + + // Populate UnscheduledPods based on the QueuedPodInfos. + podGroupInfo.UnscheduledPods = make([]*v1.Pod, 0, len(podGroupInfo.QueuedPodInfos)) + for _, pInfo := range podGroupInfo.QueuedPodInfos { + podGroupInfo.UnscheduledPods = append(podGroupInfo.UnscheduledPods, pInfo.Pod) + } + + return podGroupInfo, nil +} + +// podSchedulingContext holds the precomputed data needed to handle the pod scheduling. +// Each scheduling attempt in the same pod group scheduling cycle for the same pod +// should use a new podSchedulingContext. +type podSchedulingContext struct { + logger klog.Logger + state *framework.CycleState + podsToActivate *framework.PodsToActivate +} + +// initPodSchedulingContext initializes the scheduling context of a single pod for pod group scheduling cycle. +func initPodSchedulingContext(ctx context.Context, pod *v1.Pod, podGroupState *framework.CycleState, postFilterMode podGroupPostFilterMode) *podSchedulingContext { + logger := klog.FromContext(ctx) + // TODO(knelasevero): Remove duplicated keys from log entry calls + // When contextualized logging hits GA + // https://github.com/kubernetes/kubernetes/issues/111672 + logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) + + // Synchronously attempt to find a fit for the pod. + state := framework.NewCycleState() + // For the sake of performance, scheduler does not measure and export the scheduler_plugin_execution_duration metric + // for every plugin execution in each scheduling cycle. Instead it samples a portion of scheduling cycles - percentage + // determined by pluginMetricsSamplePercent. The line below helps to randomly pick appropriate scheduling cycles. + state.SetRecordPluginMetrics(rand.Intn(100) < pluginMetricsSamplePercent) + + // Initialize an empty podsToActivate struct, which will be filled up by plugins or stay empty. + podsToActivate := framework.NewPodsToActivate() + state.Write(framework.PodsToActivateKey, podsToActivate) + + // Marks this cycle as a pod group scheduling cycle. + state.SetPodGroupSchedulingCycle(podGroupState) + + // Skip post filters if requested. + switch postFilterMode { + case runWithoutPostFilters: + state.SetSkipAllPostFilterPlugins(true) + case runAllPostFilters: + // Default podCtx state will run all post filters. + } + + return &podSchedulingContext{ + logger: logger, + state: state, + podsToActivate: podsToActivate, + } +} + +// podGroupCycle runs a pod group scheduling cycle for the given pod group in a single cluster snapshot. +func (sched *Scheduler) podGroupCycle(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo) { + // Synchronously attempt to find a fit for the pod group. + start := time.Now() + + logger := klog.FromContext(ctx) + if err := sched.Cache.UpdateSnapshot(logger, sched.nodeInfoSnapshot); err != nil { + logger.Error(err, "Error updating snapshot", "podGroup", klog.KObj(podGroupInfo)) + result := podGroupAlgorithmResult{ + status: fwk.AsStatus(err), + } + sched.submitPodGroupAlgorithmResult(ctx, schedFwk, podGroupCycleState, podGroupInfo, result, start) + return + } + + result := sched.podGroupSchedulingAlgorithm(ctx, schedFwk, podGroupCycleState, podGroupInfo, runAllPostFilters) + metrics.PodGroupSchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) + + // Run workload aware preemption if required. If the preemption is successful, + // we need to put the pods from pod group back into the scheduling queue. + if sched.workloadAwarePreemptionEnabled && result.status.Code() == fwk.Unschedulable { + status := sched.runWorkloadAwarePreemption(ctx, schedFwk, podGroupCycleState, podGroupInfo) + if status.IsSuccess() { + result.waitingOnPreemption = true + } else if status.IsError() { + result.status = status + } else { + result.status.AppendReason(status.String()) + } + } + + sched.submitPodGroupAlgorithmResult(ctx, schedFwk, podGroupCycleState, podGroupInfo, result, start) +} + +// runWorkloadAwarePreemption runs workload-aware preemption for the given pod group. +// It saves the current snapshot of node infos, runs a PodGroupPostFilter +// which modifies the node infos to check feasibility of the +// pod group scheduling with some pods removed and reverts the snapshot to the +// original state. +// The function used for evaluating feasibility of pod group scheduling is +// scheduler.podGroupSchedulingAlgorithm run without any post filters. +func (sched *Scheduler) runWorkloadAwarePreemption(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo) *fwk.Status { + // Default preemption should be the only pod group post filter registered plugin. + plugins := schedFwk.PodGroupPostFilterPlugins() + if len(plugins) == 0 { + return fwk.NewStatus(fwk.Unschedulable, "default preemption plugin is not registered, workload aware preemption is disabled") + } + + pg, err := schedFwk.SharedInformerFactory().Scheduling().V1alpha2().PodGroups().Lister().PodGroups(podGroupInfo.Namespace).Get(podGroupInfo.Name) + if err != nil { + return fwk.AsStatus(fmt.Errorf("failed to get pod group object: %w", err)) + } + if pg.Spec.SchedulingConstraints != nil && len(pg.Spec.SchedulingConstraints.Topology) > 0 { + return fwk.NewStatus(fwk.Unschedulable, "workload aware preemption is not supported for pod groups with scheduling constraints") + } + + restoreFn, err := sched.nodeInfoSnapshot.BackupSnapshot() + if err != nil { + return fwk.AsStatus(fmt.Errorf("failed to backup snapshot: %w", err)) + } + defer restoreFn() + + return plugins[0].PodGroupPostFilter(ctx, pg, podGroupInfo.UnscheduledPods, func(ctx context.Context) *fwk.Status { + res := sched.podGroupSchedulingAlgorithm(ctx, schedFwk, podGroupCycleState, podGroupInfo, runWithoutPostFilters) + return res.status + }) +} + +// algorithmResult stores the scheduling result and status for a scheduling attempt of a single pod. +type algorithmResult struct { + // pod is the pod the result applies to. + pod *v1.Pod + // scheduleResult is a scheduling algorithm result. + scheduleResult ScheduleResult + // podCtx is a specific pod scheduling context used for the scheduling algorithm. + podCtx *podSchedulingContext + // schedulingDuration is a pod scheduling duration used for metrics recording. + schedulingDuration time.Duration + // requiresPreemption determines whether this pod requires a preemption to proceed or not. + requiresPreemption bool + // status is a scheduling algorithm status. + status *fwk.Status + // permitStatus is a status of the permit check. + // This is only set when the `status` is success or the `requiresPreemption` is true. + permitStatus *fwk.Status +} + +// podGroupPostFilterMode defines how the pod group algorithm should run post filters plugins. +type podGroupPostFilterMode int + +const ( + // The pod group algorithm should try to run all post filters in pod-by-pod cycle. + runAllPostFilters podGroupPostFilterMode = iota + // The pod group algorithm should not try post filter at all. This can be used + // by workload aware preemption that tries to check if after removing some + // pods the pod group can be scheduled. + runWithoutPostFilters +) + +func (ar *algorithmResult) GetPod() *v1.Pod { + return ar.pod +} + +func (ar *algorithmResult) GetNodeName() string { + return ar.scheduleResult.SuggestedHost +} + +// podGroupAlgorithmResult stores the scheduling pod scheduling results for a pod group +// and any information needed to act on these results. +type podGroupAlgorithmResult struct { + // podResults is the list of scheduling results for each pod in the group. + // Only in the case of a pod group-wide Unschedulable or Error status can it contain fewer pods. + podResults []algorithmResult + // status is the final status of the pod group algorithm. + // + // Success code indicates that the pod group is schedulable and does not require any preemption. + // Its feasible pods should be moved to the binding cycle. + // This should only be set when the pod group is feasible and `waitingOnPreemption` is false. + // + // Unschedulable code indicates that the pod group is unschedulable, + // and all its pods should be moved back to the scheduling queue as unschedulable. + // Result with `waitingOnPreemption` set to true should have the Unschedulable status. + // + // Error code means that pod group scheduling failed due to an unexpected error, + // and no pods will be scheduled this attempt. + status *fwk.Status + // waitingOnPreemption indicates whether this pod group requires or is waiting for preemption to complete. + // This can only be set to true when the status is Unschedulable. + waitingOnPreemption bool +} + +// podGroupSchedulingDefaultAlgorithm runs the default algorithm for scheduling a pod group. +// It tries to schedule each pod using standard filtering and scoring logic in a fixed order. +// If a pod requires preemption to be schedulable, subsequent pods in the algorithm +// treat that pod as already scheduled on that node with victims being already removed in memory. +func (sched *Scheduler) podGroupSchedulingDefaultAlgorithm(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo, postFilterMode podGroupPostFilterMode) podGroupAlgorithmResult { + result := podGroupAlgorithmResult{ + podResults: make([]algorithmResult, 0, len(podGroupInfo.QueuedPodInfos)), + status: fwk.NewStatus(fwk.Unschedulable).WithError(errPodGroupUnschedulable), + waitingOnPreemption: false, + } + + logger := klog.FromContext(ctx) + logger.V(5).Info("Running a pod group scheduling algorithm", "podGroup", klog.KObj(podGroupInfo), "unscheduledPodsCount", len(podGroupInfo.QueuedPodInfos)) + + requiresPreemption := false + for _, podInfo := range podGroupInfo.QueuedPodInfos { + podResult, revertFn := sched.podGroupPodSchedulingAlgorithm(ctx, schedFwk, podGroupCycleState, podGroupInfo, podInfo, postFilterMode) + result.podResults = append(result.podResults, podResult) + if !podResult.status.IsSuccess() && !podResult.requiresPreemption { + // When a pod is not feasible and doesn't require preemption, it means that it failed scheduling. + if podResult.status.IsRejected() { + // If the pod is rejected, the pod group can still be schedulable as long as the permit check can succeed. + continue + } + // When the algorithm returns error or unexpected status, stop evaluating the rest of the pods. + result.status = fwk.AsStatus(fmt.Errorf("failed to schedule other pod from a pod group: %w", podResult.status.AsError())) + // Clear the waiting on preemption flag that could have been set by previous pods. + result.waitingOnPreemption = false + break + } + // At this point, the pod has passed the scheduling algorithm with the Permit status being either Success or Wait. + // We unreserve the pod at the end of the whole algorithm (via defer) because it should be ultimately returned to the queue, + // without binding it yet. We only assumed the pod to check feasibility of subsequent pods in the group. + defer revertFn() + + requiresPreemption = requiresPreemption || podResult.requiresPreemption + if podResult.permitStatus.IsSuccess() { + // When the permit returns success for any pod, the pod group is schedulable. + if requiresPreemption { + // If any preemption is required, the whole pod group requires it to be feasible. + result.status = fwk.NewStatus(fwk.Unschedulable, "pod group is waiting for preemption to complete").WithError(errPodGroupUnschedulable) + // Set the waitingOnPreemption to true iff the pod group is feasible (Permit returned Success) and requires preemption. + result.waitingOnPreemption = true + } else { + result.status = nil // Success + } + } + } + + return result +} + +// podGroupPodSchedulingAlgorithm runs a scheduling algorithm for individual pod from a pod group. +// It returns the algorithm result and, if successful or the preemption is required, the permit status together with the revert function. +func (sched *Scheduler) podGroupPodSchedulingAlgorithm(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo, podInfo *framework.QueuedPodInfo, postFilterMode podGroupPostFilterMode) (algorithmResult, func()) { + pod := podInfo.Pod + podCtx := initPodSchedulingContext(ctx, pod, podGroupCycleState, postFilterMode) + logger := podCtx.logger + ctx = klog.NewContext(ctx, logger) + start := time.Now() + + logger.V(4).Info("Attempting to schedule a pod belonging to a pod group", "podGroup", klog.KObj(podGroupInfo), "pod", klog.KObj(pod)) + + requiresPreemption := false + scheduleResult, status := sched.schedulingAlgorithm(ctx, podCtx.state, schedFwk, podInfo, start) + if !status.IsSuccess() { + if scheduleResult.nominatingInfo != nil && scheduleResult.nominatingInfo.NominatedNodeName != "" { + // If the NominatedNodeName is set, the preemption is required. + // Continue with assuming and reserving, because the subsequent pods from this group + // have to see this one as already scheduled on its nominated place. + // Set SuggestedHost to NominatedNodeName to handle the pod similarly to one that is feasible. + scheduleResult.SuggestedHost = scheduleResult.nominatingInfo.NominatedNodeName + requiresPreemption = true + } else { + // In case of pod being just unschedulable or having an error, just return now. + return algorithmResult{ + pod: pod, + scheduleResult: scheduleResult, + podCtx: podCtx, + schedulingDuration: time.Since(start), + status: status, + }, nil + } + } + assumedPodInfo, assumeStatus := sched.assumeAndReserve(ctx, podCtx.state, schedFwk, podInfo, scheduleResult) + if !assumeStatus.IsSuccess() { + return algorithmResult{ + pod: pod, + scheduleResult: ScheduleResult{nominatingInfo: clearNominatedNode}, + podCtx: podCtx, + schedulingDuration: time.Since(start), + status: assumeStatus, + }, nil + } + + revertFn := func() { + err := sched.unreserveAndForget(ctx, podCtx.state, schedFwk, assumedPodInfo, scheduleResult.SuggestedHost) + if err != nil { + utilruntime.HandleErrorWithContext(ctx, err, "ForgetPod failed") + } + } + + _, permitStatus := schedFwk.RunPermitPlugins(ctx, podCtx.state, assumedPodInfo.Pod, scheduleResult.SuggestedHost) + if !permitStatus.IsWait() && !permitStatus.IsSuccess() { + revertFn() + if permitStatus.IsRejected() { + fitErr := &framework.FitError{ + NumAllNodes: 1, + Pod: assumedPodInfo.Pod, + Diagnosis: framework.Diagnosis{ + NodeToStatus: framework.NewDefaultNodeToStatus(), + }, + } + fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, permitStatus) + fitErr.Diagnosis.AddPluginStatus(permitStatus) + permitStatus = fwk.NewStatus(permitStatus.Code()).WithError(fitErr) + } + return algorithmResult{ + pod: pod, + scheduleResult: ScheduleResult{nominatingInfo: clearNominatedNode}, + podCtx: podCtx, + schedulingDuration: time.Since(start), + status: permitStatus, + }, nil + } + + return algorithmResult{ + pod: pod, + scheduleResult: scheduleResult, + podCtx: podCtx, + schedulingDuration: time.Since(start), + status: status, + permitStatus: permitStatus, + requiresPreemption: requiresPreemption, + }, revertFn +} + +// submitPodGroupAlgorithmResult submits the result of the pod group scheduling algorithm. +// If that algorithm succedeed, the schedulable pods proceed to the binding cycle. +// Unschedulable pods are moved back to the scheduling queue and need to wait +// for the next pod group scheduling cycle. +// If the preemption is required for this pod group, all pods are moved back to the scheduling queue +// and require the next pod group scheduling cycle to verify the preemption outcome. +func (sched *Scheduler) submitPodGroupAlgorithmResult(ctx context.Context, schedFwk framework.Framework, podGroupState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo, podGroupResult podGroupAlgorithmResult, start time.Time) { + logger := klog.FromContext(ctx) + + var scheduledPods, unschedulablePods int + for i, pInfo := range podGroupInfo.QueuedPodInfos { + var podResult algorithmResult + if len(podGroupResult.podResults) > i { + podResult = podGroupResult.podResults[i] + } else { + // In pod group-level unschedulable or error cases, podResult may not be defined. + // Initialize it now to handle pod failure correctly. + podResult = algorithmResult{ + podCtx: initPodSchedulingContext(ctx, pInfo.Pod, podGroupState, runAllPostFilters), + status: podGroupResult.status.Clone(), + } + } + podCtx := podResult.podCtx + ctx := klog.NewContext(ctx, podCtx.logger) + // To be consistent with pod-by-pod scheduling, construct pod scheduling start time as `now - scheduling duration`. + podSchedulingStart := time.Now().Add(-podResult.schedulingDuration) + + if podGroupResult.status.IsError() { + if podResult.status.IsError() { + // If this exact pod failed with an error, use its status instead. + sched.FailureHandler(ctx, schedFwk, pInfo, podResult.status, clearNominatedNode, podSchedulingStart) + continue + } + // Pod group failed with an error. Reject all pods with its status. + sched.FailureHandler(ctx, schedFwk, pInfo, podGroupResult.status, clearNominatedNode, podSchedulingStart) + continue + } + if podResult.status.IsSuccess() { + nominatingInfo := &fwk.NominatingInfo{ + NominatingMode: fwk.ModeOverride, + NominatedNodeName: podResult.scheduleResult.SuggestedHost, + } + switch { + case podGroupResult.status.IsSuccess(): + // Disable pod group scheduling in cycle state before binding. + podCtx.state.SetPodGroupSchedulingCycle(nil) + // Schedule result is applied for pod and its binding cycle executes. + assumedPodInfo, status := sched.prepareForBindingCycle(ctx, podCtx.state, schedFwk, pInfo, podCtx.podsToActivate, podResult.scheduleResult) + if !status.IsSuccess() { + // In such unlikely situation just reject this pod. + sched.FailureHandler(ctx, schedFwk, pInfo, status, clearNominatedNode, podSchedulingStart) + unschedulablePods++ + continue + } + go sched.runBindingCycle(ctx, podCtx.state, schedFwk, podResult.scheduleResult, assumedPodInfo, podSchedulingStart, podCtx.podsToActivate) + scheduledPods++ + case podGroupResult.status.IsRejected(): + if podGroupResult.waitingOnPreemption { + // Pod has to come back to the scheduling queue as unschedulable, waiting for preemption to complete. + sched.FailureHandler(ctx, schedFwk, pInfo, podGroupResult.status, nominatingInfo, podSchedulingStart) + } else { + // Pod group is unschedulable, so the pod has to be marked as unschedulable. + // Its rejection status is set to its permit status message. + status := fwk.NewStatus(fwk.Unschedulable, podResult.permitStatus.Message()).WithError(errPodGroupUnschedulable) + sched.FailureHandler(ctx, schedFwk, pInfo, status, clearNominatedNode, podSchedulingStart) + } + unschedulablePods++ + default: + err := fmt.Errorf("received unexpected pod group scheduling algorithm status code: %s", podGroupResult.status.Code()) + sched.FailureHandler(ctx, schedFwk, pInfo, fwk.AsStatus(err), clearNominatedNode, podSchedulingStart) + unschedulablePods++ + } + } else { + // TBD: Add a message to status if the pod used features for which finding a placement cannot be guaranteed, + // such as heterogeneous pod group or using inter-pod dependencies. + if podResult.requiresPreemption && !podGroupResult.waitingOnPreemption { + // Pod group is unschedulable, so the pod has to be marked as unschedulable, even if it just required preemption. + // Its rejection status is set to its permit status message, as the preemption message is no longer relevant. + status := fwk.NewStatus(fwk.Unschedulable, podResult.permitStatus.Message()).WithError(errPodGroupUnschedulable) + sched.FailureHandler(ctx, schedFwk, pInfo, status, clearNominatedNode, podSchedulingStart) + } else { + // When a pod is unschedulable or preemption is required, just call the FailureHandler. + sched.FailureHandler(ctx, schedFwk, pInfo, podResult.status, podResult.scheduleResult.nominatingInfo, podSchedulingStart) + } + unschedulablePods++ + } + } + + var condition *metav1.Condition + switch { + case podGroupResult.status.IsSuccess(): + condition = &metav1.Condition{ + Type: schedulingapi.PodGroupScheduled, + Status: metav1.ConditionTrue, + Reason: "Scheduled", + Message: podGroupResult.status.Message(), + } + logger.V(2).Info("Successfully scheduled a pod group", "podGroup", klog.KObj(podGroupInfo), "scheduledPods", scheduledPods, "unschedulablePods", unschedulablePods) + metrics.PodGroupScheduled(schedFwk.ProfileName(), metrics.SinceInSeconds(start)) + + case podGroupResult.status.IsRejected(): + condition = &metav1.Condition{ + Type: schedulingapi.PodGroupScheduled, + Status: metav1.ConditionFalse, + Reason: schedulingapi.PodGroupReasonUnschedulable, + Message: podGroupResult.status.Message(), + } + if podGroupResult.waitingOnPreemption { + logger.V(2).Info("Pod group is waiting for preemption", "podGroup", klog.KObj(podGroupInfo), "unschedulablePods", unschedulablePods) + metrics.PodGroupWaitingOnPreemption(schedFwk.ProfileName(), metrics.SinceInSeconds(start)) + } else { + logger.V(2).Info("Unable to schedule a pod group", "podGroup", klog.KObj(podGroupInfo), "unschedulablePods", unschedulablePods) + metrics.PodGroupUnschedulable(schedFwk.ProfileName(), metrics.SinceInSeconds(start)) + } + + default: + condition = &metav1.Condition{ + Type: schedulingapi.PodGroupScheduled, + Status: metav1.ConditionFalse, + Reason: schedulingapi.PodGroupReasonSchedulerError, + Message: podGroupResult.status.AsError().Error(), + } + utilruntime.HandleErrorWithContext(ctx, podGroupResult.status.AsError(), "Error scheduling pod group", "podGroup", klog.KObj(podGroupInfo), "errorPods", len(podGroupInfo.QueuedPodInfos)) + metrics.PodGroupScheduleError(schedFwk.ProfileName(), metrics.SinceInSeconds(start)) + } + sched.updatePodGroupCondition(ctx, podGroupInfo, condition) +} + +// updatePodGroupCondition patches the given condition on a PodGroup. +func (sched *Scheduler) updatePodGroupCondition(ctx context.Context, + podGroupInfo *framework.QueuedPodGroupInfo, condition *metav1.Condition) { + logger := klog.FromContext(ctx) + + // If the PodGroup was already successfully scheduled, don't regress the + // condition back to False on a subsequent cycle for extra pods. + pg, err := sched.podGroupLister.PodGroups(podGroupInfo.Namespace).Get(podGroupInfo.Name) + if err != nil { + utilruntime.HandleErrorWithLogger(logger, err, "Failed to get PodGroup for status update", "podGroup", klog.KObj(podGroupInfo)) + return + } + + existing := apimeta.FindStatusCondition(pg.Status.Conditions, condition.Type) + if existing != nil && existing.Status == metav1.ConditionTrue && condition.Status != metav1.ConditionTrue { + return + } + + condition.ObservedGeneration = pg.Generation + newStatus := pg.Status.DeepCopy() + if !apimeta.SetStatusCondition(&newStatus.Conditions, *condition) { + return + } + + if err := util.PatchPodGroupStatus(ctx, sched.client, podGroupInfo.Name, podGroupInfo.Namespace, &pg.Status, newStatus); err != nil { + utilruntime.HandleErrorWithLogger(logger, err, "Failed to update PodGroup status", "podGroup", klog.KObj(podGroupInfo)) + } +} + +// podGroupSchedulingPlacementAlgorithm tries several different combinations for scheduling the pod group and selects the best one. +// First it runs placement generator plugins to create a list of placements. +// Placement is a set of nodes that will be considered when scheduling a pod group. +// Then for each placement it tries to schedule the pod group through podGroupSchedulingDefaultAlgorithm. +// Finally, it runs placement scorer plugins to select the best placement. +func (sched *Scheduler) podGroupSchedulingPlacementAlgorithm(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo, postFilterMode podGroupPostFilterMode) podGroupAlgorithmResult { + logger := klog.FromContext(ctx) + allNodes, err := sched.nodeInfoSnapshot.NodeInfos().List() + if err != nil { + return podGroupAlgorithmResult{ + status: fwk.AsStatus(fmt.Errorf("failed to list node infos: %w", err)), + } + } + + // For now, always record plugin metrics until we understand its impact on performance. + podGroupCycleState.SetRecordPluginMetrics(true) + placements, status := schedFwk.RunPlacementGeneratePlugins(ctx, podGroupCycleState, podGroupInfo.PodGroupInfo, allNodes) + if !status.IsSuccess() { + return podGroupAlgorithmResult{ + status: status, + } + } + + var anyResult *podGroupAlgorithmResult + successfulResults := make(map[*fwk.Placement]*podGroupAlgorithmResult) + + for _, placement := range placements { + logger.V(4).Info("Assuming placement in snapshot", "placement", placement.Name) + err := sched.nodeInfoSnapshot.AssumePlacement(placement) + if err != nil { + return podGroupAlgorithmResult{ + status: fwk.AsStatus(fmt.Errorf("failed to assume pod group placement: %w", err)), + } + } + result := sched.podGroupSchedulingDefaultAlgorithm(ctx, schedFwk, podGroupCycleState, podGroupInfo, postFilterMode) + sched.nodeInfoSnapshot.ForgetPlacement() + if result.status.IsError() { + return result + } + + if anyResult == nil { + anyResult = &result + } + + if result.status.IsSuccess() || result.waitingOnPreemption { + successfulResults[placement] = &result + } + } + + if len(successfulResults) == 0 { + // We need to send events and set the status for pods in case all simulations were infeasible. + // The selection of which simulation we report is arbitrary for now, but may change in the future. + anyResult.status = fwk.NewStatus(fwk.Unschedulable, fmt.Sprintf("0/%d placements are available, first placement status: %v", len(placements), anyResult.status.AsError())) + return *anyResult + } + + if len(successfulResults) == 1 { + for _, result := range successfulResults { + return *result + } + } + + bestPlacement, status := sched.findBestPlacement(ctx, schedFwk, podGroupCycleState, podGroupInfo, successfulResults) + if !status.IsSuccess() { + return podGroupAlgorithmResult{ + status: status, + } + } + + return *successfulResults[bestPlacement] +} + +// findBestPlacement uses PlacementScore plugins to determine the best placement based on the scheduling results. +func (sched *Scheduler) findBestPlacement(ctx context.Context, schedFwk framework.Framework, podGroupCycleState fwk.PodGroupCycleState, podGroupInfo *framework.QueuedPodGroupInfo, successfulResults map[*fwk.Placement]*podGroupAlgorithmResult) (*fwk.Placement, *fwk.Status) { + placementPodGroupAssignments := makePodGroupAssignments(successfulResults) + + scores, status := schedFwk.RunPlacementScorePlugins(ctx, podGroupCycleState, podGroupInfo, placementPodGroupAssignments) + if !status.IsSuccess() { + return nil, status + } + + for i := range scores { + scores[i].Randomizer = rand.Int() + } + + loggerVTen := klog.FromContext(ctx).V(10) + if loggerVTen.Enabled() { + for _, score := range scores { + for _, pluginScore := range score.Scores { + loggerVTen.Info("Plugin scored placement for podGroup", "podGroup", klog.KObj(podGroupInfo), "plugin", pluginScore.Name, "placement", score.Placement.Name, "score", pluginScore.Score) + } + loggerVTen.Info("Calculated placement's final score for podGroup", "podGroup", klog.KObj(podGroupInfo), "placement", score.Placement.Name, "score", score.TotalScore) + } + } + + bestScore := &scores[0] + for _, score := range scores[1:] { + if score.TotalScore > bestScore.TotalScore || + score.TotalScore == bestScore.TotalScore && + score.Randomizer > bestScore.Randomizer { + bestScore = &score + } + } + return bestScore.Placement, nil +} + +func makePodGroupAssignments(successfulResults map[*fwk.Placement]*podGroupAlgorithmResult) []*fwk.PodGroupAssignments { + placementPodGroupAssignments := make([]*fwk.PodGroupAssignments, 0, len(successfulResults)) + for placement, result := range successfulResults { + proposedAssignments := make([]fwk.ProposedAssignment, 0) + for _, algorithmResult := range result.podResults { + if algorithmResult.GetNodeName() != "" { + proposedAssignments = append(proposedAssignments, &algorithmResult) + } + } + placementPodGroupAssignments = append(placementPodGroupAssignments, &fwk.PodGroupAssignments{ + Placement: placement, + ProposedAssignments: proposedAssignments, + }) + } + return placementPodGroupAssignments +} + +// podGroupSchedulingAlgorithm attempts to schedule pods in the pod group according to the policy and constraints and returns the scheduling result for each pod in the pod group. +func (sched *Scheduler) podGroupSchedulingAlgorithm(ctx context.Context, schedFwk framework.Framework, podGroupCycleState *framework.CycleState, podGroupInfo *framework.QueuedPodGroupInfo, postFilterMode podGroupPostFilterMode) podGroupAlgorithmResult { + podGroupCycleCtx, cancel := context.WithCancel(ctx) + defer cancel() + + if utilfeature.DefaultFeatureGate.Enabled(features.TopologyAwareWorkloadScheduling) { + return sched.podGroupSchedulingPlacementAlgorithm(podGroupCycleCtx, schedFwk, podGroupCycleState, podGroupInfo, postFilterMode) + } else { + return sched.podGroupSchedulingDefaultAlgorithm(podGroupCycleCtx, schedFwk, podGroupCycleState, podGroupInfo, postFilterMode) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go b/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go index 7c289c1541..f001ef6ec1 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go @@ -31,6 +31,7 @@ import ( "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" clientset "k8s.io/client-go/kubernetes" + schedulinglisters "k8s.io/client-go/listers/scheduling/v1alpha2" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" resourceslicetracker "k8s.io/dynamic-resource-allocation/resourceslice/tracker" @@ -45,7 +46,6 @@ import ( internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache" cachedebugger "k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger" internalqueue "k8s.io/kubernetes/pkg/scheduler/backend/queue" - internalworkloadmanager "k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager" "k8s.io/kubernetes/pkg/scheduler/framework" apicalls "k8s.io/kubernetes/pkg/scheduler/framework/api_calls" "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" @@ -60,12 +60,6 @@ import ( "k8s.io/utils/clock" ) -const ( - // Duration the scheduler will wait before expiring an assumed pod. - // See issue #106361 for more details about this parameter and its value. - durationToExpireAssumedPod time.Duration = 0 -) - // ErrNoNodesAvailable is used to describe the error that no nodes available to schedule pods. var ErrNoNodesAvailable = fmt.Errorf("no nodes available to schedule pods") @@ -90,7 +84,7 @@ type Scheduler struct { // SchedulePod tries to schedule the given pod to one of the nodes in the node list. // Return a struct of ScheduleResult with the name of suggested host on success, // otherwise will return a FitError with reasons. - SchedulePod func(ctx context.Context, fwk framework.Framework, state fwk.CycleState, pod *v1.Pod) (ScheduleResult, error) + SchedulePod func(ctx context.Context, fwk framework.Framework, state fwk.CycleState, podInfo *framework.QueuedPodInfo) (ScheduleResult, error) // Close this to shut down the scheduler. StopEverything <-chan struct{} @@ -104,9 +98,6 @@ type Scheduler struct { // framework.APICache should be used instead. APIDispatcher *apidispatcher.APIDispatcher - // WorkloadManager can be used to provide workload-aware scheduling. - WorkloadManager internalworkloadmanager.WorkloadManager - // Profiles are the scheduling profiles. Profiles profile.Map @@ -123,10 +114,14 @@ type Scheduler struct { // panic. logger klog.Logger + podGroupLister schedulinglisters.PodGroupLister + // registeredHandlers contains the registrations of all handlers. It's used to check if all handlers have finished syncing before the scheduling cycles start. registeredHandlers []cache.ResourceEventHandlerRegistration nominatedNodeNameForExpectationEnabled bool + genericWorkloadEnabled bool + workloadAwarePreemptionEnabled bool } func (sched *Scheduler) applyDefaultHandlers() { @@ -318,12 +313,19 @@ func New(ctx context.Context, podLister := informerFactory.Core().V1().Pods().Lister() nodeLister := informerFactory.Core().V1().Nodes().Lister() + var podGroupLister schedulinglisters.PodGroupLister + if feature.DefaultFeatureGate.Enabled(features.GenericWorkload) { + podGroupLister = informerFactory.Scheduling().V1alpha2().PodGroups().Lister() + } snapshot := internalcache.NewEmptySnapshot() metricsRecorder := metrics.NewMetricsAsyncRecorder(1000, time.Second, stopEverything) // waitingPods holds all the pods that are in the scheduler and waiting in the permit stage waitingPods := frameworkruntime.NewWaitingPodsMap() + // podsInPreBind holds all the pods that are in the scheduler in the preBind phase + podsInPreBind := frameworkruntime.NewPodsInPreBindMap() + var resourceClaimCache *assumecache.AssumeCache var resourceSliceTracker *resourceslicetracker.Tracker var draManager fwk.SharedDRAManager @@ -339,7 +341,7 @@ func New(ctx context.Context, // If device taint rules are disabled, the additional informers are not needed and // the tracker turns into a simple wrapper around the slice informer. if resourceSliceTrackerOpts.EnableDeviceTaintRules { - resourceSliceTrackerOpts.TaintInformer = informerFactory.Resource().V1alpha3().DeviceTaintRules() + resourceSliceTrackerOpts.TaintInformer = informerFactory.Resource().V1beta2().DeviceTaintRules() resourceSliceTrackerOpts.ClassInformer = informerFactory.Resource().V1().DeviceClasses() } resourceSliceTracker, err = resourceslicetracker.StartTracker(ctx, resourceSliceTrackerOpts) @@ -354,10 +356,8 @@ func New(ctx context.Context, if feature.DefaultFeatureGate.Enabled(features.SchedulerAsyncAPICalls) { apiDispatcher = apidispatcher.New(client, int(options.parallelism), apicalls.Relevances) } - var workloadManager internalworkloadmanager.WorkloadManager - if feature.DefaultFeatureGate.Enabled(features.GenericWorkload) { - workloadManager = internalworkloadmanager.New() - } + + schedulerCache := internalcache.New(ctx, apiDispatcher, feature.DefaultFeatureGate.Enabled(features.GenericWorkload)) profiles, err := profile.NewMap(ctx, options.profiles, registry, recorderFactory, frameworkruntime.WithComponentConfigVersion(options.componentConfigVersion), @@ -371,9 +371,10 @@ func New(ctx context.Context, frameworkruntime.WithExtenders(extenders), frameworkruntime.WithMetricsRecorder(metricsRecorder), frameworkruntime.WithWaitingPods(waitingPods), + frameworkruntime.WithPodsInPreBind(podsInPreBind), frameworkruntime.WithAPIDispatcher(apiDispatcher), frameworkruntime.WithSharedCSIManager(sharedCSIManager), - frameworkruntime.WithWorkloadManager(workloadManager), + frameworkruntime.WithPodGroupManager(schedulerCache), ) if err != nil { return nil, fmt.Errorf("initializing profiles: %v", err) @@ -403,6 +404,12 @@ func New(ctx context.Context, return nil, returnErr } + // Extract pod signing functions from each profile + podSigners := make(map[string]internalqueue.PodSigner) + for profileName, profile := range profiles { + podSigners[profileName] = profile.SignPod + } + podQueue := internalqueue.NewSchedulingQueue( profiles[options.profiles[0].SchedulerName].QueueSortFunc(), informerFactory, @@ -416,10 +423,9 @@ func New(ctx context.Context, internalqueue.WithPluginMetricsSamplePercent(pluginMetricsSamplePercent), internalqueue.WithMetricsRecorder(metricsRecorder), internalqueue.WithAPIDispatcher(apiDispatcher), + internalqueue.WithPodSigners(podSigners), ) - schedulerCache := internalcache.New(ctx, durationToExpireAssumedPod, apiDispatcher) - var apiCache fwk.APICacher if apiDispatcher != nil { apiCache = apicache.New(podQueue, schedulerCache) @@ -447,7 +453,9 @@ func New(ctx context.Context, logger: logger, APIDispatcher: apiDispatcher, nominatedNodeNameForExpectationEnabled: feature.DefaultFeatureGate.Enabled(features.NominatedNodeNameForExpectation), - WorkloadManager: workloadManager, + podGroupLister: podGroupLister, + genericWorkloadEnabled: feature.DefaultFeatureGate.Enabled(features.GenericWorkload), + workloadAwarePreemptionEnabled: feature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption), } sched.NextPod = podQueue.Pop sched.applyDefaultHandlers() diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go index fae3230bc3..0e664babc5 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go @@ -314,7 +314,6 @@ func (c *AssumeCache) delete(obj interface{}) { // An update has both as non-nil. func (c *AssumeCache) pushEvent(oldObj, newObj interface{}) { for _, handler := range c.eventHandlers { - handler := handler if oldObj == nil { c.eventQueue.WriteOne(func() { handler.OnAdd(newObj, false) @@ -463,8 +462,13 @@ func (c *AssumeCache) Assume(obj interface{}) error { c.pushEvent(objInfo.latestObj, obj) // Only update the cached object + oldObj := objInfo.latestObj objInfo.latestObj = obj - c.logger.V(4).Info("Assumed object", "description", c.description, "cacheKey", name, "version", newVersion) + if loggerV := c.logger.V(6); loggerV.Enabled() { + loggerV.Info("Assumed object", "description", c.description, "cacheKey", name, "version", newVersion, "oldObj", klog.Format(oldObj), "newObj", klog.Format(obj)) + } else { + c.logger.V(5).Info("Assumed object", "description", c.description, "cacheKey", name, "version", newVersion) + } return nil } @@ -483,7 +487,7 @@ func (c *AssumeCache) Restore(objName string) { c.pushEvent(objInfo.latestObj, objInfo.apiObj) objInfo.latestObj = objInfo.apiObj } - c.logger.V(4).Info("Restored object", "description", c.description, "cacheKey", objName) + c.logger.V(5).Info("Restored object", "description", c.description, "cacheKey", objName) } } @@ -508,7 +512,11 @@ func (c *AssumeCache) AddEventHandler(handler cache.ResourceEventHandler) cache. if c.handlerRegistration == nil { // No informer, so immediately synced. - return syncedHandlerRegistration{} + s := syncedHandlerRegistration{ + synced: make(chan struct{}), + } + close(s.synced) + return s } return c.handlerRegistration @@ -557,6 +565,14 @@ func (c *AssumeCache) emitEvents() { // syncedHandlerRegistration is an implementation of ResourceEventHandlerRegistration // which always returns true. -type syncedHandlerRegistration struct{} +type syncedHandlerRegistration struct { + synced chan struct{} +} func (syncedHandlerRegistration) HasSynced() bool { return true } + +func (s syncedHandlerRegistration) HasSyncedChecker() cache.DoneChecker { return s } + +func (s syncedHandlerRegistration) Name() string { return "AssumeCache" } + +func (s syncedHandlerRegistration) Done() <-chan struct{} { return s.synced } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go index 06ba395030..8605c60359 100644 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go +++ b/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go @@ -25,6 +25,7 @@ import ( v1 "k8s.io/api/core/v1" resourceapi "k8s.io/api/resource/v1" + schedulingv1alpha2 "k8s.io/api/scheduling/v1alpha2" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -97,7 +98,7 @@ func MoreImportantPod(pod1, pod2 *v1.Pod) bool { // Retriable defines the retriable errors during a scheduling cycle. func Retriable(err error) bool { return apierrors.IsInternalError(err) || apierrors.IsServiceUnavailable(err) || - net.IsConnectionRefused(err) + apierrors.IsConflict(err) || net.IsConnectionRefused(err) } // PatchPodStatus calculates the delta bytes change from to , @@ -107,6 +108,10 @@ func PatchPodStatus(ctx context.Context, cs kubernetes.Interface, name string, n return nil } + if oldStatus == nil { + oldStatus = &v1.PodStatus{} + } + oldData, err := json.Marshal(v1.Pod{Status: *oldStatus}) if err != nil { return err @@ -133,6 +138,45 @@ func PatchPodStatus(ctx context.Context, cs kubernetes.Interface, name string, n return retry.OnError(retry.DefaultBackoff, Retriable, patchFn) } +// PatchPodGroupStatus calculates the delta bytes change from to , +// and then submits a request to API server to patch the PodGroup status changes. +func PatchPodGroupStatus(ctx context.Context, cs kubernetes.Interface, name string, + namespace string, oldStatus *schedulingv1alpha2.PodGroupStatus, + newStatus *schedulingv1alpha2.PodGroupStatus) error { + if newStatus == nil { + return nil + } + + if oldStatus == nil { + oldStatus = &schedulingv1alpha2.PodGroupStatus{} + } + + oldData, err := json.Marshal(schedulingv1alpha2.PodGroup{Status: *oldStatus}) + if err != nil { + return err + } + + newData, err := json.Marshal(schedulingv1alpha2.PodGroup{Status: *newStatus}) + if err != nil { + return err + } + patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &schedulingv1alpha2.PodGroup{}) + if err != nil { + return fmt.Errorf("failed to create merge patch for podgroup %q/%q: %w", namespace, name, err) + } + + if string(patchBytes) == "{}" { + return nil + } + + patchFn := func() error { + _, err := cs.SchedulingV1alpha2().PodGroups(namespace).Patch(ctx, name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") + return err + } + + return retry.OnError(retry.DefaultBackoff, Retriable, patchFn) +} + // DeletePod deletes the given from API server func DeletePod(ctx context.Context, cs kubernetes.Interface, pod *v1.Pod) error { return cs.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{}) @@ -213,3 +257,15 @@ func GetHostPorts(pod *v1.Pod) []v1.ContainerPort { } return ports } + +// PodGroupPriority returns priority of a given pod group. +func PodGroupPriority(pg *schedulingv1alpha2.PodGroup) int32 { + if pg.Spec.Priority != nil { + return *pg.Spec.Priority + } + // When priority of a pod group is nil, it means it was created at a time + // that there was no global default priority class and the priority class + // name of the pod group was empty (or when the WorkloadAwarePreemption + // feature gate was disabled). So, we resolve to the static default priority. + return 0 +} diff --git a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go b/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go index 91a82c2ef8..af10414ac1 100644 --- a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go +++ b/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go index d27d2640f3..351f9ffff9 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go +++ b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go @@ -1,5 +1,4 @@ //go:build freebsd || linux || darwin -// +build freebsd linux darwin /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go index 95616d34f6..0d0799909a 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2023 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go index cbbc83985d..7103e38ecb 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go +++ b/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go @@ -18,8 +18,6 @@ package filesystem import ( "context" - "fmt" - "time" "github.com/fsnotify/fsnotify" ) @@ -32,7 +30,8 @@ type FSWatcher interface { // Starts listening for events and errors. // When an event or error occurs, the corresponding handler is called. - Run() + // The watcher stops and releases resources when ctx is canceled. + Run(ctx context.Context) // Add a filesystem path to watch AddWatch(path string) error @@ -74,11 +73,13 @@ func (w *fsnotifyWatcher) Init(eventHandler FSEventHandler, errorHandler FSError return nil } -func (w *fsnotifyWatcher) Run() { +func (w *fsnotifyWatcher) Run(ctx context.Context) { go func() { defer w.watcher.Close() for { select { + case <-ctx.Done(): + return case event := <-w.watcher.Events: if w.eventHandler != nil { w.eventHandler(event) @@ -91,126 +92,3 @@ func (w *fsnotifyWatcher) Run() { } }() } - -type watchAddRemover interface { - Add(path string) error - Remove(path string) error -} -type noopWatcher struct{} - -func (noopWatcher) Add(path string) error { return nil } -func (noopWatcher) Remove(path string) error { return nil } - -// WatchUntil watches the specified path for changes and blocks until ctx is canceled. -// eventHandler() must be non-nil, and pollInterval must be greater than 0. -// eventHandler() is invoked whenever a change event is observed or pollInterval elapses. -// errorHandler() is invoked (if non-nil) whenever an error occurs initializing or watching the specified path. -// -// If path is a directory, only the directory and immediate children are watched. -// -// If path does not exist or cannot be watched, an error is passed to errorHandler() and eventHandler() is called at pollInterval. -// -// Multiple observed events may collapse to a single invocation of eventHandler(). -// -// eventHandler() is invoked immediately after successful initialization of the filesystem watch, -// in case the path changed concurrent with calling WatchUntil(). -func WatchUntil(ctx context.Context, pollInterval time.Duration, path string, eventHandler func(), errorHandler func(err error)) { - if pollInterval <= 0 { - panic(fmt.Errorf("pollInterval must be > 0")) - } - if eventHandler == nil { - panic(fmt.Errorf("eventHandler must be non-nil")) - } - if errorHandler == nil { - errorHandler = func(err error) {} - } - - // Initialize watcher, fall back to no-op - var ( - eventsCh chan fsnotify.Event - errorCh chan error - watcher watchAddRemover - ) - if w, err := fsnotify.NewWatcher(); err != nil { - errorHandler(fmt.Errorf("error creating file watcher, falling back to poll at interval %s: %w", pollInterval, err)) - watcher = noopWatcher{} - } else { - watcher = w - eventsCh = w.Events - errorCh = w.Errors - defer func() { - _ = w.Close() - }() - } - - // Initialize background poll - t := time.NewTicker(pollInterval) - defer t.Stop() - - attemptPeriodicRewatch := false - - // Start watching the path - if err := watcher.Add(path); err != nil { - errorHandler(err) - attemptPeriodicRewatch = true - } else { - // Invoke handle() at least once after successfully registering the listener, - // in case the file changed concurrent with calling WatchUntil. - eventHandler() - } - - for { - select { - case <-ctx.Done(): - return - - case <-t.C: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // Try to re-establish the watcher if we previously got a watch error - if attemptPeriodicRewatch { - _ = watcher.Remove(path) - if err := watcher.Add(path); err != nil { - errorHandler(err) - } else { - attemptPeriodicRewatch = false - } - } - - // Handle - eventHandler() - - case e := <-eventsCh: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // Try to re-establish the watcher for events which dropped the existing watch - if e.Name == path && (e.Has(fsnotify.Remove) || e.Has(fsnotify.Rename)) { - _ = watcher.Remove(path) - if err := watcher.Add(path); err != nil { - errorHandler(err) - attemptPeriodicRewatch = true - } - } - - // Handle - eventHandler() - - case err := <-errorCh: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // If the error occurs in response to calling watcher.Add, re-adding here could hot-loop. - // The periodic poll will attempt to re-establish the watch. - errorHandler(err) - attemptPeriodicRewatch = true - } - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/flock/flock_other.go b/vendor/k8s.io/kubernetes/pkg/util/flock/flock_other.go index 33c7a0799c..1def472197 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/flock/flock_other.go +++ b/vendor/k8s.io/kubernetes/pkg/util/flock/flock_other.go @@ -1,5 +1,4 @@ //go:build !linux && !darwin && !freebsd && !openbsd && !netbsd && !dragonfly -// +build !linux,!darwin,!freebsd,!openbsd,!netbsd,!dragonfly /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/flock/flock_unix.go b/vendor/k8s.io/kubernetes/pkg/util/flock/flock_unix.go index d44c1a8d56..747b9e766c 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/flock/flock_unix.go +++ b/vendor/k8s.io/kubernetes/pkg/util/flock/flock_unix.go @@ -1,5 +1,4 @@ //go:build linux || darwin || freebsd || openbsd || netbsd || dragonfly -// +build linux darwin freebsd openbsd netbsd dragonfly /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go b/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go index 0962e5cfb5..0971a8bb09 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go +++ b/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go @@ -20,7 +20,7 @@ import ( "fmt" "hash" - "k8s.io/apimachinery/pkg/util/dump" + "k8s.io/utils/dump" ) // DeepHashObject writes specified object to hash using the spew library diff --git a/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go b/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go index 8476c1ca78..52b81f1ec8 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go +++ b/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables_linux.go b/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables_linux.go index e307917307..b038791ff6 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/util/iptables/iptables_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go b/vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go index d507adde73..d56deed2cc 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go +++ b/vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go b/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go index 1467f6c229..b178110ea9 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go +++ b/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go @@ -58,3 +58,9 @@ const TCPReceiveMemoryNamespacedKernelVersion = "4.15" // TCPTransmitMemoryNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_wmem was namespaced(netns). // (ref: https://github.com/torvalds/linux/commit/356d1833b638bd465672aefeb71def3ab93fc17d) const TCPTransmitMemoryNamespacedKernelVersion = "4.15" + +// MemoryQoSMinKernelVersion is the minimum kernel version for safe memory.high throttling. +// Kernels older than 5.9 have a livelock bug where processes can get stuck in an infinite +// reclaim loop at the memory.high boundary. +// (ref: https://github.com/torvalds/linux/commit/b3ff92916af3156df27716bb080a407e4caf9085) +const MemoryQoSMinKernelVersion = "5.9" diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go index 380967f9c0..fcfb37cd1b 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2015 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go index 1e4b926e24..0e16bd7477 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2015 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_linux.go b/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_linux.go index 3a42a14ff9..158379bc88 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_unsupported.go index 96eb990427..6025ab3fb3 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/util/rlimit/rlimit_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go b/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go deleted file mode 100644 index 872fbdcad6..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2015 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 slice provides utility methods for common operations on slices. -package slice - -import ( - "sort" -) - -// CopyStrings copies the contents of the specified string slice -// into a new slice. -func CopyStrings(s []string) []string { - if s == nil { - return nil - } - c := make([]string, len(s)) - copy(c, s) - return c -} - -// SortStrings sorts the specified string slice in place. It returns the same -// slice that was provided in order to facilitate method chaining. -func SortStrings(s []string) []string { - sort.Strings(s) - return s -} - -// ContainsString checks if a given slice of strings contains the provided string. -// If a modifier func is provided, it is called with the slice item before the comparation. -func ContainsString(slice []string, s string, modifier func(s string) string) bool { - for _, item := range slice { - if item == s { - return true - } - if modifier != nil && modifier(item) == s { - return true - } - } - return false -} - -// RemoveString returns a newly created []string that contains all items from slice that -// are not equal to s and modifier(s) in case modifier func is provided. -func RemoveString(slice []string, s string, modifier func(s string) string) []string { - newSlice := make([]string, 0) - for _, item := range slice { - if item == s { - continue - } - if modifier != nil && modifier(item) == s { - continue - } - newSlice = append(newSlice, item) - } - if len(newSlice) == 0 { - // Sanitize for unit tests so we don't need to distinguish empty array - // and nil. - newSlice = nil - } - return newSlice -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_client.go b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_client.go index 7973192803..068a7ccc35 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_client.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_client.go @@ -703,6 +703,9 @@ func (c *csiDriverClient) nodeGetCapabilities(ctx context.Context) ([]*csipbv1.N req := &csipbv1.NodeGetCapabilitiesRequest{} resp, err := nodeClient.NodeGetCapabilities(ctx, req) if err != nil { + if !isFinalError(err) { + return []*csipbv1.NodeServiceCapability{}, volumetypes.NewUncertainProgressError(err.Error()) + } return []*csipbv1.NodeServiceCapability{}, err } return resp.GetCapabilities(), nil diff --git a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_mounter.go b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_mounter.go index f8760280dc..f915179e78 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_mounter.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_mounter.go @@ -23,6 +23,7 @@ import ( "fmt" "os" "path/filepath" + "slices" authenticationv1 "k8s.io/api/authentication/v1" api "k8s.io/api/core/v1" @@ -314,7 +315,11 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error if csiRPCError != nil { // If operation finished with error then we can remove the mount directory. - if volumetypes.IsOperationFinishedError(csiRPCError) { + // Skip on remount (e.g. CSIDriver.spec.requiresRepublish=true): the volume + // was already published and the pod is observing the existing bind mount, + // so removing the mount dir here would leave the pod with stale contents + // that a subsequent successful republish cannot repair (#121271). + if volumetypes.IsOperationFinishedError(csiRPCError) && !mounterArgs.ReconstructedVolume && !mounterArgs.IsRemount { if removeMountDirErr := removeMountDir(c.plugin, dir); removeMountDirErr != nil { klog.Error(log("mounter.SetupAt failed to remove mount dir after a NodePublish() error [%s]: %v", dir, removeMountDirErr)) } @@ -453,7 +458,7 @@ func (c *csiMountMgr) TearDownAt(dir string) error { // to the spec. // // Kubelet should only be responsible for removal of json data files it - // creates and parent directories. + // creates and their parent directories. // // However, some CSI plugins maybe buggy and don't adhere to the standard, // so we still need to remove the target_path here if it's unmounted and @@ -560,12 +565,7 @@ func (c *csiMountMgr) supportsVolumeLifecycleMode() error { // containsVolumeMode checks whether the given volume mode is listed. func containsVolumeMode(modes []storage.VolumeLifecycleMode, mode storage.VolumeLifecycleMode) bool { - for _, m := range modes { - if m == mode { - return true - } - } - return false + return slices.Contains(modes, mode) } // isDirMounted returns the !notMounted result from IsLikelyNotMountPoint check diff --git a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_plugin.go b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_plugin.go index 3d2699a0d3..b77f1c1856 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_plugin.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/csi/csi_plugin.go @@ -342,7 +342,7 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error { return true }, csitranslationplugins.PortworxVolumePluginName: func() bool { - return utilfeature.DefaultFeatureGate.Enabled(features.CSIMigrationPortworx) + return true }, } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go b/vendor/k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go index ba1bde76a2..839c28ed32 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager/nodeinfomanager.go @@ -41,7 +41,6 @@ import ( nodeutil "k8s.io/component-helpers/node/util" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/volume/util" ) const ( @@ -116,7 +115,6 @@ func (nim *nodeInfoManager) InstallCSIDriver(driverName string, driverNodeID str } nodeUpdateFuncs := []nodeUpdateFunc{ - removeMaxAttachLimit(driverName), // remove in 1.35 due to the version skew policy, we have to keep it for 3 releases updateNodeIDInNode(driverName, driverNodeID), updateTopologyLabels(topology), } @@ -154,7 +152,6 @@ func (nim *nodeInfoManager) UninstallCSIDriver(driverName string) error { } err = nim.updateNode( - removeMaxAttachLimit(driverName), // remove it when this function is removed from nodeUpdateFuncs removeNodeIDFromNode(driverName), ) if err != nil { @@ -713,35 +710,3 @@ func (nim *nodeInfoManager) tryUninstallDriverFromCSINode( return err // do not wrap error } - -func removeMaxAttachLimit(driverName string) nodeUpdateFunc { - return func(node *v1.Node) (*v1.Node, bool, error) { - limitKey := v1.ResourceName(util.GetCSIAttachLimitKey(driverName)) - - capacityExists := false - if node.Status.Capacity != nil { - _, capacityExists = node.Status.Capacity[limitKey] - } - - allocatableExists := false - if node.Status.Allocatable != nil { - _, allocatableExists = node.Status.Allocatable[limitKey] - } - - if !capacityExists && !allocatableExists { - return node, false, nil - } - - delete(node.Status.Capacity, limitKey) - if len(node.Status.Capacity) == 0 { - node.Status.Capacity = nil - } - - delete(node.Status.Allocatable, limitKey) - if len(node.Status.Allocatable) == 0 { - node.Status.Allocatable = nil - } - - return node, true, nil - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/csimigration/plugin_manager.go b/vendor/k8s.io/kubernetes/pkg/volume/csimigration/plugin_manager.go index b69352c2a2..9371821612 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/csimigration/plugin_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/csimigration/plugin_manager.go @@ -21,10 +21,8 @@ import ( "fmt" v1 "k8s.io/api/core/v1" - "k8s.io/component-base/featuregate" csilibplugins "k8s.io/csi-translation-lib/plugins" "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" ) @@ -38,14 +36,12 @@ type PluginNameMapper interface { // PluginManager keeps track of migrated state of in-tree plugins type PluginManager struct { PluginNameMapper - featureGate featuregate.FeatureGate } // NewPluginManager returns a new PluginManager instance -func NewPluginManager(m PluginNameMapper, featureGate featuregate.FeatureGate) PluginManager { +func NewPluginManager(m PluginNameMapper) PluginManager { return PluginManager{ PluginNameMapper: m, - featureGate: featureGate, } } @@ -74,7 +70,7 @@ func (pm PluginManager) IsMigrationCompleteForPlugin(pluginName string) bool { case csilibplugins.VSphereInTreePluginName: return true case csilibplugins.PortworxVolumePluginName: - return pm.featureGate.Enabled(features.InTreePluginPortworxUnregister) + return true default: return false } @@ -100,7 +96,7 @@ func (pm PluginManager) IsMigrationEnabledForPlugin(pluginName string) bool { case csilibplugins.VSphereInTreePluginName: return true case csilibplugins.PortworxVolumePluginName: - return pm.featureGate.Enabled(features.CSIMigrationPortworx) + return true default: return false } @@ -152,15 +148,3 @@ func TranslateInTreeSpecToCSI(logger klog.Logger, spec *volume.Spec, podNamespac InlineVolumeSpecForCSIMigration: inlineVolume, }, nil } - -// CheckMigrationFeatureFlags checks the configuration of feature flags related -// to CSI Migration is valid. It will return whether the migration is complete -// by looking up the pluginUnregister flag -func CheckMigrationFeatureFlags(f featuregate.FeatureGate, pluginMigration, - pluginUnregister featuregate.Feature) (migrationComplete bool, err error) { - // This is for in-tree plugin that get migration finished - if f.Enabled(pluginMigration) && f.Enabled(pluginUnregister) { - return true, nil - } - return false, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir.go b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir.go index d5c29b182f..622704495d 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir.go @@ -35,6 +35,7 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" resourcehelper "k8s.io/component-helpers/resource" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" + "k8s.io/kubernetes/pkg/kubelet/apis/config" "k8s.io/kubernetes/pkg/kubelet/cm" usernamespacefeature "k8s.io/kubernetes/pkg/kubelet/userns" "k8s.io/kubernetes/pkg/volume" @@ -119,7 +120,7 @@ func calculateEmptyDirMemorySize(nodeAllocatableMemory *resource.Quantity, spec // determine pod resource allocation // we use the same function for pod cgroup assignment to maintain consistent behavior // NOTE: this could be nil on systems that do not support pod memory containment (i.e. windows) - podResourceConfig := cm.ResourceConfigForPod(pod, false, uint64(100000), false) + podResourceConfig := cm.ResourceConfigForPod(pod, false, uint64(100000), false, config.NoneMemoryReservationPolicy) if podResourceConfig != nil && podResourceConfig.Memory != nil { podMemoryLimit := resource.NewQuantity(*(podResourceConfig.Memory), resource.BinarySI) // ensure 0 < value < size diff --git a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_linux.go index 381ad4bf66..179b117e04 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2015 The Kubernetes Authors. @@ -31,12 +30,6 @@ import ( "k8s.io/api/core/v1" ) -// Defined by Linux - the type number for tmpfs mounts. -const ( - linuxTmpfsMagic = 0x01021994 - linuxHugetlbfsMagic = 0x958458f6 -) - // realMountDetector implements mountDetector in terms of syscalls. type realMountDetector struct { mounter mount.Interface @@ -98,9 +91,9 @@ func (m *realMountDetector) GetMountMedium(path string, requestedMedium v1.Stora klog.V(3).Infof("Statfs_t of %v: %+v", path, buf) - if buf.Type == linuxTmpfsMagic { + if buf.Type == unix.TMPFS_MAGIC { return v1.StorageMediumMemory, !notMnt, nil, nil - } else if int64(buf.Type) == linuxHugetlbfsMagic { + } else if int64(buf.Type) == unix.HUGETLBFS_MAGIC { // Skip page size detection if requested medium doesn't have size specified if requestedMedium == v1.StorageMediumHugePages { return v1.StorageMediumHugePages, !notMnt, nil, nil diff --git a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_unsupported.go index 106d296d99..dc710e8265 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2015 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/fake_watcher.go b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/fake_watcher.go index ce834043fb..924b6ae5c1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/fake_watcher.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/fake_watcher.go @@ -17,6 +17,8 @@ limitations under the License. package flexvolume import ( + "context" + "github.com/fsnotify/fsnotify" utilfs "k8s.io/kubernetes/pkg/util/filesystem" ) @@ -40,7 +42,7 @@ func (w *fakeWatcher) Init(eventHandler utilfs.FSEventHandler, _ utilfs.FSErrorH return nil } -func (w *fakeWatcher) Run() { /* no-op */ } +func (w *fakeWatcher) Run(_ context.Context) { /* no-op */ } func (w *fakeWatcher) AddWatch(path string) error { w.watches = append(w.watches, path) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/plugin.go b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/plugin.go index f8d3c08cd0..17e352cb53 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/plugin.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/plugin.go @@ -20,6 +20,7 @@ import ( "fmt" "path/filepath" "runtime" + "slices" "strings" "sync" @@ -297,12 +298,7 @@ func (plugin *flexVolumePlugin) SupportsSELinuxContextMount(spec *volume.Spec) ( func (plugin *flexVolumePlugin) isUnsupported(command string) bool { plugin.Lock() defer plugin.Unlock() - for _, unsupportedCommand := range plugin.unsupportedCommands { - if command == unsupportedCommand { - return true - } - } - return false + return slices.Contains(plugin.unsupportedCommands, command) } func (plugin *flexVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/probe.go b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/probe.go index 2c4c5d0f98..e6f875ab2e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/probe.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/flexvolume/probe.go @@ -17,6 +17,7 @@ limitations under the License. package flexvolume import ( + "context" "fmt" "os" "path/filepath" @@ -39,18 +40,20 @@ type flexVolumeProber struct { watcher utilfs.FSWatcher factory PluginFactory fs utilfs.Filesystem + ctx context.Context probeAllNeeded bool eventsMap map[string]volume.ProbeOperation // the key is the driver directory path, the value is the corresponding operation } // GetDynamicPluginProber creates dynamic plugin prober -func GetDynamicPluginProber(pluginDir string, runner exec.Interface) volume.DynamicPluginProber { +func GetDynamicPluginProber(ctx context.Context, pluginDir string, runner exec.Interface) volume.DynamicPluginProber { return &flexVolumeProber{ pluginDir: pluginDir, watcher: utilfs.NewFsnotifyWatcher(), factory: pluginFactory{}, runner: runner, fs: &utilfs.DefaultFs{}, + ctx: ctx, } } @@ -261,7 +264,7 @@ func (prober *flexVolumeProber) initWatcher() error { return fmt.Errorf("error adding watch on Flexvolume directory: %s", err) } - prober.watcher.Run() + prober.watcher.Run(prober.ctx) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go b/vendor/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go index 1d43db1857..39daacb390 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/iscsi/iscsi.go @@ -631,7 +631,7 @@ func createSecretMap(spec *volume.Spec, plugin *iscsiPlugin, namespace string) ( } if len(secretName) > 0 && len(secretNamespace) > 0 { - // if secret is provideded, retrieve it + // if secret is provided, retrieve it kubeClient := plugin.host.GetKubeClient() if kubeClient == nil { return nil, fmt.Errorf("cannot get kube client") diff --git a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go index 24b661493f..e80603a52c 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go @@ -390,9 +390,6 @@ type VolumeHost interface { // Get mounter interface. GetMounter() mount.Interface - // Returns the hostname of the host kubelet is running on - GetHostName() string - // Returns node allocatable. GetNodeAllocatable() (v1.ResourceList, error) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/OWNERS b/vendor/k8s.io/kubernetes/pkg/volume/portworx/OWNERS deleted file mode 100644 index a38b2de0f8..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - saad-ali -reviewers: - - saad-ali -emeritus_approvers: - - lpabon - - rootfs diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/doc.go b/vendor/k8s.io/kubernetes/pkg/volume/portworx/doc.go deleted file mode 100644 index 9ba9ad256e..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2017 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 portworx contains the internal representation of Portworx -// Block Device volumes. -package portworx diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go deleted file mode 100644 index f8d4c348c4..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx.go +++ /dev/null @@ -1,464 +0,0 @@ -/* -Copyright 2017 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 portworx - -import ( - "fmt" - "net" - "os" - "strconv" - - "k8s.io/klog/v2" - "k8s.io/mount-utils" - "k8s.io/utils/exec" - utilstrings "k8s.io/utils/strings" - - volumeclient "github.com/libopenstorage/openstorage/api/client/volume" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/volume/util" -) - -const ( - attachContextKey = "context" - attachHostKey = "host" -) - -// ProbeVolumePlugins is the primary entrypoint for volume plugins. -func ProbeVolumePlugins() []volume.VolumePlugin { - return []volume.VolumePlugin{&portworxVolumePlugin{nil, nil}} -} - -type portworxVolumePlugin struct { - host volume.VolumeHost - util *portworxVolumeUtil -} - -var _ volume.VolumePlugin = &portworxVolumePlugin{} -var _ volume.PersistentVolumePlugin = &portworxVolumePlugin{} -var _ volume.DeletableVolumePlugin = &portworxVolumePlugin{} -var _ volume.ProvisionableVolumePlugin = &portworxVolumePlugin{} -var _ volume.ExpandableVolumePlugin = &portworxVolumePlugin{} - -const ( - portworxVolumePluginName = "kubernetes.io/portworx-volume" -) - -func getPath(uid types.UID, volName string, host volume.VolumeHost) string { - return host.GetPodVolumeDir(uid, utilstrings.EscapeQualifiedName(portworxVolumePluginName), volName) -} - -func (plugin *portworxVolumePlugin) IsMigratedToCSI() bool { - return utilfeature.DefaultFeatureGate.Enabled(features.CSIMigrationPortworx) -} - -func (plugin *portworxVolumePlugin) Init(host volume.VolumeHost) error { - client, err := volumeclient.NewDriverClient( - fmt.Sprintf("http://%s", net.JoinHostPort(host.GetHostName(), strconv.Itoa(osdMgmtDefaultPort))), - pxdDriverName, osdDriverVersion, pxDriverName) - if err != nil { - return err - } - - plugin.host = host - plugin.util = &portworxVolumeUtil{ - portworxClient: client, - } - - return nil -} - -func (plugin *portworxVolumePlugin) GetPluginName() string { - return portworxVolumePluginName -} - -func (plugin *portworxVolumePlugin) GetVolumeName(spec *volume.Spec) (string, error) { - volumeSource, _, err := getVolumeSource(spec) - if err != nil { - return "", err - } - - return volumeSource.VolumeID, nil -} - -func (plugin *portworxVolumePlugin) CanSupport(spec *volume.Spec) bool { - return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.PortworxVolume != nil) || - (spec.Volume != nil && spec.Volume.PortworxVolume != nil) -} - -func (plugin *portworxVolumePlugin) RequiresRemount(spec *volume.Spec) bool { - return false -} - -func (plugin *portworxVolumePlugin) GetAccessModes() []v1.PersistentVolumeAccessMode { - return []v1.PersistentVolumeAccessMode{ - v1.ReadWriteOnce, - v1.ReadWriteMany, - } -} - -func (plugin *portworxVolumePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod) (volume.Mounter, error) { - return plugin.newMounterInternal(spec, pod.UID, plugin.util, plugin.host.GetMounter()) -} - -func (plugin *portworxVolumePlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager portworxManager, mounter mount.Interface) (volume.Mounter, error) { - pwx, readOnly, err := getVolumeSource(spec) - if err != nil { - return nil, err - } - - volumeID := pwx.VolumeID - fsType := pwx.FSType - - return &portworxVolumeMounter{ - portworxVolume: &portworxVolume{ - podUID: podUID, - volName: spec.Name(), - volumeID: volumeID, - manager: manager, - mounter: mounter, - plugin: plugin, - MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)), - }, - fsType: fsType, - readOnly: readOnly, - diskMounter: mount.NewSafeFormatAndMount(plugin.host.GetMounter(), exec.New())}, nil -} - -func (plugin *portworxVolumePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { - return plugin.newUnmounterInternal(volName, podUID, plugin.util, plugin.host.GetMounter()) -} - -func (plugin *portworxVolumePlugin) newUnmounterInternal(volName string, podUID types.UID, manager portworxManager, - mounter mount.Interface) (volume.Unmounter, error) { - return &portworxVolumeUnmounter{ - &portworxVolume{ - podUID: podUID, - volName: volName, - manager: manager, - mounter: mounter, - plugin: plugin, - MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, volName, plugin.host)), - }}, nil -} - -func (plugin *portworxVolumePlugin) NewDeleter(logger klog.Logger, spec *volume.Spec) (volume.Deleter, error) { - return plugin.newDeleterInternal(spec, plugin.util) -} - -func (plugin *portworxVolumePlugin) newDeleterInternal(spec *volume.Spec, manager portworxManager) (volume.Deleter, error) { - if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.PortworxVolume == nil { - return nil, fmt.Errorf("spec.PersistentVolumeSource.PortworxVolume is nil") - } - - return &portworxVolumeDeleter{ - portworxVolume: &portworxVolume{ - volName: spec.Name(), - volumeID: spec.PersistentVolume.Spec.PortworxVolume.VolumeID, - manager: manager, - plugin: plugin, - }}, nil -} - -func (plugin *portworxVolumePlugin) NewProvisioner(logger klog.Logger, options volume.VolumeOptions) (volume.Provisioner, error) { - return plugin.newProvisionerInternal(options, plugin.util) -} - -func (plugin *portworxVolumePlugin) newProvisionerInternal(options volume.VolumeOptions, manager portworxManager) (volume.Provisioner, error) { - return &portworxVolumeProvisioner{ - portworxVolume: &portworxVolume{ - manager: manager, - plugin: plugin, - }, - options: options, - }, nil -} - -func (plugin *portworxVolumePlugin) RequiresFSResize() bool { - return false -} - -func (plugin *portworxVolumePlugin) ExpandVolumeDevice( - spec *volume.Spec, - newSize resource.Quantity, - oldSize resource.Quantity) (resource.Quantity, error) { - klog.V(4).Infof("Expanding: %s from %v to %v", spec.Name(), oldSize, newSize) - err := plugin.util.ResizeVolume(spec, newSize, plugin.host) - if err != nil { - return oldSize, err - } - - klog.V(4).Infof("Successfully resized %s to %v", spec.Name(), newSize) - return newSize, nil -} - -func (plugin *portworxVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (volume.ReconstructedVolume, error) { - portworxVolume := &v1.Volume{ - Name: volumeName, - VolumeSource: v1.VolumeSource{ - PortworxVolume: &v1.PortworxVolumeSource{ - VolumeID: volumeName, - }, - }, - } - return volume.ReconstructedVolume{ - Spec: volume.NewSpecFromVolume(portworxVolume), - }, nil -} - -func (plugin *portworxVolumePlugin) SupportsMountOption() bool { - return false -} - -func (plugin *portworxVolumePlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) { - return false, nil -} - -func getVolumeSource( - spec *volume.Spec) (*v1.PortworxVolumeSource, bool, error) { - if spec.Volume != nil && spec.Volume.PortworxVolume != nil { - return spec.Volume.PortworxVolume, spec.Volume.PortworxVolume.ReadOnly, nil - } else if spec.PersistentVolume != nil && - spec.PersistentVolume.Spec.PortworxVolume != nil { - return spec.PersistentVolume.Spec.PortworxVolume, spec.ReadOnly, nil - } - - return nil, false, fmt.Errorf("Spec does not reference a Portworx Volume type") -} - -// Abstract interface to PD operations. -type portworxManager interface { - // Creates a volume - CreateVolume(provisioner *portworxVolumeProvisioner) (volumeID string, volumeSizeGB int64, labels map[string]string, err error) - // Deletes a volume - DeleteVolume(deleter *portworxVolumeDeleter) error - // Attach a volume - AttachVolume(mounter *portworxVolumeMounter, attachOptions map[string]string) (string, error) - // Detach a volume - DetachVolume(unmounter *portworxVolumeUnmounter) error - // Mount a volume - MountVolume(mounter *portworxVolumeMounter, mountDir string) error - // Unmount a volume - UnmountVolume(unmounter *portworxVolumeUnmounter, mountDir string) error - // Resize a volume - ResizeVolume(spec *volume.Spec, newSize resource.Quantity, host volume.VolumeHost) error -} - -// portworxVolume volumes are portworx block devices -// that are attached to the kubelet's host machine and exposed to the pod. -type portworxVolume struct { - volName string - podUID types.UID - // Unique id of the PD, used to find the disk resource in the provider. - volumeID string - // Utility interface that provides API calls to the provider to attach/detach disks. - manager portworxManager - // Mounter interface that provides system calls to mount the global path to the pod local path. - mounter mount.Interface - plugin *portworxVolumePlugin - volume.MetricsProvider -} - -type portworxVolumeMounter struct { - *portworxVolume - // Filesystem type, optional. - fsType string - // Specifies whether the disk will be attached as read-only. - readOnly bool - // diskMounter provides the interface that is used to mount the actual block device. - diskMounter *mount.SafeFormatAndMount -} - -var _ volume.Mounter = &portworxVolumeMounter{} - -func (b *portworxVolumeMounter) GetAttributes() volume.Attributes { - return volume.Attributes{ - ReadOnly: b.readOnly, - Managed: !b.readOnly, - SELinuxRelabel: false, - } -} - -// SetUp attaches the disk and bind mounts to the volume path. -func (b *portworxVolumeMounter) SetUp(mounterArgs volume.MounterArgs) error { - return b.SetUpAt(b.GetPath(), mounterArgs) -} - -// SetUpAt attaches the disk and bind mounts to the volume path. -func (b *portworxVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) error { - notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) - klog.Infof("Portworx Volume set up. Dir: %s %v %v", dir, !notMnt, err) - if err != nil && !os.IsNotExist(err) { - // don't log error details from client calls in events - klog.V(4).Infof("Cannot validate mountpoint %s: %v", dir, err) - return fmt.Errorf("failed to validate mountpoint: see kube-controller-manager.log for details") - } - if !notMnt { - return nil - } - - attachOptions := make(map[string]string) - attachOptions[attachContextKey] = dir - attachOptions[attachHostKey] = b.plugin.host.GetHostName() - if _, err := b.manager.AttachVolume(b, attachOptions); err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to attach volume %s: %v", b.volumeID, err) - return fmt.Errorf("failed to attach volume: see kube-controller-manager.log for details") - } - - klog.V(4).Infof("Portworx Volume %s attached", b.volumeID) - - if err := os.MkdirAll(dir, 0750); err != nil { - return err - } - - if err := b.manager.MountVolume(b, dir); err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to mount volume %s: %v", b.volumeID, err) - return fmt.Errorf("failed to mount volume: see kube-controller-manager.log for details") - } - if !b.readOnly { - // Since portworxVolume is in process of being removed from in-tree, we avoid larger refactor to add progress tracking for ownership operation - ownershipChanger := volume.NewVolumeOwnership(b, dir, mounterArgs.FsGroup, mounterArgs.FSGroupChangePolicy, util.FSGroupCompleteHook(b.plugin, nil)) - _ = ownershipChanger.ChangePermissions() - } - klog.Infof("Portworx Volume %s setup at %s", b.volumeID, dir) - return nil -} - -func (pwx *portworxVolume) GetPath() string { - return getPath(pwx.podUID, pwx.volName, pwx.plugin.host) -} - -type portworxVolumeUnmounter struct { - *portworxVolume -} - -var _ volume.Unmounter = &portworxVolumeUnmounter{} - -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. -func (c *portworxVolumeUnmounter) TearDown() error { - return c.TearDownAt(c.GetPath()) -} - -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. -func (c *portworxVolumeUnmounter) TearDownAt(dir string) error { - klog.Infof("Portworx Volume TearDown of %s", dir) - - if err := c.manager.UnmountVolume(c, dir); err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to unmount volume %s: %v", c.volumeID, err) - return fmt.Errorf("failed to unmount volume: see kube-controller-manager.log for details") - } - - // Call Portworx Detach Volume. - if err := c.manager.DetachVolume(c); err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to detach volume %s: %v", c.volumeID, err) - return fmt.Errorf("failed to detach volume: see kube-controller-manager.log for details") - } - - return nil -} - -type portworxVolumeDeleter struct { - *portworxVolume -} - -var _ volume.Deleter = &portworxVolumeDeleter{} - -func (d *portworxVolumeDeleter) GetPath() string { - return getPath(d.podUID, d.volName, d.plugin.host) -} - -func (d *portworxVolumeDeleter) Delete() error { - err := d.manager.DeleteVolume(d) - if err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to delete volume %s: %v", d.volumeID, err) - return fmt.Errorf("failed to delete volume: see kube-controller-manager.log for details") - } - return nil -} - -type portworxVolumeProvisioner struct { - *portworxVolume - options volume.VolumeOptions -} - -var _ volume.Provisioner = &portworxVolumeProvisioner{} - -func (c *portworxVolumeProvisioner) Provision(selectedNode *v1.Node, allowedTopologies []v1.TopologySelectorTerm) (*v1.PersistentVolume, error) { - if !util.ContainsAllAccessModes(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) { - return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes()) - } - - if util.CheckPersistentVolumeClaimModeBlock(c.options.PVC) { - return nil, fmt.Errorf("%s does not support block volume provisioning", c.plugin.GetPluginName()) - } - - volumeID, sizeGiB, labels, err := c.manager.CreateVolume(c) - if err != nil { - // don't log error details from client calls in events - klog.V(4).Infof("Failed to create volume: %v", err) - return nil, fmt.Errorf("failed to create volume: see kube-controller-manager.log for details") - } - - pv := &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: c.options.PVName, - Labels: map[string]string{}, - Annotations: map[string]string{ - util.VolumeDynamicallyCreatedByKey: "portworx-volume-dynamic-provisioner", - }, - }, - Spec: v1.PersistentVolumeSpec{ - PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, - AccessModes: c.options.PVC.Spec.AccessModes, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGiB)), - }, - PersistentVolumeSource: v1.PersistentVolumeSource{ - PortworxVolume: &v1.PortworxVolumeSource{ - VolumeID: volumeID, - }, - }, - }, - } - - if len(labels) != 0 { - if pv.Labels == nil { - pv.Labels = make(map[string]string) - } - for k, v := range labels { - pv.Labels[k] = v - } - } - - if len(c.options.PVC.Spec.AccessModes) == 0 { - pv.Spec.AccessModes = c.plugin.GetAccessModes() - } - - return pv, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go deleted file mode 100644 index 1d201bcf4a..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go +++ /dev/null @@ -1,387 +0,0 @@ -/* -Copyright 2017 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 portworx - -import ( - "context" - "fmt" - "net" - "strconv" - - osdapi "github.com/libopenstorage/openstorage/api" - osdclient "github.com/libopenstorage/openstorage/api/client" - volumeclient "github.com/libopenstorage/openstorage/api/client/volume" - osdspec "github.com/libopenstorage/openstorage/api/spec" - volumeapi "github.com/libopenstorage/openstorage/volume" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - volumehelpers "k8s.io/cloud-provider/volume/helpers" - "k8s.io/klog/v2" - - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/volume" -) - -const ( - osdMgmtDefaultPort = 9001 - osdDriverVersion = "v1" - pxdDriverName = "pxd" - pvcClaimLabel = "pvc" - pvcNamespaceLabel = "namespace" - pxServiceName = "portworx-service" - pxDriverName = "pxd-sched" -) - -type portworxVolumeUtil struct { - portworxClient *osdclient.Client -} - -// CreateVolume creates a Portworx volume. -func (util *portworxVolumeUtil) CreateVolume(p *portworxVolumeProvisioner) (string, int64, map[string]string, error) { - driver, err := util.getPortworxDriver(p.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return "", 0, nil, err - } - - klog.Infof("Creating Portworx volume for PVC: %v", p.options.PVC.Name) - - capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] - // Portworx Volumes are specified in GiB - requestGiB, err := volumehelpers.RoundUpToGiB(capacity) - if err != nil { - return "", 0, nil, err - } - - // Perform a best-effort parsing of parameters. Portworx 1.2.9 and later parses volume parameters from - // spec.VolumeLabels. So even if below SpecFromOpts() fails to parse certain parameters or - // doesn't support new parameters, the server-side processing will parse it correctly. - // We still need to call SpecFromOpts() here to handle cases where someone is running Portworx 1.2.8 and lower. - specHandler := osdspec.NewSpecHandler() - spec, locator, source, _ := specHandler.SpecFromOpts(p.options.Parameters) - if spec == nil { - spec = specHandler.DefaultSpec() - } - - // Pass all parameters as volume labels for Portworx server-side processing - if spec.VolumeLabels == nil { - spec.VolumeLabels = make(map[string]string, 0) - } - - for k, v := range p.options.Parameters { - spec.VolumeLabels[k] = v - } - - // Update the requested size in the spec - spec.Size = uint64(requestGiB * volumehelpers.GiB) - - // Change the Portworx Volume name to PV name - if locator == nil { - locator = &osdapi.VolumeLocator{ - VolumeLabels: make(map[string]string), - } - } - locator.Name = p.options.PVName - - // Add claim Name as a part of Portworx Volume Labels - locator.VolumeLabels[pvcClaimLabel] = p.options.PVC.Name - locator.VolumeLabels[pvcNamespaceLabel] = p.options.PVC.Namespace - - for k, v := range p.options.PVC.Annotations { - if _, present := spec.VolumeLabels[k]; present { - klog.Warningf("not saving annotation: %s=%s in spec labels due to an existing key", k, v) - continue - } - spec.VolumeLabels[k] = v - } - - volumeID, err := driver.Create(locator, source, spec) - if err != nil { - klog.Errorf("Error creating Portworx Volume : %v", err) - return "", 0, nil, err - } - - klog.Infof("Successfully created Portworx volume for PVC: %v", p.options.PVC.Name) - return volumeID, requestGiB, nil, err -} - -// DeleteVolume deletes a Portworx volume -func (util *portworxVolumeUtil) DeleteVolume(d *portworxVolumeDeleter) error { - driver, err := util.getPortworxDriver(d.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return err - } - - err = driver.Delete(d.volumeID) - if err != nil { - klog.Errorf("Error deleting Portworx Volume (%v): %v", d.volName, err) - return err - } - return nil -} - -// AttachVolume attaches a Portworx Volume -func (util *portworxVolumeUtil) AttachVolume(m *portworxVolumeMounter, attachOptions map[string]string) (string, error) { - driver, err := util.getLocalPortworxDriver(m.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return "", err - } - - devicePath, err := driver.Attach(m.volName, attachOptions) - if err != nil { - klog.Errorf("Error attaching Portworx Volume (%v): %v", m.volName, err) - return "", err - } - return devicePath, nil -} - -// DetachVolume detaches a Portworx Volume -func (util *portworxVolumeUtil) DetachVolume(u *portworxVolumeUnmounter) error { - driver, err := util.getLocalPortworxDriver(u.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return err - } - - err = driver.Detach(u.volName, false /*doNotForceDetach*/) - if err != nil { - klog.Errorf("Error detaching Portworx Volume (%v): %v", u.volName, err) - return err - } - return nil -} - -// MountVolume mounts a Portworx Volume on the specified mountPath -func (util *portworxVolumeUtil) MountVolume(m *portworxVolumeMounter, mountPath string) error { - driver, err := util.getLocalPortworxDriver(m.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return err - } - - err = driver.Mount(m.volName, mountPath) - if err != nil { - klog.Errorf("Error mounting Portworx Volume (%v) on Path (%v): %v", m.volName, mountPath, err) - return err - } - return nil -} - -// UnmountVolume unmounts a Portworx Volume -func (util *portworxVolumeUtil) UnmountVolume(u *portworxVolumeUnmounter, mountPath string) error { - driver, err := util.getLocalPortworxDriver(u.plugin.host) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return err - } - - err = driver.Unmount(u.volName, mountPath) - if err != nil { - klog.Errorf("Error unmounting Portworx Volume (%v) on Path (%v): %v", u.volName, mountPath, err) - return err - } - return nil -} - -func (util *portworxVolumeUtil) ResizeVolume(spec *volume.Spec, newSize resource.Quantity, volumeHost volume.VolumeHost) error { - driver, err := util.getPortworxDriver(volumeHost) - if err != nil || driver == nil { - klog.Errorf("Failed to get portworx driver. Err: %v", err) - return err - } - - vols, err := driver.Inspect([]string{spec.Name()}) - if err != nil { - return err - } - - if len(vols) != 1 { - return fmt.Errorf("failed to inspect Portworx volume: %s. Found: %d volumes", spec.Name(), len(vols)) - } - - vol := vols[0] - tBytes, err := volumehelpers.RoundUpToB(newSize) - if err != nil { - return err - } - newSizeInBytes := uint64(tBytes) - if vol.Spec.Size >= newSizeInBytes { - klog.Infof("Portworx volume: %s already at size: %d greater than or equal to new "+ - "requested size: %d. Skipping resize.", spec.Name(), vol.Spec.Size, newSizeInBytes) - return nil - } - - vol.Spec.Size = newSizeInBytes - err = driver.Set(spec.Name(), vol.Locator, vol.Spec) - if err != nil { - return err - } - - // check if the volume's size actually got updated - vols, err = driver.Inspect([]string{spec.Name()}) - if err != nil { - return err - } - - if len(vols) != 1 { - return fmt.Errorf("failed to inspect resized Portworx volume: %s. Found: %d volumes", spec.Name(), len(vols)) - } - - updatedVol := vols[0] - if updatedVol.Spec.Size < vol.Spec.Size { - return fmt.Errorf("Portworx volume: %s doesn't match expected size after resize. expected:%v actual:%v", - spec.Name(), vol.Spec.Size, updatedVol.Spec.Size) - } - - return nil -} - -func isClientValid(client *osdclient.Client) (bool, error) { - if client == nil { - return false, nil - } - - _, err := client.Versions(osdapi.OsdVolumePath) - if err != nil { - klog.Errorf("portworx client failed driver versions check. Err: %v", err) - return false, err - } - - return true, nil -} - -func createDriverClient(hostname string, port int32) (*osdclient.Client, error) { - client, err := volumeclient.NewDriverClient(fmt.Sprintf("http://%s", net.JoinHostPort(hostname, strconv.Itoa(int(port)))), - pxdDriverName, osdDriverVersion, pxDriverName) - if err != nil { - return nil, err - } - - isValid, err := isClientValid(client) - if isValid { - return client, nil - } - return nil, err -} - -// getPortworxDriver returns a Portworx volume driver which can be used for cluster wide operations. -// -// Operations like create and delete volume don't need to be restricted to local volume host since -// any node in the Portworx cluster can coordinate the create/delete request and forward the operations to -// the Portworx node that will own/owns the data. -func (util *portworxVolumeUtil) getPortworxDriver(volumeHost volume.VolumeHost) (volumeapi.VolumeDriver, error) { - // check if existing saved client is valid - if isValid, _ := isClientValid(util.portworxClient); isValid { - return volumeclient.VolumeDriver(util.portworxClient), nil - } - - // create new client - var err error - util.portworxClient, err = createDriverClient(volumeHost.GetHostName(), osdMgmtDefaultPort) // for backward compatibility - if err != nil || util.portworxClient == nil { - // Create client from portworx k8s service. - svc, err := getPortworxService(volumeHost) - if err != nil { - return nil, err - } - - // The port here is always the default one since it's the service port - util.portworxClient, err = createDriverClient(svc.Spec.ClusterIP, osdMgmtDefaultPort) - if err != nil || util.portworxClient == nil { - klog.Errorf("Failed to connect to portworx service. Err: %v", err) - return nil, err - } - - klog.Infof("Using portworx cluster service at: %v:%d as api endpoint", - svc.Spec.ClusterIP, osdMgmtDefaultPort) - } else { - klog.Infof("Using portworx service at: %v:%d as api endpoint", - volumeHost.GetHostName(), osdMgmtDefaultPort) - } - - return volumeclient.VolumeDriver(util.portworxClient), nil -} - -// getLocalPortworxDriver returns driver connected to Portworx API server on volume host. -// -// This is required to force certain operations (mount, unmount, detach, attach) to -// go to the volume host instead of the k8s service which might route it to any host. This pertains to how -// Portworx mounts and attaches a volume to the running container. The node getting these requests needs to -// see the pod container mounts (specifically /var/lib/kubelet/pods/) -func (util *portworxVolumeUtil) getLocalPortworxDriver(volumeHost volume.VolumeHost) (volumeapi.VolumeDriver, error) { - if util.portworxClient != nil { - // check if existing saved client is valid - if isValid, _ := isClientValid(util.portworxClient); isValid { - return volumeclient.VolumeDriver(util.portworxClient), nil - } - } - - // Lookup port - svc, err := getPortworxService(volumeHost) - if err != nil { - return nil, err - } - - osgMgmtPort := lookupPXAPIPortFromService(svc) - util.portworxClient, err = createDriverClient(volumeHost.GetHostName(), osgMgmtPort) - if err != nil { - return nil, err - } - - klog.Infof("Using portworx local service at: %v:%d as api endpoint", - volumeHost.GetHostName(), osgMgmtPort) - return volumeclient.VolumeDriver(util.portworxClient), nil -} - -// lookupPXAPIPortFromService goes over all the ports in the given service and returns the target -// port for osdMgmtDefaultPort -func lookupPXAPIPortFromService(svc *v1.Service) int32 { - for _, p := range svc.Spec.Ports { - if p.Port == osdMgmtDefaultPort { - return p.TargetPort.IntVal - } - } - return osdMgmtDefaultPort // default -} - -// getPortworxService returns the portworx cluster service from the API server -func getPortworxService(host volume.VolumeHost) (*v1.Service, error) { - kubeClient := host.GetKubeClient() - if kubeClient == nil { - err := fmt.Errorf("failed to get kubeclient when creating portworx client") - klog.Error(err.Error()) - return nil, err - } - - opts := metav1.GetOptions{} - svc, err := kubeClient.CoreV1().Services(api.NamespaceSystem).Get(context.TODO(), pxServiceName, opts) - if err != nil { - klog.Errorf("Failed to get service. Err: %v", err) - return nil, err - } - - if svc == nil { - err = fmt.Errorf("service: %v not found. Consult Portworx docs to deploy it", pxServiceName) - klog.Error(err.Error()) - return nil, err - } - - return svc, nil -} 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 0466dffacd..cd61baabc1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go @@ -445,7 +445,7 @@ func (w *AtomicWriter) writePayloadToDir(payload map[string]FileProjection, dir continue } - if err := w.chown(fullPath, int(*fileProjection.FsUser), -1); err != nil { + if err := w.lchown(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 } @@ -465,7 +465,7 @@ func (w *AtomicWriter) writePayloadToDir(payload map[string]FileProjection, dir // foo -> ..data/foo // baz -> ..data/baz func (w *AtomicWriter) createUserVisibleFiles(payload map[string]FileProjection) error { - for userVisiblePath := range payload { + for userVisiblePath, fileProjection := range payload { slashpos := strings.Index(userVisiblePath, string(os.PathSeparator)) if slashpos == -1 { slashpos = len(userVisiblePath) @@ -481,6 +481,15 @@ func (w *AtomicWriter) createUserVisibleFiles(payload map[string]FileProjection) if err != nil { return err } + + if fileProjection.FsUser == nil { + continue + } + + if err := w.lchown(visibleFile, int(*fileProjection.FsUser), -1); err != nil { + klog.Errorf("%s: unable to change file %s with owner %v: %v", w.logContext, visibleFile, int(*fileProjection.FsUser), err) + return err + } } } return nil 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 index c12a0f4cd3..ba3b64c55c 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2024 The Kubernetes Authors. @@ -21,7 +20,8 @@ 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) +// lchown changes the numeric uid and gid of the named file. +// If the file is a symbolic link, it changes the uid and gid of the link itself. +func (w *AtomicWriter) lchown(name string, uid, gid int) error { + return os.Lchown(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 index cdfb83e639..a77ef9414e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2024 The Kubernetes Authors. @@ -25,9 +24,10 @@ import ( "k8s.io/klog/v2" ) -// chown changes the numeric uid and gid of the named file. +// lchown changes the numeric uid and gid of the named file. +// If the file is a symbolic link, it changes the uid and gid of the link itself. // This is a no-op on unsupported platforms. -func (w *AtomicWriter) chown(name string, uid, _ /* gid */ int) error { +func (w *AtomicWriter) lchown(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/attach_limit.go b/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go deleted file mode 100644 index 4249a6be4f..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2018 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 ( - "crypto/sha1" - "encoding/hex" -) - -// This file is a common place holder for volume limit utility constants -// shared between volume package and scheduler - -const ( - // CSIAttachLimitPrefix defines prefix used for CSI volumes - CSIAttachLimitPrefix = "attachable-volumes-csi-" - - // ResourceNameLengthLimit stores maximum allowed Length for a ResourceName - ResourceNameLengthLimit = 63 -) - -// GetCSIAttachLimitKey returns limit key used for CSI volumes -func GetCSIAttachLimitKey(driverName string) string { - csiPrefixLength := len(CSIAttachLimitPrefix) - totalkeyLength := csiPrefixLength + len(driverName) - if totalkeyLength >= ResourceNameLengthLimit { - charsFromDriverName := driverName[:23] - hash := sha1.New() - hash.Write([]byte(driverName)) - hashed := hex.EncodeToString(hash.Sum(nil)) - hashed = hashed[:16] - return CSIAttachLimitPrefix + charsFromDriverName + hashed - } - return CSIAttachLimitPrefix + driverName -} 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 18cbec072f..b9e5be201f 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 @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_unsupported.go index ea4786aff6..cbbf035e85 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/device_util_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go index 64301fd5de..fea83301b4 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs.go @@ -1,5 +1,4 @@ //go:build linux || darwin -// +build linux darwin /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go index f66df0d066..82065e3160 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !darwin && !windows -// +build !linux,!darwin,!windows /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go index 3e654d3fd3..9afe97e579 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go index 77f845837b..d0ef4b26a2 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go index a995966239..f50c2777c0 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go index 16d25d6c3f..e1b2f0a96a 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go index 6ddf4d4d50..da93b5d2e9 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go index 31d3e4f655..dcebb4faa4 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go index 19bcc5f14e..5444257f81 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. @@ -24,6 +23,7 @@ import ( "os" "path" "path/filepath" + "slices" "strings" "syscall" @@ -245,17 +245,7 @@ func GetSELinux(path string, mountInfoFilename string, selinuxEnabled seLinuxEna } // "seclabel" can be both in mount options and super options. - for _, opt := range info.SuperOptions { - if opt == "seclabel" { - return true, nil - } - } - for _, opt := range info.MountOptions { - if opt == "seclabel" { - return true, nil - } - } - return false, nil + return slices.Contains(info.SuperOptions, "seclabel") || slices.Contains(info.MountOptions, "seclabel"), nil } // GetSELinuxSupport returns true if given path is on a mount that supports diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_unsupported.go index c5ff9c0b5e..2fd765938a 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go index b702d1e7e9..fcaebdf7d1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/hostutil_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/node_expander.go b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/node_expander.go index 780f5563f3..3e29c95448 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/node_expander.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/node_expander.go @@ -209,8 +209,8 @@ func (ne *NodeExpander) expandOnPlugin() (bool, resource.Quantity, error) { return false, ne.pluginResizeOpts.OldSize, resizeErr } simpleMsg, detailedMsg := ne.vmt.GenerateMsg("MountVolume.NodeExpandVolume succeeded", nodeName) - ne.recorder.Eventf(ne.vmt.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) - ne.recorder.Eventf(ne.pvc, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) + ne.recorder.Eventf(ne.vmt.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, "%s", simpleMsg) + ne.recorder.Eventf(ne.pvc, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, "%s", simpleMsg) klog.InfoS(detailedMsg, "pod", klog.KObj(ne.vmt.Pod)) ne.testStatus = testResponseData{true /*resizeCalledOnPlugin */, true /* assumeResizeFinished */} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go index 9d5c937d95..cf16f99688 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "strings" "time" @@ -290,29 +291,29 @@ func (og *operationGenerator) GenerateAttachVolumeFunc( return volumetypes.NewOperationContext(eventErr, detailedErr, migrated) } - // Successful attach event is useful for user debugging - simpleMsg, _ := volumeToAttach.GenerateMsg("AttachVolume.Attach succeeded", "") - for _, pod := range volumeToAttach.ScheduledPods { - og.recorder.Eventf(pod, v1.EventTypeNormal, kevents.SuccessfulAttachVolume, simpleMsg) - } - klog.Info(volumeToAttach.GenerateMsgDetailed("AttachVolume.Attach succeeded", "")) - // Update actual state of world addVolumeNodeErr := actualStateOfWorld.MarkVolumeAsAttached( - logger, v1.UniqueVolumeName(""), volumeToAttach.VolumeSpec, volumeToAttach.NodeName, devicePath) + logger, volumeToAttach.VolumeName, volumeToAttach.VolumeSpec, volumeToAttach.NodeName, devicePath) if addVolumeNodeErr != nil { // On failure, return error. Caller will log and retry. eventErr, detailedErr := volumeToAttach.GenerateError("AttachVolume.MarkVolumeAsAttached failed", addVolumeNodeErr) return volumetypes.NewOperationContext(eventErr, detailedErr, migrated) } + // Successful attach event is useful for user debugging + simpleMsg, _ := volumeToAttach.GenerateMsg("AttachVolume.Attach succeeded", "") + for _, pod := range volumeToAttach.ScheduledPods { + og.recorder.Eventf(pod, v1.EventTypeNormal, kevents.SuccessfulAttachVolume, "%s", simpleMsg) + } + klog.Info(volumeToAttach.GenerateMsgDetailed("AttachVolume.Attach succeeded", "")) + return volumetypes.NewOperationContext(nil, nil, migrated) } eventRecorderFunc := func(err *error) { if *err != nil { for _, pod := range volumeToAttach.ScheduledPods { - og.recorder.Eventf(pod, v1.EventTypeWarning, kevents.FailedAttachVolume, (*err).Error()) + og.recorder.Eventf(pod, v1.EventTypeWarning, kevents.FailedAttachVolume, "%s", (*err).Error()) } } } @@ -586,6 +587,8 @@ func (og *operationGenerator) GenerateMountVolumeFunc( FSGroupChangePolicy: fsGroupChangePolicy, Recorder: og.recorder, SELinuxLabel: volumeToMount.SELinuxLabel, + ReconstructedVolume: actualStateOfWorld.IsVolumeReconstructed(volumeToMount.VolumeName, volumeToMount.PodName), + IsRemount: isRemount, }) // Update actual state of world markOpts := MarkVolumeOpts{ @@ -646,7 +649,7 @@ func (og *operationGenerator) GenerateMountVolumeFunc( eventRecorderFunc := func(err *error) { if *err != nil { - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, (*err).Error()) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, "%s", (*err).Error()) } } @@ -666,7 +669,7 @@ func (og *operationGenerator) checkForFailedMount(volumeToMount VolumeToMount, m if volumetypes.IsFilesystemMismatchError(mountError) { simpleMsg, _ := volumeToMount.GenerateMsg("MountVolume failed", mountError.Error()) - og.recorder.Eventf(pv, v1.EventTypeWarning, kevents.FailedMountOnFilesystemMismatch, simpleMsg) + og.recorder.Eventf(pv, v1.EventTypeWarning, kevents.FailedMountOnFilesystemMismatch, "%s", simpleMsg) } } @@ -939,7 +942,7 @@ func (og *operationGenerator) GenerateMapVolumeFunc( affinityErr := checkNodeAffinity(og, volumeToMount) if affinityErr != nil { eventErr, detailedErr := volumeToMount.GenerateError("MapVolume.NodeAffinity check failed", affinityErr) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, eventErr.Error()) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, "%s", eventErr.Error()) return volumetypes.GeneratedOperations{}, detailedErr } blockVolumeMapper, newMapperErr := blockVolumePlugin.NewBlockVolumeMapper( @@ -947,7 +950,7 @@ func (og *operationGenerator) GenerateMapVolumeFunc( volumeToMount.Pod) if newMapperErr != nil { eventErr, detailedErr := volumeToMount.GenerateError("MapVolume.NewBlockVolumeMapper initialization failed", newMapperErr) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMapVolume, eventErr.Error()) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMapVolume, "%s", eventErr.Error()) return volumetypes.GeneratedOperations{}, detailedErr } @@ -1102,13 +1105,13 @@ func (og *operationGenerator) GenerateMapVolumeFunc( // Device mapping for global map path succeeded simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MapVolume.MapPodDevice succeeded", fmt.Sprintf("globalMapPath %q", globalMapPath)) verbosity := klog.Level(4) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.SuccessfulMountVolume, simpleMsg) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.SuccessfulMountVolume, "%s", simpleMsg) klog.V(verbosity).InfoS(detailedMsg, "pod", klog.KObj(volumeToMount.Pod)) // Device mapping for pod device map path succeeded simpleMsg, detailedMsg = volumeToMount.GenerateMsg("MapVolume.MapPodDevice succeeded", fmt.Sprintf("volumeMapPath %q", volumeMapPath)) verbosity = klog.Level(1) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.SuccessfulMountVolume, simpleMsg) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.SuccessfulMountVolume, "%s", simpleMsg) klog.V(verbosity).InfoS(detailedMsg, "pod", klog.KObj(volumeToMount.Pod)) resizeOptions := volume.NodeResizeOptions{ @@ -1142,7 +1145,7 @@ func (og *operationGenerator) GenerateMapVolumeFunc( eventRecorderFunc := func(err *error) { if *err != nil { - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMapVolume, (*err).Error()) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMapVolume, "%s", (*err).Error()) } } @@ -1499,12 +1502,10 @@ func (og *operationGenerator) verifyVolumeIsSafeToDetach( return volumeToDetach.GenerateErrorDetailed("DetachVolume failed fetching node from API server", fetchErr) } - for _, inUseVolume := range node.Status.VolumesInUse { - if inUseVolume == volumeToDetach.VolumeName { - return volumeToDetach.GenerateErrorDetailed( - "DetachVolume failed", - fmt.Errorf("volume is still in use by node, according to Node status")) - } + if slices.Contains(node.Status.VolumesInUse, volumeToDetach.VolumeName) { + return volumeToDetach.GenerateErrorDetailed( + "DetachVolume failed", + fmt.Errorf("volume is still in use by node, according to Node status")) } // Volume is not marked as in use by node @@ -1570,7 +1571,7 @@ func (og *operationGenerator) GenerateExpandVolumeFunc( return volumetypes.NewOperationContext(detailedErr, detailedErr, migrated) } successMsg := fmt.Sprintf("ExpandVolume succeeded for volume %s", util.GetPersistentVolumeClaimQualifiedName(pvc)) - og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.VolumeResizeSuccess, successMsg) + og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.VolumeResizeSuccess, "%s", successMsg) } else { _, err := util.MarkForFSResize(pvc, og.kubeClient) if err != nil { @@ -1592,7 +1593,7 @@ func (og *operationGenerator) GenerateExpandVolumeFunc( eventRecorderFunc := func(err *error) { if *err != nil { - og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.VolumeResizeFailed, (*err).Error()) + og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.VolumeResizeFailed, "%s", (*err).Error()) } } @@ -1637,7 +1638,7 @@ func (og *operationGenerator) GenerateExpandAndRecoverVolumeFunc( eventRecorderFunc := func(err *error) { if *err != nil { - og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.VolumeResizeFailed, (*err).Error()) + og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.VolumeResizeFailed, "%s", (*err).Error()) } } @@ -1779,7 +1780,7 @@ func (og *operationGenerator) expandAndRecoverFunction(resizeOpts inTreeResizeOp } resizeResponse.pvc = pvc successMsg := fmt.Sprintf("ExpandVolume succeeded for volume %s", util.GetPersistentVolumeClaimQualifiedName(pvc)) - og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.VolumeResizeSuccess, successMsg) + og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.VolumeResizeSuccess, "%s", successMsg) } else { pvc, err = og.markForPendingNodeExpansion(pvc, pv) resizeResponse.pvc = pvc @@ -1911,7 +1912,7 @@ func (og *operationGenerator) GenerateExpandInUseVolumeFunc( eventRecorderFunc := func(err *error) { if *err != nil { - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.VolumeResizeFailed, (*err).Error()) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.VolumeResizeFailed, "%s", (*err).Error()) } } @@ -1962,8 +1963,8 @@ func (og *operationGenerator) expandVolumeDuringMount(volumeToMount VolumeToMoun if volumeToMount.VolumeSpec.ReadOnly { simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MountVolume.NodeExpandVolume failed", "requested read-only file system") klog.Warning(detailedMsg) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FileSystemResizeFailed, simpleMsg) - og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.FileSystemResizeFailed, simpleMsg) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FileSystemResizeFailed, "%s", simpleMsg) + og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.FileSystemResizeFailed, "%s", simpleMsg) return true, nil } @@ -2032,8 +2033,8 @@ func (og *operationGenerator) nodeExpandVolume( if volumeToMount.VolumeSpec.ReadOnly { simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MountVolume.NodeExpandVolume failed", "requested read-only file system") klog.Warning(detailedMsg) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FileSystemResizeFailed, simpleMsg) - og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.FileSystemResizeFailed, simpleMsg) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FileSystemResizeFailed, "%s", simpleMsg) + og.recorder.Eventf(pvc, v1.EventTypeWarning, kevents.FileSystemResizeFailed, "%s", simpleMsg) return true, *currentSize, nil } resizeOp := nodeResizeOperationOpts{ @@ -2130,8 +2131,8 @@ func (og *operationGenerator) legacyCallNodeExpandOnPlugin(resizeOp nodeResizeOp } simpleMsg, detailedMsg := volumeToMount.GenerateMsg("MountVolume.NodeExpandVolume succeeded", nodeName) - og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) - og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, simpleMsg) + og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, "%s", simpleMsg) + og.recorder.Eventf(pvc, v1.EventTypeNormal, kevents.FileSystemResizeSuccess, "%s", simpleMsg) klog.InfoS(detailedMsg, "pod", klog.KObj(volumeToMount.Pod)) // if PVC already has new size, there is no need to update it. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go index f1958cd605..0ed994d126 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go index 1771bc16b8..b294ffdfd6 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go index 14b52a365f..06ff952d99 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/subpath/subpath_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go index 29cc749235..f9c07f8c67 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go @@ -22,6 +22,7 @@ import ( "os" "path/filepath" "reflect" + "slices" "strings" "time" @@ -220,12 +221,7 @@ func JoinMountOptions(userOptions []string, systemOptions []string) []string { // ContainsAccessMode returns whether the requested mode is contained by modes func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool { - for _, m := range modes { - if m == mode { - return true - } - } - return false + return slices.Contains(modes, mode) } // ContainsAllAccessModes returns whether all of the requested modes are contained by modes diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go index 541d0b65d3..b1256a2152 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_unsupported.go index 66fb2fe1f4..ec78ef8da1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/validation/pv_validation.go b/vendor/k8s.io/kubernetes/pkg/volume/validation/pv_validation.go index 23fa51fdac..8c0391cc49 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/validation/pv_validation.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/validation/pv_validation.go @@ -19,6 +19,7 @@ package validation import ( "errors" "path/filepath" + "slices" "strings" "k8s.io/apimachinery/pkg/util/validation/field" @@ -61,10 +62,8 @@ func checkMountOption(pv *api.PersistentVolume) field.ErrorList { // ValidatePathNoBacksteps will make sure the targetPath does not have any element which is ".." func ValidatePathNoBacksteps(targetPath string) error { parts := strings.Split(filepath.ToSlash(targetPath), "/") - for _, item := range parts { - if item == ".." { - return errors.New("must not contain '..'") - } + if slices.Contains(parts, "..") { + return errors.New("must not contain '..'") } return nil diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume.go b/vendor/k8s.io/kubernetes/pkg/volume/volume.go index 4a6fc55e29..4a166f000f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume.go @@ -138,6 +138,17 @@ type MounterArgs struct { // Optional interface that will be used to change the ownership of the volume, if specified. // mainly used by unit tests VolumeOwnershipApplicator VolumeOwnershipChanger + ReconstructedVolume bool + + // IsRemount is true when SetUp is being invoked on a volume that the + // reconciler considers already mounted to the pod, e.g. a periodic + // republish triggered by CSIDriver.spec.requiresRepublish=true. Volume + // plugins should use this to avoid destroying state (e.g. mount + // directories, volume metadata files) that the pod is currently + // observing through an existing bind mount, since teardown on a + // failed remount cannot be repaired by a subsequent successful + // remount and would leave the pod with stale contents. + IsRemount bool } type VolumeOwnershipChanger interface { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go index c3caf8c66c..48e6a8f385 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go index ef46dac618..e73bb4a14a 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2016 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/pkg/windows/service/service.go b/vendor/k8s.io/kubernetes/pkg/windows/service/service.go index 15e004a1fa..818a736a0b 100644 --- a/vendor/k8s.io/kubernetes/pkg/windows/service/service.go +++ b/vendor/k8s.io/kubernetes/pkg/windows/service/service.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2018 The Kubernetes Authors. diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/container_probe.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/container_probe.go index 60053a4986..7ec421a486 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/container_probe.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/container_probe.go @@ -261,7 +261,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod liveness probe, container exec timeout, restart Description: A Pod is created with liveness probe with a Exec action on the Pod. If the liveness probe call does not return within the timeout specified, liveness probe MUST restart the Pod. */ - ginkgo.It("should be restarted with a failing exec liveness probe that took longer than the timeout", func(ctx context.Context) { + f.It("should be restarted with a failing exec liveness probe that took longer than the timeout", f.WithNodeConformance(), func(ctx context.Context) { cmd := []string{"/bin/sh", "-c", "sleep 600"} livenessProbe := &v1.Probe{ ProbeHandler: execHandler([]string{"/bin/sh", "-c", "sleep 10 & exit 1"}), @@ -278,7 +278,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod http liveness probe, redirected to a local address Description: A Pod is created with liveness probe on http endpoint /redirect?loc=healthz. The http handler on the /redirect will redirect to the /healthz endpoint, which will return a http error after 10 seconds since the Pod is started. This MUST result in liveness check failure. The Pod MUST now be killed and restarted incrementing restart count to 1. */ - ginkgo.It("should be restarted with a local redirect http liveness probe", func(ctx context.Context) { + f.It("should be restarted with a local redirect http liveness probe", f.WithNodeConformance(), func(ctx context.Context) { livenessProbe := &v1.Probe{ ProbeHandler: httpGetHandler("/redirect?loc="+url.QueryEscape("/healthz"), 8080), InitialDelaySeconds: 15, @@ -293,7 +293,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod http liveness probe, redirected to a non-local address Description: A Pod is created with liveness probe on http endpoint /redirect with a redirect to http://0.0.0.0/. The http handler on the /redirect should not follow the redirect, but instead treat it as a success and generate an event. */ - ginkgo.It("should *not* be restarted with a non-local redirect http liveness probe", func(ctx context.Context) { + f.It("should *not* be restarted with a non-local redirect http liveness probe", f.WithNodeConformance(), func(ctx context.Context) { livenessProbe := &v1.Probe{ ProbeHandler: httpGetHandler("/redirect?loc="+url.QueryEscape("http://0.0.0.0/"), 8080), InitialDelaySeconds: 15, @@ -317,7 +317,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod startup probe restart Description: A Pod is created with a failing startup probe. The Pod MUST be killed and restarted incrementing restart count to 1, even if liveness would succeed. */ - ginkgo.It("should be restarted startup probe fails", func(ctx context.Context) { + f.It("should be restarted startup probe fails", f.WithNodeConformance(), func(ctx context.Context) { cmd := []string{"/bin/sh", "-c", "sleep 600"} livenessProbe := &v1.Probe{ ProbeHandler: v1.ProbeHandler{ @@ -346,7 +346,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod liveness probe delayed (long) by startup probe Description: A Pod is created with failing liveness and startup probes. Liveness probe MUST NOT fail until startup probe expires. */ - ginkgo.It("should *not* be restarted by liveness probe because startup probe delays it", func(ctx context.Context) { + f.It("should *not* be restarted by liveness probe because startup probe delays it", f.WithNodeConformance(), func(ctx context.Context) { cmd := []string{"/bin/sh", "-c", "sleep 600"} livenessProbe := &v1.Probe{ ProbeHandler: v1.ProbeHandler{ @@ -375,7 +375,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod liveness probe fails after startup success Description: A Pod is created with failing liveness probe and delayed startup probe that uses 'exec' command to cat /temp/health file. The Container is started by creating /tmp/startup after 10 seconds, triggering liveness probe to fail. The Pod MUST now be killed and restarted incrementing restart count to 1. */ - ginkgo.It("should be restarted by liveness probe after startup probe enables it", func(ctx context.Context) { + f.It("should be restarted by liveness probe after startup probe enables it", f.WithNodeConformance(), func(ctx context.Context) { cmd := []string{"/bin/sh", "-c", "sleep 10; echo ok >/tmp/startup; sleep 600"} livenessProbe := &v1.Probe{ ProbeHandler: v1.ProbeHandler{ @@ -404,7 +404,7 @@ var _ = SIGDescribe("Probing container", func() { Testname: Pod readiness probe, delayed by startup probe Description: A Pod is created with startup and readiness probes. The Container is started by creating /tmp/startup after 45 seconds, delaying the ready state by this amount of time. This is similar to the "Pod readiness probe, with initial delay" test. */ - ginkgo.It("should be ready immediately after startupProbe succeeds", func(ctx context.Context) { + f.It("should be ready immediately after startupProbe succeeds", f.WithNodeConformance(), func(ctx context.Context) { // Probe workers sleep at Kubelet start for a random time which is at most PeriodSeconds // this test requires both readiness and startup workers running before updating statuses // to avoid flakes, ensure sleep before startup (32s) > readinessProbe.PeriodSeconds @@ -562,7 +562,7 @@ var _ = SIGDescribe("Probing container", func() { RunLivenessTest(ctx, f, pod, 1, defaultObservationTimeout) }) - ginkgo.It("should mark readiness on pods to false while pod is in progress of terminating when a pod has a readiness probe", func(ctx context.Context) { + f.It("should mark readiness on pods to false while pod is in progress of terminating when a pod has a readiness probe", f.WithNodeConformance(), func(ctx context.Context) { podName := "probe-test-" + string(uuid.NewUUID()) podClient := e2epod.NewPodClient(f) terminationGracePeriod := int64(30) @@ -628,7 +628,7 @@ done framework.ExpectNoError(err) }) - ginkgo.It("should mark readiness on pods to false and disable liveness probes while pod is in progress of terminating", func(ctx context.Context) { + f.It("should mark readiness on pods to false and disable liveness probes while pod is in progress of terminating", f.WithNodeConformance(), func(ctx context.Context) { podName := "probe-test-" + string(uuid.NewUUID()) podClient := e2epod.NewPodClient(f) terminationGracePeriod := int64(30) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/container_restart_policy.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/container_restart_policy.go new file mode 100644 index 0000000000..ff1c955857 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/container_restart_policy.go @@ -0,0 +1,555 @@ +/* +Copyright 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 node + +import ( + "context" + "fmt" + "time" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/test/e2e/framework" + e2epod "k8s.io/kubernetes/test/e2e/framework/pod" + imageutils "k8s.io/kubernetes/test/utils/image" + admissionapi "k8s.io/pod-security-admission/api" + + "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" +) + +var _ = SIGDescribe("Pod Extended (container restart policy)", framework.WithFeatureGate(features.ContainerRestartRules), func() { + f := framework.NewDefaultFramework("pods") + f.NamespacePodSecurityLevel = admissionapi.LevelBaseline + + ginkgo.Describe("Container Restart Rules", func() { + var ( + containerRestartPolicyAlways = v1.ContainerRestartPolicyAlways + containerRestartPolicyNever = v1.ContainerRestartPolicyNever + ) + + ginkgo.It("should restart container on rule match", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + Containers: []v1.Container{ + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 42"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: []v1.ContainerRestartRule{ + { + Action: v1.ContainerRestartRuleActionRestart, + ExitCodes: &v1.ContainerRestartRuleOnExitCodes{ + Operator: v1.ContainerRestartRuleOnExitCodesOpIn, + Values: []int32{42}, + }, + }, + }, + }, + }, + }, + } + + createAndValidateRestartableContainer(ctx, f, pod, podName, "main-container") + }) + + ginkgo.It("should not restart container on rule mismatch, container restart policy Never", func(ctx context.Context) { + podName := "restart-rules-no-restart-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + Containers: []v1.Container{ + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 1"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: []v1.ContainerRestartRule{ + { + Action: v1.ContainerRestartRuleActionRestart, + ExitCodes: &v1.ContainerRestartRuleOnExitCodes{ + Operator: v1.ContainerRestartRuleOnExitCodesOpIn, + Values: []int32{42}, + }, + }, + }, + }, + }, + }, + } + + createAndValidateNonRestartableContainer(ctx, f, pod, podName, "main-container") + }) + + ginkgo.It("should restart container on container-level restart policy Never", func(ctx context.Context) { + podName := "restart-rules-no-restart-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyAlways, + Containers: []v1.Container{ + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 1"}, + RestartPolicy: &containerRestartPolicyNever, + }, + }, + }, + } + + createAndValidateNonRestartableContainer(ctx, f, pod, podName, "main-container") + }) + + ginkgo.It("should restart container on container-level restart policy Always", func(ctx context.Context) { + podName := "restart-rules-no-restart-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + Containers: []v1.Container{ + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 1"}, + RestartPolicy: &containerRestartPolicyAlways, + }, + }, + }, + } + + createAndValidateRestartableContainer(ctx, f, pod, podName, "main-container") + }) + + ginkgo.It("should restart container on pod-level restart policy Always when no container-level restart policy", func(ctx context.Context) { + podName := "restart-rules-no-match-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyAlways, + Containers: []v1.Container{ + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 1"}, + }, + }, + }, + } + + createAndValidateRestartableContainer(ctx, f, pod, podName, "main-container") + }) + }) +}) + +var _ = SIGDescribe("Pod Extended (RestartAllContainers)", framework.WithFeatureGate(features.ContainerRestartRules), framework.WithFeatureGate(features.RestartAllContainersOnContainerExits), func() { + f := framework.NewDefaultFramework("pods") + f.NamespacePodSecurityLevel = admissionapi.LevelBaseline + + ginkgo.Describe("RestartAllContainers", func() { + var ( + containerRestartPolicyAlways = v1.ContainerRestartPolicyAlways + containerRestartPolicyNever = v1.ContainerRestartPolicyNever + ) + + restartAllContainersRules := []v1.ContainerRestartRule{ + { + Action: v1.ContainerRestartRuleActionRestartAllContainers, + ExitCodes: &v1.ContainerRestartRuleOnExitCodes{ + Operator: v1.ContainerRestartRuleOnExitCodesOpIn, + Values: []int32{42}, + }, + }, + } + + ginkgo.It("should restart all containers on regular container exit", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + InitContainers: []v1.Container{ + { + Name: "init", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 0"}, + }, + { + Name: "sidecar", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + RestartPolicy: &containerRestartPolicyAlways, + }, + }, + Containers: []v1.Container{ + { + Name: "source-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "if [ -f /mnt/restart-complete ]; then sleep 10000; else touch /mnt/restart-complete; exit 42; fi"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: restartAllContainersRules, + VolumeMounts: []v1.VolumeMount{ + { + Name: "workdir", + MountPath: "/mnt", + }, + }, + }, + { + Name: "regular", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + }, + }, + Volumes: []v1.Volume{ + { + Name: "workdir", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + // All containers should be restarted once + podClient := e2epod.NewPodClient(f) + podClient.Create(ctx, pod) + ginkgo.DeferCleanup(func(ctx context.Context) error { + ginkgo.By("deleting the pod") + return podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }) + validateAllContainersRestarted(ctx, f, pod, []string{"init", "sidecar", "source-container", "regular"}) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "source-container", 3*time.Minute)) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "regular", 3*time.Minute)) + }) + + ginkgo.It("should restart all containers on sidecar container exit", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + InitContainers: []v1.Container{ + { + Name: "init", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 0"}, + }, + { + Name: "sidecar", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + RestartPolicy: &containerRestartPolicyAlways, + }, + { + Name: "source-sidecar", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "if [ -f /mnt/init-complete ]; then sleep 10000; else touch /mnt/init-complete; sleep 30; exit 42; fi"}, + RestartPolicy: &containerRestartPolicyAlways, + RestartPolicyRules: restartAllContainersRules, + VolumeMounts: []v1.VolumeMount{ + { + Name: "workdir", + MountPath: "/mnt", + }, + }, + }, + }, + Containers: []v1.Container{ + { + Name: "regular", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + }, + }, + Volumes: []v1.Volume{ + { + Name: "workdir", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + // All containers should be restarted once + podClient := e2epod.NewPodClient(f) + podClient.Create(ctx, pod) + ginkgo.DeferCleanup(func(ctx context.Context) error { + ginkgo.By("deleting the pod") + return podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }) + validateAllContainersRestarted(ctx, f, pod, []string{"init", "sidecar", "source-sidecar", "regular"}) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "regular", 3*time.Minute)) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "source-sidecar", 3*time.Minute)) + }) + + ginkgo.It("should restart init and sidecar containers on init container exit", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + InitContainers: []v1.Container{ + { + Name: "sidecar", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + RestartPolicy: &containerRestartPolicyAlways, + }, + { + Name: "init", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "exit 0"}, + }, + { + Name: "source-init", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "if [ -f /mnt/init-complete ]; then exit 0; else touch /mnt/init-complete; exit 42; fi"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: restartAllContainersRules, + VolumeMounts: []v1.VolumeMount{ + { + Name: "workdir", + MountPath: "/mnt", + }, + }, + }, + }, + Containers: []v1.Container{ + { + Name: "regular", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + }, + }, + Volumes: []v1.Volume{ + { + Name: "workdir", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + // All containers should be restarted once + podClient := e2epod.NewPodClient(f) + podClient.Create(ctx, pod) + ginkgo.DeferCleanup(func(ctx context.Context) error { + ginkgo.By("deleting the pod") + return podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }) + validateAllContainersRestarted(ctx, f, pod, []string{"init", "sidecar", "source-init"}) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "regular", 3*time.Minute)) + }) + + ginkgo.It("should allow multiple RestartAllContainers actions and not introduce a loop", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + Containers: []v1.Container{ + { + Name: "source-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "if [ -f /mnt/restart-complete ]; then sleep 10000; else touch /mnt/restart-complete; sleep 10; exit 42; fi"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: restartAllContainersRules, + VolumeMounts: []v1.VolumeMount{ + { + Name: "workdir", + MountPath: "/mnt", + }, + }, + }, + { + Name: "regular", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + RestartPolicy: &containerRestartPolicyNever, + RestartPolicyRules: restartAllContainersRules, + }, + }, + Volumes: []v1.Volume{ + { + Name: "workdir", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + // All containers should be restarted once + podClient := e2epod.NewPodClient(f) + podClient.Create(ctx, pod) + ginkgo.DeferCleanup(func(ctx context.Context) error { + ginkgo.By("deleting the pod") + return podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }) + validateAllContainersRestarted(ctx, f, pod, []string{"source-container", "regular"}) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "source-container", 3*time.Minute)) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "regular", 3*time.Minute)) + }) + + ginkgo.It("should restart all containers on a previously restarted regular container exit", func(ctx context.Context) { + podName := "restart-rules-exit-code-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "source-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "if [ -f /mnt/restart-complete ]; then sleep 10000; elif [ -f /mnt/restart-1 ]; then touch /mnt/restart-complete; exit 42; else touch /mnt/restart-1; exit 1; fi"}, + RestartPolicy: &containerRestartPolicyAlways, + RestartPolicyRules: restartAllContainersRules, + VolumeMounts: []v1.VolumeMount{ + { + Name: "workdir", + MountPath: "/mnt", + }, + }, + }, + { + Name: "regular", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "sleep 10000"}, + }, + }, + Volumes: []v1.Volume{ + { + Name: "workdir", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + // All containers should be restarted once + podClient := e2epod.NewPodClient(f) + podClient.Create(ctx, pod) + ginkgo.DeferCleanup(func(ctx context.Context) error { + ginkgo.By("deleting the pod") + return podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }) + validateAllContainersRestarted(ctx, f, pod, []string{"source-container", "regular"}) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "source-container", 3*time.Minute)) + framework.ExpectNoError(e2epod.WaitForContainerRunning(ctx, f.ClientSet, f.Namespace.Name, podName, "regular", 3*time.Minute)) + }) + }) +}) + +func validateAllContainersRestarted(ctx context.Context, f *framework.Framework, pod *v1.Pod, containers []string) { + ginkgo.By("Waiting for all containers to restart") + err := e2epod.WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, pod.Name, "all containers restarted", 3*time.Minute, func(pod *v1.Pod) (bool, error) { + restartedCount := 0 + for _, cName := range containers { + var cStatus v1.ContainerStatus + for _, status := range pod.Status.ContainerStatuses { + if status.Name == cName { + cStatus = status + } + } + for _, status := range pod.Status.InitContainerStatuses { + if status.Name == cName { + cStatus = status + } + } + if cStatus.RestartCount > 0 { + restartedCount++ + } else { + framework.Logf("container %s did not restart", cName) + } + if cStatus.LastTerminationState.Terminated == nil { + return false, fmt.Errorf("container %s do not have lastTerminationState", cName) + } + } + framework.Logf("%d out of %d containers restarted", restartedCount, len(containers)) + return restartedCount == len(containers), nil + }) + framework.ExpectNoError(err, "failed to see all containers restart") +} + +func createAndValidateRestartableContainer(ctx context.Context, f *framework.Framework, pod *v1.Pod, podName, containerName string) { + ginkgo.By("Creating the pod") + e2epod.NewPodClient(f).Create(ctx, pod) + + ginkgo.By("Waiting for the container to restart") + err := e2epod.WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, podName, "container restarted", 10*time.Minute, func(pod *v1.Pod) (bool, error) { + for _, status := range pod.Status.ContainerStatuses { + if status.Name == containerName && status.RestartCount > 0 { + return true, nil + } + } + return false, nil + }) + framework.ExpectNoError(err, "failed to see container restart") +} + +func createAndValidateNonRestartableContainer(ctx context.Context, f *framework.Framework, pod *v1.Pod, podName, containerName string) { + ginkgo.By("Creating the pod") + e2epod.NewPodClient(f).Create(ctx, pod) + + ginkgo.By("Waiting for the pod to terminate") + err := e2epod.WaitTimeoutForPodNoLongerRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name, 10*time.Minute) + framework.ExpectNoError(err, "failed to wait for pod terminate") + + ginkgo.By("Checking container restart count") + p, err := e2epod.NewPodClient(f).Get(ctx, podName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get pod") + for _, status := range p.Status.ContainerStatuses { + if status.Name == containerName { + gomega.Expect(status.RestartCount).To(gomega.BeZero()) + } + } +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/downwardapi.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/downwardapi.go index b6cc1556b9..51dcda79da 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/downwardapi.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/downwardapi.go @@ -139,7 +139,7 @@ var _ = SIGDescribe("Downward API", func() { testDownwardAPI(ctx, f, podName, env, expectations) }) - ginkgo.It("should provide host IP and pod IP as an env var if pod uses host network [LinuxOnly]", func(ctx context.Context) { + f.It("should provide host IP and pod IP as an env var if pod uses host network [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { podName := "downward-api-" + string(uuid.NewUUID()) env := []v1.EnvVar{ { @@ -163,7 +163,7 @@ var _ = SIGDescribe("Downward API", func() { } expectations := []string{ - fmt.Sprintf("OK"), + "OK", } pod := &v1.Pod{ diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/file_key.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/file_key.go index 5aed89c53a..e319b5ecc6 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/file_key.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/file_key.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/test/e2e/feature" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output" @@ -38,7 +39,7 @@ import ( "github.com/onsi/gomega" ) -var _ = SIGDescribe("FileKeyRef", framework.WithFeatureGate(features.EnvFiles), func() { +var _ = SIGDescribe("FileKeyRef", feature.EnvFiles, framework.WithFeatureGate(features.EnvFiles), func() { f := framework.NewDefaultFramework("filekeyref") f.NamespacePodSecurityLevel = admissionapi.LevelBaseline diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/cgroups/cgroups.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/cgroups/cgroups.go index 001127afe3..00573c9f92 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/cgroups/cgroups.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/cgroups/cgroups.go @@ -216,7 +216,7 @@ func getExpectedMemLimitString(memLimit *resource.Quantity, podOnCgroupv2 bool) return expectedMemLimitString } -func verifyContainerCPUWeight(f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func verifyContainerCPUWeight(ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { cpuWeightCgPath := getCgroupCPURequestPath(cgroupFsPath, podOnCgroupv2) cpuLim := expectedResources.Limits.Cpu() if cpuLim.IsZero() && pod.Spec.Resources != nil { @@ -232,26 +232,26 @@ func verifyContainerCPUWeight(f *framework.Framework, pod *v1.Pod, containerName } expectedCPUShares := getExpectedCPUShares(cpuReq, cpuLim, podOnCgroupv2) - if err := VerifyCgroupValue(f, pod, containerName, cpuWeightCgPath, expectedCPUShares...); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, containerName, cpuWeightCgPath, expectedCPUShares...); err != nil { return fmt.Errorf("failed to verify cpu request cgroup value: %w", err) } return nil } -func VerifyContainerCPULimit(f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func VerifyContainerCPULimit(ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { cpuLimCgPath := getCgroupCPULimitPath(cgroupFsPath, podOnCgroupv2) cpuLim := expectedResources.Limits.Cpu() if cpuLim.IsZero() && pod.Spec.Resources != nil { cpuLim = pod.Spec.Resources.Limits.Cpu() } expectedCPULimits := getCPULimitCgroupExpectations(cpuLim, podOnCgroupv2) - if err := VerifyCgroupValue(f, pod, containerName, cpuLimCgPath, expectedCPULimits...); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, containerName, cpuLimCgPath, expectedCPULimits...); err != nil { return fmt.Errorf("failed to verify cpu limit cgroup value: %w", err) } return nil } -func VerifyContainerMemoryLimit(f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func VerifyContainerMemoryLimit(ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { memLimCgPath := getCgroupMemLimitPath(cgroupFsPath, podOnCgroupv2) memLim := expectedResources.Limits.Memory() if memLim.IsZero() && pod.Spec.Resources != nil { @@ -261,21 +261,21 @@ func VerifyContainerMemoryLimit(f *framework.Framework, pod *v1.Pod, containerNa if expectedMemLim == "0" { return nil } - if err := VerifyCgroupValue(f, pod, containerName, memLimCgPath, expectedMemLim); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, containerName, memLimCgPath, expectedMemLim); err != nil { return fmt.Errorf("failed to verify memory limit cgroup value: %w", err) } return nil } -func VerifyContainerCgroupValues(f *framework.Framework, pod *v1.Pod, tc *v1.Container, podOnCgroupv2 bool) error { +func VerifyContainerCgroupValues(ctx context.Context, f *framework.Framework, pod *v1.Pod, tc *v1.Container, podOnCgroupv2 bool) error { var errs []error - errs = append(errs, VerifyContainerMemoryLimit(f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) - errs = append(errs, VerifyContainerCPULimit(f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) - errs = append(errs, verifyContainerCPUWeight(f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) + errs = append(errs, VerifyContainerMemoryLimit(ctx, f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) + errs = append(errs, VerifyContainerCPULimit(ctx, f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) + errs = append(errs, verifyContainerCPUWeight(ctx, f, pod, tc.Name, &tc.Resources, podOnCgroupv2)) return utilerrors.NewAggregate(errs) } -func verifyPodCPUWeight(f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func verifyPodCPUWeight(ctx context.Context, f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { podCgPath, err := getPodCgroupPath(f, pod, podOnCgroupv2, "cpu") if err != nil { if podCgPath, err = getPodCgroupPath(f, pod, podOnCgroupv2, "cpu,cpuacct"); err != nil { @@ -290,13 +290,13 @@ func verifyPodCPUWeight(f *framework.Framework, pod *v1.Pod, expectedResources * cpuWeightCgPath = fmt.Sprintf("%s/%s", podCgPath, cgroupCPUSharesFile) } expectedCPUShares := getExpectedCPUShares(expectedResources.Requests.Cpu(), expectedResources.Limits.Cpu(), podOnCgroupv2) - if err := VerifyCgroupValue(f, pod, pod.Spec.Containers[0].Name, cpuWeightCgPath, expectedCPUShares...); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, pod.Spec.Containers[0].Name, cpuWeightCgPath, expectedCPUShares...); err != nil { return fmt.Errorf("pod cgroup cpu weight verification failed: %w", err) } return nil } -func verifyPodCPULimit(f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func verifyPodCPULimit(ctx context.Context, f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { podCgPath, err := getPodCgroupPath(f, pod, podOnCgroupv2, "cpu") if err != nil { if podCgPath, err = getPodCgroupPath(f, pod, podOnCgroupv2, "cpu,cpuacct"); err != nil { @@ -311,13 +311,13 @@ func verifyPodCPULimit(f *framework.Framework, pod *v1.Pod, expectedResources *v cpuLimCgPath = fmt.Sprintf("%s/%s", podCgPath, cgroupCPUQuotaFile) } expectedCPULimits := getCPULimitCgroupExpectations(expectedResources.Limits.Cpu(), podOnCgroupv2) - if err := VerifyCgroupValue(f, pod, pod.Spec.Containers[0].Name, cpuLimCgPath, expectedCPULimits...); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, pod.Spec.Containers[0].Name, cpuLimCgPath, expectedCPULimits...); err != nil { return fmt.Errorf("pod cgroup cpu limit verification failed: %w", err) } return nil } -func verifyPodMemoryLimit(f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { +func verifyPodMemoryLimit(ctx context.Context, f *framework.Framework, pod *v1.Pod, expectedResources *v1.ResourceRequirements, podOnCgroupv2 bool) error { podCgPath, err := getPodCgroupPath(f, pod, podOnCgroupv2, "memory") if err != nil { return err @@ -334,7 +334,7 @@ func verifyPodMemoryLimit(f *framework.Framework, pod *v1.Pod, expectedResources return nil } - if err := VerifyCgroupValue(f, pod, pod.Spec.Containers[0].Name, memLimCgPath, expectedMemLim); err != nil { + if err := VerifyCgroupValue(ctx, f, pod, pod.Spec.Containers[0].Name, memLimCgPath, expectedMemLim); err != nil { return fmt.Errorf("pod cgroup memory limit verification failed: %w", err) } return nil @@ -344,14 +344,14 @@ func verifyPodMemoryLimit(f *framework.Framework, pod *v1.Pod, expectedResources func VerifyPodCgroups(ctx context.Context, f *framework.Framework, pod *v1.Pod, info *ContainerResources) error { ginkgo.GinkgoHelper() - onCgroupV2 := IsPodOnCgroupv2Node(f, pod) + onCgroupV2 := IsPodOnCgroupv2Node(f, pod.Name, pod.Spec.Containers[0].Name) // Verify cgroup values expectedResources := info.ResourceRequirements() var errs []error - errs = append(errs, verifyPodCPUWeight(f, pod, expectedResources, onCgroupV2)) - errs = append(errs, verifyPodCPULimit(f, pod, expectedResources, onCgroupV2)) - errs = append(errs, verifyPodMemoryLimit(f, pod, expectedResources, onCgroupV2)) + errs = append(errs, verifyPodCPUWeight(ctx, f, pod, expectedResources, onCgroupV2)) + errs = append(errs, verifyPodCPULimit(ctx, f, pod, expectedResources, onCgroupV2)) + errs = append(errs, verifyPodMemoryLimit(ctx, f, pod, expectedResources, onCgroupV2)) return utilerrors.NewAggregate(errs) } @@ -374,32 +374,22 @@ func BuildPodResourceInfo(podCPURequestMilliValue, podCPULimitMilliValue, podMem // the specified container of the pod. It execs into the container to retrieve the // cgroup value, and ensures that the retrieved cgroup value is equivalent to at // least one of the values in expectedCgValues. -func VerifyCgroupValue(f *framework.Framework, pod *v1.Pod, cName, cgPath string, expectedCgValues ...string) error { +func VerifyCgroupValue(ctx context.Context, f *framework.Framework, pod *v1.Pod, cName, cgPath string, expectedCgValues ...string) error { cmd := fmt.Sprintf("head -n 1 %s", cgPath) framework.Logf("Namespace %s Pod %s Container %s - looking for one of the expected cgroup values %s in path %s", pod.Namespace, pod.Name, cName, expectedCgValues, cgPath) - const maxRetries = 3 - var cgValue string - var err error - for i := range maxRetries { - cgValue, _, err = e2epod.ExecCommandInContainerWithFullOutput(f, pod.Name, cName, "/bin/sh", "-c", cmd) - if err == nil { - cgValue = strings.Trim(cgValue, "\n") - break - } else { - framework.Logf("[Attempt %d of %d] Failed to read cgroup value %q for container %q: %v", i+1, maxRetries, cgPath, cName, err) + return framework.Gomega().Eventually(ctx, framework.HandleRetry(func(ctx context.Context) (error, error) { + cgValue, _, err := e2epod.ExecCommandInContainerWithFullOutput(f, pod.Name, cName, "/bin/sh", "-c", cmd) + if err != nil { + return fmt.Errorf("failed to read cgroup value %q for container %q: %w", cgPath, cName, err), nil } - } - if err != nil { - return fmt.Errorf("failed to read cgroup value %q for container %q after %d attempts: %w", cgPath, cName, maxRetries, err) - } - - if err := framework.Gomega().Expect(cgValue).To(gomega.BeElementOf(expectedCgValues)); err != nil { - return fmt.Errorf("value of cgroup %q for container %q was %q; expected one of %q", cgPath, cName, cgValue, expectedCgValues) - } - - return nil + cgValue = strings.Trim(cgValue, "\n") + if err := framework.Gomega().Expect(cgValue).To(gomega.BeElementOf(expectedCgValues)); err != nil { + return nil, fmt.Errorf("value of cgroup %q for container %q was %q; expected one of %q: %w", cgPath, cName, cgValue, expectedCgValues, err) + } + return nil, nil + })).WithTimeout(framework.PollShortTimeout).Should(gomega.Succeed()) } // VerifyOomScoreAdjValue verifies that oom_score_adj for pid 1 (pidof init/systemd -> app) @@ -411,11 +401,11 @@ func VerifyOomScoreAdjValue(f *framework.Framework, pod *v1.Pod, cName, expected pod.Namespace, pod.Name, cName, expectedOomScoreAdj) oomScoreAdj, _, err := e2epod.ExecCommandInContainerWithFullOutput(f, pod.Name, cName, "/bin/sh", "-c", cmd) if err != nil { - return fmt.Errorf("failed to find expected value %s for container app process", expectedOomScoreAdj) + return fmt.Errorf("failed to find expected oom_score_adj value %s for container %s in pod %s", expectedOomScoreAdj, cName, pod.Name) } oomScoreAdj = strings.Trim(oomScoreAdj, "\n") if oomScoreAdj != expectedOomScoreAdj { - return fmt.Errorf("oom_score_adj value %s not equal to expected %s", oomScoreAdj, expectedOomScoreAdj) + return fmt.Errorf("oom_score_adj value %s not equal to expected %s for container %s in pod %s", oomScoreAdj, expectedOomScoreAdj, cName, pod.Name) } return nil } @@ -423,7 +413,7 @@ func VerifyOomScoreAdjValue(f *framework.Framework, pod *v1.Pod, cName, expected // IsPodOnCgroupv2Node checks whether the pod is running on cgroupv2 node. // TODO: Deduplicate this function with NPD cluster e2e test: // https://github.com/kubernetes/kubernetes/blob/2049360379bcc5d6467769cef112e6e492d3d2f0/test/e2e/node/node_problem_detector.go#L369 -func IsPodOnCgroupv2Node(f *framework.Framework, pod *v1.Pod) (result bool) { +func IsPodOnCgroupv2Node(f *framework.Framework, podName, containerName string) (result bool) { podOnCgroupv2NodeMutex.Lock() defer podOnCgroupv2NodeMutex.Unlock() if podOnCgroupv2Node != nil { @@ -434,7 +424,7 @@ func IsPodOnCgroupv2Node(f *framework.Framework, pod *v1.Pod) (result bool) { }() cmd := "mount -t cgroup2" - out, _, err := e2epod.ExecCommandInContainerWithFullOutput(f, pod.Name, pod.Spec.Containers[0].Name, "/bin/sh", "-c", cmd) + out, _, err := e2epod.ExecCommandInContainerWithFullOutput(f, podName, containerName, "/bin/sh", "-c", cmd) if err != nil { return false } diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/podresize/resize.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/podresize/resize.go index fc6c92452b..5065883f62 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/podresize/resize.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/framework/podresize/resize.go @@ -186,10 +186,10 @@ func VerifyPodStatusResources(gotPod *v1.Pod, wantInfo []ResizableContainerInfo) wantInitCtrs, wantCtrs := separateContainers(wantInfo) var errs []error - if err := verifyPodContainersStatusResources(gotPod.Status.InitContainerStatuses, wantInitCtrs); err != nil { + if err := VerifyPodContainersStatusResources(gotPod.Status.InitContainerStatuses, wantInitCtrs); err != nil { errs = append(errs, err) } - if err := verifyPodContainersStatusResources(gotPod.Status.ContainerStatuses, wantCtrs); err != nil { + if err := VerifyPodContainersStatusResources(gotPod.Status.ContainerStatuses, wantCtrs); err != nil { errs = append(errs, err) } @@ -208,7 +208,7 @@ func VerifyPodLevelStatusResources(gotPod *v1.Pod, wantPodResources *v1.Resource return utilerrors.NewAggregate(errs) } -func verifyPodContainersStatusResources(gotCtrStatuses []v1.ContainerStatus, wantCtrs []v1.Container) error { +func VerifyPodContainersStatusResources(gotCtrStatuses []v1.ContainerStatus, wantCtrs []v1.Container) error { ginkgo.GinkgoHelper() var errs []error @@ -295,32 +295,32 @@ func addResourceList(des, src v1.ResourceList) { func VerifyPodContainersCgroupValues(ctx context.Context, f *framework.Framework, pod *v1.Pod, tcInfo []ResizableContainerInfo) error { ginkgo.GinkgoHelper() - onCgroupv2 := cgroups.IsPodOnCgroupv2Node(f, pod) + onCgroupv2 := cgroups.IsPodOnCgroupv2Node(f, pod.Name, pod.Spec.Containers[0].Name) var errs []error for _, ci := range tcInfo { tc := makeResizableContainer(ci) - errs = append(errs, cgroups.VerifyContainerCgroupValues(f, pod, &tc, onCgroupv2)) + errs = append(errs, cgroups.VerifyContainerCgroupValues(ctx, f, pod, &tc, onCgroupv2)) } return utilerrors.NewAggregate(errs) } -func verifyPodRestarts(f *framework.Framework, pod *v1.Pod, wantInfo []ResizableContainerInfo) error { +func verifyPodRestarts(ctx context.Context, f *framework.Framework, pod *v1.Pod, wantInfo []ResizableContainerInfo) error { ginkgo.GinkgoHelper() initCtrStatuses, ctrStatuses := separateContainerStatuses(wantInfo) errs := []error{} - if err := verifyContainerRestarts(f, pod, pod.Status.InitContainerStatuses, initCtrStatuses); err != nil { + if err := verifyContainerRestarts(ctx, f, pod, pod.Status.InitContainerStatuses, initCtrStatuses); err != nil { errs = append(errs, err) } - if err := verifyContainerRestarts(f, pod, pod.Status.ContainerStatuses, ctrStatuses); err != nil { + if err := verifyContainerRestarts(ctx, f, pod, pod.Status.ContainerStatuses, ctrStatuses); err != nil { errs = append(errs, err) } return utilerrors.NewAggregate(errs) } -func verifyContainerRestarts(f *framework.Framework, pod *v1.Pod, gotStatuses []v1.ContainerStatus, wantStatuses []v1.ContainerStatus) error { +func verifyContainerRestarts(ctx context.Context, f *framework.Framework, pod *v1.Pod, gotStatuses []v1.ContainerStatus, wantStatuses []v1.ContainerStatus) error { ginkgo.GinkgoHelper() if len(gotStatuses) != len(wantStatuses) { @@ -333,7 +333,7 @@ func verifyContainerRestarts(f *framework.Framework, pod *v1.Pod, gotStatuses [] if gotStatus.RestartCount != wantStatuses[i].RestartCount { errs = append(errs, fmt.Errorf("unexpected number of restarts for container %s: got %d, want %d", gotStatus.Name, gotStatus.RestartCount, wantStatuses[i].RestartCount)) } else if gotStatus.RestartCount > 0 { - if err := verifyOomScoreAdj(f, pod, gotStatus.Name); err != nil { + if err := verifyOomScoreAdj(ctx, f, pod, gotStatus.Name); err != nil { errs = append(errs, err) } } @@ -341,7 +341,7 @@ func verifyContainerRestarts(f *framework.Framework, pod *v1.Pod, gotStatuses [] return utilerrors.NewAggregate(errs) } -func verifyOomScoreAdj(f *framework.Framework, pod *v1.Pod, containerName string) error { +func verifyOomScoreAdj(ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string) error { container := e2epod.FindContainerInPod(pod, containerName) if container == nil { return fmt.Errorf("failed to find container %s in pod %s", containerName, pod.Name) @@ -356,7 +356,9 @@ func verifyOomScoreAdj(f *framework.Framework, pod *v1.Pod, containerName string oomScoreAdj := kubeqos.GetContainerOOMScoreAdjust(pod, container, int64(nodeMemoryCapacity.Value())) expectedOomScoreAdj := strconv.FormatInt(int64(oomScoreAdj), 10) - return cgroups.VerifyOomScoreAdjValue(f, pod, container.Name, expectedOomScoreAdj) + return framework.Gomega().Eventually(ctx, framework.HandleRetry(func(ctx context.Context) (error, error) { + return cgroups.VerifyOomScoreAdjValue(f, pod, container.Name, expectedOomScoreAdj), nil + })).WithTimeout(framework.PollShortTimeout).Should(gomega.Succeed()) } func WaitForPodResizeActuation(ctx context.Context, f *framework.Framework, podClient *e2epod.PodClient, pod *v1.Pod, expectedContainers []ResizableContainerInfo) *v1.Pod { @@ -373,13 +375,14 @@ func WaitForPodResizeActuation(ctx context.Context, f *framework.Framework, podC return "resize is infeasible" }, nil } - // TODO: Replace this check with a combination of checking the status.observedGeneration - // and the resize status when available. - if resourceErrs := VerifyPodStatusResources(pod, expectedContainers); resourceErrs != nil { + + if pod.Status.ObservedGeneration < pod.Generation { return func() string { - return fmt.Sprintf("container status resources don't match expected: %v", formatErrors(resourceErrs)) + return fmt.Sprintf("waiting for observedGeneration (%d) to catch up to generation (%d)", + pod.Status.ObservedGeneration, pod.Generation) }, nil } + // Wait for kubelet to clear the resize status conditions. for _, c := range pod.Status.Conditions { if c.Type == v1.PodResizePending || c.Type == v1.PodResizeInProgress { @@ -388,6 +391,7 @@ func WaitForPodResizeActuation(ctx context.Context, f *framework.Framework, podC }, nil } } + // Wait for the pod to be ready. if !podutils.IsPodReady(pod) { return func() string { return "pod is not ready" }, nil @@ -438,7 +442,7 @@ func ExpectPodResized(ctx context.Context, f *framework.Framework, resizedPod *v errs = append(errs, fmt.Errorf("container status resources don't match expected: %w", formatErrors(resourceErrs))) } - if restartErrs := verifyPodRestarts(f, resizedPod, expectedContainers); restartErrs != nil { + if restartErrs := verifyPodRestarts(ctx, f, resizedPod, expectedContainers); restartErrs != nil { errs = append(errs, fmt.Errorf("container restart counts don't match expected: %w", formatErrors(restartErrs))) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/image_credential_provider.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/image_credential_provider.go index e6c43afb39..615356bca4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/image_credential_provider.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/image_credential_provider.go @@ -48,7 +48,7 @@ var _ = SIGDescribe("ImageCredentialProvider", feature.KubeletCredentialProvider Testname: Test kubelet image pull with external credential provider plugins Description: Create Pod with an image from a private registry. This test assumes that the kubelet credential provider plugin is enabled for the registry hosting imageutils.AgnhostPrivate. */ - ginkgo.It("should be able to create pod with image credentials fetched from external credential provider ", func(ctx context.Context) { + ginkgo.It("should be able to create pod with image credentials fetched from external credential provider", func(ctx context.Context) { privateimage := imageutils.GetConfig(imageutils.AgnhostPrivate) name := "pod-auth-image-" + string(uuid.NewUUID()) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/image_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/image_volume.go new file mode 100644 index 0000000000..3bcf748664 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/image_volume.go @@ -0,0 +1,123 @@ +/* +Copyright 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 node + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + "github.com/opencontainers/selinux/go-selinux" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/test/e2e/framework" + e2epod "k8s.io/kubernetes/test/e2e/framework/pod" + imageutils "k8s.io/kubernetes/test/utils/image" + admissionapi "k8s.io/pod-security-admission/api" +) + +var _ = SIGDescribe("ImageVolume", func() { + f := framework.NewDefaultFramework("image-volume") + f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged + + volumeImage := imageutils.GetE2EImage(imageutils.Kitten) + + const ( + podName = "test-pod" + containerName = "test-container" + volumeName = "volume" + volumePathPrefix = "/volume" + defaultSELinuxUser = "system_u" + defaultSELinuxRole = "system_r" + defaultSELinuxType = "svirt_lxc_net_t" // that's the SELinux type used by Debian/Ubuntu. Keep it for maximum test compatibility. + defaultSELinuxLevel = "s0:c1,c5" + ) + + createPod := func(ctx context.Context, podName, nodeName string, volumes []v1.Volume, volumeMounts []v1.VolumeMount, selinuxOptions *v1.SELinuxOptions) { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + Namespace: f.Namespace.Name, + }, + Spec: v1.PodSpec{ + NodeName: nodeName, + RestartPolicy: v1.RestartPolicyAlways, + SecurityContext: &v1.PodSecurityContext{ + SELinuxOptions: selinuxOptions, + }, + Containers: []v1.Container{ + { + Name: containerName, + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sh", "-c", "while true; do echo test; sleep 1; done"}, + VolumeMounts: volumeMounts, + }, + }, + Volumes: volumes, + }, + } + + ginkgo.By(fmt.Sprintf("Creating a pod (%s/%s)", f.Namespace.Name, podName)) + e2epod.NewPodClient(f).Create(ctx, pod) + } + + verifyFileContents := func(podName, volumePath string) { + ginkgo.By(fmt.Sprintf("Verifying the volume mount contents for path: %s", volumePath)) + + firstFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePath, "data.json")) + gomega.Expect(firstFileContents).To(gomega.ContainSubstring("kitten.jpg")) + + secondFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePath, "etc", "os-release")) + gomega.Expect(secondFileContents).To(gomega.ContainSubstring("Alpine Linux")) + } + + /* + Release: v1.36 + Testname: Image Volume + Description: Create a Pod using an image volume and a pull policy of Always. + This test verifies that the image volume functionality is available by default and works as intended. + [LinuxOnly]: This test is marked as LinuxOnly since Windows does not support image volumes. + */ + framework.ConformanceIt("should succeed with pod and pull policy of Always [LinuxOnly] [MinimumKubeletVersion:1.35]", func(ctx context.Context) { + var selinuxOptions *v1.SELinuxOptions + if selinux.GetEnabled() { + selinuxOptions = &v1.SELinuxOptions{ + User: defaultSELinuxUser, + Role: defaultSELinuxRole, + Type: defaultSELinuxType, + Level: defaultSELinuxLevel, + } + ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions)) + } + + createPod(ctx, + podName, + "", + []v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: volumeImage, PullPolicy: v1.PullAlways}}}}, + []v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix}}, + selinuxOptions, + ) + + ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName)) + err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name) + framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName) + + verifyFileContents(podName, volumePathPrefix) + }) +}) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/lifecycle_hook.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/lifecycle_hook.go index a7a7d51c2c..d51a565222 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/lifecycle_hook.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/lifecycle_hook.go @@ -19,6 +19,7 @@ package node import ( "context" "fmt" + "net/url" "strings" "time" @@ -41,8 +42,7 @@ import ( var _ = SIGDescribe("Container Lifecycle Hook", func() { f := framework.NewDefaultFramework("container-lifecycle-hook") - // FIXME: This test is being run in the privileged mode because of https://github.com/kubernetes/kubernetes/issues/133091 - f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged + f.NamespacePodSecurityLevel = admissionapi.LevelBaseline var podClient *e2epod.PodClient const ( podCheckInterval = 1 * time.Second @@ -52,33 +52,36 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { ginkgo.Context("when create a pod with lifecycle hook", func() { var ( targetIP, targetURL, targetNode string - - httpPorts = []v1.ContainerPort{ - { - ContainerPort: 8080, - Protocol: v1.ProtocolTCP, - }, - } - httpsPorts = []v1.ContainerPort{ - { - ContainerPort: 9090, - Protocol: v1.ProtocolTCP, - }, - } - httpsArgs = []string{ - "netexec", - "--http-port", "9090", - "--udp-port", "9091", - "--tls-cert-file", "/localhost.crt", - "--tls-private-key-file", "/localhost.key", - } ) + // We test the probes by creating an HTTP server and looking at its logs + // to verify that it got hit with the expected probes. This is tricky + // though: when testing PostStart, the HTTP server can't be the container + // we're starting, because PostStart may run before the container starts. + // We can solve that by using a sidecar container, but that doesn't work + // for PreStop, because we can't reliably ensure that the sidecar stays + // around long enough after we Delete the pod for us to have a chance to + // read the logs. + // + // To make both cases work, we run a separate pod to do the logging, and + // then use a sidecar container in the test pod that can receive probes at + // the test pod's IP and handle them by making a request to the logging + // pod. + // + // (The Exec case is much simpler, since we can just have it curl the + // logging pod directly.) podHandleHookRequest := e2epod.NewAgnhostPodFromContainers( "", "pod-handle-http-request", nil, - e2epod.NewAgnhostContainer("container-handle-http-request", nil, httpPorts, "netexec"), - e2epod.NewAgnhostContainer("container-handle-https-request", nil, httpsPorts, httpsArgs...), + e2epod.NewAgnhostContainer("container-handle-http-request", nil, nil, "netexec"), ) + // netexecConnect takes a target and a request, and returns a netexec + // command that will connect to `target` and request `req`. + netexecConnect := func(target, req string) string { + return fmt.Sprintf("/dial?host=%s&port=8080&request=%s", + target, + url.QueryEscape(strings.TrimLeft(req, "/")), + ) + } ginkgo.BeforeEach(func(ctx context.Context) { node, err := e2enode.GetRandomReadySchedulableNode(ctx, f.ClientSet) @@ -98,22 +101,47 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { } }) testPodWithHook := func(ctx context.Context, podWithHook *v1.Pod) { + testContainer := podWithHook.Spec.Containers[0] + scheme := v1.URISchemeHTTP + if testContainer.Lifecycle.PostStart != nil && testContainer.Lifecycle.PostStart.HTTPGet != nil { + scheme = testContainer.Lifecycle.PostStart.HTTPGet.Scheme + } else if testContainer.Lifecycle.PreStop != nil && testContainer.Lifecycle.PreStop.HTTPGet != nil { + scheme = testContainer.Lifecycle.PreStop.HTTPGet.Scheme + } + + ginkgo.By("add a sidecar to the test pod") + sidecarArgs := []string{ + "netexec", + "--udp-port", "-1", + } + if scheme == v1.URISchemeHTTPS { + sidecarArgs = append(sidecarArgs, + "--tls-cert-file", "/localhost.crt", + "--tls-private-key-file", "/localhost.key", + ) + } + sidecarContainer := e2epod.NewAgnhostContainer("container-redirect", nil, nil, sidecarArgs...) + sidecarContainer.RestartPolicy = ptr.To(v1.ContainerRestartPolicyAlways) + sidecarContainer.StartupProbe = &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Scheme: scheme, + Path: "/echo?msg=startup", + Port: intstr.FromInt32(8080), + }, + }, + } + podWithHook.Spec.InitContainers = append( + []v1.Container{sidecarContainer}, + podWithHook.Spec.InitContainers..., + ) + ginkgo.By("create the pod with lifecycle hook") podClient.CreateSync(ctx, podWithHook) - const ( - defaultHandler = iota - httpsHandler - ) - handlerContainer := defaultHandler if podWithHook.Spec.Containers[0].Lifecycle.PostStart != nil { ginkgo.By("check poststart hook") - if podWithHook.Spec.Containers[0].Lifecycle.PostStart.HTTPGet != nil { - if v1.URISchemeHTTPS == podWithHook.Spec.Containers[0].Lifecycle.PostStart.HTTPGet.Scheme { - handlerContainer = httpsHandler - } - } gomega.Eventually(ctx, func(ctx context.Context) error { - return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[handlerContainer].Name, + return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name, `GET /echo\?msg=poststart`) }, postStartWaitTimeout, podCheckInterval).Should(gomega.BeNil()) } @@ -121,13 +149,8 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { podClient.DeleteSync(ctx, podWithHook.Name, *metav1.NewDeleteOptions(15), f.Timeouts.PodDelete) if podWithHook.Spec.Containers[0].Lifecycle.PreStop != nil { ginkgo.By("check prestop hook") - if podWithHook.Spec.Containers[0].Lifecycle.PreStop.HTTPGet != nil { - if v1.URISchemeHTTPS == podWithHook.Spec.Containers[0].Lifecycle.PreStop.HTTPGet.Scheme { - handlerContainer = httpsHandler - } - } gomega.Eventually(ctx, func(ctx context.Context) error { - return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[handlerContainer].Name, + return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name, `GET /echo\?msg=prestop`) }, preStopWaitTimeout, podCheckInterval).Should(gomega.BeNil()) } @@ -174,8 +197,7 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { lifecycle := &v1.Lifecycle{ PostStart: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ - Path: "/echo?msg=poststart", - Host: targetIP, + Path: netexecConnect(targetIP, "/echo?msg=poststart"), Port: intstr.FromInt32(8080), }, }, @@ -197,9 +219,8 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { PostStart: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ Scheme: v1.URISchemeHTTPS, - Path: "/echo?msg=poststart", - Host: targetIP, - Port: intstr.FromInt32(9090), + Path: netexecConnect(targetIP, "/echo?msg=poststart"), + Port: intstr.FromInt32(8080), }, }, } @@ -219,8 +240,7 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { lifecycle := &v1.Lifecycle{ PreStop: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ - Path: "/echo?msg=prestop", - Host: targetIP, + Path: netexecConnect(targetIP, "/echo?msg=prestop"), Port: intstr.FromInt32(8080), }, }, @@ -242,9 +262,8 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { PreStop: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ Scheme: v1.URISchemeHTTPS, - Path: "/echo?msg=prestop", - Host: targetIP, - Port: intstr.FromInt32(9090), + Path: netexecConnect(targetIP, "/echo?msg=prestop"), + Port: intstr.FromInt32(8080), }, }, } @@ -260,8 +279,7 @@ var _ = SIGDescribe("Container Lifecycle Hook", func() { var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(features.SidecarContainers), "Restartable Init Container Lifecycle Hook", func() { f := framework.NewDefaultFramework("restartable-init-container-lifecycle-hook") - // FIXME: This test is being run in the privileged mode because of https://github.com/kubernetes/kubernetes/issues/133091 - f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged + f.NamespacePodSecurityLevel = admissionapi.LevelBaseline var podClient *e2epod.PodClient const ( podCheckInterval = 1 * time.Second @@ -271,33 +289,19 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f ginkgo.Context("when create a pod with lifecycle hook", func() { var ( targetIP, targetURL, targetNode string - - httpPorts = []v1.ContainerPort{ - { - ContainerPort: 8080, - Protocol: v1.ProtocolTCP, - }, - } - httpsPorts = []v1.ContainerPort{ - { - ContainerPort: 9090, - Protocol: v1.ProtocolTCP, - }, - } - httpsArgs = []string{ - "netexec", - "--http-port", "9090", - "--udp-port", "9091", - "--tls-cert-file", "/localhost.crt", - "--tls-private-key-file", "/localhost.key", - } ) + // See description above in the "Container Lifecycle Hook" tests podHandleHookRequest := e2epod.NewAgnhostPodFromContainers( "", "pod-handle-http-request", nil, - e2epod.NewAgnhostContainer("container-handle-http-request", nil, httpPorts, "netexec"), - e2epod.NewAgnhostContainer("container-handle-https-request", nil, httpsPorts, httpsArgs...), + e2epod.NewAgnhostContainer("container-handle-http-request", nil, nil, "netexec"), ) + netexecConnect := func(target, req string) string { + return fmt.Sprintf("/dial?host=%s&port=8080&request=%s", + target, + url.QueryEscape(strings.TrimLeft(req, "/")), + ) + } ginkgo.BeforeEach(func(ctx context.Context) { node, err := e2enode.GetRandomReadySchedulableNode(ctx, f.ClientSet) @@ -317,36 +321,56 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f } }) testPodWithHook := func(ctx context.Context, podWithHook *v1.Pod) { + testContainer := podWithHook.Spec.InitContainers[0] + scheme := v1.URISchemeHTTP + if testContainer.Lifecycle.PostStart != nil && testContainer.Lifecycle.PostStart.HTTPGet != nil { + scheme = testContainer.Lifecycle.PostStart.HTTPGet.Scheme + } else if testContainer.Lifecycle.PreStop != nil && testContainer.Lifecycle.PreStop.HTTPGet != nil { + scheme = testContainer.Lifecycle.PreStop.HTTPGet.Scheme + } + + ginkgo.By("add a sidecar to the test pod") + sidecarArgs := []string{ + "netexec", + "--udp-port", "-1", + } + if scheme == v1.URISchemeHTTPS { + sidecarArgs = append(sidecarArgs, + "--tls-cert-file", "/localhost.crt", + "--tls-private-key-file", "/localhost.key", + ) + } + sidecarContainer := e2epod.NewAgnhostContainer("container-redirect", nil, nil, sidecarArgs...) + sidecarContainer.RestartPolicy = ptr.To(v1.ContainerRestartPolicyAlways) + sidecarContainer.StartupProbe = &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Scheme: scheme, + Path: "/echo?msg=startup", + Port: intstr.FromInt32(8080), + }, + }, + } + podWithHook.Spec.InitContainers = append( + []v1.Container{sidecarContainer}, + podWithHook.Spec.InitContainers..., + ) + ginkgo.By("create the pod with lifecycle hook") podClient.CreateSync(ctx, podWithHook) - const ( - defaultHandler = iota - httpsHandler - ) - handlerContainer := defaultHandler - if podWithHook.Spec.InitContainers[0].Lifecycle.PostStart != nil { + if testContainer.Lifecycle.PostStart != nil { ginkgo.By("check poststart hook") - if podWithHook.Spec.InitContainers[0].Lifecycle.PostStart.HTTPGet != nil { - if v1.URISchemeHTTPS == podWithHook.Spec.InitContainers[0].Lifecycle.PostStart.HTTPGet.Scheme { - handlerContainer = httpsHandler - } - } gomega.Eventually(ctx, func(ctx context.Context) error { - return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[handlerContainer].Name, + return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name, `GET /echo\?msg=poststart`) }, postStartWaitTimeout, podCheckInterval).Should(gomega.BeNil()) } ginkgo.By("delete the pod with lifecycle hook") podClient.DeleteSync(ctx, podWithHook.Name, *metav1.NewDeleteOptions(15), f.Timeouts.PodDelete) - if podWithHook.Spec.InitContainers[0].Lifecycle.PreStop != nil { + if testContainer.Lifecycle.PreStop != nil { ginkgo.By("check prestop hook") - if podWithHook.Spec.InitContainers[0].Lifecycle.PreStop.HTTPGet != nil { - if v1.URISchemeHTTPS == podWithHook.Spec.InitContainers[0].Lifecycle.PreStop.HTTPGet.Scheme { - handlerContainer = httpsHandler - } - } gomega.Eventually(ctx, func(ctx context.Context) error { - return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[handlerContainer].Name, + return podClient.MatchContainerOutput(ctx, podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name, `GET /echo\?msg=prestop`) }, preStopWaitTimeout, podCheckInterval).Should(gomega.BeNil()) } @@ -408,8 +432,7 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f lifecycle := &v1.Lifecycle{ PostStart: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ - Path: "/echo?msg=poststart", - Host: targetIP, + Path: netexecConnect(targetIP, "/echo?msg=poststart"), Port: intstr.FromInt32(8080), }, }, @@ -436,9 +459,8 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f PostStart: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ Scheme: v1.URISchemeHTTPS, - Path: "/echo?msg=poststart", - Host: targetIP, - Port: intstr.FromInt32(9090), + Path: netexecConnect(targetIP, "/echo?msg=poststart"), + Port: intstr.FromInt32(8080), }, }, } @@ -463,8 +485,7 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f lifecycle := &v1.Lifecycle{ PreStop: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ - Path: "/echo?msg=prestop", - Host: targetIP, + Path: netexecConnect(targetIP, "/echo?msg=prestop"), Port: intstr.FromInt32(8080), }, }, @@ -491,9 +512,8 @@ var _ = SIGDescribe(framework.WithNodeConformance(), framework.WithFeatureGate(f PreStop: &v1.LifecycleHandler{ HTTPGet: &v1.HTTPGetAction{ Scheme: v1.URISchemeHTTPS, - Path: "/echo?msg=prestop", - Host: targetIP, - Port: intstr.FromInt32(9090), + Path: netexecConnect(targetIP, "/echo?msg=prestop"), + Port: intstr.FromInt32(8080), }, }, } @@ -555,7 +575,7 @@ func validDuration(duration time.Duration, low, high int64) bool { return duration >= time.Second*time.Duration(low) && duration <= time.Second*time.Duration(high) } -var _ = SIGDescribe("Lifecycle Sleep Hook", func() { +var _ = SIGDescribe("Lifecycle Sleep Hook", framework.WithNodeConformance(), func() { f := framework.NewDefaultFramework("pod-lifecycle-sleep-action") f.NamespacePodSecurityLevel = admissionapi.LevelBaseline var podClient *e2epod.PodClient @@ -712,7 +732,7 @@ var _ = SIGDescribe("Lifecycle Sleep Hook", func() { }) }) -var _ = SIGDescribe("Lifecycle sleep action zero value", func() { +var _ = SIGDescribe("Lifecycle sleep action zero value", framework.WithNodeConformance(), func() { f := framework.NewDefaultFramework("pod-lifecycle-sleep-action-allow-zero") f.NamespacePodSecurityLevel = admissionapi.LevelBaseline var podClient *e2epod.PodClient diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/node_lease.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/node_lease.go index e1a671d958..d97e17304d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/node_lease.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/node_lease.go @@ -38,7 +38,7 @@ import ( "github.com/onsi/gomega" ) -var _ = SIGDescribe("NodeLease", func() { +var _ = SIGDescribe("NodeLease", framework.WithNodeConformance(), func() { var nodeName string f := framework.NewDefaultFramework("node-lease-test") f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_hostnameoverride.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_hostnameoverride.go index 32e9c93347..1b02e10d22 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_hostnameoverride.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_hostnameoverride.go @@ -43,7 +43,7 @@ func newTestPod(namespace string) *v1.Pod { Containers: []v1.Container{ { Name: "test-pod-hostname-override", - Image: imageutils.GetE2EImage(imageutils.JessieDnsutils), + Image: imageutils.GetE2EImage(imageutils.GlibcDnsTesting), Command: []string{"sh", "-c", "echo $(hostname)';'$(hostname -f)';'"}, }, }, @@ -52,7 +52,7 @@ func newTestPod(namespace string) *v1.Pod { } } -var _ = SIGDescribe("Override hostname of Pod", framework.WithFeatureGate(features.HostnameOverride), func() { +var _ = SIGDescribe("Override hostname of Pod", framework.WithNodeConformance(), framework.WithFeatureGate(features.HostnameOverride), func() { f := framework.NewDefaultFramework("hostfqdn") f.NamespacePodSecurityLevel = admissionapi.LevelBaseline diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources.go index 0cd60e8047..21d1ec3e8f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources.go @@ -90,7 +90,7 @@ func isCgroupv2Node(f *framework.Framework, ctx context.Context) bool { framework.ExpectNoError(delErr, "failed to delete pod %s", delErr) }() - return cgroups.IsPodOnCgroupv2Node(f, pod) + return cgroups.IsPodOnCgroupv2Node(f, pod.Name, pod.Spec.Containers[0].Name) } func makeObjectMetadata(name, namespace string) metav1.ObjectMeta { @@ -440,7 +440,7 @@ func podLevelResourcesTests(f *framework.Framework) { framework.ExpectNoError(err, "failed to verify pod's cgroup values: %v", err) ginkgo.By("verifying containers cgroup limits are same as pod container's cgroup limits") - err = verifyContainersCgroupLimits(f, pod) + err = verifyContainersCgroupLimits(ctx, f, pod) framework.ExpectNoError(err, "failed to verify containers cgroup values: %v", err) ginkgo.By("deleting pods") @@ -450,12 +450,12 @@ func podLevelResourcesTests(f *framework.Framework) { } } -func verifyContainersCgroupLimits(f *framework.Framework, pod *v1.Pod) error { +func verifyContainersCgroupLimits(ctx context.Context, f *framework.Framework, pod *v1.Pod) error { var errs []error for _, container := range pod.Spec.Containers { if pod.Spec.Resources != nil && pod.Spec.Resources.Limits.Memory() != nil && container.Resources.Limits.Memory() == nil { - err := cgroups.VerifyContainerMemoryLimit(f, pod, container.Name, &container.Resources, true) + err := cgroups.VerifyContainerMemoryLimit(ctx, f, pod, container.Name, &container.Resources, true) if err != nil { errs = append(errs, fmt.Errorf("failed to verify memory limit cgroup value: %w", err)) } @@ -463,7 +463,7 @@ func verifyContainersCgroupLimits(f *framework.Framework, pod *v1.Pod) error { if pod.Spec.Resources != nil && pod.Spec.Resources.Limits.Cpu() != nil && container.Resources.Limits.Cpu() == nil { - err := cgroups.VerifyContainerCPULimit(f, pod, container.Name, &container.Resources, true) + err := cgroups.VerifyContainerCPULimit(ctx, f, pod, container.Name, &container.Resources, true) if err != nil { errs = append(errs, fmt.Errorf("failed to verify cpu limit cgroup value: %w", err)) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources_resize.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources_resize.go index 92690114c1..f855299456 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources_resize.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_level_resources_resize.go @@ -29,7 +29,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/client-go/kubernetes/scheme" "k8s.io/kubernetes/pkg/features" + kubeletevents "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/test/e2e/common/node/framework/cgroups" "k8s.io/kubernetes/test/e2e/common/node/framework/podresize" "k8s.io/kubernetes/test/e2e/framework" @@ -71,17 +73,20 @@ func doGuaranteedPodLevelResizeTests(f *framework.Framework) { expectedContainers := makeGuaranteedContainers(1, cpuPolicy, memPolicy, true, true, desiredCtrCPU, desiredCtrMem) for i, c := range expectedContainers { // If the pod has init containers, but we are not resizing them, keep the original resources. - if c.InitCtr && !resizeInitCtrs { + podLevelOnly := (desiredCtrCPU == "" && desiredPodCPU != originalCPU) || (desiredCtrMem == "" && desiredPodMem != originalMem) + + if c.InitCtr && !resizeInitCtrs && !podLevelOnly { c.Resources = originalContainers[i].Resources expectedContainers[i] = c continue } // For containers where the resize policy is "restart", we expect a restart. expectRestart := int32(0) - if cpuPolicy == v1.RestartContainer && desiredCtrCPU != originalCtrCPU { + + if cpuPolicy == v1.RestartContainer && (desiredCtrCPU != originalCtrCPU || (desiredCtrCPU == "" && desiredPodCPU != originalCPU)) { expectRestart = 1 } - if memPolicy == v1.RestartContainer && desiredCtrMem != originalCtrMem { + if memPolicy == v1.RestartContainer && (desiredCtrMem != originalCtrMem || (desiredCtrMem == "" && desiredPodMem != originalMem)) { expectRestart = 1 } c.RestartCount = expectRestart @@ -90,8 +95,8 @@ func doGuaranteedPodLevelResizeTests(f *framework.Framework) { var originalPodResources, desiredPodResources *v1.ResourceRequirements if desiredPodCPU != "" || desiredPodMem != "" { - originalPodResources = makePodResources(offsetCPU(15, originalCPU), offsetCPU(15, originalCPU), offsetMemory(15, originalMem), offsetMemory(15, originalMem)) - desiredPodResources = makePodResources(offsetCPU(15, desiredPodCPU), offsetCPU(15, desiredPodCPU), offsetMemory(15, desiredPodMem), offsetMemory(15, desiredPodMem)) + originalPodResources = makePodResources(offsetCPU(30, originalCPU), offsetCPU(30, originalCPU), offsetMemory(30, originalMem), offsetMemory(30, originalMem)) + desiredPodResources = makePodResources(offsetCPU(30, desiredPodCPU), offsetCPU(30, desiredPodCPU), offsetMemory(30, desiredPodMem), offsetMemory(30, desiredPodMem)) } doPatchAndRollbackPLR(ctx, f, originalContainers, expectedContainers, originalPodResources, desiredPodResources, true, true) @@ -445,6 +450,7 @@ var _ = SIGDescribe("PLR Pod InPlace Resize", framework.WithFeatureGate(features doGuaranteedPodLevelResizeTests(f) doBurstablePodLevelResizeTests(f) doPodLevelResourcesMemoryLimitDecreaseTest(f) + doInitialCreationNoResizeEventTest(f) }) func makePodResources(cpuReq, cpuLim, memReq, memLim string) *v1.ResourceRequirements { @@ -639,6 +645,39 @@ func doPodLevelResourcesMemoryLimitDecreaseTest(f *framework.Framework) { }) } +func doInitialCreationNoResizeEventTest(f *framework.Framework) { + framework.It("should not emit ResizeCompleted event on initial creation", framework.WithKubeletMinVersion("1.36"), func(ctx context.Context) { + podClient := e2epod.NewPodClient(f) + originalPLR := &v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("200m"), + v1.ResourceMemory: resource.MustParse("256Mi"), + }, + Limits: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("200m"), + v1.ResourceMemory: resource.MustParse("256Mi"), + }, + } + + containers := []podresize.ResizableContainerInfo{{ + Name: "c1", + }} + + ginkgo.By("creating and verifying pod") + testPod := createAndVerifyPodPLR(ctx, f, podClient, containers, originalPLR, true) + + ginkgo.By("verifying no ResizeCompleted event was emitted") + events, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).SearchWithContext(ctx, scheme.Scheme, testPod) + framework.ExpectNoError(err, "failed to list events") + + for _, event := range events.Items { + if event.Reason == kubeletevents.ResizeCompleted { + framework.Failf("Unexpected ResizeCompleted event found for pod %s: %v", testPod.Name, event) + } + } + }) +} + func doPatchAndRollbackPLR(ctx context.Context, f *framework.Framework, originalContainers, expectedContainers []podresize.ResizableContainerInfo, originalPodResources, expectedPodResources *v1.ResourceRequirements, doRollback bool, mountPodCgroup bool) { ginkgo.By("creating and verifying pod") podClient := e2epod.NewPodClient(f) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_resize.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_resize.go index c1f31a16e3..8e551ba2fb 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_resize.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/pod_resize.go @@ -29,8 +29,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/test/e2e/common/node/framework/cgroups" "k8s.io/kubernetes/test/e2e/common/node/framework/podresize" + "k8s.io/kubernetes/test/e2e/feature" "k8s.io/kubernetes/test/e2e/framework" e2enode "k8s.io/kubernetes/test/e2e/framework/node" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" @@ -80,7 +82,7 @@ func offsetMemory(index int64, value string) string { } func doGuaranteedPodResizeTests(f *framework.Framework) { - ginkgo.DescribeTableSubtree("guaranteed qos - 1 container with resize policy", func(cpuPolicy, memPolicy v1.ResourceResizeRestartPolicy, resizeInitCtrs bool) { + ginkgo.DescribeTableSubtree("guaranteed qos - 1 container with resize policy", feature.InPlacePodVerticalScaling, func(cpuPolicy, memPolicy v1.ResourceResizeRestartPolicy, resizeInitCtrs bool) { ginkgo.DescribeTable("resizing", func(ctx context.Context, desiredCPU, desiredMem string) { // The tests for guaranteed pods include extended resources. @@ -237,7 +239,7 @@ type resourceRequestsLimits struct { } func doBurstablePodResizeTests(f *framework.Framework) { - ginkgo.DescribeTableSubtree("burstable pods - 1 container with all requests & limits set and resize policy", func(cpuPolicy, memPolicy v1.ResourceResizeRestartPolicy) { + ginkgo.DescribeTableSubtree("burstable pods - 1 container with all requests & limits set and resize policy", feature.InPlacePodVerticalScaling, func(cpuPolicy, memPolicy v1.ResourceResizeRestartPolicy) { ginkgo.DescribeTable("resizing", func(ctx context.Context, desiredContainerResources resourceRequestsLimits) { originalContainers := makeBurstableContainers(1, cpuPolicy, memPolicy, originalCPU, originalCPULimit, originalMem, originalMemLimit) expectedContainers := makeBurstableContainers(1, cpuPolicy, memPolicy, desiredContainerResources.cpuReq, desiredContainerResources.cpuLim, desiredContainerResources.memReq, desiredContainerResources.memLim) @@ -366,7 +368,7 @@ func doBurstablePodResizeTests(f *framework.Framework) { } func doPodResizePatchErrorTests(f *framework.Framework) { - ginkgo.DescribeTable("apply invalid resize patch requests", func(ctx context.Context, originalContainers, desiredContainers []podresize.ResizableContainerInfo, patchError string, waitForStart bool) { + ginkgo.DescribeTable("apply invalid resize patch requests", feature.InPlacePodVerticalScaling, func(ctx context.Context, originalContainers, desiredContainers []podresize.ResizableContainerInfo, patchError string, waitForStart bool) { podClient := e2epod.NewPodClient(f) var newPod *v1.Pod @@ -575,34 +577,6 @@ func doPodResizePatchErrorTests(f *framework.Framework) { "only cpu and memory resources are mutable", true, ), - ginkgo.Entry("Burstable pod - nonrestartable initContainer", - []podresize.ResizableContainerInfo{ - { - Name: "c1-init", - InitCtr: true, - Resources: &cgroups.ContainerResources{CPUReq: originalCPU, MemReq: originalMem}, - RestartPolicy: v1.ContainerRestartPolicyNever, - }, - { - Name: "c1", - Resources: &cgroups.ContainerResources{}, - }, - }, - []podresize.ResizableContainerInfo{ - { - Name: "c1-init", - InitCtr: true, - Resources: &cgroups.ContainerResources{CPUReq: increasedCPU, MemReq: increasedMem}, - RestartPolicy: v1.ContainerRestartPolicyNever, - }, - { - Name: "c1", - Resources: &cgroups.ContainerResources{}, - }, - }, - "resources for non-sidecar init containers are immutable", - false, - ), ) } @@ -611,7 +585,7 @@ func doPodResizeMemoryLimitDecreaseTest(f *framework.Framework) { // 1. Decrease the limit a little bit - should succeed // 2. Decrease the limit down to a tiny amount - should fail // 3. Revert the limit back to the original value - should succeed - ginkgo.It("decrease memory limit below usage", func(ctx context.Context) { + ginkgo.It("decrease memory limit below usage", feature.InPlacePodVerticalScaling, func(ctx context.Context) { podClient := e2epod.NewPodClient(f) original := []podresize.ResizableContainerInfo{{ Name: "c1", @@ -717,6 +691,86 @@ func doPodResizeMemoryLimitDecreaseTest(f *framework.Framework) { }) } +func doPodResizeInitContainerResizeTest(f *framework.Framework) { + ginkgo.It("should support resizing a non-sidecar init container", func(ctx context.Context) { + // A command that never exits, to allow us to patch the init container while it's running. + cmd := "tail -f /dev/null" + + originalContainers := []podresize.ResizableContainerInfo{ + { + Name: "init-c1", + InitCtr: true, + Resources: &cgroups.ContainerResources{CPUReq: originalCPU, CPULim: originalCPU, MemReq: originalMem, MemLim: originalMem}, + RestartPolicy: v1.ContainerRestartPolicyNever, + }, + { + Name: "main-c1", + Resources: &cgroups.ContainerResources{CPUReq: originalCPU, CPULim: originalCPU, MemReq: originalMem, MemLim: originalMem}, + }, + } + resizedContainers := []podresize.ResizableContainerInfo{ + { + Name: "init-c1", + InitCtr: true, + Resources: &cgroups.ContainerResources{CPUReq: increasedCPU, CPULim: increasedCPU, MemReq: increasedMem, MemLim: increasedMem}, + RestartPolicy: v1.ContainerRestartPolicyNever, + }, + { + Name: "main-c1", + Resources: originalContainers[1].Resources, + }, + } + + originalInitCtr := cgroups.MakeContainerWithResources( + originalContainers[0].Name, + originalContainers[0].Resources, + cmd, + ) + resizedInitCtr := cgroups.MakeContainerWithResources( + resizedContainers[0].Name, + resizedContainers[0].Resources, + cmd, + ) + + ginkgo.By("Creating pod with an nonrestartable init container") + testPod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "resize-test-", + }, + Spec: v1.PodSpec{ + InitContainers: []v1.Container{originalInitCtr}, + Containers: []v1.Container{cgroups.MakeContainerWithResources( + originalContainers[1].Name, + originalContainers[1].Resources, + cmd, + )}, + }, + } + testPod = e2epod.MustMixinRestrictedPodSecurity(testPod) + podClient := e2epod.NewPodClient(f) + newPod := podClient.Create(ctx, testPod) + verifyInitContainerResources(ctx, f, newPod, originalContainers, originalInitCtr) + + ginkgo.By("patching and verifying pod for resize") + patch := podresize.MakeResizePatch(originalContainers, resizedContainers, nil, nil) + patchedPod, pErr := f.ClientSet.CoreV1().Pods(newPod.Namespace).Patch(ctx, newPod.Name, + types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "resize") + framework.ExpectNoError(pErr, "failed to patch pod for resize") + verifyInitContainerResources(ctx, f, patchedPod, resizedContainers, resizedInitCtr) + + // Resize has been actuated, test the reverse operation. + ginkgo.By("patching and verifying pod to revert to original resources") + patch = podresize.MakeResizePatch(resizedContainers, originalContainers, nil, nil) + patchedPod, pErr = f.ClientSet.CoreV1().Pods(newPod.Namespace).Patch(ctx, newPod.Name, + types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "resize") + framework.ExpectNoError(pErr, "failed to patch pod for resize") + verifyInitContainerResources(ctx, f, patchedPod, originalContainers, originalInitCtr) + + ginkgo.By("deleting pod") + podClient.DeleteSync(ctx, newPod.Name, metav1.DeleteOptions{}, f.Timeouts.PodDelete) + }) +} + func doPodResizeReadAndReplaceTests(f *framework.Framework) { /* Release: v1.35 @@ -825,6 +879,20 @@ var _ = SIGDescribe("Pod InPlace Resize Container", func() { doPodResizeMemoryLimitDecreaseTest(f) }) +var _ = SIGDescribe("Pod InPlace Resize Init Container", framework.WithFeatureGate(features.InPlacePodVerticalScalingInitContainers), func() { + f := framework.NewDefaultFramework("pod-resize-tests") + + ginkgo.BeforeEach(func(ctx context.Context) { + _, err := e2enode.GetRandomReadySchedulableNode(ctx, f.ClientSet) + framework.ExpectNoError(err) + if framework.NodeOSDistroIs("windows") { + e2eskipper.Skipf("runtime does not support InPlacePodVerticalScaling -- skipping") + } + }) + + doPodResizeInitContainerResizeTest(f) +}) + func doPatchAndRollback(ctx context.Context, f *framework.Framework, originalContainers, expectedContainers []podresize.ResizableContainerInfo, originalPodResources, expectedPodResources *v1.ResourceRequirements, doRollback bool, mountPodCgroup bool) { ginkgo.By("creating and verifying pod") podClient := e2epod.NewPodClient(f) @@ -874,8 +942,8 @@ func createAndVerifyPod(ctx context.Context, f *framework.Framework, podClient * } newPod := podClient.CreateSync(ctx, testPod) - podresize.VerifyPodResources(newPod, originalContainers, podResources) + podresize.VerifyPodResources(newPod, originalContainers, podResources) podresize.VerifyPodResizePolicy(newPod, originalContainers) framework.ExpectNoError(podresize.VerifyPodStatusResources(newPod, originalContainers)) framework.ExpectNoError(podresize.VerifyPodContainersCgroupValues(ctx, f, newPod, originalContainers)) @@ -956,3 +1024,34 @@ func createRollbackContainers(originalContainers, expectedContainers []podresize } return rollbackContainers } + +func verifyInitContainerResources(ctx context.Context, f *framework.Framework, pod *v1.Pod, expectedContainers []podresize.ResizableContainerInfo, expectedInitCtr v1.Container) { + ginkgo.GinkgoHelper() + + podresize.VerifyPodResizePolicy(pod, expectedContainers) + podresize.VerifyPodResources(pod, expectedContainers, nil) + + // Wait for the init container to display the expected resources in its status, and that + // the cgroups are as expected. + framework.ExpectNoError(framework.Gomega(). + Eventually(ctx, framework.RetryNotFound(framework.GetObject(f.ClientSet.CoreV1().Pods(pod.Namespace).Get, pod.Name, metav1.GetOptions{}))). + WithTimeout(f.Timeouts.PodStart). + Should(framework.MakeMatcher(func(pod *v1.Pod) (func() string, error) { + if pod == nil || len(pod.Status.InitContainerStatuses) == 0 || pod.Status.InitContainerStatuses[0].Resources == nil { + return func() string { return "pod or init container status is not available yet" }, nil + } + if err := podresize.VerifyPodContainersStatusResources(pod.Status.InitContainerStatuses, []v1.Container{expectedInitCtr}); err != nil { + return func() string { + return fmt.Sprintf("init container status resources don't match expected: %v", err) + }, nil + } + onCgroupv2 := cgroups.IsPodOnCgroupv2Node(f, pod.Name, pod.Spec.InitContainers[0].Name) + if err := cgroups.VerifyContainerCgroupValues(ctx, f, pod, &expectedInitCtr, onCgroupv2); err != nil { + return func() string { + return fmt.Sprintf("cgroup values for init container don't match expected: %v", err) + }, nil + } + return nil, nil + })), + ) +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/pods.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/pods.go index 00e0eae1c9..c948a2e544 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/pods.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/pods.go @@ -176,7 +176,7 @@ func getRestartDelay(ctx context.Context, podClient *e2epod.PodClient, podName s func expectNoErrorWithRetries(fn func() error, maxRetries int, explain ...interface{}) { // TODO (pohly): replace the entire function with gomege.Eventually. var err error - for i := 0; i < maxRetries; i++ { + for i := range maxRetries { err = fn() if err == nil { return @@ -750,7 +750,7 @@ var _ = SIGDescribe("Pods", func() { delay1 time.Duration err error ) - for i := 0; i < 3; i++ { + for range 3 { delay1, err = getRestartDelay(ctx, podClient, podName, containerName) if err != nil { framework.Failf("timed out waiting for container restart in pod=%s/%s", podName, containerName) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/runtime.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/runtime.go index e455e0c1bb..ec5bc38e3c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/runtime.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/runtime.go @@ -376,7 +376,7 @@ func ImagePullTest(ctx context.Context, f *framework.Framework, image string, im ginkgo.By("check the container status") var latestErr error - err := wait.PollUntilContextCancel(ctx, ContainerStatusPollInterval, true, func(ctx context.Context) (bool, error) { + err := wait.PollUntilContextTimeout(ctx, ContainerStatusPollInterval, ContainerStatusRetryTimeout, true, func(ctx context.Context) (bool, error) { if latestErr = checkContainerStatus(ctx); latestErr != nil { return false, nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/node/security_context.go b/vendor/k8s.io/kubernetes/test/e2e/common/node/security_context.go index 85400318d2..1cbfa7e13a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/node/security_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/node/security_context.go @@ -28,7 +28,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/test/e2e/feature" @@ -88,7 +87,7 @@ var _ = SIGDescribe("Security Context", func() { } } - f.It("must create the user namespace if set to false [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("must create the user namespace if set to false [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { // with hostUsers=false the pod must use a new user namespace podClient := e2epod.PodClientNS(f, f.Namespace.Name) @@ -126,82 +125,7 @@ var _ = SIGDescribe("Security Context", func() { } }) - f.It("must create a user namespace and use host network when hostUsers is false and hostNetwork is true [LinuxOnly]", feature.UserNamespacesHostNetworkSupport, framework.WithFeatureGate(features.UserNamespacesHostNetworkSupport), - feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { - // with hostUsers=false the pod must use a new user namespace. - // with hostNetwork=true the pod must use the host network namespace. - podClient := e2epod.PodClientNS(f, f.Namespace.Name) - - // Schedule pods on the same node to ensure they share the same host network namespace. - targetNode, err := findLinuxNode(ctx, f) - framework.ExpectNoError(err, "Error finding Linux node") - - makePodForHostNetTest := func(nodeName string) *v1.Pod { - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "userns-hostnet-" + string(uuid.NewUUID()), - }, - Spec: v1.PodSpec{ - NodeName: nodeName, - Containers: []v1.Container{ - { - Name: containerName, - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"sh", "-c", "cat /proc/self/uid_map && readlink /proc/self/ns/net"}, - }, - }, - RestartPolicy: v1.RestartPolicyNever, - HostUsers: ptr.To(false), - HostNetwork: true, - }, - } - } - - createdPod1 := podClient.Create(ctx, makePodForHostNetTest(targetNode.Name)) - createdPod2 := podClient.Create(ctx, makePodForHostNetTest(targetNode.Name)) - ginkgo.DeferCleanup(func(ctx context.Context) { - ginkgo.By("delete the pods") - podClient.DeleteSync(ctx, createdPod1.Name, metav1.DeleteOptions{}, f.Timeouts.PodDelete) - podClient.DeleteSync(ctx, createdPod2.Name, metav1.DeleteOptions{}, f.Timeouts.PodDelete) - }) - getLogs := func(pod *v1.Pod) (string, string, error) { - err := e2epod.WaitForPodSuccessInNamespaceTimeout(ctx, f.ClientSet, pod.Name, f.Namespace.Name, f.Timeouts.PodStart) - if err != nil { - return "", "", err - } - podStatus, err := podClient.Get(ctx, pod.Name, metav1.GetOptions{}) - if err != nil { - return "", "", err - } - logs, err := e2epod.GetPodLogs(ctx, f.ClientSet, f.Namespace.Name, podStatus.Name, containerName) - if err != nil { - return "", "", err - } - parts := strings.Split(strings.TrimSpace(logs), "\n") - if len(parts) != 2 { - return "", "", fmt.Errorf("expected 2 lines of logs, got %d: %q", len(parts), logs) - } - return parts[0], parts[1], nil - } - - uidMap1, netNs1, err := getLogs(createdPod1) - framework.ExpectNoError(err) - uidMap2, netNs2, err := getLogs(createdPod2) - framework.ExpectNoError(err) - - // 65536 is the size used for a user namespace. Verify that the value is present - // in the /proc/self/uid_map file. - gomega.Expect(uidMap1).To(gomega.ContainSubstring("65536"), "user namespace not created for pod1") - gomega.Expect(uidMap2).To(gomega.ContainSubstring("65536"), "user namespace not created for pod2") - - // Check they are in different user namespaces. - gomega.Expect(uidMap1).NotTo(gomega.Equal(uidMap2), "two different pods are running with the same user namespace configuration") - - // Check they are in the same network namespace (the host's one). - gomega.Expect(netNs1).To(gomega.Equal(netNs2), "two different pods with hostNetwork=true should be in the same network namespace, but they are not. NetNS1: %s, NetNS2: %s", netNs1, netNs2) - }) - - f.It("must create the user namespace in the configured hostUID/hostGID range [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("must create the user namespace in the configured hostUID/hostGID range [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { // We need to check with the binary "getsubuids" the mappings for the kubelet. // If something is not present, we skip the test as the node wasn't configured to run this test. id, length, err := kubeletUsernsMappings(getsubuidsBinary) @@ -209,7 +133,7 @@ var _ = SIGDescribe("Security Context", func() { e2eskipper.Skipf("node is not setup for userns with kubelet mappings: %v", err) } - for i := 0; i < 4; i++ { + for range 4 { // makePod(false) creates the pod with user namespace podClient := e2epod.PodClientNS(f, f.Namespace.Name) createdPod := podClient.Create(ctx, makePod(false)) @@ -269,7 +193,7 @@ var _ = SIGDescribe("Security Context", func() { } }) - f.It("must not create the user namespace if set to true [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("must not create the user namespace if set to true [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { // with hostUsers=true the pod must use the host user namespace pod := makePod(true) // When running in the host's user namespace, the /proc/self/uid_map file content looks like: @@ -280,7 +204,7 @@ var _ = SIGDescribe("Security Context", func() { }) }) - f.It("should mount all volumes with proper permissions with hostUsers=false [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("should mount all volumes with proper permissions with hostUsers=false [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { // Create configmap. name := "userns-volumes-test-" + string(uuid.NewUUID()) configMap := newConfigMap(f, name) @@ -402,7 +326,7 @@ var _ = SIGDescribe("Security Context", func() { }) }) - f.It("should set FSGroup to user inside the container with hostUsers=false [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("should set FSGroup to user inside the container with hostUsers=false [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { // Create configmap. name := "userns-volumes-test-" + string(uuid.NewUUID()) configMap := newConfigMap(f, name) @@ -461,7 +385,7 @@ var _ = SIGDescribe("Security Context", func() { strings.Repeat(fmt.Sprintf("=%v\n", fsGroup), len(configMap.Data)), }) }) - f.It("metrics should report count of started and failed user namespaced pods [LinuxOnly]", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { + f.It("metrics should report count of started and failed user namespaced pods [LinuxOnly]", feature.UserNamespacesSupport, func(ctx context.Context) { targetNode, err := findLinuxNode(ctx, f) framework.ExpectNoError(err, "Error finding Linux node") framework.Logf("Using node: %v", targetNode.Name) @@ -549,7 +473,7 @@ var _ = SIGDescribe("Security Context", func() { }) }) - ginkgo.Context("When creating a container with runAsNonRoot", func() { + f.Context("When creating a container with runAsNonRoot", f.WithNodeConformance(), func() { rootImage := imageutils.GetE2EImage(imageutils.BusyBox) nonRootImage := imageutils.GetE2EImage(imageutils.NonRoot) makeNonRootPod := func(podName, image string, userid *int64) *v1.Pod { @@ -821,7 +745,7 @@ var _ = SIGDescribe("Security Context", func() { }) }) - f.Context("SupplementalGroupsPolicy [LinuxOnly]", func() { + f.Context("SupplementalGroupsPolicy [LinuxOnly]", feature.SupplementalGroupsPolicy, func() { timeout := 1 * time.Minute agnhostImage := imageutils.GetE2EImage(imageutils.Agnhost) @@ -976,32 +900,30 @@ var _ = SIGDescribe("User Namespaces for Restricted Pod Security Standards [Linu f := framework.NewDefaultFramework("user-namespaces-pss-test") f.NamespacePodSecurityLevel = admissionapi.LevelRestricted - ginkgo.Context("with UserNamespacesSupport enabled", func() { - f.It("should allow pod", feature.UserNamespacesSupport, framework.WithFeatureGate(features.UserNamespacesSupport), func(ctx context.Context) { - name := "pod-user-namespaces-pss-" + string(uuid.NewUUID()) - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: v1.PodSpec{ - RestartPolicy: v1.RestartPolicyNever, - HostUsers: ptr.To(false), - SecurityContext: &v1.PodSecurityContext{}, - Containers: []v1.Container{ - { - Name: name, - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"whoami"}, - SecurityContext: &v1.SecurityContext{ - AllowPrivilegeEscalation: ptr.To(false), - Capabilities: &v1.Capabilities{Drop: []v1.Capability{"ALL"}}, - SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}, - }, + f.It("should allow userns pod", feature.UserNamespacesSupport, func(ctx context.Context) { + name := "pod-user-namespaces-pss-" + string(uuid.NewUUID()) + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyNever, + HostUsers: ptr.To(false), + SecurityContext: &v1.PodSecurityContext{}, + Containers: []v1.Container{ + { + Name: name, + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"whoami"}, + SecurityContext: &v1.SecurityContext{ + AllowPrivilegeEscalation: ptr.To(false), + Capabilities: &v1.Capabilities{Drop: []v1.Capability{"ALL"}}, + SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}, }, }, }, - } + }, + } - e2epodoutput.TestContainerOutput(ctx, f, "RunAsUser-RunAsNonRoot", pod, 0, []string{"root"}) - }) + e2epodoutput.TestContainerOutput(ctx, f, "RunAsUser-RunAsNonRoot", pod, 0, []string{"root"}) }) }) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/configmap_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/configmap_volume.go index bfdf085f78..e7dde43f63 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/configmap_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/configmap_volume.go @@ -59,7 +59,7 @@ var _ = SIGDescribe("ConfigMap", func() { doConfigMapE2EWithoutMappings(ctx, f, false, 0, &defaultMode) }) - f.It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options, and it does not support setting file permissions. e2eskipper.SkipIfNodeOSDistroIs("windows") defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */ @@ -75,7 +75,7 @@ var _ = SIGDescribe("ConfigMap", func() { doConfigMapE2EWithoutMappings(ctx, f, true, 0, nil) }) - f.It("should be consumable from pods in volume as non-root with FSGroup [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume as non-root with FSGroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") doConfigMapE2EWithoutMappings(ctx, f, true, 1001, nil) @@ -110,7 +110,7 @@ var _ = SIGDescribe("ConfigMap", func() { doConfigMapE2EWithMappings(ctx, f, true, 0, nil) }) - f.It("should be consumable from pods in volume with mappings as non-root with FSGroup [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume with mappings as non-root with FSGroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") doConfigMapE2EWithMappings(ctx, f, true, 1001, nil) @@ -554,7 +554,7 @@ var _ = SIGDescribe("ConfigMap", func() { // The pod is in pending during volume creation until the configMap objects are available // or until mount the configMap volume times out. There is no configMap object defined for the pod, so it should return timeout exception unless it is marked optional. // Slow (~5 mins) - f.It("Should fail non-optional pod creation due to configMap object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to configMap object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/configmap-volumes" pod := createNonOptionalConfigMapPod(ctx, f, volumeMountPath) getPod := e2epod.Get(f.ClientSet, pod) @@ -564,7 +564,7 @@ var _ = SIGDescribe("ConfigMap", func() { // ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap, // the volume setup will error unless it is marked optional, during the pod creation. // Slow (~5 mins) - f.It("Should fail non-optional pod creation due to the key in the configMap object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to the key in the configMap object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/configmap-volumes" pod := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath) getPod := e2epod.Get(f.ClientSet, pod) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/downwardapi_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/downwardapi_volume.go index e2334df72d..51c3970273 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/downwardapi_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/downwardapi_volume.go @@ -92,7 +92,7 @@ var _ = SIGDescribe("Downward API volume", func() { }) }) - f.It("should provide podname as non-root with fsgroup [LinuxOnly]", func(ctx context.Context) { + f.It("should provide podname as non-root with fsgroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") podName := "metadata-volume-" + string(uuid.NewUUID()) @@ -107,7 +107,7 @@ var _ = SIGDescribe("Downward API volume", func() { }) }) - f.It("should provide podname as non-root with fsgroup and defaultMode [LinuxOnly]", func(ctx context.Context) { + f.It("should provide podname as non-root with fsgroup and defaultMode [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options, and it does not support setting file permissions. e2eskipper.SkipIfNodeOSDistroIs("windows") podName := "metadata-volume-" + string(uuid.NewUUID()) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/empty_dir.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/empty_dir.go index 7c8d5427fd..fd1b18b72e 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/empty_dir.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/empty_dir.go @@ -48,7 +48,7 @@ var _ = SIGDescribe("EmptyDir volumes", func() { f := framework.NewDefaultFramework("emptydir") f.NamespacePodSecurityLevel = admissionapi.LevelBaseline - f.Context("when FSGroup is specified [LinuxOnly]", func() { + f.Context("when FSGroup is specified [LinuxOnly]", f.WithNodeConformance(), func() { ginkgo.BeforeEach(func() { // Windows does not support the FSGroup SecurityContext option. @@ -298,7 +298,7 @@ var _ = SIGDescribe("EmptyDir volumes", func() { Testname: EmptyDir, Memory backed volume is sized to specified limit Description: A Pod created with an 'emptyDir' Volume backed by memory should be sized to user provided value. */ - ginkgo.It("pod should support memory backed volumes of specified size", func(ctx context.Context) { + f.It("pod should support memory backed volumes of specified size", f.WithNodeConformance(), func(ctx context.Context) { var ( volumeName = "shared-data" busyBoxMainVolumeMountPath = "/usr/share/volumeshare" diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_configmap.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_configmap.go index a1d8dac010..0b1a229ac0 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_configmap.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_configmap.go @@ -59,7 +59,7 @@ var _ = SIGDescribe("Projected configMap", func() { doProjectedConfigMapE2EWithoutMappings(ctx, f, false, 0, &defaultMode) }) - f.It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options, and it does not support setting file permissions. e2eskipper.SkipIfNodeOSDistroIs("windows") defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */ @@ -75,7 +75,7 @@ var _ = SIGDescribe("Projected configMap", func() { doProjectedConfigMapE2EWithoutMappings(ctx, f, true, 0, nil) }) - f.It("should be consumable from pods in volume as non-root with FSGroup [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume as non-root with FSGroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") doProjectedConfigMapE2EWithoutMappings(ctx, f, true, 1001, nil) @@ -110,7 +110,7 @@ var _ = SIGDescribe("Projected configMap", func() { doProjectedConfigMapE2EWithMappings(ctx, f, true, 0, nil) }) - f.It("should be consumable from pods in volume with mappings as non-root with FSGroup [LinuxOnly]", func(ctx context.Context) { + f.It("should be consumable from pods in volume with mappings as non-root with FSGroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") doProjectedConfigMapE2EWithMappings(ctx, f, true, 1001, nil) @@ -460,7 +460,7 @@ var _ = SIGDescribe("Projected configMap", func() { //The pod is in pending during volume creation until the configMap objects are available //or until mount the configMap volume times out. There is no configMap object defined for the pod, so it should return timeout exception unless it is marked optional. //Slow (~5 mins) - f.It("Should fail non-optional pod creation due to configMap object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to configMap object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/projected-configmap-volumes" pod := createNonOptionalConfigMapPod(ctx, f, volumeMountPath) getPod := e2epod.Get(f.ClientSet, pod) @@ -470,7 +470,7 @@ var _ = SIGDescribe("Projected configMap", func() { //ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap, // the volume setup will error unless it is marked optional, during the pod creation. //Slow (~5 mins) - f.It("Should fail non-optional pod creation due to the key in the configMap object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to the key in the configMap object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/configmap-volumes" pod := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath) getPod := e2epod.Get(f.ClientSet, pod) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_downwardapi.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_downwardapi.go index 78ed1c9022..2c0b605f57 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_downwardapi.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_downwardapi.go @@ -92,7 +92,7 @@ var _ = SIGDescribe("Projected downwardAPI", func() { }) }) - f.It("should provide podname as non-root with fsgroup [LinuxOnly]", func(ctx context.Context) { + f.It("should provide podname as non-root with fsgroup [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options. e2eskipper.SkipIfNodeOSDistroIs("windows") podName := "metadata-volume-" + string(uuid.NewUUID()) @@ -107,7 +107,7 @@ var _ = SIGDescribe("Projected downwardAPI", func() { }) }) - f.It("should provide podname as non-root with fsgroup and defaultMode [LinuxOnly]", func(ctx context.Context) { + f.It("should provide podname as non-root with fsgroup and defaultMode [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) { // Windows does not support RunAsUser / FSGroup SecurityContext options, and it does not support setting file permissions. e2eskipper.SkipIfNodeOSDistroIs("windows") podName := "metadata-volume-" + string(uuid.NewUUID()) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_secret.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_secret.go index cf1f81ea61..d26d17ce80 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_secret.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/projected_secret.go @@ -411,7 +411,7 @@ var _ = SIGDescribe("Projected secret", func() { //The secret is in pending during volume creation until the secret objects are available //or until mount the secret volume times out. There is no secret object defined for the pod, so it should return timeout exception unless it is marked optional. //Slow (~5 mins) - f.It("Should fail non-optional pod creation due to secret object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to secret object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/projected-secret-volumes" podName := "pod-secrets-" + string(uuid.NewUUID()) pod := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName) @@ -422,7 +422,7 @@ var _ = SIGDescribe("Projected secret", func() { //Secret object defined for the pod, If a key is specified which is not present in the secret, // the volume setup will error unless it is marked optional, during the pod creation. //Slow (~5 mins) - f.It("Should fail non-optional pod creation due to the key in the secret object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to the key in the secret object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/secret-volumes" podName := "pod-secrets-" + string(uuid.NewUUID()) pod := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName) diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/storage/secrets_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/storage/secrets_volume.go index a41595aa9a..22cb3eea43 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/storage/secrets_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/storage/secrets_volume.go @@ -436,7 +436,7 @@ var _ = SIGDescribe("Secrets", func() { // The secret is in pending during volume creation until the secret objects are available // or until mount the secret volume times out. There is no secret object defined for the pod, so it should return timeout exception unless it is marked optional. // Slow (~5 mins) - f.It("Should fail non-optional pod creation due to secret object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to secret object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/secret-volumes" podName := "pod-secrets-" + string(uuid.NewUUID()) pod := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName) @@ -447,7 +447,7 @@ var _ = SIGDescribe("Secrets", func() { // Secret object defined for the pod, If a key is specified which is not present in the secret, // the volume setup will error unless it is marked optional, during the pod creation. // Slow (~5 mins) - f.It("Should fail non-optional pod creation due to the key in the secret object does not exist", f.WithSlow(), func(ctx context.Context) { + f.It("Should fail non-optional pod creation due to the key in the secret object does not exist", f.WithSlow(), f.WithNodeConformance(), func(ctx context.Context) { volumeMountPath := "/etc/secret-volumes" podName := "pod-secrets-" + string(uuid.NewUUID()) pod := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName) diff --git a/vendor/k8s.io/kubernetes/test/e2e/e2e.go b/vendor/k8s.io/kubernetes/test/e2e/e2e.go index f80c76f013..34a74a4c6b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/e2e.go +++ b/vendor/k8s.io/kubernetes/test/e2e/e2e.go @@ -253,11 +253,6 @@ func setupSuite(ctx context.Context) { if serverVersion != nil { framework.Logf("kube-apiserver version: %s", serverVersion.GitVersion) } - - if framework.TestContext.NodeKiller.Enabled { - nodeKiller := e2enode.NewNodeKiller(framework.TestContext.NodeKiller, c, framework.TestContext.Provider) - go nodeKiller.Run(framework.TestContext.NodeKiller.NodeKillerStopCtx) - } } // logClusterImageSources writes out cluster image sources. diff --git a/vendor/k8s.io/kubernetes/test/e2e/feature/feature.go b/vendor/k8s.io/kubernetes/test/e2e/feature/feature.go index e097f4c7a1..95eb58995b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/feature/feature.go +++ b/vendor/k8s.io/kubernetes/test/e2e/feature/feature.go @@ -99,9 +99,6 @@ var ( // Testing critical pod admission CriticalPod = framework.WithFeature(framework.ValidFeatures.Add("CriticalPod")) - // TODO: document the feature (owning SIG, when to use this feature for a test) - CustomMetricsAutoscaling = framework.WithFeature(framework.ValidFeatures.Add("CustomMetricsAutoscaling")) - // OWNER: sig-node // Testing device managers DeviceManager = framework.WithFeature(framework.ValidFeatures.Add("DeviceManager")) @@ -132,6 +129,10 @@ var ( // their dependency on specific feature gates and the corresponding API groups. DynamicResourceAllocation = framework.WithFeature(framework.ValidFeatures.Add("DynamicResourceAllocation")) + // Owner: sig-node + // EnvFiles is used for testing the EnvFiles feature (file-based environment variables). + EnvFiles = framework.WithFeature(framework.ValidFeatures.Add("EnvFiles")) + // TODO: document the feature (owning SIG, when to use this feature for a test) EphemeralStorage = framework.WithFeature(framework.ValidFeatures.Add("EphemeralStorage")) @@ -205,12 +206,17 @@ var ( // ImageVolume is used for testing the image volume source feature (https://kep.k8s.io/4639). ImageVolume = framework.WithFeature(framework.ValidFeatures.Add("ImageVolume")) + // Owner: sig-node + // InPlacePodVerticalScaling is used for testing in-place pod vertical scaling (https://kep.k8s.io/1287). + InPlacePodVerticalScaling = framework.WithFeature(framework.ValidFeatures.Add("InPlacePodVerticalScaling")) + // Owner: sig-network // Marks tests that require a conforming implementation of // Ingress.networking.k8s.io to be present. Ingress = framework.WithFeature(framework.ValidFeatures.Add("Ingress")) - // TODO: document the feature (owning SIG, when to use this feature for a test) + // Owner: sig-storage + // Marks tests that only work with a sigs.k8s.io/kind cluster Kind = framework.WithFeature(framework.ValidFeatures.Add("Kind")) // Owner: sig-network @@ -305,7 +311,10 @@ var ( // TODO: document the feature (owning SIG, when to use this feature for a test) NodeAuthorizer = framework.WithFeature(framework.ValidFeatures.Add("NodeAuthorizer")) - // TODO: document the feature (owning SIG, when to use this feature for a test) + // Owner: sig-windows, sig-node + // kep: https://kep.k8s.io/2271 + // Marks tests that require the kubelet to have enableSystemLogQuery set to true + // in the kubelet configuration. This handler is off by default. NodeLogQuery = framework.WithFeature(framework.ValidFeatures.Add("NodeLogQuery")) // Owner: sig-node @@ -323,6 +332,11 @@ var ( // TODO: document the feature (owning SIG, when to use this feature for a test) PodGarbageCollector = framework.WithFeature(framework.ValidFeatures.Add("PodGarbageCollector")) + // owner: sig-node + // Marks a test for pod-level resource managers feature that requires + // PodLevelResourceManagers feature gate to be enabled. + PodLevelResourceManagers = framework.WithFeature(framework.ValidFeatures.Add("PodLevelResourceManagers")) + // owner: sig-node // Marks a test for pod-level resources feature that requires // PodLevelResources feature gate to be enabled. @@ -407,6 +421,15 @@ var ( // and the networking.k8s.io/v1alpha1 API. ServiceCIDRs = framework.WithFeature(framework.ValidFeatures.Add("ServiceCIDRs")) + // Owner: sig-storage + // KEP: https://kep.k8s.io/3314 + // Tests marked with this feature require: + // - A CSI driver that supports the snapshot metadata service (e.g., CSI hostpath driver with --enable-snapshot-metadata) + // - The external-snapshot-metadata sidecar deployed alongside the CSI driver + // - The SnapshotMetadataService CRD (cbt.storage.k8s.io/v1beta1) installed + // - A storage driver that implements the CapSnapshotMetadata capability + SnapshotMetadata = framework.WithFeature(framework.ValidFeatures.Add("snapshotmetadata")) + // TODO: document the feature (owning SIG, when to use this feature for a test) StackdriverAcceleratorMonitoring = framework.WithFeature(framework.ValidFeatures.Add("StackdriverAcceleratorMonitoring")) @@ -439,6 +462,10 @@ var ( // TODO: document the feature (owning SIG, when to use this feature for a test) StorageVersionAPI = framework.WithFeature(framework.ValidFeatures.Add("StorageVersionAPI")) + // Owner: sig-node + // SupplementalGroupsPolicy is used for testing the SupplementalGroupsPolicy feature. + SupplementalGroupsPolicy = framework.WithFeature(framework.ValidFeatures.Add("SupplementalGroupsPolicy")) + // The Swap feature tests must run on nodes with the swap memory allocated and kubelet swap enabled. KEP-2400 (Node Swap Support) Swap = framework.WithFeature(framework.ValidFeatures.Add("NodeSwap")) @@ -455,7 +482,9 @@ var ( // This feature can be removed once Containerd and CRI-O both added this support. UserNamespacesHostNetworkSupport = framework.WithFeature(framework.ValidFeatures.Add("UserNamespacesHostNetworkSupport")) - // TODO: document the feature (owning SIG, when to use this feature for a test) + // UserNamespacesSupport is in test-infra nodes that have runtimes with user-namespaces + // support. It will be dropped after containerd 1.7 support is removed from CI. + // Owner: sig-node UserNamespacesSupport = framework.WithFeature(framework.ValidFeatures.Add("UserNamespacesSupport")) // TODO: document the feature (owning SIG, when to use this feature for a test) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go index 073cbe891a..9da8e92180 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go @@ -175,7 +175,7 @@ func NewLogsVerifier(ctx context.Context, c clientset.Interface) *LogsSizeVerifi workers: workers, } verifier.wg.Add(workersNo) - for i := 0; i < workersNo; i++ { + for i := range workersNo { workers[i] = &LogSizeGatherer{ data: verifier.data, wg: &verifier.wg, diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go index 74df75a634..33c786277d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go @@ -31,12 +31,12 @@ import ( "strings" "time" - "k8s.io/apimachinery/pkg/runtime" - v1 "k8s.io/api/core/v1" + apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" v1svc "k8s.io/client-go/applyconfigurations/core/v1" @@ -48,8 +48,10 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" scaleclient "k8s.io/client-go/scale" + "k8s.io/kubernetes/test/utils/ktesting" admissionapi "k8s.io/pod-security-admission/api" + "github.com/go-logr/logr" "github.com/onsi/ginkgo/v2" ) @@ -95,7 +97,17 @@ var ( // The default pod security profile is "restricted". // Each of the labels can be overridden by using more specific NamespacePodSecurity* attributes of this // struct. +// +// A framework instance implements ktesting.TB and thus can be passed as +// first parameter to [github.com/stretchr/testify/assert]. +// There are just two caveats: +// - Error and Errorf abort the currently running test. +// - This only works while a test runs, not while defining tests. +// Incorrect tests may panic. The same applies to using ginkgo.Fail +// outside of tests. type Framework struct { + ktesting.TB + BaseName string // Set together with creating the ClientSet and the namespace. @@ -104,6 +116,7 @@ type Framework struct { UniqueName string clientConfig *rest.Config + restMapper *restmapper.DeferredDiscoveryRESTMapper ClientSet clientset.Interface KubemarkExternalClusterClientSet clientset.Interface @@ -139,6 +152,94 @@ type Framework struct { DumpAllNamespaceInfo DumpAllNamespaceInfoAction } +// CleanupCtx implements [ktesting.ContextTB.CleanupCtx]. It's identical to +// ginkgo.DeferCleanup. +func (f *Framework) CleanupCtx(cb func(context.Context)) { + ginkgo.GinkgoHelper() + ginkgo.DeferCleanup(cb) +} + +// Log implements TB.Log. It overrides the implementation from Ginkgo to ensure consistent output. +func (f *Framework) Log(args ...any) { + log(1, strings.TrimSuffix(fmt.Sprintln(args...), "\n")) +} + +// Logf implements TB.Logf. It overrides the implementation from Ginkgo to ensure consistent output. +func (f *Framework) Logf(format string, args ...any) { + log(1, fmt.Sprintf(format, args...)) +} + +var _ ktesting.ContextTB = &Framework{} + +// TContext combines the framework and the context in a [ktesting.TContext]. +// +// Legacy code which accepts separate [context.Context] and [clientset.Interface] +// parameters can call [ContextTODO] with those two parameters to +// create a [ktesting.TContext] which also has all clients, but this is +// an interim solution. It's cleaner to rewrite that code to accept +// a [ktesting.TContext]. +func (f *Framework) TContext(ctx context.Context) ktesting.TContext { + if f.TB == nil { + // Test setup typically has no context, so this is unlikely to be reached. + // A sufficiently determined developer might pass in context.Background(), + // so let's be explicit anyway. + panic("TContext may only be used while a test runs.") + } + tCtx := ktesting.InitCtx(ctx, f /* intentionally using f here and not f.TB because f overrides some methods */) + tCtx = tCtx.WithClients(f.clientConfig, f.restMapper, f.ClientSet, f.DynamicClient, apiextensions.NewForConfigOrDie(f.clientConfig)) + if f.Namespace != nil { + tCtx = tCtx.WithNamespace(f.Namespace.Name) + } + tCtx = ensureLogger(tCtx) + return tCtx +} + +// ContextTODO can be used as interim solution in functions which currently +// accept a [context.Context] and [clientset.Interface] to create +// a [ktesting.TContext] for other code which already uses that instead +// of different parameters. If the client is [Framework.ClientSet], +// the result is identical to the one from [Framework.TContext]. +// In particular, dynamic client and rest config are available. +// +// Long-term code relying on ContextTODO should get rewritten. +func ContextTODO(ctx context.Context, client clientset.Interface) ktesting.TContext { + // If the client was taken from a framework instance, then + // we can cast it here to prepare a complete context. + if fc, ok := client.(fClient); ok { + return fc.f.TContext(ctx) + } + f := NewDefaultFramework("tcontext") + tCtx := ktesting.InitCtx(ctx, f) + tCtx = tCtx.WithClients(nil, nil, client, nil, nil) + tCtx = ensureLogger(tCtx) + return tCtx +} + +// ensureLogger installs the Ginkgo logger in the context if there isn't one +// already. +// +// This isn't needed for code which uses klog.FromContext because that uses the +// klog logger as default, which is the Gingko logger. But there might also be +// code which uses go-logr directly: then providing the logger through the +// context is useful. +func ensureLogger(tCtx ktesting.TContext) ktesting.TContext { + _, ok := logr.FromContext(tCtx) + if ok == nil { + return tCtx + } + + return tCtx.WithLogger(ginkgoLogger) +} + +// fClient is stored in framework.ClientSet and used by ContextTODO. +// +// TODO: remove this and ContextTODO once it is no longer needed, i.e. +// when all code accepts a TContext. +type fClient struct { + clientset.Interface + f *Framework +} + // DumpAllNamespaceInfoAction is called after each failed test for namespaces // created for the test. type DumpAllNamespaceInfoAction func(ctx context.Context, f *Framework, namespace string) @@ -188,6 +289,7 @@ func NewDefaultFramework(baseName string) *Framework { // NewFramework creates a test framework. func NewFramework(baseName string, options Options, client clientset.Interface) *Framework { f := &Framework{ + // TB initially not set yet. It may only be used while tests run. BaseName: baseName, Options: options, ClientSet: client, @@ -207,6 +309,8 @@ func NewFramework(baseName string, options Options, client clientset.Interface) // BeforeEach gets a client and makes a namespace. func (f *Framework) BeforeEach(ctx context.Context) { + f.TB = ginkgo.GinkgoT() + // DeferCleanup, in contrast to AfterEach, triggers execution in // first-in-last-out order. This ensures that the framework instance // remains valid as long as possible. @@ -230,8 +334,12 @@ func (f *Framework) BeforeEach(ctx context.Context) { config.ContentType = TestContext.KubeAPIContentType } f.clientConfig = rest.CopyConfig(config) - f.ClientSet, err = clientset.NewForConfig(config) + clientSet, err := clientset.NewForConfig(config) ExpectNoError(err) + f.ClientSet = fClient{ + Interface: clientSet, + f: f, + } f.DynamicClient, err = dynamic.NewForConfig(config) ExpectNoError(err) @@ -250,6 +358,7 @@ func (f *Framework) BeforeEach(ctx context.Context) { cachedDiscoClient := cacheddiscovery.NewMemCacheClient(discoClient) restMapper := restmapper.NewDeferredDiscoveryRESTMapper(cachedDiscoClient) restMapper.Reset() + f.restMapper = restMapper resolver := scaleclient.NewDiscoveryScaleKindResolver(cachedDiscoClient) f.ScalesGetter = scaleclient.New(restClient, restMapper, dynamic.LegacyAPIPathResolverFunc, resolver) @@ -386,6 +495,7 @@ func (f *Framework) AfterEach(ctx context.Context) { f.clientConfig = nil f.ClientSet = nil f.namespacesToDelete = nil + f.TB = nil // if we had errors deleting, report them now. if len(nsDeletionErrors) != 0 { diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgologger.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgologger.go index 6e2c956997..d25c3d61b7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgologger.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgologger.go @@ -110,7 +110,7 @@ func log(offset int, msg string) { } _, month, day := now.Date() hour, minute, second := now.Clock() - header := fmt.Sprintf("I%02d%02d %02d:%02d:%02d.%06d %d %s:%d]", + header := fmt.Sprintf("I%02d%02d %02d:%02d:%02d.%06d %7d %s:%d]", month, day, hour, minute, second, now.Nanosecond()/1000, Pid, file, line) fmt.Fprintln(ginkgo.GinkgoWriter, header, msg) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go index 1dca00dc22..2a85a8d64c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go @@ -128,10 +128,12 @@ func AnnotatedLocationWithOffset(annotation string, offset int) types.CodeLocati // the SIG name as annotation. The parameter should be lowercase with // no spaces and no sig- or SIG- prefix. func SIGDescribe(sig string) func(...interface{}) bool { + ginkgo.GinkgoHelper() if !sigRE.MatchString(sig) || strings.HasPrefix(sig, "sig-") { - RecordBug(NewBug(fmt.Sprintf("SIG label must be lowercase, no spaces and no sig- prefix, got instead: %q", sig), 1)) + RecordBug(NewBug(fmt.Sprintf("SIG label must be lowercase, no spaces and no sig- prefix, got instead: %q", sig), 0)) } return func(args ...interface{}) bool { + ginkgo.GinkgoHelper() args = append([]interface{}{WithLabel("sig-" + sig)}, args...) return registerInSuite(ginkgo.Describe, args) } @@ -145,58 +147,127 @@ func ConformanceIt(args ...interface{}) bool { return It(args...) } -// It is a wrapper around [ginkgo.It] which supports framework With* labels as -// optional arguments in addition to those already supported by ginkgo itself, -// like [ginkgo.Label] and [ginkgo.Offset]. -// +// It is a wrapper around [ginkgo.It] which removes the requirement +// to start parameters with a text string. // Text and arguments may be mixed. The final text is a concatenation // of the text arguments and special tags from the With functions. func It(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.It, args) } // It is a shorthand for the corresponding package function. func (f *Framework) It(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.It, args) } -// Describe is a wrapper around [ginkgo.Describe] which supports framework -// With* labels as optional arguments in addition to those already supported by -// ginkgo itself, like [ginkgo.Label] and [ginkgo.Offset]. -// +// Describe is a wrapper around [ginkgo.Describe] which removes the requirement +// to start parameters with a text string. // Text and arguments may be mixed. The final text is a concatenation // of the text arguments and special tags from the With functions. func Describe(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.Describe, args) } // Describe is a shorthand for the corresponding package function. func (f *Framework) Describe(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.Describe, args) } -// Context is a wrapper around [ginkgo.Context] which supports framework With* -// labels as optional arguments in addition to those already supported by -// ginkgo itself, like [ginkgo.Label] and [ginkgo.Offset]. -// +// Context is a wrapper around [ginkgo.Context] which removes the requirement +// to start parameters with a text string. // Text and arguments may be mixed. The final text is a concatenation // of the text arguments and special tags from the With functions. func Context(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.Context, args) } // Context is a shorthand for the corresponding package function. func (f *Framework) Context(args ...interface{}) bool { + ginkgo.GinkgoHelper() return registerInSuite(ginkgo.Context, args) } // registerInSuite is the common implementation of all wrapper functions. It // expects to be called through one intermediate wrapper. func registerInSuite(ginkgoCall func(string, ...interface{}) bool, args []interface{}) bool { - var ginkgoArgs []interface{} var offset ginkgo.Offset + for arg := range allArgs(args) { + if o, ok := arg.(ginkgo.Offset); ok { + offset = o + } + } + offset += 2 // This function and the top-level wrapper. + return ginkgoCall("", args, offset) +} + +// allArgs produces an iterator which handles nesting without flattening the slices. +func allArgs(args []any) func(yield func(arg any) bool) { + return func(yield func(arg any) bool) { + iterArgs(args, yield) + } +} + +// iterArgs descends recursively into []any and calls yield for all other arguments. +func iterArgs(args []any, yield func(arg any) bool) bool { + for _, arg := range args { + switch arg := arg.(type) { + case []any: + if !iterArgs(arg, yield) { + return false + } + default: + if !yield(arg) { + return false + } + } + } + return true +} + +// If the framework is used, the user might also use our special test +// arguments. To ensure that test registration works we inject our code into +// the test tree construction. Therefore it doesn't matter anymore whether +// ginkgo.It or framework.It is used. +// +// Code flow is as follows: +// - init registers transformGinkgoNodeArgs. +// From now on, all ginkgo.Describe/Context/It invocations invoke +// transformGinkgoNodeArgs. transformGinkgoNodeArgs replaces +// our special arguments with something that Ginkgo can handle. +// - Top-level Describe calls register callbacks with more test definitions. +// Callbacks are not invoked yet. +// - Argument parsing. +// - Ginkgo invokes the callbacks recursively to get a complete tree of tests. +// - Ginkgo runs those tests. +// +// This init is guaranteed to happen before our special argument functions +// can be called because this is the init code of their package. +// Code which does not use the framework might call ginkgo.Describe before +// transformGinkgoNodeArgs is registered. This is not a problem because none of the parameters can be special. +func init() { + ginkgo.AddTreeConstructionNodeArgsTransformer(transformGinkgoNodeArgs) +} + +func transformGinkgoNodeArgs(nodeType types.NodeType, offset ginkgo.Offset, text string, args []any) (string, []any, []error) { + text, args = expandGinkgoArgs(offset+1, text, args) + return text, args, nil +} + +// expandGinkgoArgs concatenates all strings and translates our custom +// arguments into something that Ginkgo can handle. +func expandGinkgoArgs(offset ginkgo.Offset, text string, args []any) (string, []any) { + var ginkgoArgs []interface{} var texts []string + if text != "" { + texts = append(texts, text) + } + addLabel := func(label string) { texts = append(texts, fmt.Sprintf("[%s]", label)) ginkgoArgs = append(ginkgoArgs, ginkgo.Label(label)) @@ -221,6 +292,9 @@ func registerInSuite(ginkgoCall func(string, ...interface{}) bool, args []interf ginkgoArgs = append(ginkgoArgs, ginkgo.Label("BetaOffByDefault")) } } + if arg.parts[0] == "KubeletMinVersion" { + ginkgoArgs = append(ginkgoArgs, ginkgo.ComponentSemVerConstraint("kubelet", ">="+arg.parts[1])) + } switch fullLabel { case "Serial": ginkgoArgs = append(ginkgoArgs, ginkgo.Serial) @@ -230,8 +304,6 @@ func registerInSuite(ginkgoCall func(string, ...interface{}) bool, args []interf // run and then make the run longer overall. ginkgoArgs = append(ginkgoArgs, ginkgo.SpecPriority(1)) } - case ginkgo.Offset: - offset = arg case string: if arg == "" { haveEmptyStrings = true @@ -241,9 +313,7 @@ func registerInSuite(ginkgoCall func(string, ...interface{}) bool, args []interf ginkgoArgs = append(ginkgoArgs, arg) } } - offset += 2 // This function and its direct caller. - // Now that we have the final offset, we can record bugs. if haveEmptyStrings { RecordBug(NewBug("empty strings as separators are unnecessary and need to be removed", int(offset))) } @@ -256,9 +326,8 @@ func registerInSuite(ginkgoCall func(string, ...interface{}) bool, args []interf } } - ginkgoArgs = append(ginkgoArgs, offset) - text := strings.Join(texts, " ") - return ginkgoCall(text, ginkgoArgs...) + text = strings.Join(texts, " ") + return text, ginkgoArgs } var ( @@ -383,8 +452,8 @@ func recordTextBug(location types.CodeLocation, message string) { } // WithFeature specifies that a certain test or group of tests only works -// with a feature available. The return value must be passed as additional -// argument to [framework.It], [framework.Describe], [framework.Context]. +// with a feature available. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. // // The feature must be listed in ValidFeatures. func WithFeature(name Feature) interface{} { @@ -405,8 +474,8 @@ func withFeature(name Feature) interface{} { // WithFeatureGate specifies that a certain test or group of tests depends on a // feature gate and the corresponding API group (if there is one) -// being enabled. The return value must be passed as additional -// argument to [framework.It], [framework.Describe], [framework.Context]. +// being enabled. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. // // The feature gate must be listed in // [k8s.io/apiserver/pkg/util/feature.DefaultMutableFeatureGate]. Once a @@ -463,8 +532,8 @@ func withFeatureGate(featureGate featuregate.Feature) interface{} { } // WithEnvironment specifies that a certain test or group of tests only works -// in a certain environment. The return value must be passed as additional -// argument to [framework.It], [framework.Describe], [framework.Context]. +// in a certain environment. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. // // The environment must be listed in ValidEnvironments. func WithEnvironment(name Environment) interface{} { @@ -484,9 +553,8 @@ func withEnvironment(name Environment) interface{} { } // WithConformance specifies that a certain test or group of tests must pass in -// all conformant Kubernetes clusters. The return value must be passed as -// additional argument to [framework.It], [framework.Describe], -// [framework.Context]. +// all conformant Kubernetes clusters. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. func WithConformance() interface{} { return withConformance() } @@ -502,8 +570,8 @@ func withConformance() interface{} { // WithNodeConformance specifies that a certain test or group of tests for node // functionality that does not depend on runtime or Kubernetes distro specific -// behavior. The return value must be passed as additional argument to -// [framework.It], [framework.Describe], [framework.Context]. +// behavior. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. func WithNodeConformance() interface{} { return withNodeConformance() } @@ -535,8 +603,8 @@ func withDisruptive() interface{} { } // WithSerial specifies that a certain test or group of tests must not run in -// parallel with other tests. The return value must be passed as additional -// argument to [framework.It], [framework.Describe], [framework.Context]. +// parallel with other tests. The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. // // Starting with ginkgo v2, serial and parallel tests can be executed in the // same invocation. Ginkgo itself will ensure that the serial tests run @@ -556,8 +624,8 @@ func withSerial() interface{} { // WithSlow specifies that a certain test, or each test within a group of // tests, is slow (is expected to take longer than 5 minutes to run in CI). -// The return value must be passed as additional argument to [framework.It], -// [framework.Describe], [framework.Context]. +// The return value may be passed as additional +// argument to the framework wrappers and the Ginkgo functions directly. func WithSlow() interface{} { return withSlow() } @@ -602,6 +670,32 @@ func withFlaky() interface{} { return newLabel("Flaky") } +// WithKubeletMinVersion specifies that a certain test or group tests needs +// a kubelet version >= the given version string. Specifying the minimum +// version as `.` is sufficient. The patch version may be +// added, but is not required. +// +// This adds +// - a `[KubeletMinVersion:]` tag in the text, +// - a `KubeletMinVersion:` label, +// - and a Ginkgo semver constraint for the "kubelet" component. +// +// The easiest way to filter tests is via `ginkgo +// --sem-ver-filter="kubelet=1.35"` which filters out tests that need a newer +// kubelet. +func WithKubeletMinVersion(version string) interface{} { + return withKubeletMinVersion(version) +} + +// WithKubeletMinVersion is a shorthand for the corresponding package function. +func (f *Framework) WithKubeletMinVersion(version string) interface{} { + return withKubeletMinVersion(version) +} + +func withKubeletMinVersion(version string) interface{} { + return newLabel("KubeletMinVersion", version) +} + type label struct { // parts get concatenated with ":" to build the full label. parts []string diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go index b3fe86b8bb..2b67d5d68d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go @@ -161,7 +161,7 @@ func (tk *TestKubeconfig) ReadFileViaContainer(podName, containerName string, pa } func (tk *TestKubeconfig) kubectlExecWithRetry(namespace string, podName, containerName string, args ...string) ([]byte, []byte, error) { - for numRetries := 0; numRetries < maxKubectlExecRetries; numRetries++ { + for numRetries := range maxKubectlExecRetries { if numRetries > 0 { framework.Logf("Retrying kubectl exec (retry count=%v/%v)", numRetries+1, maxKubectlExecRetries) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go index da86979feb..beed66b92d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/network/utils.go @@ -47,7 +47,6 @@ import ( e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output" e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" imageutils "k8s.io/kubernetes/test/utils/image" - netutils "k8s.io/utils/net" ) const ( @@ -332,7 +331,7 @@ func (config *NetworkingTestConfig) DialFromContainer(ctx context.Context, proto responses := sets.NewString() - for i := 0; i < maxTries; i++ { + for i := range maxTries { resp, err := config.GetResponseFromContainer(ctx, protocol, dialCommand, containerIP, targetIP, containerHTTPPort, targetPort) if err != nil { // A failure to kubectl exec counts as a try, not a hard fail. @@ -388,7 +387,7 @@ func (config *NetworkingTestConfig) GetEndpointsFromContainer(ctx context.Contex eps := sets.NewString() - for i := 0; i < tries; i++ { + for i := range tries { stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, config.f, config.TestContainerPod.Name, cmd) if err != nil { // A failure to kubectl exec counts as a try, not a hard fail. @@ -494,7 +493,7 @@ func (config *NetworkingTestConfig) DialFromNode(ctx context.Context, protocol, filterCmd := fmt.Sprintf("%s | grep -v '^\\s*$'", cmd) framework.Logf("Going to poll %v on port %v at least %v times, with a maximum of %v tries before failing", targetIP, targetPort, minTries, maxTries) - for i := 0; i < maxTries; i++ { + for i := range maxTries { stdout, stderr, err := e2epod.ExecShellInPodWithFullOutput(ctx, config.f, config.HostTestContainerPod.Name, filterCmd) if err != nil || len(stderr) > 0 { // A failure to exec command counts as a try, not a hard fail. @@ -838,14 +837,10 @@ func (config *NetworkingTestConfig) setup(ctx context.Context, selector map[stri config.SecondaryClusterIP = config.NodePortService.Spec.ClusterIPs[1] } - // Obtain the primary IP family of the Cluster based on the first ClusterIP - // TODO: Eventually we should just be getting these from Spec.IPFamilies - // but for now that would only if the feature gate is enabled. - family := v1.IPv4Protocol - secondaryFamily := v1.IPv6Protocol - if netutils.IsIPv6String(config.ClusterIP) { - family = v1.IPv6Protocol - secondaryFamily = v1.IPv4Protocol + var family, secondaryFamily v1.IPFamily + family = config.NodePortService.Spec.IPFamilies[0] + if len(config.NodePortService.Spec.IPFamilies) == 2 { + secondaryFamily = config.NodePortService.Spec.IPFamilies[1] } if config.PreferExternalAddresses { // Get Node IPs from the cluster, ExternalIPs take precedence diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go deleted file mode 100644 index fafb6b6a64..0000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 2014 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 node - -import ( - "context" - "sync" - "time" - - "github.com/onsi/ginkgo/v2" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/wait" - clientset "k8s.io/client-go/kubernetes" - - "k8s.io/kubernetes/test/e2e/framework" - e2essh "k8s.io/kubernetes/test/e2e/framework/ssh" -) - -// NodeKiller is a utility to simulate node failures. -type NodeKiller struct { - config framework.NodeKillerConfig - client clientset.Interface - provider string -} - -// NewNodeKiller creates new NodeKiller. -func NewNodeKiller(config framework.NodeKillerConfig, client clientset.Interface, provider string) *NodeKiller { - config.NodeKillerStopCtx, config.NodeKillerStop = context.WithCancel(context.Background()) - return &NodeKiller{config, client, provider} -} - -// Run starts NodeKiller until stopCh is closed. -func (k *NodeKiller) Run(ctx context.Context) { - // wait.JitterUntil starts work immediately, so wait first. - time.Sleep(wait.Jitter(k.config.Interval, k.config.JitterFactor)) - wait.JitterUntilWithContext(ctx, func(ctx context.Context) { - nodes := k.pickNodes(ctx) - k.kill(ctx, nodes) - }, k.config.Interval, k.config.JitterFactor, true) -} - -func (k *NodeKiller) pickNodes(ctx context.Context) []v1.Node { - nodes, err := GetReadySchedulableNodes(ctx, k.client) - framework.ExpectNoError(err) - numNodes := int(k.config.FailureRatio * float64(len(nodes.Items))) - - nodes, err = GetBoundedReadySchedulableNodes(ctx, k.client, numNodes) - framework.ExpectNoError(err) - return nodes.Items -} - -func (k *NodeKiller) kill(ctx context.Context, nodes []v1.Node) { - wg := sync.WaitGroup{} - wg.Add(len(nodes)) - for _, node := range nodes { - node := node - go func() { - defer ginkgo.GinkgoRecover() - defer wg.Done() - - framework.Logf("Stopping docker and kubelet on %q to simulate failure", node.Name) - err := e2essh.IssueSSHCommand(ctx, "sudo systemctl stop docker kubelet", k.provider, &node) - if err != nil { - framework.Logf("ERROR while stopping node %q: %v", node.Name, err) - return - } - - time.Sleep(k.config.SimulatedDowntime) - - framework.Logf("Rebooting %q to repair the node", node.Name) - err = e2essh.IssueSSHCommand(ctx, "sudo reboot", k.provider, &node) - if err != nil { - framework.Logf("ERROR while rebooting node %q: %v", node.Name, err) - return - } - }() - } - wg.Wait() -} 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 5c154d6899..d6359a2d80 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go @@ -41,6 +41,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" clientretry "k8s.io/client-go/util/retry" + resourceapi "k8s.io/kubernetes/pkg/api/v1/resource" "k8s.io/kubernetes/test/e2e/framework" netutil "k8s.io/utils/net" ) @@ -88,18 +89,6 @@ type PodNode struct { Node string } -// FirstAddress returns the first address of the given type of each node. -func FirstAddress(nodelist *v1.NodeList, addrType v1.NodeAddressType) string { - for _, n := range nodelist.Items { - for _, addr := range n.Status.Addresses { - if addr.Type == addrType && addr.Address != "" { - return addr.Address - } - } - } - return "" -} - func isNodeConditionSetAsExpected(node *v1.Node, conditionType v1.NodeConditionType, wantTrue, silent bool) bool { // Check the node readiness condition (logging all). for _, cond := range node.Status.Conditions { @@ -293,19 +282,6 @@ func CollectAddresses(nodes *v1.NodeList, addressType v1.NodeAddressType) []stri return ips } -// PickIP picks one public node IP -func PickIP(ctx context.Context, c clientset.Interface) (string, error) { - publicIps, err := GetPublicIps(ctx, c) - if err != nil { - return "", fmt.Errorf("get node public IPs error: %w", err) - } - if len(publicIps) == 0 { - return "", fmt.Errorf("got unexpected number (%d) of public IPs", len(publicIps)) - } - ip := publicIps[0] - return ip, nil -} - // GetPublicIps returns a public IP list of nodes. func GetPublicIps(ctx context.Context, c clientset.Interface) ([]string, error) { nodes, err := GetReadySchedulableNodes(ctx, c) @@ -500,6 +476,49 @@ func hasNonblockingTaint(node *v1.Node, nonblockingTaints string) bool { return false } +// GetNodeAllocatableAndAvailableQuantities with resourceName set to v1.ResourceCPU ( or set to v1.ResourceMemory ) returns +// - the first return value, upon success is the allocatable portion of a node's total "CPU" ( or "Memory" ) capacity that's available for pods to use, +// calculated by subtracting "CPU" ( or "Memory") resources reserved for node's operating system, Kubelet and other +// system daemons from the node's total "CPU" ( or "Memory" ) resource, upon failure is empty. +// - the second return value, upon success is the available portion of a node's allocatable "CPU" capacity, calculated by subtracting "CPU" +// ( or "Memory" ) resource reserved for node's pods from the node's allocatable "CPU" ( or "Memory" ) resource, upon failure is empty. +// - the third return value, upon success is nil, upon failure is the coresponding error. +func GetNodeAllocatableAndAvailableQuantities(ctx context.Context, c clientset.Interface, n *v1.Node, resourceName v1.ResourceName) (resource.Quantity, resource.Quantity, error) { + var nodeAllocatable, podAllocated, nodeAvailable resource.Quantity + switch resourceName { + case v1.ResourceCPU: + nodeAllocatable = n.Status.Allocatable.Cpu().DeepCopy() + case v1.ResourceMemory: + nodeAllocatable = n.Status.Allocatable.Memory().DeepCopy() + default: + return resource.Quantity{}, resource.Quantity{}, fmt.Errorf("unexpected resource type %q; expected either 'CPU' or 'Memory'", resourceName) + } + + if n.Status.Allocatable == nil { + return resource.Quantity{}, resource.Quantity{}, fmt.Errorf("unexpected empty value of allocatable, while attempting to get node's allocatable %s", resourceName.String()) + } + + // Exclude pods that are in the Succeeded or Failed states + selector := fmt.Sprintf("spec.nodeName=%s,status.phase!=%v,status.phase!=%v", n.Name, v1.PodSucceeded, v1.PodFailed) + listOptions := metav1.ListOptions{FieldSelector: selector} + podList, err := c.CoreV1().Pods(metav1.NamespaceAll).List(ctx, listOptions) + if err != nil { + return resource.Quantity{}, resource.Quantity{}, fmt.Errorf("error getting list of pods: %w, while attempting to get node's allocatable %s", err, resourceName.String()) + } + + for _, pod := range podList.Items { + podRequest := resourceapi.GetResourceRequestQuantity(&pod, resourceName) + podAllocated.Add(podRequest) + } + nodeAvailable = nodeAllocatable.DeepCopy() + nodeAvailable.Sub(podAllocated) + if nodeAvailable.Sign() < 0 { + return resource.Quantity{}, resource.Quantity{}, fmt.Errorf("unexpected negative value of nodeAvailable %s, while attempting to get node's allocatable and available %s", nodeAvailable.String(), resourceName.String()) + } + + return nodeAllocatable, nodeAvailable, nil +} + // GetNodeHeartbeatTime returns the timestamp of the last status update of the node. func GetNodeHeartbeatTime(node *v1.Node) metav1.Time { for _, condition := range node.Status.Conditions { @@ -533,7 +552,7 @@ func PodNodePairs(ctx context.Context, c clientset.Interface, ns string) ([]PodN func GetClusterZones(ctx context.Context, c clientset.Interface) (sets.String, error) { nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("Error getting nodes while attempting to list cluster zones: %w", err) + return nil, fmt.Errorf("error getting nodes while attempting to list cluster zones: %w", err) } // collect values of zone label from all nodes diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/util_sampledevice.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/util_sampledevice.go new file mode 100644 index 0000000000..7d3ac25c6c --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/util_sampledevice.go @@ -0,0 +1,57 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package node + +import ( + v1 "k8s.io/api/core/v1" +) + +const ( + // SampleDevicePluginDSYAML is the path of the daemonset template of the sample device plugin. // TODO: Parametrize it by making it a feature in TestFramework. + SampleDevicePluginDSYAML = "test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin.yaml" + SampleDevicePluginControlRegistrationDSYAML = "test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin-control-registration.yaml" + + // SampleDevicePluginName is the name of the device plugin pod + SampleDevicePluginName = "sample-device-plugin" + + // SampleDeviceResourceName is the name of the resource provided by the sample device plugin + SampleDeviceResourceName = "example.com/resource" + + SampleDeviceEnvVarNamePluginSockDir = "PLUGIN_SOCK_DIR" + + // SampleDevsAmount is an amount of devices provided by the sample device plugin: + // https://github.com/kubernetes/kubernetes/blob/111a2a0d2dfe13639724506f674bc4f342ccfbab/test/images/sample-device-plugin/sampledeviceplugin.go#L100-L101 + SampleDevsAmount int64 = 2 +) + +// CountSampleDeviceCapacity returns the number of devices of SampleDeviceResourceName advertised by a node capacity +func CountSampleDeviceCapacity(node *v1.Node) int64 { + val, ok := node.Status.Capacity[v1.ResourceName(SampleDeviceResourceName)] + if !ok { + return 0 + } + return val.Value() +} + +// CountSampleDeviceAllocatable returns the number of devices of SampleDeviceResourceName advertised by a node allocatable +func CountSampleDeviceAllocatable(node *v1.Node) int64 { + val, ok := node.Status.Allocatable[v1.ResourceName(SampleDeviceResourceName)] + if !ok { + return 0 + } + return val.Value() +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go index 7846426d6e..37aeef0a3a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go @@ -29,7 +29,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -37,6 +36,7 @@ import ( "k8s.io/client-go/transport/spdy" "k8s.io/klog/v2" "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/streaming/pkg/httpstream" ) // NewTransport creates a transport which uses the port forward dialer. @@ -90,14 +90,14 @@ func (d *Dialer) DialContainerPort(ctx context.Context, addr Addr) (conn net.Con if err != nil { return nil, fmt.Errorf("create round tripper: %w", err) } - dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) + dialer := spdy.NewDialerForStreaming(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) - tunnelingDialer, err := portforward.NewSPDYOverWebsocketDialer(req.URL(), restConfig) + tunnelingDialer, err := portforward.NewSPDYOverWebsocketDialerForStreaming(req.URL(), restConfig) if err != nil { return nil, err } // First attempt tunneling (websocket) dialer, then fallback to spdy dialer. - dialer = portforward.NewFallbackDialer(tunnelingDialer, dialer, func(err error) bool { + dialer = portforward.NewFallbackDialerForStreaming(tunnelingDialer, dialer, func(err error) bool { if httpstream.IsUpgradeFailure(err) || httpstream.IsHTTPSProxyError(err) { framework.Logf("fallback to secondary dialer from primary dialer err: %v", err) return true diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go index d2d09c464b..e4a34fe1d4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go @@ -27,12 +27,12 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/kubernetes/scheme" - restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" clientexec "k8s.io/client-go/util/exec" "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/utils/ktesting" + "k8s.io/streaming/pkg/httpstream" "github.com/onsi/gomega" ) @@ -59,14 +59,18 @@ func ExecWithOptions(f *framework.Framework, options ExecOptions) (string, strin } func ExecWithOptionsContext(ctx context.Context, f *framework.Framework, options ExecOptions) (string, string, error) { + return ExecWithOptionsTCtx(f.TContext(ctx), options) +} + +func ExecWithOptionsTCtx(tCtx ktesting.TContext, options ExecOptions) (string, string, error) { if !options.Quiet { - framework.Logf("ExecWithOptions %+v", options) + tCtx.Logf("ExecWithOptions %+v", options) } const tty = false - framework.Logf("ExecWithOptions: Clientset creation") - req := f.ClientSet.CoreV1().RESTClient().Post(). + tCtx.Logf("ExecWithOptions: Clientset creation") + req := tCtx.Client().CoreV1().RESTClient().Post(). Resource("pods"). Name(options.PodName). Namespace(options.Namespace). @@ -81,8 +85,8 @@ func ExecWithOptionsContext(ctx context.Context, f *framework.Framework, options }, scheme.ParameterCodec) var stdout, stderr bytes.Buffer - framework.Logf("ExecWithOptions: execute(%s)", req.URL()) - err := execute(ctx, req.URL(), f.ClientConfig(), options.Stdin, &stdout, &stderr, tty) + tCtx.Logf("ExecWithOptions: execute(%s)", req.URL()) + err := execute(tCtx, req.URL(), options.Stdin, &stdout, &stderr, tty) if options.PreserveWhitespace { return stdout.String(), stderr.String(), err @@ -182,7 +186,8 @@ func VerifyExecInPodFail(ctx context.Context, f *framework.Framework, pod *v1.Po return fmt.Errorf("%q should fail with exit code %d, but exit without error", shExec, exitCode) } -func execute(ctx context.Context, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { +func execute(tCtx ktesting.TContext, url *url.URL, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { + config := tCtx.RESTConfig() // WebSocketExecutor executor is default // WebSocketExecutor must be "GET" method as described in RFC 6455 Sec. 4.1 (page 17). websocketExec, err := remotecommand.NewWebSocketExecutor(config, "GET", url.String()) @@ -205,7 +210,7 @@ func execute(ctx context.Context, url *url.URL, config *restclient.Config, stdin return err } - return exec.StreamWithContext(ctx, remotecommand.StreamOptions{ + return exec.StreamWithContext(tCtx, remotecommand.StreamOptions{ Stdin: stdin, Stdout: stdout, Stderr: stderr, diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go index fac0076444..b66e037456 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go @@ -273,7 +273,6 @@ func TestContainerOutputsMatcher(ctx context.Context, f *framework.Framework, expectedNameOutputs := make(map[string][]string, len(expectedOutputs)) for containerIndex, expectedOutput := range expectedOutputs { - expectedOutput := expectedOutput if containerIndex < 0 || containerIndex >= len(pod.Spec.Containers) { framework.Failf("Invalid container index: %d", containerIndex) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go index 104f9dec80..b7e4200019 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "regexp" + "slices" "strings" "sync" "time" @@ -371,29 +372,10 @@ func (c *PodClient) PodIsReady(ctx context.Context, name string) bool { return podutils.IsPodReady(pod) } -// RemoveString returns a newly created []string that contains all items from slice -// that are not equal to s. -// This code is taken from k/k/pkg/util/slice/slice.go to remove -// e2e/framework/pod -> k/k/pkg/util/slice dependency. -func removeString(slice []string, s string) []string { - newSlice := make([]string, 0) - for _, item := range slice { - if item != s { - newSlice = append(newSlice, item) - } - } - if len(newSlice) == 0 { - // Sanitize for unit tests so we don't need to distinguish empty array - // and nil. - return nil - } - return newSlice -} - // RemoveFinalizer removes the pod's finalizer func (c *PodClient) RemoveFinalizer(ctx context.Context, podName string, finalizerName string) { framework.Logf("Removing pod's %q finalizer: %q", podName, finalizerName) c.Update(ctx, podName, func(pod *v1.Pod) { - pod.ObjectMeta.Finalizers = removeString(pod.ObjectMeta.Finalizers, finalizerName) + pod.ObjectMeta.Finalizers = slices.DeleteFunc(pod.ObjectMeta.Finalizers, func(actual string) bool { return actual == finalizerName }) }) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go index d748b5b002..938a1b54aa 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go @@ -433,7 +433,7 @@ func CreatePVsPVCs(ctx context.Context, numpvs, numpvcs int, c clientset.Interfa pvsToCreate := numpvs - extraPVs // want the min(numpvs, numpvcs) // create pvs and pvcs - for i := 0; i < pvsToCreate; i++ { + for range pvsToCreate { pv, pvc, err := CreatePVPVC(ctx, c, timeouts, pvConfig, pvcConfig, ns, false) if err != nil { return pvMap, pvcMap, err diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/registry/registry.go b/vendor/k8s.io/kubernetes/test/e2e/framework/registry/registry.go index 139d61aec3..d483919179 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/registry/registry.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/registry/registry.go @@ -127,6 +127,10 @@ func podManifest(podTestLabel string) (*v1.Pod, error) { }, } pod.Spec.Containers[0].SecurityContext.RunAsUser = ptr.To[int64](5123) + pod.Spec.Containers[0].SecurityContext.WindowsOptions = &v1.WindowsSecurityContextOptions{ + RunAsUserName: ptr.To("NT AUTHORITY\\SYSTEM"), + HostProcess: ptr.To(true), + } // setting HostNetwork to true so that the registry is accessible on localhost: // and we don't have to deal with any CNI quirks. pod.Spec.HostNetwork = true diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go index e193175458..c9a136d8d7 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go @@ -125,8 +125,7 @@ func makePrivateKeySignerFromFile(key string) (ssh.Signer, error) { // NodeSSHHosts returns SSH-able host names for all schedulable nodes. // If it can't find any external IPs, it falls back to // looking for internal IPs. If it can't find an internal IP for every node it -// returns an error, though it still returns all hosts that it found in that -// case. +// returns an error. func NodeSSHHosts(ctx context.Context, c clientset.Interface) ([]string, error) { nodelist := waitListSchedulableNodesOrDie(ctx, c) @@ -136,10 +135,9 @@ func NodeSSHHosts(ctx context.Context, c clientset.Interface) ([]string, error) framework.Logf("No external IP address on nodes, falling back to internal IPs") hosts = nodeAddresses(nodelist, v1.NodeInternalIP) } - - // Error if neither External nor Internal IPs weren't available for all nodes. if len(hosts) != len(nodelist.Items) { - return hosts, fmt.Errorf( + // Something is wrong; all schedulable nodes should have at least one IP. + return nil, fmt.Errorf( "only found %d IPs on nodes, but found %d nodes. Nodelist: %v", len(hosts), len(nodelist.Items), nodelist) } @@ -247,16 +245,12 @@ func runSSHCommand(ctx context.Context, cmd, user, host string, signer ssh.Signe Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } - client, err := ssh.Dial("tcp", host, config) - if err != nil { - err = wait.PollUntilContextTimeout(ctx, 5*time.Second, 20*time.Second, false, func(ctx context.Context) (bool, error) { - fmt.Printf("error dialing %s@%s: '%v', retrying\n", user, host, err) - if client, err = ssh.Dial("tcp", host, config); err != nil { - return false, nil // retrying, error will be logged above - } - return true, nil - }) - } + var client *ssh.Client + err := framework.Gomega().Eventually(ctx, func() error { + c, err := ssh.Dial("tcp", host, config) + client = c + return err + }).WithPolling(5 * time.Second).WithTimeout(20 * time.Second).Should(gomega.Succeed()) if err != nil { return "", "", 0, fmt.Errorf("error getting SSH client to %s@%s: %w", user, host, err) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go index aa35cebd15..e82e6d353b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go @@ -17,7 +17,6 @@ limitations under the License. package framework import ( - "context" "crypto/rand" "encoding/base64" "errors" @@ -30,7 +29,6 @@ import ( "path/filepath" "sort" "strings" - "time" "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/reporters" @@ -187,9 +185,6 @@ type TestContextType struct { // The DNS Domain of the cluster. ClusterDNSDomain string - // The configuration of NodeKiller. - NodeKiller NodeKillerConfig - // The Default IP Family of the cluster ("ipv4" or "ipv6") IPFamily string @@ -229,30 +224,6 @@ type TestContextType struct { EnabledVolumeDrivers []string } -// NodeKillerConfig describes configuration of NodeKiller -- a utility to -// simulate node failures. -// -// TODO: move this and the corresponding command line flags into -// test/e2e/framework/node. -type NodeKillerConfig struct { - // Enabled determines whether NodeKill should do anything at all. - // All other options below are ignored if Enabled = false. - Enabled bool - // FailureRatio is a percentage of all nodes that could fail simultinously. - FailureRatio float64 - // Interval is time between node failures. - Interval time.Duration - // JitterFactor is factor used to jitter node failures. - // Node will be killed between [Interval, Interval + (1.0 + JitterFactor)]. - JitterFactor float64 - // SimulatedDowntime is a duration between node is killed and recreated. - SimulatedDowntime time.Duration - // NodeKillerStopCtx is a context that is used to notify NodeKiller to stop killing nodes. - NodeKillerStopCtx context.Context - // NodeKillerStop is the cancel function for NodeKillerStopCtx. - NodeKillerStop func() -} - // NodeTestContextType is part of TestContextType, it is shared by all node e2e test. type NodeTestContextType struct { // NodeE2E indicates whether it is running node e2e. @@ -443,7 +414,7 @@ func RegisterClusterFlags(flags *flag.FlagSet) { flags.StringVar(&cloudConfig.Cluster, "gke-cluster", "", "GKE name of cluster being used, if applicable") flags.StringVar(&cloudConfig.NodeInstanceGroup, "node-instance-group", "", "Name of the managed instance group for nodes. Valid only for gce, gke or aws. If there is more than one group: comma separated list of groups.") flags.StringVar(&cloudConfig.Network, "network", "e2e", "The cloud provider network for this e2e cluster.") - flags.IntVar(&cloudConfig.NumNodes, "num-nodes", DefaultNumNodes, fmt.Sprintf("Number of nodes in the cluster. If the default value of '%q' is used the number of schedulable nodes is auto-detected.", DefaultNumNodes)) + flags.IntVar(&cloudConfig.NumNodes, "num-nodes", DefaultNumNodes, fmt.Sprintf("Number of nodes in the cluster. If the default value of '%d' is used the number of schedulable nodes is auto-detected.", DefaultNumNodes)) flags.StringVar(&cloudConfig.ClusterIPRange, "cluster-ip-range", "10.64.0.0/14", "A CIDR notation IP range from which to assign IPs in the cluster.") flags.StringVar(&cloudConfig.NodeTag, "node-tag", "", "Network tags used on node instances. Valid only for gce, gke") flags.StringVar(&cloudConfig.MasterTag, "master-tag", "", "Network tags used on master instances. Valid only for gce, gke") @@ -458,13 +429,6 @@ func RegisterClusterFlags(flags *flag.FlagSet) { flags.StringVar(&TestContext.EtcdUpgradeVersion, "etcd-upgrade-version", "", "The etcd binary version to upgrade to (e.g., '3.0.14', '2.3.7') if doing an etcd upgrade test.") flags.StringVar(&TestContext.GCEUpgradeScript, "gce-upgrade-script", "", "Script to use to upgrade a GCE cluster.") flags.BoolVar(&TestContext.CleanStart, "clean-start", false, "If true, purge all namespaces except default and system before running tests. This serves to Cleanup test namespaces from failed/interrupted e2e runs in a long-lived cluster.") - - nodeKiller := &TestContext.NodeKiller - flags.BoolVar(&nodeKiller.Enabled, "node-killer", false, "Whether NodeKiller should kill any nodes.") - flags.Float64Var(&nodeKiller.FailureRatio, "node-killer-failure-ratio", 0.01, "Percentage of nodes to be killed") - flags.DurationVar(&nodeKiller.Interval, "node-killer-interval", 1*time.Minute, "Time between node failures.") - flags.Float64Var(&nodeKiller.JitterFactor, "node-killer-jitter-factor", 60, "Factor used to jitter node failures.") - flags.DurationVar(&nodeKiller.SimulatedDowntime, "node-killer-simulated-downtime", 10*time.Minute, "A delay between node death and recreation") } // generateSecureToken returns a string of length tokenLen, consisting diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go index ecc59b63da..ebbc0083a5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go @@ -256,6 +256,24 @@ func getVolumeHandle(ctx context.Context, cs clientset.Interface, claimName stri return pv.Spec.CSI.VolumeHandle } +// WaitForVolumeAttachmentCreated waits for the VolumeAttachment with the passed in attachmentName to be created. +func WaitForVolumeAttachmentCreated(ctx context.Context, attachmentName string, cs clientset.Interface, interval, timeout time.Duration) error { + waitErr := wait.PollUntilContextTimeout(ctx, interval, timeout, true, func(ctx context.Context) (bool, error) { + _, err := cs.StorageV1().VolumeAttachments().Get(ctx, attachmentName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if waitErr != nil { + return fmt.Errorf("error waiting volume attachment %v to be created: %w", attachmentName, waitErr) + } + return nil +} + // WaitForVolumeAttachmentTerminated waits for the VolumeAttachment with the passed in attachmentName to be terminated. func WaitForVolumeAttachmentTerminated(ctx context.Context, attachmentName string, cs clientset.Interface, timeout time.Duration) error { waitErr := wait.PollUntilContextTimeout(ctx, 10*time.Second, timeout, true, func(ctx context.Context) (bool, error) { @@ -284,7 +302,7 @@ func startVolumeServer(ctx context.Context, client clientset.Interface, config T portCount := len(config.ServerPorts) serverPodPorts := make([]v1.ContainerPort, portCount) - for i := 0; i < portCount; i++ { + for i := range portCount { portName := fmt.Sprintf("%s-%d", config.Prefix, i) serverPodPorts[i] = v1.ContainerPort{ diff --git a/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/logcheck.go b/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/logcheck.go new file mode 100644 index 0000000000..c691c7aeef --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/logcheck.go @@ -0,0 +1,667 @@ +/* +Copyright 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 logcheck extends a Ginkgo test suite with optional monitoring +// of system log files. Right now it can detect DATA RACE problems. +// +// This may get expanded in the future, for example to check also +// for unhandled and potentially unexpected errors (https://github.com/kubernetes/kubernetes/issues/122005) +// or log spam (https://github.com/kubernetes/kubernetes/issues/109297). +// +// Because it grabs log output as it is produced, it is possible to dump *all* +// data into $ARTIFACTS/system-logs, in contrast to other approaches which +// potentially only capture the tail of the output (log rotation). +// +// The additional check(s) must be opt-in because they are not portable. +// The package registers additional command line flags for that. +// Dedicated jobs are necessary which enable them. +// +// For DATA RACE, the binaries in the cluster must be compiled with race +// detection (https://github.com/kubernetes/kubernetes/pull/133834/files). +// It's also necessary to specify which containers to check. Other output +// (e.g. kubelet in a kind cluster) currently cannot be checked. +// +// In ginkgo.ReportBeforeSuite, the main Ginkgo worker process starts +// monitoring log output: +// +// - The podlogs package watches pods in namespaces of interest (by default, +// any that have "system" in their name). For each container in those pods, +// a logOutputChecker instance is created and is passed log output lines +// via Write. podlogs streams output, similar to "kubectl logs -f". +// +// - Kubelet log output is retrieved periodically via the node log query +// feature. Start and end times of each chunk are chosen so that there +// are no gaps. The output is stripped of additional journald line +// headers and then passed to one logOutputChecker per node. +// +// - logOutputChecker detects DATA RACE reports based on their prefix and suffix lines. +// +// - Log entries emitted during monitoring are buffered. +// +// In ginkgo.ReportAfterSuite, the log output is emitted as stdout of the check +// together with a summary of what was checked without detecting problems. +// DATA RACEs and unexpected log errors are turned into a failure. +package logcheck + +import ( + "bufio" + "context" + "errors" + "flag" + "fmt" + "io" + "maps" + "os" + "path" + "regexp" + "slices" + "strconv" + "strings" + "sync" + "time" + + "github.com/onsi/ginkgo/v2" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" + "k8s.io/klog/v2/textlogger" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/storage/podlogs" +) + +const ( + // defaultNamespacesRE is the default regular expression for which namespaces need to be checked, + // if checking is enabled: anything which contains the word "system". + // + // If we had an API for identifying "system" namespaces, we could use that, but we + // don't have that yet (https://github.com/kubernetes/enhancements/issues/5708). + defaultNamespacesRE = `system` + + // defaultNodesRE is the default regular expression for which nodes + // should have their kubelet log output checked via the log query + // feature (https://kubernetes.io/docs/concepts/cluster-administration/system-logs/#log-query). + defaultNodesRE = `.*` + + dataRaceStart = "WARNING: DATA RACE\n" + dataRaceEnd = "==================\n" + maxBacktraceLines = 20 +) + +var ( + enabledLogChecks = logCheck{ + namespaces: regexpValue{ + re: regexp.MustCompile(defaultNamespacesRE), + }, + nodes: regexpValue{ + re: regexp.MustCompile(defaultNodesRE), + }, + } + + lc *logChecker + lcLogger klog.Logger +) + +// logCheck determines what gets checked in log output. +type logCheck struct { + // namespaces contains a regular expression which determines which namespaces need to be checked. + // All containers in those namespaces are checked. + // If the regular expression is nil, the default is used. + namespaces regexpValue + + // namespaces contains a regular expression which determines which nodes need to be checked + // by retrieving the kubelet log via the log query feature (https://kubernetes.io/docs/concepts/cluster-administration/system-logs/#log-query). + nodes regexpValue + + // dataRaces enables checking for "DATA RACE" reports. + dataRaces bool + // More checks may get added in the future. +} + +// any returns true if any log output check is enabled. +func (c logCheck) any() bool { + // Needs to be extended when adding new checks. + return c.dataRaces +} + +// regexpValue implements flag.Value for a regular expression. +type regexpValue struct { + re *regexp.Regexp +} + +var _ flag.Value = ®expValue{} + +func (r *regexpValue) String() string { return r.re.String() } +func (r *regexpValue) Set(expr string) error { + re, err := regexp.Compile(expr) + if err != nil { + // This already starts with "error parsing regexp" and + // the caller adds the expression string, + // so no need to wrap the error here. + return err + } + r.re = re + return nil +} + +// RegisterFlags adds command line flags for configuring the package to the given flag set. +// They have "logcheck" as prefix. +func RegisterFlags(fs *flag.FlagSet) { + fs.BoolVar(&enabledLogChecks.dataRaces, "logcheck-data-races", false, "enables checking logs for DATA RACE warnings") + fs.Var(&enabledLogChecks.namespaces, "logcheck-namespaces-regexp", "all namespaces matching this regular expressions get checked") + fs.Var(&enabledLogChecks.nodes, "logcheck-nodes-regexp", "all kubelets on nodes matching this regular expressions get checked") +} + +var _ = ginkgo.ReportBeforeSuite(func(ctx ginkgo.SpecContext, report ginkgo.Report) { + if report.SuiteConfig.DryRun { + return + } + + // This is only reached in the main process. + initialize() +}) + +// SIG Testing runs this as a service for the SIGs which own the code. +var _ = ginkgo.ReportAfterSuite("[sig-testing] Log Check", func(ctx ginkgo.SpecContext, report ginkgo.Report) { + if report.SuiteConfig.DryRun { + return + } + + // This is reached only in the main process after the test run has completed. + finalize() +}) + +// initialize gets called once before tests start to run. +// It sets up monitoring of system component log output, if requested. +func initialize() { + if !enabledLogChecks.any() { + return + } + + config, err := framework.LoadConfig() + framework.ExpectNoError(err, "loading client config") + client, err := kubernetes.NewForConfig(config) + framework.ExpectNoError(err, "creating client") + + ctx, l, err := newLogChecker(context.Background(), client, enabledLogChecks, framework.TestContext.ReportDir) + framework.ExpectNoError(err, "set up log checker") + + lc = l + lcLogger = klog.FromContext(ctx) + lc.start(ctx, podlogs.CopyAllLogs, kubeletLogQuery) +} + +// finalize gets called once after tests have run, in the process where initialize was also called. +func finalize() { + if lc == nil { + return + } + + failure, stdout := lc.stop(lcLogger) + _, _ = ginkgo.GinkgoWriter.Write([]byte(stdout)) + if failure != "" { + // Reports as post-suite failure. + ginkgo.Fail(failure) + } +} + +func newLogChecker(ctx context.Context, client kubernetes.Interface, check logCheck, logDir string) (context.Context, *logChecker, error) { + var logFile string + + if logDir != "" { + // Redirect log output. Also, check for errors when we stop, those mustn't go unnoticed in a CI job. + logFile = path.Join(logDir, "system-logs.log") + output, err := os.Create(logFile) + if err != nil { + return ctx, nil, fmt.Errorf("create log file: %w", err) + } + // Allow increasing verbosity via the command line, but always use at + // least 4 when writing into a file - we can afford that. + vflag := flag.CommandLine.Lookup("v") + v, _ := strconv.Atoi(vflag.Value.String()) + if v < 5 { + v = 5 + } + + logger := textlogger.NewLogger(textlogger.NewConfig(textlogger.Output(output), textlogger.Verbosity((int(v))))) + ctx = klog.NewContext(ctx, logger) + } + if check.namespaces.re == nil { + check.namespaces.re = regexp.MustCompile(defaultNamespacesRE) + } + if check.nodes.re == nil { + check.nodes.re = regexp.MustCompile(defaultNodesRE) + } + + ctx, cancel := context.WithCancelCause(ctx) + return ctx, &logChecker{ + wg: newWaitGroup(), + client: client, + cancel: cancel, + check: check, + logDir: logDir, + logFile: logFile, + dataRaces: make(map[string][][]string), + }, nil +} + +type logChecker struct { + client kubernetes.Interface + cancel func(err error) + check logCheck + logDir string + logFile string + + // wg tracks background activity. + wg *waitGroup + + // mutex protects all following fields. + mutex sync.Mutex + + // All data races detected so far, indexed by "//" + // or "kubelet/". + // + // The last entry is initially empty while waiting for the next data race. + // + // Only entities for which at least some output was received get added here, + // therefore also the ": okay" part of the report only appears for those. + dataRaces map[string][][]string +} + +// stop cancels pod monitoring, waits until that is shut down, and then produces text for a failure message (ideally empty) and stdout. +func (l *logChecker) stop(logger klog.Logger) (failure, stdout string) { + logger.V(4).Info("Asking log monitors to stop") + l.cancel(errors.New("asked to stop")) + + // Wait for completion. + l.wg.wait() + + // Now we can proceed and produce the report. + l.mutex.Lock() + defer l.mutex.Unlock() + + var failureBuffer strings.Builder + var stdoutBuffer strings.Builder + if l.logFile != "" { + logData, err := os.ReadFile(l.logFile) + if err != nil { + stdoutBuffer.WriteString(fmt.Sprintf("Reading %s failed: %v", l.logFile, err)) + } else { + stdoutBuffer.Write(logData) + } + + // Find all error log lines. A bit crude (doesn't handle multi-line outout), but good enough + // because the full log is available. + errorLogs := regexp.MustCompile(`(?m)^E.*\n`).FindAllString(string(logData), -1) + if len(errorLogs) > 0 { + failureBuffer.WriteString("Unexpected errors during log data collection (see stdout for full log):\n\n") + for _, errorLog := range errorLogs { + // Indented to make it a verbatim block in Markdown. + failureBuffer.WriteString(" ") + failureBuffer.WriteString(errorLog) + } + } + } + + keys := slices.AppendSeq([]string(nil), maps.Keys(l.dataRaces)) + slices.Sort(keys) + for _, k := range keys { + races := l.dataRaces[k] + buffer := &failureBuffer + if len(races) == 0 { + buffer = &stdoutBuffer + } + if buffer.Len() > 0 { + buffer.WriteString("\n") + } + buffer.WriteString("#### " + k + "\n") + if len(races) == 0 { + buffer.WriteString("\nOkay.\n") + continue + } + for _, race := range races { + indent := " " + buffer.WriteString("\n") + if len(races) > 1 { + // Format as bullet-point list. + buffer.WriteString("- DATA RACE:\n \n") + // This also shifts the text block to the right. + indent += " " + } else { + // Single line of intro text, then the text block. + buffer.WriteString("DATA RACE:\n\n") + } + // Indented lines are stack backtraces. Those can be long, + // so collect them as we iterate over lines and truncate in the middle. + var backtrace []string + dumpBacktrace := func() { + if len(backtrace) == 0 { + return + } + + if len(backtrace) > maxBacktraceLines { + head := backtrace[0 : maxBacktraceLines/2] + tail := backtrace[len(backtrace)-maxBacktraceLines/2:] + + backtrace = slices.Clone(head) + backtrace = append(backtrace, " ...\n") + backtrace = append(backtrace, tail...) + } + + for _, line := range backtrace { + buffer.WriteString(indent) + buffer.WriteString(line) + } + + backtrace = nil + } + for _, line := range race { + if !strings.HasPrefix(line, " ") { + // Non-backtrace line => flush and write the line. + dumpBacktrace() + buffer.WriteString(indent) + buffer.WriteString(line) + continue + } + backtrace = append(backtrace, line) + } + dumpBacktrace() + } + } + + return failureBuffer.String(), stdoutBuffer.String() +} + +func (l *logChecker) start(ctx context.Context, startCopyAllLogs func(ctx context.Context, cs kubernetes.Interface, ns string, to podlogs.LogOutput) error, startNodeLog func(ctx context.Context, cs kubernetes.Interface, wg *waitGroup, nodeName string) io.Reader) { + if !l.check.any() { + return + } + + logger := klog.FromContext(ctx) + + // Figure out which namespace(s) to watch. + namespaces, err := l.client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) + if err != nil { + logger.Error(err, "Failed to list namespaces") + return + } + + // Same for nodes. + nodes, err := l.client.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) + if err != nil { + logger.Error(err, "Failed to list nodes") + return + } + + for _, namespace := range namespaces.Items { + if !l.check.namespaces.re.MatchString(namespace.Name) { + continue + } + to := podlogs.LogOutput{ + StatusWriter: &statusWriter{logger: logger, namespace: &namespace}, + LogPathPrefix: path.Join(l.logDir, namespace.Name) + "/", + LogOpen: func(podName, containerName string) io.Writer { + return l.logOpen(logger, namespace.Name, podName, containerName) + }, + } + + logger.Info("Watching", "namespace", klog.KObj(&namespace)) + if err := startCopyAllLogs(ctx, l.client, namespace.Name, to); err != nil { + logger.Error(err, "Log output collection failed", "namespace", klog.KObj(&namespace)) + } + } + + for _, node := range nodes.Items { + if !l.check.nodes.re.MatchString(node.Name) { + continue + } + + logger.Info("Watching", "node", klog.KObj(&node)) + kubeletLog := startNodeLog(ctx, l.client, l.wg, node.Name) + l.wg.goIfNotShuttingDown(nil, func() { + scanner := bufio.NewScanner(kubeletLog) + writer := logOutputChecker{ + logger: logger, + k: "kubelet/" + node.Name, + l: l, + } + for scanner.Scan() { + // We need to strip whatever headers might have been added by the log storage + // that was queried the log query feature. We don't exactly know what that might be, + // so let's use a regexp that matches all known line headers. + // + // Unknown lines are passed through, which is okayish (they get treated like + // unknown, raw output from the kubelet). + line := scanner.Text() + line = logQueryLineHeaderRE.ReplaceAllString(line, "") + _, _ = writer.Write([]byte(line + "\n")) + } + if err := scanner.Err(); err != nil { + logger.Error(err, "Reading kubelet log failed", "node", klog.KObj(&node)) + } + }) + } +} + +// journaldHeader matches journald lines containing output from the kubelet: +// +// Jan 06 15:20:26.641748 kind-worker2 kubelet[311]: I0106 15:20:26.641743 311 labels.go:289] ... +// +// We also get messages from systemd itself. Those are not matched: +// +// Jan 07 08:35:52.139136 kind-worker3 systemd[1]: Started kubelet.service - kubelet: The Kubernetes Node Agent. +const journaldHeader = `... .. ..:..:......... \S+ kubelet\[\d+\]: ` + +// logQueryLineHeaderRE combines all supported log query data formats. +// Currently only journald is supported. +var logQueryLineHeaderRE = regexp.MustCompile(`^(?:` + journaldHeader + `)`) + +func (l *logChecker) logOpen(logger klog.Logger, names ...string) io.Writer { + if !l.check.dataRaces { + return nil + } + + if !l.wg.add(1) { + return io.Discard + } + + k := strings.Join(names, "/") + logger.Info("Starting to check for data races", "container", k) + return &logOutputChecker{logger: logger, k: k, l: l} +} + +type statusWriter struct { + logger klog.Logger + namespace *v1.Namespace +} + +// Write gets called with text that describes problems encountered while monitoring pods and their output. +func (s *statusWriter) Write(data []byte) (int, error) { + msg := string(data) + msg = strings.TrimRight(msg, "\n") + if strings.HasPrefix(msg, "WARNING:") { + // Warnings are informational, podlogs recovers from problems (like "connection refused" + // under load, "pod not found" when a pod terminates while trying to read log output). + // They don't need to be treated as a logcheck failure when looking at logs later. + s.logger.Info("PodLogs status", "namespace", klog.KObj(s.namespace), "msg", msg) + } else { + s.logger.Error(nil, "PodLogs status", "namespace", klog.KObj(s.namespace), "msg", msg) + } + return len(msg), nil +} + +// logOutputChecker receives log output for one component and detects embedded DATA RACE reports. +type logOutputChecker struct { + logger klog.Logger + k string + l *logChecker + inDataRace bool +} + +var ( + _ io.Writer = &logOutputChecker{} + _ io.Closer = &logOutputChecker{} +) + +// Write gets called for each line of output received from a container or kubelet instance. +// The line ends with a newline. +func (p *logOutputChecker) Write(l []byte) (int, error) { + line := string(l) + + p.l.mutex.Lock() + defer p.l.mutex.Unlock() + + races := p.l.dataRaces[p.k] + switch { + case p.inDataRace && line != dataRaceEnd: + races[len(races)-1] = append(races[len(races)-1], line) + case p.inDataRace && line == dataRaceEnd: + // Stop collecting data race lines. + p.inDataRace = false + p.logger.Info("Completed data race", "container", p.k, "count", len(races), "dataRace", strings.Join(races[len(races)-1], "")) + case !p.inDataRace && line == dataRaceStart: + // Start collecting data race lines. + p.inDataRace = true + races = append(races, nil) + p.logger.Info("Started new data race", "container", p.k, "count", len(races)) + default: + // Some other log output. + } + p.l.dataRaces[p.k] = races + + return len(l), nil +} + +// Close gets called once all output is processed. +func (p *logOutputChecker) Close() error { + p.logger.Info("Done checking for data races", "container", p.k) + p.l.wg.done() + return nil +} + +// kubeletLogQuery sets up repeatedly querying the log of kubelet on the given node +// via the log query feature. +// +// All background goroutines stop when the context gets canceled and are added +// to the given WaitGroup before kubeletLogQuery returns. The reader will +// stop providing data when that happens. +// +// The lines in the data written to the reader may contain journald headers or other, +// platform specific headers (this is not specified for the log query feature). +func kubeletLogQuery(ctx context.Context, cs kubernetes.Interface, wg *waitGroup, nodeName string) io.Reader { + logger := klog.FromContext(ctx) + logger = klog.LoggerWithName(logger, "KubeletLogQuery") + logger = klog.LoggerWithValues(logger, "node", klog.KRef("", nodeName)) + reader, writer := io.Pipe() + + wg.goIfNotShuttingDown(func() { + _ = writer.Close() + }, func() { + logger.V(4).Info("Started") + defer func() { + logger.V(4).Info("Stopped", "reason", context.Cause(ctx)) + }() + + // How long to wait between queries is a compromise between "too long" (= too much data) + // and "too short" (= too much overhead because of frequent queries). It's not clear + // where the sweet spot is. With the current default, there were 12 calls for one worker node + // during a ~1h pull-kubernetes-e2e-kind-alpha-beta-features run, with an average result + // size of ~16MB. + // + // All log checking activities share the same client instance. It's created specifically + // for that purpose, so client-side throttling does not affect other tests. + ticker := time.NewTicker(300 * time.Second) + defer ticker.Stop() + + var since time.Time + for { + select { + case <-ctx.Done(): + logger.V(4).Info("Asked to stop, will query log one last time", "reason", context.Cause(ctx)) + case <-ticker.C: + logger.V(6).Info("Starting periodic log query") + } + + // Query once also when asked to stop via cancelation, to get the tail of the output. + // We use a timeout to prevent blocking forever here. + err := func() error { + ctx := context.WithoutCancel(ctx) + ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + now := time.Now() + untilTime := now.Format(time.RFC3339) + sinceTime := "" + if !since.IsZero() { + sinceTime = since.Format(time.RFC3339) + } + // The next query will use the current end time as start time. Both start and end + // are inclusive, so unfortunately there is a risk that we get the same log + // output for that time stamp twice. There's no good way to avoid that. + // Let's hope it's rare and doesn't matter when it occurs. Missing + // output would be worse because then the end marker of a DATA RACE + // report could be missed. + since = now + req := cs.CoreV1().RESTClient().Get(). + Resource("nodes"). + Name(nodeName). + SubResource("proxy"). + Suffix("logs"). + Param("query", "kubelet"). + Param("untilTime", untilTime) + if sinceTime != "" { + req = req.Param("sinceTime", sinceTime) + } + data, err := req.DoRaw(ctx) + if loggerV := logger.V(4); loggerV.Enabled() { + head := string(data) + if len(head) > 30 { + head = head[:30] + head += "..." + } + loggerV.Info("Queried log", "sinceTime", sinceTime, "endTime", now, "len", len(data), "data", head, "err", err) + } + + // Let's process whatever data we have. The exact result of the query is a bit + // underspecified. This is based on observed behavior in Kubernetes 1.35. + + // HTML seems to be what the kubelet responds when the feature is disabled?! + // May or may not be intentional according to a Slack discussion, + // to be clarified in https://github.com/kubernetes/kubernetes/issues/136275. + if strings.HasPrefix(string(data), "") { + return fmt.Errorf("unexpected result of log query (feature disabled?): %q", string(data)) + } + + // Skip the special string that is used for "no data available". + if string(data) != "-- No entries --\n" { + _, _ = writer.Write(data) + } + return err + }() + + if err != nil { + logger.Error(err, "Log query failed") + return + } + + if ctx.Err() != nil { + return + } + } + }) + return reader +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/waitgroup.go b/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/waitgroup.go new file mode 100644 index 0000000000..d9413f673d --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/invariants/logcheck/waitgroup.go @@ -0,0 +1,91 @@ +/* +Copyright 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 logcheck + +import ( + "sync" +) + +// waitGroup, in contrast to sync.WaitGroup, supports races between +// go and wait. Once wait is called, no new goroutines are started. +type waitGroup struct { + mutex sync.Mutex + cond *sync.Cond + + shuttingDown bool + running int +} + +func (wg *waitGroup) wait() { + wg.mutex.Lock() + defer wg.mutex.Unlock() + + wg.shuttingDown = true + for wg.running > 0 { + wg.cond.Wait() + } +} + +func (wg *waitGroup) add(n int) bool { + wg.mutex.Lock() + defer wg.mutex.Unlock() + + if wg.shuttingDown { + return false + } + + wg.running += n + return true +} + +func (wg *waitGroup) done() { + wg.mutex.Lock() + defer wg.mutex.Unlock() + + wg.running-- + wg.cond.Broadcast() +} + +// goIfNotShuttingDown executes the callback in a goroutine if the wait group +// is not already shutting down. It always calls the cleanup callback once, either way. +func (wg *waitGroup) goIfNotShuttingDown(cleanup, cb func()) { + wg.mutex.Lock() + defer wg.mutex.Unlock() + + if cleanup == nil { + cleanup = func() {} + } + + if wg.shuttingDown { + // Clean up directly. + cleanup() + return + } + + wg.running++ + go func() { + defer wg.done() + defer cleanup() + cb() + }() +} + +func newWaitGroup() *waitGroup { + var wg waitGroup + wg.cond = sync.NewCond(&wg.mutex) + return &wg +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/patch_e2e.go b/vendor/k8s.io/kubernetes/test/e2e/patch_e2e.go index c0aecd32cd..06aca7a328 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/patch_e2e.go +++ b/vendor/k8s.io/kubernetes/test/e2e/patch_e2e.go @@ -5,11 +5,13 @@ import ( "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework/config" + "k8s.io/kubernetes/test/e2e/invariants/logcheck" ) func HandleFlags() { config.CopyFlags(config.Flags, flag.CommandLine) framework.RegisterCommonFlags(flag.CommandLine) framework.RegisterClusterFlags(flag.CommandLine) + logcheck.RegisterFlags(flag.CommandLine) flag.Parse() } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi-test/mock/service/service.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi-test/mock/service/service.go index 798b7c275f..09534c4326 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi-test/mock/service/service.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi-test/mock/service/service.go @@ -120,9 +120,9 @@ type service struct { nodeID string vols []csi.Volume volsRWL sync.RWMutex - volsNID uint64 + volsNID atomic.Uint64 snapshots cache.SnapshotCache - snapshotsNID uint64 + snapshotsNID atomic.Uint64 config Config } @@ -173,7 +173,7 @@ const ( func (s *service) newVolume(name string, capcity int64) csi.Volume { vol := csi.Volume{ - VolumeId: fmt.Sprintf("%d", atomic.AddUint64(&s.volsNID, 1)), + VolumeId: fmt.Sprintf("%d", s.volsNID.Add(1)), VolumeContext: map[string]string{"name": name}, CapacityBytes: capcity, } @@ -263,7 +263,7 @@ func (s *service) newSnapshot(name, sourceVolumeId string, parameters map[string Name: name, Parameters: parameters, SnapshotCSI: csi.Snapshot{ - SnapshotId: fmt.Sprintf("%d", atomic.AddUint64(&s.snapshotsNID, 1)), + SnapshotId: fmt.Sprintf("%d", s.snapshotsNID.Add(1)), CreationTime: ptime, SourceVolumeId: sourceVolumeId, ReadyToUse: true, diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go index 8d892e99bc..d25f3a3674 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/csi.go @@ -122,6 +122,10 @@ func initHostPathCSIDriver(name string, capabilities map[storageframework.Capabi VolumeModifyStressTestOptions: &storageframework.VolumeModifyStressTestOptions{ NumPods: 10, }, + VolumeGroupSnapshotStressTestOptions: &storageframework.VolumeGroupSnapshotStressTestOptions{ + NumPods: 5, + NumSnapshots: 5, + }, PerformanceTestOptions: &storageframework.PerformanceTestOptions{ ProvisioningOptions: &storageframework.PerformanceTestProvisioningOptions{ VolumeSize: "1Mi", @@ -174,6 +178,9 @@ func InitHostPathCSIDriver() storageframework.TestDriver { if os.Getenv("CSI_PROW_ENABLE_GROUP_SNAPSHOT") == "true" { capabilities[storageframework.CapVolumeGroupSnapshot] = true } + if os.Getenv("CSI_PROW_ENABLE_SNAPSHOT_METADATA") == "true" { + capabilities[storageframework.CapSnapshotMetadata] = true + } return initHostPathCSIDriver("csi-hostpath", capabilities, // Volume attributes don't matter, but we have to provide at least one map. @@ -182,6 +189,7 @@ func InitHostPathCSIDriver() storageframework.TestDriver { }, "test/e2e/testing-manifests/storage-csi/external-attacher/rbac.yaml", "test/e2e/testing-manifests/storage-csi/external-provisioner/rbac.yaml", + "test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/rbac.yaml", "test/e2e/testing-manifests/storage-csi/external-snapshotter/csi-snapshotter/rbac-csi-snapshotter.yaml", "test/e2e/testing-manifests/storage-csi/external-health-monitor/external-health-monitor-controller/rbac.yaml", "test/e2e/testing-manifests/storage-csi/external-resizer/rbac.yaml", @@ -306,6 +314,15 @@ func (h *hostpathCSIDriver) PrepareTest(ctx context.Context, f *framework.Framew }) } + // SnapshotMetadata feature E2E patches + // TODO: These can be removed after the SnapshotMetadata feature is default enabled + if os.Getenv("CSI_PROW_ENABLE_SNAPSHOT_METADATA") == "true" { + patches = append(patches, utils.PatchCSIOptions{ + DriverContainerName: "hostpath", + DriverContainerArguments: []string{"--enable-snapshot-metadata"}, + }) + } + err = utils.CreateFromManifests(ctx, config.Framework, driverNamespace, func(item interface{}) error { for _, o := range patches { if err := utils.PatchCSIDeployment(config.Framework, o, item); err != nil { @@ -323,16 +340,34 @@ func (h *hostpathCSIDriver) PrepareTest(ctx context.Context, f *framework.Framew switch item := item.(type) { case *appsv1.StatefulSet: var containers []v1.Container + var volumes []v1.Volume for _, container := range item.Spec.Template.Spec.Containers { switch container.Name { case "csi-external-health-monitor-agent", "csi-external-health-monitor-controller": // Remove these containers. + case "csi-snapshot-metadata": + // Only keep the snapshot metadata sidecar when the feature is enabled. + if h.driverInfo.Capabilities[storageframework.CapSnapshotMetadata] { + containers = append(containers, container) + } default: // Keep the others. containers = append(containers, container) } } + for _, volume := range item.Spec.Template.Spec.Volumes { + switch volume.Name { + case "csi-snapshot-metadata-server-certs": + // Only keep the snapshot metadata sidecar when the feature is enabled. + if h.driverInfo.Capabilities[storageframework.CapSnapshotMetadata] { + volumes = append(volumes, volume) + } + default: + volumes = append(volumes, volume) + } + } item.Spec.Template.Spec.Containers = containers + item.Spec.Template.Spec.Volumes = volumes } return nil }, h.manifests...) @@ -657,7 +692,7 @@ func (m *mockCSIDriver) PrepareTest(ctx context.Context, f *framework.Framework) VolumeMountGroupRequired: m.enableVolumeMountGroup, EnableTopology: m.enableTopology, IO: proxy.PodDirIO{ - F: f, + TCtx: f.TContext(context.Background() /* no cancellation, the traditional behavior! */), Namespace: m.driverNamespace.Name, PodName: podname, ContainerName: "busybox", diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/openshift_group_snapshot_driver.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/openshift_group_snapshot_driver.go index fcf1b82d6b..379f62d55f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/openshift_group_snapshot_driver.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/openshift_group_snapshot_driver.go @@ -253,16 +253,34 @@ func (h *groupSnapshotHostpathCSIDriver) PrepareTest(ctx context.Context, f *fra switch item := item.(type) { case *appsv1.StatefulSet: var containers []v1.Container + var volumes []v1.Volume for _, container := range item.Spec.Template.Spec.Containers { switch container.Name { case "csi-external-health-monitor-agent", "csi-external-health-monitor-controller": // Remove these containers. + case "csi-snapshot-metadata": + // Only keep the snapshot metadata sidecar when the feature is enabled. + if h.driverInfo.Capabilities[storageframework.CapSnapshotMetadata] { + containers = append(containers, container) + } default: // Keep the others. containers = append(containers, container) } } + for _, volume := range item.Spec.Template.Spec.Volumes { + switch volume.Name { + case "csi-snapshot-metadata-server-certs": + // Only keep the snapshot metadata volume when the feature is enabled. + if h.driverInfo.Capabilities[storageframework.CapSnapshotMetadata] { + volumes = append(volumes, volume) + } + default: + volumes = append(volumes, volume) + } + } item.Spec.Template.Spec.Containers = containers + item.Spec.Template.Spec.Volumes = volumes } return nil }, h.manifests...) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/io.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/io.go index 0d64587755..163de4f230 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/io.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/io.go @@ -22,13 +22,13 @@ import ( "io" "k8s.io/klog/v2" - "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" "k8s.io/kubernetes/test/e2e/storage/drivers/csi-test/mock/service" + "k8s.io/kubernetes/test/utils/ktesting" ) type PodDirIO struct { - F *framework.Framework + TCtx ktesting.TContext Namespace string PodName string ContainerName string @@ -105,7 +105,7 @@ func (p PodDirIO) RemoveAll(path string) error { } func (p PodDirIO) execute(command []string, stdin io.Reader) (string, string, error) { - stdout, stderr, err := e2epod.ExecWithOptions(p.F, e2epod.ExecOptions{ + stdout, stderr, err := e2epod.ExecWithOptionsTCtx(p.TCtx, e2epod.ExecOptions{ Command: command, Namespace: p.Namespace, PodName: p.PodName, diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/portproxy.go b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/portproxy.go index 27b5948823..6a8274ade8 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/portproxy.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/drivers/proxy/portproxy.go @@ -29,13 +29,13 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/portforward" "k8s.io/client-go/transport/spdy" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // Maximum number of forwarded connections. In practice we don't @@ -99,7 +99,7 @@ func Listen(ctx context.Context, clientset kubernetes.Interface, restConfig *res if err != nil { return nil, fmt.Errorf("create round tripper: %w", err) } - dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) + dialer := spdy.NewDialerForStreaming(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) prefix := fmt.Sprintf("port forwarding for %s", addr) ctx, cancel := context.WithCancel(ctx) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/snapshot_resource.go b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/snapshot_resource.go index 2b72849a2a..7be751f1ea 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/snapshot_resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/snapshot_resource.go @@ -125,7 +125,7 @@ func CreateSnapshotResource(ctx context.Context, sDriver SnapshottableTestDriver framework.ExpectNoError(err) ginkgo.By("checking the Snapshot has been deleted") - err = utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.SnapshotGVR, r.Vs.GetName(), r.Vs.GetNamespace(), framework.Poll, timeouts.SnapshotDelete) + err = utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.SnapshotGVR, r.Vs.GetNamespace(), r.Vs.GetName(), framework.Poll, timeouts.SnapshotDelete) framework.ExpectNoError(err) err = dc.Resource(utils.SnapshotContentGVR).Delete(ctx, r.Vscontent.GetName(), metav1.DeleteOptions{}) @@ -212,7 +212,7 @@ func (sr *SnapshotResource) CleanupResource(ctx context.Context, timeouts *frame } framework.ExpectNoError(err) - err = utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.SnapshotGVR, sr.Vs.GetName(), sr.Vs.GetNamespace(), framework.Poll, timeouts.SnapshotDelete) + err = utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.SnapshotGVR, sr.Vs.GetNamespace(), sr.Vs.GetName(), framework.Poll, timeouts.SnapshotDelete) framework.ExpectNoError(err) default: cleanupErrs = append(cleanupErrs, err) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testdriver.go b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testdriver.go index 259fd1222b..7c61033ea8 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testdriver.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testdriver.go @@ -130,6 +130,10 @@ type SnapshottableTestDriver interface { GetSnapshotClass(ctx context.Context, config *PerTestConfig, parameters map[string]string) *unstructured.Unstructured } +type SnapshotMetadataTestDriver interface { + TestDriver +} + // VolumeGroupSnapshottableTestDriver represents an interface for a TestDriver that supports DynamicGroupSnapshot type VolumeGroupSnapshottableTestDriver interface { TestDriver @@ -171,6 +175,7 @@ const ( CapVolumeMountGroup Capability = "volumeMountGroup" // Driver has the VolumeMountGroup CSI node capability. Because this is a FSGroup feature, the fsGroup capability must also be set to true. CapExec Capability = "exec" // exec a file in the volume CapSnapshotDataSource Capability = "snapshotDataSource" // support populate data from snapshot + CapSnapshotMetadata Capability = "snapshotMetadata" // support snapshot metadata CapVolumeGroupSnapshot Capability = "groupSnapshot" // support group snapshot CapPVCDataSource Capability = "pvcDataSource" // support populate data from pvc @@ -271,6 +276,8 @@ type DriverInfo struct { VolumeModifyStressTestOptions *VolumeModifyStressTestOptions // [Optional] Parameters for performance tests PerformanceTestOptions *PerformanceTestOptions + // [Optional] Scale parameters for volume group snapshot stress tests. + VolumeGroupSnapshotStressTestOptions *VolumeGroupSnapshotStressTestOptions } // StressTestOptions contains parameters used for stress tests. @@ -318,3 +325,12 @@ type PerformanceTestProvisioningOptions struct { type PerformanceTestOptions struct { ProvisioningOptions *PerformanceTestProvisioningOptions } + +// VolumeGroupSnapshotStressTestOptions contains parameters used for volume group snapshot stress tests. +type VolumeGroupSnapshotStressTestOptions struct { + // Number of pods to create in the StatefulSet. This will create + // that many PVCs with the same label for group snapshotting. + NumPods int + // Number of volume group snapshots to create. + NumSnapshots int +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testpattern.go b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testpattern.go index 5f6218e549..d8901c5cbb 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testpattern.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/testpattern.go @@ -60,8 +60,10 @@ var ( DynamicCreatedSnapshot TestSnapshotType = "DynamicSnapshot" // PreprovisionedCreatedSnapshot represents a snapshot type for pre-provisioned snapshot PreprovisionedCreatedSnapshot TestSnapshotType = "PreprovisionedSnapshot" - + // VolumeGroupSnapshot represents a group snapshot type for dynamic created volumegroupsnapshot VolumeGroupSnapshot TestSnapshotType = "VolumeGroupSnapshot" + // PreprovisionedCreatedVolumeGroupSnapshot represents a group snapshot type for pre-provisioned volumegroupsnapshot + PreprovisionedCreatedVolumeGroupSnapshot TestSnapshotType = "PreprovisionedVolumeGroupSnapshot" ) // TestSnapshotDeletionPolicy represents the deletion policy of the snapshot class @@ -229,6 +231,7 @@ var ( TestTags: []interface{}{framework.WithSlow()}, SnapshotType: DynamicCreatedSnapshot, SnapshotDeletionPolicy: DeleteSnapshot, + AllowExpansion: true, } // Definitions for ntfs @@ -311,6 +314,15 @@ var ( AllowExpansion: true, } + // Definition for snapshot metadata + SnapshotMetadata = TestPattern{ + Name: "SnapshotMetadata", + VolType: DynamicPV, + VolMode: v1.PersistentVolumeBlock, + SnapshotType: DynamicCreatedSnapshot, + SnapshotDeletionPolicy: DeleteSnapshot, + } + // Definitions for snapshot case // DynamicSnapshotDelete is TestPattern for "Dynamic snapshot" @@ -328,6 +340,31 @@ var ( SnapshotDeletionPolicy: DeleteSnapshot, VolType: DynamicPV, } + + // VolumeGroupSnapshotRetain is TestPattern for "VolumeGroupSnapshot" + VolumeGroupSnapshotRetain = TestPattern{ + Name: " (retain policy)", + SnapshotType: VolumeGroupSnapshot, + SnapshotDeletionPolicy: RetainSnapshot, + VolType: DynamicPV, + } + + // PreprovisionedVolumeGroupSnapshotDelete is TestPattern for "Pre-provisioned VolumeGroupSnapshot" + PreprovisionedVolumeGroupSnapshotDelete = TestPattern{ + Name: "Pre-provisioned VolumeGroupSnapshot (delete policy)", + SnapshotType: PreprovisionedCreatedVolumeGroupSnapshot, + SnapshotDeletionPolicy: DeleteSnapshot, + VolType: DynamicPV, + } + + // PreprovisionedVolumeGroupSnapshotRetain is TestPattern for "Pre-provisioned VolumeGroupSnapshot" + PreprovisionedVolumeGroupSnapshotRetain = TestPattern{ + Name: "Pre-provisioned VolumeGroupSnapshot (retain policy)", + SnapshotType: PreprovisionedCreatedVolumeGroupSnapshot, + SnapshotDeletionPolicy: RetainSnapshot, + VolType: DynamicPV, + } + // PreprovisionedSnapshotDelete is TestPattern for "Pre-provisioned snapshot" PreprovisionedSnapshotDelete = TestPattern{ Name: "Pre-provisioned Snapshot (delete policy)", @@ -357,7 +394,7 @@ var ( SnapshotDeletionPolicy: RetainSnapshot, VolType: DynamicPV, } - // EphemeralSnapshotDelete is TestPattern for snapshotting of a generic ephemeral volume + // EphemeralSnapshotRetain is TestPattern for snapshotting of a generic ephemeral volume // where snapshots are preserved. EphemeralSnapshotRetain = TestPattern{ Name: "Ephemeral Snapshot (retain policy)", diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/volume_group_snapshot_resource.go b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/volume_group_snapshot_resource.go index 1a7a180b12..06530190cb 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/framework/volume_group_snapshot_resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/framework/volume_group_snapshot_resource.go @@ -22,14 +22,33 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/dynamic" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/storage/utils" ) -func getVolumeGroupSnapshot(labels map[string]interface{}, ns, snapshotClassName string) *unstructured.Unstructured { - snapshot := &unstructured.Unstructured{ +// GetVolumeGroupSnapshot constructs a VolumeGroupSnapshot object with a label selector. +// vgsclassName is optional; if empty, the cluster's default VolumeGroupSnapshotClass +// will be used by the controller. +func GetVolumeGroupSnapshot(ns string, matchLabels map[string]interface{}, vgsclassName string) *unstructured.Unstructured { + spec := map[string]interface{}{ + "source": map[string]interface{}{ + "selector": map[string]interface{}{ + "matchLabels": matchLabels, + }, + }, + } + if vgsclassName != "" { + spec["volumeGroupSnapshotClassName"] = vgsclassName + } + return &unstructured.Unstructured{ Object: map[string]interface{}{ "kind": "VolumeGroupSnapshot", "apiVersion": utils.VolumeGroupSnapshotAPIVersion, @@ -37,18 +56,9 @@ func getVolumeGroupSnapshot(labels map[string]interface{}, ns, snapshotClassName "generateName": "group-snapshot-", "namespace": ns, }, - "spec": map[string]interface{}{ - "volumeGroupSnapshotClassName": snapshotClassName, - "source": map[string]interface{}{ - "selector": map[string]interface{}{ - "matchLabels": labels, - }, - }, - }, + "spec": spec, }, } - - return snapshot } // VolumeGroupSnapshotResource represents a volumegroupsnapshot class, a volumegroupsnapshot and its bound contents for a specific test case @@ -59,6 +69,11 @@ type VolumeGroupSnapshotResource struct { VGS *unstructured.Unstructured VGSContent *unstructured.Unstructured VGSClass *unstructured.Unstructured + + // SnapshotHandleToPVCName maps snapshot handle to source PVC name + // This is populated during conversion to pre-provisioned snapshots + // to preserve the PVC name information that is lost in pre-provisioned resources + SnapshotHandleToPVCName map[string]string } // CreateVolumeGroupSnapshot creates a VolumeGroupSnapshotClass with given SnapshotDeletionPolicy and a VolumeGroupSnapshot @@ -67,9 +82,9 @@ type VolumeGroupSnapshotResource struct { func CreateVolumeGroupSnapshot(ctx context.Context, sDriver VolumeGroupSnapshottableTestDriver, config *PerTestConfig, pattern TestPattern, groupName string, pvcNamespace string, timeouts *framework.TimeoutContext, parameters map[string]string) (*unstructured.Unstructured, *unstructured.Unstructured, *unstructured.Unstructured) { defer ginkgo.GinkgoRecover() var err error - if pattern.SnapshotType != VolumeGroupSnapshot { - err = fmt.Errorf("SnapshotType must be set to VolumeGroupSnapshot") - framework.ExpectNoError(err, "SnapshotType is set to VolumeGroupSnapshot") + if pattern.SnapshotType != VolumeGroupSnapshot && pattern.SnapshotType != PreprovisionedCreatedVolumeGroupSnapshot { + err = fmt.Errorf("SnapshotType must be set to either VolumeGroupSnapshot or PreprovisionedCreatedVolumeGroupSnapshot") + framework.ExpectNoError(err, "SnapshotType is set to VolumeGroupSnapshot or PreprovisionedCreatedVolumeGroupSnapshot") } dc := config.Framework.DynamicClient @@ -87,9 +102,9 @@ func CreateVolumeGroupSnapshot(ctx context.Context, sDriver VolumeGroupSnapshott ginkgo.By("creating a dynamic VolumeGroupSnapshot") // Prepare a dynamically provisioned group volume snapshot with certain data - volumeGroupSnapshot := getVolumeGroupSnapshot(map[string]interface{}{ + volumeGroupSnapshot := GetVolumeGroupSnapshot(pvcNamespace, map[string]interface{}{ "group": groupName, - }, pvcNamespace, gsclass.GetName()) + }, gsclass.GetName()) volumeGroupSnapshot, err = dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(volumeGroupSnapshot.GetNamespace()).Create(ctx, volumeGroupSnapshot, metav1.CreateOptions{}) framework.ExpectNoError(err, "Failed to create volume group snapshot") @@ -110,24 +125,599 @@ func CreateVolumeGroupSnapshot(ctx context.Context, sDriver VolumeGroupSnapshott return gsclass, volumeGroupSnapshot, vgsc } -// CleanupResource deletes the VolumeGroupSnapshotClass and VolumeGroupSnapshot objects using a dynamic client. -func (r *VolumeGroupSnapshotResource) CleanupResource(ctx context.Context, timeouts *framework.TimeoutContext) error { - defer ginkgo.GinkgoRecover() +// patchVGSCDeletionPolicy patches the deletion policy of a single VolumeGroupSnapshotContent +func patchVGSCDeletionPolicy(ctx context.Context, dc dynamic.Interface, vgscName string, deletionPolicy string) error { + patchData := fmt.Appendf(nil, `{"spec":{"deletionPolicy":"%s"}}`, deletionPolicy) + _, err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Patch(ctx, vgscName, types.MergePatchType, patchData, metav1.PatchOptions{}) + if err != nil { + return fmt.Errorf("failed to patch VGSC %q deletion policy to %s: %w", vgscName, deletionPolicy, err) + } + return nil +} + +// patchVSCDeletionPolicy patches the deletion policy of a single VolumeSnapshotContent +func patchVSCDeletionPolicy(ctx context.Context, dc dynamic.Interface, vscName string, deletionPolicy string) error { + patchData := fmt.Appendf(nil, `{"spec":{"deletionPolicy":"%s"}}`, deletionPolicy) + _, err := dc.Resource(utils.SnapshotContentGVR).Patch(ctx, vscName, types.MergePatchType, patchData, metav1.PatchOptions{}) + if err != nil { + return fmt.Errorf("failed to patch VSC %q deletion policy to %s: %w", vscName, deletionPolicy, err) + } + return nil +} + +// patchVSCsDeletionPolicy patches deletion policy for all VolumeSnapshotContents owned by the given VGS +func (r *VolumeGroupSnapshotResource) patchVSCsDeletionPolicy(ctx context.Context, dc dynamic.Interface, vgsNamespace string, vgsUID types.UID, deletionPolicy string) error { + // Get all VolumeSnapshotContent names owned by this VGS + contentNamesSet, err := r.getVolumeSnapshotContentNames(ctx, dc, vgsNamespace, vgsUID) + if err != nil { + return fmt.Errorf("failed to get VolumeSnapshotContent names: %w", err) + } + + // Patch all VolumeSnapshotContents deletion policy + for _, contentName := range contentNamesSet.UnsortedList() { + if err := patchVSCDeletionPolicy(ctx, dc, contentName, deletionPolicy); err != nil { + return err + } + } + + return nil +} + +// patchVGSAndVSCsDeletionPolicy patches the deletion policy of the VGSC and all its associated VSCs +func (r *VolumeGroupSnapshotResource) patchVGSAndVSCsDeletionPolicy(ctx context.Context, dc dynamic.Interface, vgsc *unstructured.Unstructured, vgsNamespace string, vgsUID types.UID, deletionPolicy string) (*unstructured.Unstructured, error) { + // Patch VGSC deletion policy + if err := patchVGSCDeletionPolicy(ctx, dc, vgsc.GetName(), deletionPolicy); err != nil { + return nil, err + } + + // Get the updated VGSC + updatedVGSC, err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Get(ctx, vgsc.GetName(), metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get updated VGSC %q: %w", vgsc.GetName(), err) + } + + // Patch all VolumeSnapshotContents deletion policy + if err := r.patchVSCsDeletionPolicy(ctx, dc, vgsNamespace, vgsUID, deletionPolicy); err != nil { + return nil, err + } + + return updatedVGSC, nil +} + +// getVolumeSnapshotContentNames returns the set of VolumeSnapshotContent names bound to VolumeSnapshots owned by the given VGS +func (r *VolumeGroupSnapshotResource) getVolumeSnapshotContentNames(ctx context.Context, dc dynamic.Interface, vgsNamespace string, vgsUID types.UID) (sets.Set[string], error) { + vss, err := dc.Resource(utils.SnapshotGVR).Namespace(vgsNamespace).List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, err + } + + // Filter to VolumeSnapshots owned by this VGS + ownedSnapshots := utils.FilterResourcesByOwner(vss.Items, "VolumeGroupSnapshot", vgsUID) + + // Extract VolumeSnapshotContent names from owned snapshots + contentNamesSet := sets.New[string]() + for _, vs := range ownedSnapshots { + if status, ok := vs.Object["status"].(map[string]interface{}); ok { + if cName, ok := status["boundVolumeSnapshotContentName"].(string); ok && cName != "" { + contentNamesSet.Insert(cName) + } + } + } + return contentNamesSet, nil +} + +// cleanupRetainedVolumeSnapshotContents forcibly deletes VolumeSnapshotContents with Retain policy +func (r *VolumeGroupSnapshotResource) cleanupRetainedVolumeSnapshotContents(ctx context.Context, dc dynamic.Interface, contentNames sets.Set[string], timeouts *framework.TimeoutContext) { + // Update deletion policy and delete each VolumeSnapshotContent + for _, contentName := range contentNames.UnsortedList() { + // Patch deletion policy to Delete + if err := patchVSCDeletionPolicy(ctx, dc, contentName, "Delete"); err != nil { + framework.Failf("Failed to patch VolumeSnapshotContent %q deletion policy: %v", contentName, err) + return + } + + // Delete VolumeSnapshotContent + err := dc.Resource(utils.SnapshotContentGVR).Delete(ctx, contentName, metav1.DeleteOptions{}) + if err != nil { + framework.Failf("Failed to delete VolumeSnapshotContent %q: %v", contentName, err) + return + } + } + + // Wait for all VolumeSnapshotContents to be deleted + framework.Logf("Waiting for VolumeSnapshotContents to be deleted") + for _, contentName := range contentNames.UnsortedList() { + if err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete); err != nil { + framework.Failf("VolumeSnapshotContent %q was not fully deleted: %v", contentName, err) + return + } + } +} + +// cleanupRetainedVGSContent forcibly deletes VolumeGroupSnapshotContent with Retain policy +func (r *VolumeGroupSnapshotResource) cleanupRetainedVGSContent(ctx context.Context, dc dynamic.Interface, vgscName string, timeouts *framework.TimeoutContext) { + framework.Logf("Deleting VGSContent %q", vgscName) + + // Patch deletion policy to Delete + if err := patchVGSCDeletionPolicy(ctx, dc, vgscName, "Delete"); err != nil { + framework.Failf("Failed to patch VGSContent %q deletion policy: %v", vgscName, err) + return + } + + // Delete VGSContent + err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Delete(ctx, vgscName, metav1.DeleteOptions{}) + if err != nil { + framework.Failf("Failed to delete VGSContent %q: %v", vgscName, err) + return + } + + // Wait for VGSContent to be deleted + framework.Logf("Waiting for VGSContent %q to be deleted", vgscName) + err = utils.WaitForGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgscName, framework.Poll, timeouts.SnapshotDelete) + if err != nil { + framework.Failf("VGSContent %q was not fully deleted: %v", vgscName, err) + return + } +} + +// verifyVolumeSnapshotContentsDeletion verifies that all VolumeSnapshotContents have been deleted +func (r *VolumeGroupSnapshotResource) verifyVolumeSnapshotContentsDeletion(ctx context.Context, dc dynamic.Interface, contentNames sets.Set[string], timeouts *framework.TimeoutContext) { + ginkgo.By("Verifying all VolumeSnapshotContents have been deleted") + var verifyErrs []error + for _, contentName := range contentNames.UnsortedList() { + err := utils.EnsureGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete, "") + if err != nil { + verifyErrs = append(verifyErrs, fmt.Errorf("VolumeSnapshotContent %q should be deleted: %w", contentName, err)) + } + } + if len(verifyErrs) > 0 { + framework.ExpectNoError(utilerrors.NewAggregate(verifyErrs), "Failed to verify VolumeSnapshotContents deletion") + } +} + +// CleanupVGS deletes the VolumeGroupSnapshot and ensures the bound VolumeGroupSnapshotContent has Delete policy. +// It waits for the VolumeGroupSnapshot, its owned VolumeSnapshots, VolumeSnapshotContents, and the bound +// VolumeGroupSnapshotContent to be fully deleted to prevent resource leaks. +func (r *VolumeGroupSnapshotResource) CleanupVGS(ctx context.Context, timeouts *framework.TimeoutContext) error { + if r.VGS == nil { + return nil + } + dc := r.Config.Framework.DynamicClient - err := dc.Resource(utils.VolumeGroupSnapshotClassGVR).Delete(ctx, r.VGSClass.GetName(), metav1.DeleteOptions{}) - framework.ExpectNoError(err, "Failed to delete volume group snapshot class") + vgsNamespace := r.VGS.GetNamespace() + vgsName := r.VGS.GetName() + vgsUID := r.VGS.GetUID() + framework.Logf("deleting groupSnapshot %q/%q and ensuring content has Delete policy", vgsNamespace, vgsName) + + // Get the VGS to ensure it exists + vgs, err := dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(vgsNamespace).Get(ctx, vgsName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return fmt.Errorf("failed to get VGS %q: %w", vgsName, err) + } + r.VGS = vgs + + // Get all VolumeSnapshotContent names owned by this VGS + contentNamesSet, err := r.getVolumeSnapshotContentNames(ctx, dc, vgsNamespace, vgsUID) + if err != nil { + return err + } + + // Get the bound VolumeGroupSnapshotContent + groupSnapshotStatus := r.VGS.Object["status"].(map[string]interface{}) + groupSnapshotContentName := groupSnapshotStatus["boundVolumeGroupSnapshotContentName"].(string) + framework.Logf("received groupSnapshotStatus %v", groupSnapshotStatus) + framework.Logf("groupSnapshotContentName %q", groupSnapshotContentName) + + boundVGSContent, err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Get(ctx, groupSnapshotContentName, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get bound VGSContent %q: %w", groupSnapshotContentName, err) + } + + // For Delete policy, ensure deletion policy is set to Delete to prevent leaks + // For Retain policy, we'll update it after verifying retention behavior + if boundVGSContent != nil && r.Pattern.SnapshotDeletionPolicy == DeleteSnapshot { + spec := boundVGSContent.Object["spec"].(map[string]interface{}) + if spec["deletionPolicy"] != "Delete" { + boundVGSContent, err = r.patchVGSAndVSCsDeletionPolicy(ctx, dc, boundVGSContent, vgsNamespace, vgsUID, "Delete") + if err != nil { + return fmt.Errorf("failed to update deletion policy: %w", err) + } + } + } + r.VGSContent = boundVGSContent + + // Delete the VolumeGroupSnapshot + if err := dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(vgsNamespace).Delete(ctx, vgsName, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to delete VGS %q: %w", vgsName, err) + } + + // Wait for VolumeGroupSnapshot deleted + if err := utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotGVR, vgsNamespace, vgsName, framework.Poll, timeouts.SnapshotDelete); err != nil { + return fmt.Errorf("failed waiting for VGS %q deletion: %w", vgsName, err) + } + + // Wait for VolumeSnapshots owned by this VGS to be cascade-deleted + // This happens regardless of deletion policy because VGS owns VolumeSnapshots via owner references + if vgsUID != "" { + if err := utils.WaitForOwnedResourcesDeleted(ctx, dc, utils.SnapshotGVR, vgsNamespace, vgsUID, framework.Poll, timeouts.SnapshotDelete); err != nil { + return fmt.Errorf("failed waiting for owned snapshots deletion of VGS %q: %w", vgsName, err) + } + } + + // Verify deletion policy behavior for VolumeGroupSnapshotContent + if boundVGSContent != nil { + vgscName := boundVGSContent.GetName() + + switch r.Pattern.SnapshotDeletionPolicy { + case DeleteSnapshot: + ginkgo.By(fmt.Sprintf("Verifying VolumeGroupSnapshotContent %q has been deleted per Delete policy", vgscName)) + err = utils.EnsureGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgscName, framework.Poll, timeouts.SnapshotDelete, "") + framework.ExpectNoError(err, "VolumeGroupSnapshotContent should be deleted with Delete policy") + r.VGSContent = nil + case RetainSnapshot: + ginkgo.By(fmt.Sprintf("Verifying VolumeGroupSnapshotContent %q has been retained per Retain policy", vgscName)) + err = utils.EnsureNoGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgscName, framework.Poll, 20*framework.Poll, "") + framework.ExpectNoError(err, "VolumeGroupSnapshotContent should be retained with Retain policy") + + // Force cleanup to prevent leaks + // Cleanup order: + // 1. VolumeSnapshotContents (update policy + delete + wait) + // 2. VGSContent (update policy + delete + wait) + framework.Logf("Retain policy verified, now forcing cleanup to prevent leaks") + r.cleanupRetainedVolumeSnapshotContents(ctx, dc, contentNamesSet, timeouts) + r.cleanupRetainedVGSContent(ctx, dc, vgscName, timeouts) + r.VGSContent = nil + } + } + + // Verify all VolumeSnapshotContents have been deleted + r.verifyVolumeSnapshotContentsDeletion(ctx, dc, contentNamesSet, timeouts) + return nil } +// CleanupVGSClass deletes the VolumeGroupSnapshotClass. +func (r *VolumeGroupSnapshotResource) CleanupVGSClass(ctx context.Context, timeouts *framework.TimeoutContext) error { + if r.VGSClass == nil { + framework.Logf("VGSClass is nil, skipping cleanup") + return nil + } + + dc := r.Config.Framework.DynamicClient + vgsClassName := r.VGSClass.GetName() + framework.Logf("deleting VolumeGroupSnapshotClass %q", vgsClassName) + + err := dc.Resource(utils.VolumeGroupSnapshotClassGVR).Delete(ctx, vgsClassName, metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to delete groupSnapshotClass %q: %w", vgsClassName, err) + } + + if err = utils.WaitForGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotClassGVR, vgsClassName, framework.Poll, timeouts.SnapshotDelete); err != nil { + return fmt.Errorf("failed waiting for VolumeGroupSnapshotClass %q deletion: %w", vgsClassName, err) + } + + framework.Logf("successfully deleted VolumeGroupSnapshotClass %q", vgsClassName) + r.VGSClass = nil + return nil +} + +// CleanupResource deletes the VolumeGroupSnapshotClass and VolumeGroupSnapshot objects using a dynamic client, +// and ignores not found errors. +func (r *VolumeGroupSnapshotResource) CleanupResource(ctx context.Context, timeouts *framework.TimeoutContext) error { + var cleanupErrs []error + + if err := r.CleanupVGS(ctx, timeouts); err != nil { + cleanupErrs = append(cleanupErrs, err) + } + + if err := r.CleanupVGSClass(ctx, timeouts); err != nil { + cleanupErrs = append(cleanupErrs, err) + } + + return utilerrors.NewAggregate(cleanupErrs) +} + // CreateVolumeGroupSnapshotResource creates a VolumeGroupSnapshotResource object with the given parameters. func CreateVolumeGroupSnapshotResource(ctx context.Context, sDriver VolumeGroupSnapshottableTestDriver, config *PerTestConfig, pattern TestPattern, pvcName string, pvcNamespace string, timeouts *framework.TimeoutContext, parameters map[string]string) *VolumeGroupSnapshotResource { vgsClass, snapshot, vgsc := CreateVolumeGroupSnapshot(ctx, sDriver, config, pattern, pvcName, pvcNamespace, timeouts, parameters) - vgs := &VolumeGroupSnapshotResource{ + r := &VolumeGroupSnapshotResource{ Config: config, Pattern: pattern, VGS: snapshot, VGSClass: vgsClass, VGSContent: vgsc, } - return vgs + + dc := config.Framework.DynamicClient + + if pattern.SnapshotType == PreprovisionedCreatedVolumeGroupSnapshot { + r.convertToPreprovisioned(ctx, dc, snapshot, vgsc, vgsClass, pvcNamespace, timeouts) + } + + return r +} + +// convertToPreprovisioned converts a dynamic VolumeGroupSnapshot to a pre-provisioned one. +// This is done by: +// 1. Recording the snapshot handles from the dynamic snapshot +// 2. Deleting the dynamic snapshot resources (with Retain policy to keep backend snapshots) +// 3. Creating new pre-provisioned resources that reference the same backend snapshots +func (r *VolumeGroupSnapshotResource) convertToPreprovisioned(ctx context.Context, dc dynamic.Interface, snapshot, vgsc, vgsClass *unstructured.Unstructured, pvcNamespace string, timeouts *framework.TimeoutContext) { + var err error + vgsUID := snapshot.GetUID() + + // Only update to Retain if the pattern specifies Delete policy + // This preserves the backend snapshots when we delete the dynamic resources + if r.Pattern.SnapshotDeletionPolicy == DeleteSnapshot { + ginkgo.By("updating VGSC and VSC deletion policies to Retain") + vgsc, err = r.patchVGSAndVSCsDeletionPolicy(ctx, dc, vgsc, pvcNamespace, vgsUID, "Retain") + framework.ExpectNoError(err, "failed to update VGSC and VSC deletion policies to Retain") + } + + ginkgo.By("recording properties of the pre-provisioned group snapshot") + vgscStatus := vgsc.Object["status"].(map[string]interface{}) + groupSnapshotHandle := vgscStatus["volumeGroupSnapshotHandle"].(string) + framework.Logf("Recording group snapshot content handle: %s", groupSnapshotHandle) + + // Extract individual volume snapshot handles from volumeSnapshotInfoList + volumeSnapshotInfoList := vgscStatus["volumeSnapshotInfoList"].([]interface{}) + volumeSnapshotHandles := make([]string, 0, len(volumeSnapshotInfoList)) + for _, info := range volumeSnapshotInfoList { + infoMap := info.(map[string]interface{}) + snapshotHandle := infoMap["snapshotHandle"].(string) + volumeSnapshotHandles = append(volumeSnapshotHandles, snapshotHandle) + } + framework.Logf("Recording %d volume snapshot handles", len(volumeSnapshotHandles)) + + csiDriverName := vgsClass.Object["driver"].(string) + framework.Logf("Recording snapshot driver: %s", csiDriverName) + + // Get all VolumeSnapshotContent names owned by this VGS before deletion + contentNamesSet, err := r.getVolumeSnapshotContentNames(ctx, dc, pvcNamespace, vgsUID) + framework.ExpectNoError(err, "failed to get VolumeSnapshotContent names owned by VGS %s", vgsUID) + + // Capture the mapping of snapshot handle to source PVC name before deleting dynamic snapshots + // This is needed because pre-provisioned snapshots don't have spec.source.persistentVolumeClaimName + ginkgo.By("capturing source PVC names from dynamic VolumeSnapshots") + vsList, err := dc.Resource(utils.SnapshotGVR).Namespace(pvcNamespace).List(ctx, metav1.ListOptions{}) + framework.ExpectNoError(err, "failed to list VolumeSnapshots") + + // Filter to VolumeSnapshots owned by this VGS + ownedSnapshots := utils.FilterResourcesByOwner(vsList.Items, "VolumeGroupSnapshot", vgsUID) + + // Map snapshotHandle to source PVC name and store in the resource struct + r.SnapshotHandleToPVCName = make(map[string]string) + for _, vs := range ownedSnapshots { + // Get the source PVC name from the dynamic VolumeSnapshot + // Since we waited for VGS to be ready, the VS should be bound and have source PVC name + spec := vs.Object["spec"].(map[string]interface{}) + source := spec["source"].(map[string]interface{}) + sourcePVCName := source["persistentVolumeClaimName"].(string) + + // Get the VSC name from status (VS is bound since VGS is ready) + status := vs.Object["status"].(map[string]interface{}) + vscName := status["boundVolumeSnapshotContentName"].(string) + + // Get the VSC to find the snapshot handle (should exist since VS is bound) + vsc, err := dc.Resource(utils.SnapshotContentGVR).Get(ctx, vscName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get VolumeSnapshotContent %s for bound VolumeSnapshot %s", vscName, vs.GetName()) + + vscStatus := vsc.Object["status"].(map[string]interface{}) + snapshotHandle := vscStatus["snapshotHandle"].(string) + r.SnapshotHandleToPVCName[snapshotHandle] = sourcePVCName + framework.Logf("Mapped snapshot handle %s to PVC %s", snapshotHandle, sourcePVCName) + } + + // If the deletion policy is retain on vgsc: + // when vgs is deleted vgsc will not be deleted + // when the vgsc is manually deleted then the underlying group snapshot resource will not be deleted. + // We exploit this to create a group snapshot resource from which we can create a preprovisioned snapshot + ginkgo.By("deleting the group snapshot") + err = dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(snapshot.GetNamespace()).Delete(ctx, snapshot.GetName(), metav1.DeleteOptions{}) + framework.ExpectNoError(err, "failed to delete VolumeGroupSnapshot %s/%s", snapshot.GetNamespace(), snapshot.GetName()) + + ginkgo.By("checking the VolumeGroupSnapshot has been deleted") + err = utils.WaitForNamespacedGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotGVR, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, timeouts.SnapshotDelete) + framework.ExpectNoError(err, "VolumeGroupSnapshot %s/%s was not deleted within timeout", snapshot.GetNamespace(), snapshot.GetName()) + + // Wait for VolumeSnapshots owned by this VGS to be cascade-deleted + ginkgo.By("waiting for owned VolumeSnapshots to be deleted") + err = utils.WaitForOwnedResourcesDeleted(ctx, dc, utils.SnapshotGVR, pvcNamespace, vgsUID, framework.Poll, timeouts.SnapshotDelete) + framework.ExpectNoError(err, "VolumeSnapshots owned by VGS %s were not deleted within timeout", vgsUID) + + // Delete the VolumeSnapshotContents (with Retain policy, so physical snapshots remain) + ginkgo.By("deleting VolumeSnapshotContents") + for _, contentName := range contentNamesSet.UnsortedList() { + err := dc.Resource(utils.SnapshotContentGVR).Delete(ctx, contentName, metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + framework.ExpectNoError(err, "failed to delete VolumeSnapshotContent %s", contentName) + } + } + + // Wait for VolumeSnapshotContents to be deleted + for _, contentName := range contentNamesSet.UnsortedList() { + err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete) + framework.ExpectNoError(err, "VolumeSnapshotContent %s was not deleted within timeout", contentName) + } + + // Delete the VolumeGroupSnapshotContent (with Retain policy, so physical group snapshot remains) + err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Delete(ctx, vgsc.GetName(), metav1.DeleteOptions{}) + framework.ExpectNoError(err, "failed to delete VolumeGroupSnapshotContent %s", vgsc.GetName()) + + ginkgo.By("checking the VolumeGroupSnapshotContent has been deleted") + err = utils.WaitForGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgsc.GetName(), framework.Poll, timeouts.SnapshotDelete) + framework.ExpectNoError(err, "VolumeGroupSnapshotContent %s was not deleted within timeout", vgsc.GetName()) + + // Create new pre-provisioned VGSContent with the extracted group snapshot handle + ginkgo.By("creating a new pre-provisioned VolumeGroupSnapshotContent with the group snapshot handle") + vgsUUID := uuid.NewUUID() + + vgsName := getPreProvisionedVolumeGroupSnapshotName(vgsUUID) + vgscName := getPreProvisionedVolumeGroupSnapshotContentName(vgsUUID) + + r.VGSContent = getPreProvisionedVolumeGroupSnapshotContent(vgscName, vgsName, pvcNamespace, groupSnapshotHandle, volumeSnapshotHandles, r.Pattern.SnapshotDeletionPolicy.String(), csiDriverName) + r.VGSContent, err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Create(ctx, r.VGSContent, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create pre-provisioned VolumeGroupSnapshotContent %s", vgscName) + + ginkgo.By("creating a pre-provisioned VGS with that VGSContent") + r.VGS = getPreProvisionedVolumeGroupSnapshot(vgsName, pvcNamespace, vgscName) + r.VGS, err = dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(r.VGS.GetNamespace()).Create(ctx, r.VGS, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create pre-provisioned VolumeGroupSnapshot %s/%s", pvcNamespace, vgsName) + + err = utils.WaitForVolumeGroupSnapshotReady(ctx, dc, r.VGS.GetNamespace(), r.VGS.GetName(), framework.Poll, timeouts.SnapshotCreate*10) + framework.ExpectNoError(err, "pre-provisioned VolumeGroupSnapshot %s/%s did not become ready within timeout", r.VGS.GetNamespace(), r.VGS.GetName()) + + // Get the new VGS UID for owner references + r.VGS, err = dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(r.VGS.GetNamespace()).Get(ctx, r.VGS.GetName(), metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get VolumeGroupSnapshot %s/%s for UID", r.VGS.GetNamespace(), r.VGS.GetName()) + newVgsUID := r.VGS.GetUID() + vgsAPIVersion := r.VGS.GetAPIVersion() + vgsKind := r.VGS.GetKind() + + // Create new pre-provisioned VolumeSnapshotContents and VolumeSnapshots + // The VolumeSnapshots need to be owned by the VGS so the controller can discover them + ginkgo.By("creating pre-provisioned VolumeSnapshotContents and VolumeSnapshots owned by the VGS") + + for i, snapshotHandle := range volumeSnapshotHandles { + // Generate unique names for the pre-provisioned VolumeSnapshotContent and VolumeSnapshot + // Using VGS UUID + index to make names predictable and associated with parent VGS + snapName := fmt.Sprintf("pre-provisioned-vs-%s-%d", string(vgsUUID), i) + snapContentName := fmt.Sprintf("pre-provisioned-vsc-%s-%d", string(vgsUUID), i) + + // Create pre-provisioned VolumeSnapshotContent first + // Note: volumeSnapshotClassName is not required for pre-provisioned VolumeSnapshotContent + vsc := getPreProvisionedVolumeSnapshotContent(snapContentName, snapName, pvcNamespace, snapshotHandle, r.Pattern.SnapshotDeletionPolicy.String(), csiDriverName) + _, err := dc.Resource(utils.SnapshotContentGVR).Create(ctx, vsc, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create pre-provisioned VolumeSnapshotContent %s", snapContentName) + + // Get the source PVC name mapping for this snapshot handle + sourcePVCName := r.SnapshotHandleToPVCName[snapshotHandle] + gomega.Expect(sourcePVCName).NotTo(gomega.BeEmpty(), "no source PVC name mapping found for snapshot handle %s", snapshotHandle) + framework.Logf("Creating pre-provisioned snapshot %s for PVC %s (handle: %s)", snapName, sourcePVCName, snapshotHandle) + + // Create pre-provisioned VolumeSnapshot + preProvisionedVS := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "VolumeSnapshot", + "apiVersion": utils.SnapshotAPIVersion, + "metadata": map[string]interface{}{ + "name": snapName, + "namespace": pvcNamespace, + "ownerReferences": []interface{}{ + map[string]interface{}{ + "apiVersion": vgsAPIVersion, + "kind": vgsKind, + "name": r.VGS.GetName(), + "uid": newVgsUID, + }, + }, + }, + "spec": map[string]interface{}{ + "source": map[string]interface{}{ + "volumeSnapshotContentName": snapContentName, + }, + }, + }, + } + + _, err = dc.Resource(utils.SnapshotGVR).Namespace(pvcNamespace).Create(ctx, preProvisionedVS, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create pre-provisioned VolumeSnapshot %s/%s", pvcNamespace, snapName) + + // Wait for the VolumeSnapshot to be ready + err = utils.WaitForSnapshotReady(ctx, dc, pvcNamespace, snapName, framework.Poll, timeouts.SnapshotCreate) + framework.ExpectNoError(err, "pre-provisioned VolumeSnapshot %s/%s did not become ready within timeout", pvcNamespace, snapName) + + framework.Logf("Created pre-provisioned VolumeSnapshotContent %s and VolumeSnapshot %s (%d/%d)", snapContentName, snapName, i+1, len(volumeSnapshotHandles)) + } + + ginkgo.By("getting the group snapshot and group snapshot content") + r.VGS, err = dc.Resource(utils.VolumeGroupSnapshotGVR).Namespace(r.VGS.GetNamespace()).Get(ctx, r.VGS.GetName(), metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get final VolumeGroupSnapshot %s/%s", r.VGS.GetNamespace(), r.VGS.GetName()) + + r.VGSContent, err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Get(ctx, r.VGSContent.GetName(), metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get final VolumeGroupSnapshotContent %s", r.VGSContent.GetName()) +} + +func getPreProvisionedVolumeGroupSnapshot(vgsName, ns, vgscName string) *unstructured.Unstructured { + snapshot := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "VolumeGroupSnapshot", + "apiVersion": utils.VolumeGroupSnapshotAPIVersion, + "metadata": map[string]interface{}{ + "name": vgsName, + "namespace": ns, + }, + "spec": map[string]interface{}{ + "source": map[string]interface{}{ + "volumeGroupSnapshotContentName": vgscName, + }, + }, + }, + } + + return snapshot +} + +func getPreProvisionedVolumeGroupSnapshotName(uuid types.UID) string { + return fmt.Sprintf("pre-provisioned-vgs-%s", string(uuid)) +} + +func getPreProvisionedVolumeGroupSnapshotContentName(uuid types.UID) string { + return fmt.Sprintf("pre-provisioned-vgsc-%s", string(uuid)) +} + +func getPreProvisionedVolumeGroupSnapshotContent(vgscName, vgsName, vgsNamespace, groupSnapshotHandle string, volumeSnapshotHandles []string, deletionPolicy, csiDriverName string) *unstructured.Unstructured { + snapshotContent := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "VolumeGroupSnapshotContent", + "apiVersion": utils.VolumeGroupSnapshotAPIVersion, + "metadata": map[string]interface{}{ + "name": vgscName, + }, + "spec": map[string]interface{}{ + "source": map[string]interface{}{ + "groupSnapshotHandles": map[string]interface{}{ + "volumeGroupSnapshotHandle": groupSnapshotHandle, + "volumeSnapshotHandles": volumeSnapshotHandles, + }, + }, + "volumeGroupSnapshotRef": map[string]interface{}{ + "name": vgsName, + "namespace": vgsNamespace, + }, + "driver": csiDriverName, + "deletionPolicy": deletionPolicy, + }, + }, + } + + return snapshotContent +} + +func getPreProvisionedVolumeSnapshotContent(snapcontentName, snapshotName, snapshotNamespace, snapshotHandle, deletionPolicy, csiDriverName string) *unstructured.Unstructured { + snapshotContent := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": "VolumeSnapshotContent", + "apiVersion": utils.SnapshotAPIVersion, + "metadata": map[string]interface{}{ + "name": snapcontentName, + }, + "spec": map[string]interface{}{ + "source": map[string]interface{}{ + "snapshotHandle": snapshotHandle, + }, + "volumeSnapshotRef": map[string]interface{}{ + "name": snapshotName, + "namespace": snapshotNamespace, + }, + "driver": csiDriverName, + "deletionPolicy": deletionPolicy, + }, + }, + } + + return snapshotContent } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go b/vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go index da1c35fcc0..7002bb9ef4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/podlogs/podlogs.go @@ -41,20 +41,36 @@ import ( ) // LogOutput determines where output from CopyAllLogs goes. +// +// Error messages about receiving log output is kept +// separate from the log output and optionally goes to StatusWriter +// +// The log output can go to one or more possible destinations. type LogOutput struct { - // If not nil, errors will be logged here. + // If not nil, errors encountered will be logged here. StatusWriter io.Writer - // If not nil, all output goes to this writer with "/:" as prefix. + // If not nil, all container output goes to this writer with "/:" as prefix. LogWriter io.Writer // Base directory for one log file per container. - // The full path of each log file will be -.log. + // The full path of each log file will be -.log, + // if not empty. LogPathPrefix string + + // LogOpen, if not nil, gets called whenever log output watching starts for + // a certain container. Returning nil means that the output can be discarded + // unless it gets written elsewhere. + // + // The container's stdout and stderr output get written to the returned writer. + // The writer gets closed once all output is processed if the writer implements io.Closer. + // Each write is a single line, including a newline. + // Write errors are ignored. + LogOpen func(podName, containerName string) io.Writer } // Matches harmless errors from pkg/kubelet/kubelet_pods.go. -var expectedErrors = regexp.MustCompile(`container .* in pod .* is (terminated|waiting to start|not available)|the server could not find the requested resource`) +var expectedErrors = regexp.MustCompile(`container .* in pod .* is (terminated|waiting to start|not available)|the server could not find the requested resource|context canceled`) // CopyPodLogs is basically CopyPodLogs for all current or future pods in the given namespace ns func CopyAllLogs(ctx context.Context, cs clientset.Interface, ns string, to LogOutput) error { @@ -92,7 +108,7 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string FieldSelector: fmt.Sprintf("metadata.name=%s", podName), } } - watcher, err := cs.CoreV1().Pods(ns).Watch(context.TODO(), options) + watcher, err := cs.CoreV1().Pods(ns).Watch(ctx, options) if err != nil { return fmt.Errorf("cannot create Pod event watcher: %w", err) @@ -104,15 +120,17 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string active := map[string]bool{} // Key is pod/container/container-id, true if we have ever started to capture its output. started := map[string]bool{} + // Key is pod/container/container-id, value the time stamp of the last log line that has been seen. + latest := map[string]*meta.Time{} check := func() { m.Lock() defer m.Unlock() - pods, err := cs.CoreV1().Pods(ns).List(context.TODO(), options) + pods, err := cs.CoreV1().Pods(ns).List(ctx, options) if err != nil { - if to.StatusWriter != nil { - fmt.Fprintf(to.StatusWriter, "ERROR: get pod list in %s: %s\n", ns, err) + if ctx.Err() == nil && to.StatusWriter != nil { + _, _ = fmt.Fprintf(to.StatusWriter, "ERROR: get pod list in %s: %s\n", ns, err) } return } @@ -139,41 +157,28 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string pod.Status.ContainerStatuses[i].State.Terminated == nil) { continue } - readCloser, err := logsForPod(ctx, cs, ns, pod.ObjectMeta.Name, - &v1.PodLogOptions{ - Container: c.Name, - Follow: true, - }) - if err != nil { - // We do get "normal" errors here, like trying to read too early. - // We can ignore those. - if to.StatusWriter != nil && - expectedErrors.FindStringIndex(err.Error()) == nil { - fmt.Fprintf(to.StatusWriter, "WARNING: pod log: %s: %s\n", name, err) - } - continue - } // Determine where we write. If this fails, we intentionally return without clearing // the active[name] flag, which prevents trying over and over again to // create the output file. - var out io.Writer - var closer io.Closer + var logWithPrefix, logWithoutPrefix, output io.Writer var prefix string + podHandled := false if to.LogWriter != nil { - out = to.LogWriter + podHandled = true + logWithPrefix = to.LogWriter nodeName := pod.Spec.NodeName if len(nodeName) > 10 { nodeName = nodeName[0:4] + ".." + nodeName[len(nodeName)-4:] } prefix = name + "@" + nodeName + ": " - } else { - var err error + } + if to.LogPathPrefix != "" { + podHandled = true filename := to.LogPathPrefix + pod.ObjectMeta.Name + "-" + c.Name + ".log" - err = os.MkdirAll(path.Dir(filename), 0755) - if err != nil { + if err := os.MkdirAll(path.Dir(filename), 0755); err != nil { if to.StatusWriter != nil { - fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create directory for %s: %s\n", filename, err) + _, _ = fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create directory for %s: %s\n", filename, err) } return } @@ -182,26 +187,66 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { if to.StatusWriter != nil { - fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create file %s: %s\n", filename, err) + _, _ = fmt.Fprintf(to.StatusWriter, "ERROR: pod log: create file %s: %s\n", filename, err) } return } - closer = file - out = file + logWithoutPrefix = file } - go func() { - if closer != nil { - defer closer.Close() + if to.LogOpen != nil { + if writer := to.LogOpen(pod.Name, c.Name); writer != nil { + podHandled = true + output = writer } + } + + if !podHandled { + // No-one is interested in this pod, don't bother... + continue + } + + closeOutput := func() { + // Execute all of these, even if one one of them panics. + defer maybeClose(logWithPrefix) + defer maybeClose(logWithoutPrefix) + defer maybeClose(output) + } + + sinceTime := latest[id] + readCloser, err := logsForPod(ctx, cs, ns, pod.ObjectMeta.Name, + &v1.PodLogOptions{ + Container: c.Name, + Follow: true, + Timestamps: true, + SinceTime: sinceTime, + }) + if err != nil { + closeOutput() + + // We do get "normal" errors here, like trying to read too early. + // We can ignore those. + if to.StatusWriter != nil && + expectedErrors.FindStringIndex(err.Error()) == nil { + _, _ = fmt.Fprintf(to.StatusWriter, "WARNING: pod log: %s: %s\n", name, err) + } + continue + } + + active[name] = true + started[id] = true + + go func() { + defer closeOutput() first := true defer func() { m.Lock() // If we never printed anything, then also skip the final message. if !first { - if prefix != "" { - fmt.Fprintf(out, "%s==== end of pod log ====\n", prefix) - } else { - fmt.Fprintf(out, "==== end of pod log for container %s ====\n", name) + if logWithPrefix != nil { + _, _ = fmt.Fprintf(logWithPrefix, "%s==== end of pod log at %s ====\n", prefix, latest[id]) + } + if logWithoutPrefix != nil { + _, _ = fmt.Fprintf(logWithoutPrefix, "==== end of pod log for container %s at %s ====\n", name, latest[id]) } } active[name] = false @@ -209,6 +254,7 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string readCloser.Close() }() scanner := bufio.NewScanner(readCloser) + var latestTS time.Time for scanner.Scan() { line := scanner.Text() // Filter out the expected "end of stream" error message, @@ -222,30 +268,62 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string // Because the same log might be written to multiple times // in different test instances, log an extra line to separate them. // Also provides some useful extra information. - if prefix == "" { - fmt.Fprintf(out, "==== start of pod log for container %s ====\n", name) - } else { - fmt.Fprintf(out, "%s==== start of pod log ====\n", prefix) + since := "(initial part)" + if sinceTime != nil { + since = fmt.Sprintf("since %s", sinceTime) + } + if logWithPrefix != nil { + _, _ = fmt.Fprintf(logWithPrefix, "%s==== start of pod log %s ====\n", prefix, since) + } + if logWithoutPrefix != nil { + _, _ = fmt.Fprintf(logWithoutPrefix, "==== start of pod log for container %s %s ====\n", name, since) } first = false } - fmt.Fprintf(out, "%s%s\n", prefix, line) + index := strings.Index(line, " ") + if index > 0 { + ts, err := time.Parse(time.RFC3339, line[:index]) + if err == nil { + latestTS = ts + // Log output typically has it's own log header with a time stamp, + // so let's strip the PodLogOptions time stamp. + line = line[index+1:] + } + } + if logWithPrefix != nil { + _, _ = fmt.Fprintf(logWithPrefix, "%s%s\n", prefix, line) + } + if logWithoutPrefix != nil { + _, _ = fmt.Fprintln(logWithoutPrefix, line) + } + if output != nil { + _, _ = output.Write([]byte(line + "\n")) + } } } + + if !latestTS.IsZero() { + m.Lock() + defer m.Unlock() + latest[id] = &meta.Time{Time: latestTS} + } }() - active[name] = true - started[id] = true } } } // Watch events to see whether we can start logging - // and log interesting ones. + // and log interesting ones. Also check periodically, + // in case of failures which are not followed by + // some pod change. + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() check() for { select { case <-watcher.ResultChan(): check() + case <-ticker.C: case <-ctx.Done(): return } @@ -255,6 +333,12 @@ func CopyPodLogs(ctx context.Context, cs clientset.Interface, ns, podName string return nil } +func maybeClose(writer io.Writer) { + if closer, ok := writer.(io.Closer); ok { + _ = closer.Close() + } +} + // logsForPod starts reading the logs for a certain pod. If the pod has more than one // container, opts.Container must be set. Reading stops when the context is done. // The stream includes formatted error messages and ends with @@ -276,7 +360,7 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri } }() - pods, err := cs.CoreV1().Pods(ns).Watch(context.Background(), meta.ListOptions{}) + pods, err := cs.CoreV1().Pods(ns).Watch(ctx, meta.ListOptions{}) if err != nil { return fmt.Errorf("cannot create Pod watcher: %w", err) } @@ -286,7 +370,7 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri } }() - events, err := cs.CoreV1().Events(ns).Watch(context.Background(), meta.ListOptions{}) + events, err := cs.CoreV1().Events(ns).Watch(ctx, meta.ListOptions{}) if err != nil { return fmt.Errorf("cannot create Event watcher: %w", err) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go index a0cdafe18a..394df21afd 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go @@ -23,13 +23,12 @@ import ( "errors" "fmt" - "github.com/onsi/ginkgo/v2" - appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -39,6 +38,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2etestfiles "k8s.io/kubernetes/test/e2e/framework/testfiles" imageutils "k8s.io/kubernetes/test/utils/image" + "k8s.io/kubernetes/test/utils/ktesting" ) // LoadFromManifests loads .yaml or .json manifest files and returns @@ -121,31 +121,31 @@ func visitManifests(cb func([]byte) error, files ...string) error { // - only some common items are supported, unknown ones trigger an error // - only the latest stable API version for each item is supported func PatchItems(f *framework.Framework, driverNamespace *v1.Namespace, items ...interface{}) error { + tCtx := f.TContext(context.Background()) + if driverNamespace != nil { + tCtx = tCtx.WithNamespace(driverNamespace.Name) + } + return PatchItemsTCtx(tCtx, items...) +} + +// PatchItemsTCtx is a variant of PatchItems where all parameters, including +// the namespace, are passed through a TContext. +func PatchItemsTCtx(tCtx ktesting.TContext, items ...interface{}) error { for _, item := range items { // Uncomment when debugging the loading and patching of items. // Logf("patching original content of %T:\n%s", item, PrettyPrint(item)) - if err := patchItemRecursively(f, driverNamespace, item); err != nil { + if err := patchItemRecursively(tCtx, item); err != nil { return err } } return nil } -// CreateItems creates the items. Each of them must be an API object +// createItems creates the items. Each of them must be an API object // of a type that is registered in Factory. // -// It returns either a cleanup function or an error, but never both. -// -// Cleaning up after a test can be triggered in two ways: -// - the test invokes the returned cleanup function, -// usually in an AfterEach -// - the test suite terminates, potentially after -// skipping the test's AfterEach (https://github.com/onsi/ginkgo/issues/222) -// -// PatchItems has the some limitations as LoadFromManifests: -// - only some common items are supported, unknown ones trigger an error -// - only the latest stable API version for each item is supported -func CreateItems(ctx context.Context, f *framework.Framework, ns *v1.Namespace, items ...interface{}) error { +// Object get deleted automatically during test cleanup. +func createItems(tCtx ktesting.TContext, items ...interface{}) error { var result error for _, item := range items { // Each factory knows which item(s) it supports, so try each one. @@ -153,11 +153,17 @@ func CreateItems(ctx context.Context, f *framework.Framework, ns *v1.Namespace, description := describeItem(item) // Uncomment this line to get a full dump of the entire item. // description = fmt.Sprintf("%s:\n%s", description, PrettyPrint(item)) - framework.Logf("creating %s", description) + tCtx.Logf("creating %s", description) for _, factory := range factories { - destructor, err := factory.Create(ctx, f, ns, item) + destructor, err := factory.Create(tCtx, item) if destructor != nil { - ginkgo.DeferCleanup(framework.IgnoreNotFound(destructor), framework.AnnotatedLocation(fmt.Sprintf("deleting %s", description))) + tCtx.CleanupCtx(func(tCtx ktesting.TContext) { + err := destructor(tCtx) + if apierrors.IsNotFound(err) { + return + } + tCtx.ExpectNoError(err, fmt.Sprintf("deleting %s", description)) + }) } if err == nil { done = true @@ -178,13 +184,25 @@ func CreateItems(ctx context.Context, f *framework.Framework, ns *v1.Namespace, // CreateFromManifests is a combination of LoadFromManifests, // PatchItems, patching with an optional custom function, -// and CreateItems. +// and creating the resulting items. +// +// Objects get deleted automatically during test cleanup. func CreateFromManifests(ctx context.Context, f *framework.Framework, driverNamespace *v1.Namespace, patch func(item interface{}) error, files ...string) error { + tCtx := f.TContext(ctx) + if driverNamespace != nil { + tCtx = tCtx.WithNamespace(driverNamespace.Name) + } + return CreateFromManifestsTCtx(tCtx, patch, files...) +} + +// CreateFromManifestsTCtx is a variant of CreateFromManifests where all parameters, including +// the driver namespace, are passed through a TContext. It is therefore usable from Go unit tests. +func CreateFromManifestsTCtx(tCtx ktesting.TContext, patch func(item interface{}) error, files ...string) error { items, err := LoadFromManifests(files...) if err != nil { return fmt.Errorf("CreateFromManifests: %w", err) } - if err := PatchItems(f, driverNamespace, items...); err != nil { + if err := PatchItemsTCtx(tCtx, items...); err != nil { return err } if patch != nil { @@ -194,7 +212,7 @@ func CreateFromManifests(ctx context.Context, f *framework.Framework, driverName } } } - return CreateItems(ctx, f, driverNamespace, items...) + return createItems(tCtx, items...) } // What is a subset of metav1.TypeMeta which (in contrast to @@ -234,7 +252,7 @@ type ItemFactory interface { // error or a cleanup function for the created item. // If the item is of an unsupported type, it must return // an error that has errorItemNotSupported as cause. - Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, item interface{}) (func(ctx context.Context) error, error) + Create(tCtx ktesting.TContext, item interface{}) (func(ctx context.Context) error, error) } // describeItem always returns a string that describes the item, @@ -271,82 +289,79 @@ var factories = map[What]ItemFactory{ {"CustomResourceDefinition"}: &customResourceDefinitionFactory{}, } -// PatchName makes the name of some item unique by appending the +// patchName makes the name of some item unique by appending the // generated unique name. -func PatchName(f *framework.Framework, item *string) { +func patchName(uniqueName string, item *string) { if *item != "" { - *item = *item + "-" + f.UniqueName + *item = *item + "-" + uniqueName } } -// PatchNamespace moves the item into the test's namespace. Not +// patchNamespace moves the item into the test's namespace. Not // all items can be namespaced. For those, the name also needs to be // patched. -func PatchNamespace(f *framework.Framework, driverNamespace *v1.Namespace, item *string) { - if driverNamespace != nil { - *item = driverNamespace.GetName() - return - } - - if f.Namespace != nil { - *item = f.Namespace.GetName() +func patchNamespace(tCtx ktesting.TContext, item *string) { + namespace := tCtx.Namespace() + if namespace != "" { + *item = namespace } } -func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace, item interface{}) error { +func patchItemRecursively(tCtx ktesting.TContext, item interface{}) error { + uniqueName := tCtx.Namespace() switch item := item.(type) { case *rbacv1.Subject: - PatchNamespace(f, driverNamespace, &item.Namespace) + patchNamespace(tCtx, &item.Namespace) case *rbacv1.RoleRef: // TODO: avoid hard-coding this special name. Perhaps add a Framework.PredefinedRoles // which contains all role names that are defined cluster-wide before the test starts? // All those names are exempt from renaming. That list could be populated by querying // and get extended by tests. if item.Name != "e2e-test-privileged-psp" { - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) } case *rbacv1.ClusterRole: - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) case *rbacv1.Role: - PatchNamespace(f, driverNamespace, &item.Namespace) + patchNamespace(tCtx, &item.Namespace) // Roles are namespaced, but because for RoleRef above we don't // know whether the referenced role is a ClusterRole or Role // and therefore always renames, we have to do the same here. - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) case *storagev1.StorageClass: - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) case *storagev1.VolumeAttributesClass: - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) case *storagev1.CSIDriver: - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) case *v1.ServiceAccount: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) case *v1.Secret: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) case *rbacv1.ClusterRoleBinding: - PatchName(f, &item.Name) + patchName(uniqueName, &item.Name) for i := range item.Subjects { - if err := patchItemRecursively(f, driverNamespace, &item.Subjects[i]); err != nil { - return fmt.Errorf("%T: %w", f, err) + if err := patchItemRecursively(tCtx, &item.Subjects[i]); err != nil { + return fmt.Errorf("%T: %w", &item.Subjects[i], err) } } - if err := patchItemRecursively(f, driverNamespace, &item.RoleRef); err != nil { - return fmt.Errorf("%T: %w", f, err) + if err := patchItemRecursively(tCtx, &item.RoleRef); err != nil { + return fmt.Errorf("%T: %w", &item.RoleRef, err) } case *rbacv1.RoleBinding: - PatchNamespace(f, driverNamespace, &item.Namespace) + patchNamespace(tCtx, &item.Namespace) for i := range item.Subjects { - if err := patchItemRecursively(f, driverNamespace, &item.Subjects[i]); err != nil { - return fmt.Errorf("%T: %w", f, err) + if err := patchItemRecursively(tCtx, &item.Subjects[i]); err != nil { + return fmt.Errorf("%T: %w", &item.Subjects[i], err) } } - if err := patchItemRecursively(f, driverNamespace, &item.RoleRef); err != nil { - return fmt.Errorf("%T: %w", f, err) + if err := patchItemRecursively(tCtx, &item.RoleRef); err != nil { + return fmt.Errorf("%T: %w", &item.RoleRef, err) } case *v1.Service: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) case *appsv1.StatefulSet: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) if err := patchContainerImages(item.Spec.Template.Spec.Containers); err != nil { return err } @@ -354,7 +369,7 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace, return err } case *appsv1.Deployment: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) if err := patchContainerImages(item.Spec.Template.Spec.Containers); err != nil { return err } @@ -362,7 +377,7 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace, return err } case *appsv1.DaemonSet: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) if err := patchContainerImages(item.Spec.Template.Spec.Containers); err != nil { return err } @@ -370,7 +385,7 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace, return err } case *appsv1.ReplicaSet: - PatchNamespace(f, driverNamespace, &item.ObjectMeta.Namespace) + patchNamespace(tCtx, &item.ObjectMeta.Namespace) if err := patchContainerImages(item.Spec.Template.Spec.Containers); err != nil { return err } @@ -396,13 +411,13 @@ func (f *serviceAccountFactory) New() runtime.Object { return &v1.ServiceAccount{} } -func (*serviceAccountFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*serviceAccountFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.ServiceAccount) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.CoreV1().ServiceAccounts(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().CoreV1().ServiceAccounts(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ServiceAccount: %w", err) } return func(ctx context.Context) error { @@ -416,15 +431,15 @@ func (f *clusterRoleFactory) New() runtime.Object { return &rbacv1.ClusterRole{} } -func (*clusterRoleFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*clusterRoleFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.ClusterRole) if !ok { return nil, errorItemNotSupported } - framework.Logf("Define cluster role %v", item.GetName()) - client := f.ClientSet.RbacV1().ClusterRoles() - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + tCtx.Logf("define cluster role %v", item.GetName()) + client := tCtx.Client().RbacV1().ClusterRoles() + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ClusterRole: %w", err) } return func(ctx context.Context) error { @@ -438,14 +453,14 @@ func (f *clusterRoleBindingFactory) New() runtime.Object { return &rbacv1.ClusterRoleBinding{} } -func (*clusterRoleBindingFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*clusterRoleBindingFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.ClusterRoleBinding) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.RbacV1().ClusterRoleBindings() - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().RbacV1().ClusterRoleBindings() + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ClusterRoleBinding: %w", err) } return func(ctx context.Context) error { @@ -459,14 +474,14 @@ func (f *roleFactory) New() runtime.Object { return &rbacv1.Role{} } -func (*roleFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*roleFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.Role) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.RbacV1().Roles(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().RbacV1().Roles(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Role: %w", err) } return func(ctx context.Context) error { @@ -480,14 +495,14 @@ func (f *roleBindingFactory) New() runtime.Object { return &rbacv1.RoleBinding{} } -func (*roleBindingFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*roleBindingFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.RoleBinding) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.RbacV1().RoleBindings(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().RbacV1().RoleBindings(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create RoleBinding: %w", err) } return func(ctx context.Context) error { @@ -501,14 +516,14 @@ func (f *serviceFactory) New() runtime.Object { return &v1.Service{} } -func (*serviceFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*serviceFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.Service) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.CoreV1().Services(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().CoreV1().Services(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Service: %w", err) } return func(ctx context.Context) error { @@ -522,14 +537,14 @@ func (f *statefulSetFactory) New() runtime.Object { return &appsv1.StatefulSet{} } -func (*statefulSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*statefulSetFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.StatefulSet) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.AppsV1().StatefulSets(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().AppsV1().StatefulSets(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create StatefulSet: %w", err) } return func(ctx context.Context) error { @@ -543,14 +558,14 @@ func (f *deploymentFactory) New() runtime.Object { return &appsv1.Deployment{} } -func (*deploymentFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*deploymentFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.Deployment) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.AppsV1().Deployments(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().AppsV1().Deployments(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Deployment: %w", err) } return func(ctx context.Context) error { @@ -564,14 +579,14 @@ func (f *daemonSetFactory) New() runtime.Object { return &appsv1.DaemonSet{} } -func (*daemonSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*daemonSetFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.DaemonSet) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.AppsV1().DaemonSets(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().AppsV1().DaemonSets(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create DaemonSet: %w", err) } return func(ctx context.Context) error { @@ -585,14 +600,14 @@ func (f *replicaSetFactory) New() runtime.Object { return &appsv1.ReplicaSet{} } -func (*replicaSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*replicaSetFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.ReplicaSet) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.AppsV1().ReplicaSets(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().AppsV1().ReplicaSets(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ReplicaSet: %w", err) } return func(ctx context.Context) error { @@ -606,14 +621,14 @@ func (f *storageClassFactory) New() runtime.Object { return &storagev1.StorageClass{} } -func (*storageClassFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*storageClassFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*storagev1.StorageClass) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.StorageV1().StorageClasses() - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().StorageV1().StorageClasses() + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create StorageClass: %w", err) } return func(ctx context.Context) error { @@ -627,14 +642,14 @@ func (f *volumeAttributesClassFactory) New() runtime.Object { return &storagev1.VolumeAttributesClass{} } -func (*volumeAttributesClassFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*volumeAttributesClassFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*storagev1.VolumeAttributesClass) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.StorageV1().VolumeAttributesClasses() - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().StorageV1().VolumeAttributesClasses() + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create VolumeAttributesClass: %w", err) } return func(ctx context.Context) error { @@ -648,14 +663,14 @@ func (f *csiDriverFactory) New() runtime.Object { return &storagev1.CSIDriver{} } -func (*csiDriverFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*csiDriverFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*storagev1.CSIDriver) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.StorageV1().CSIDrivers() - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().StorageV1().CSIDrivers() + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create CSIDriver: %w", err) } return func(ctx context.Context) error { @@ -669,14 +684,14 @@ func (f *secretFactory) New() runtime.Object { return &v1.Secret{} } -func (*secretFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*secretFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.Secret) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.CoreV1().Secrets(ns.Name) - if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { + client := tCtx.Client().CoreV1().Secrets(tCtx.Namespace()) + if _, err := client.Create(tCtx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Secret: %w", err) } return func(ctx context.Context) error { @@ -690,7 +705,7 @@ func (f *customResourceDefinitionFactory) New() runtime.Object { return &apiextensionsv1.CustomResourceDefinition{} } -func (*customResourceDefinitionFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { +func (*customResourceDefinitionFactory) Create(tCtx ktesting.TContext, i interface{}) (func(ctx context.Context) error, error) { var err error unstructCRD := &unstructured.Unstructured{} gvr := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"} @@ -705,11 +720,11 @@ func (*customResourceDefinitionFactory) Create(ctx context.Context, f *framework return nil, err } - if _, err = f.DynamicClient.Resource(gvr).Create(ctx, unstructCRD, metav1.CreateOptions{}); err != nil { + if _, err = tCtx.Dynamic().Resource(gvr).Create(tCtx, unstructCRD, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create CustomResourceDefinition: %w", err) } return func(ctx context.Context) error { - return f.DynamicClient.Resource(gvr).Delete(ctx, item.GetName(), metav1.DeleteOptions{}) + return tCtx.Dynamic().Resource(gvr).Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot-metadata.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot-metadata.go new file mode 100644 index 0000000000..a272044e7e --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot-metadata.go @@ -0,0 +1,274 @@ +/* +Copyright 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 utils + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "time" + + "github.com/onsi/ginkgo/v2" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kubernetes/test/e2e/framework" +) + +// Constants for common values +const ( + CommonName = "csi-snapshot-metadata" + TLSSecretName = "csi-snapshot-metadata-server-certs" + ServicePort = 6443 + TargetPort = 50051 + CertificateValidityDays = 365 + ServerCertificateValidity = 60 + CertificateKeySize = 4096 + AppSelectorKey = "app.kubernetes.io/name" + AppSelectorValue = "csi-hostpathplugin" + SnapshotMetadataCRAudience = "csi-snapshot-metadata-test" + + // SnapshotMetadataService API constants + SnapshotMetadataServiceGroup = "cbt.storage.k8s.io" + SnapshotMetadataServiceVersion = "v1beta1" + SnapshotMetadataServiceAPIVersion = SnapshotMetadataServiceGroup + "/" + SnapshotMetadataServiceVersion + SnapshotMetadataServiceKind = "SnapshotMetadataService" + SnapshotMetadataServiceResource = "snapshotmetadataservices" +) + +// generateCA creates a self-signed CA certificate and private key using RSA. +func generateCA() (*x509.Certificate, *rsa.PrivateKey, error) { + ginkgo.By("Generating CA certificate and private key") + + caPrivateKey, err := rsa.GenerateKey(rand.Reader, CertificateKeySize) + if err != nil { + return nil, nil, fmt.Errorf("failed to generate CA private key: %w", err) + } + + caTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: CommonName, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(CertificateValidityDays * 24 * time.Hour), + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature, + BasicConstraintsValid: true, + IsCA: true, + } + + caCertBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &caPrivateKey.PublicKey, caPrivateKey) + if err != nil { + return nil, nil, fmt.Errorf("failed to create CA certificate: %w", err) + } + + caCert, err := x509.ParseCertificate(caCertBytes) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse CA certificate: %w", err) + } + return caCert, caPrivateKey, nil +} + +// generateServerCert creates a server certificate signed by the given CA using RSA. +func generateServerCert(driverNamespace string, caCert *x509.Certificate, caPrivateKey *rsa.PrivateKey) ([]byte, []byte, error) { + ginkgo.By("Generating server certificate and private key") + + serverPrivateKey, err := rsa.GenerateKey(rand.Reader, CertificateKeySize) + if err != nil { + return nil, nil, fmt.Errorf("failed to generate server private key: %w", err) + } + + serverTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(2), + Subject: pkix.Name{ + CommonName: CommonName, + }, + DNSNames: []string{ + fmt.Sprintf(".%s", driverNamespace), + fmt.Sprintf("%s.%s", CommonName, driverNamespace), + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(ServerCertificateValidity * 24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + } + + serverCertBytes, err := x509.CreateCertificate(rand.Reader, serverTemplate, caCert, &serverPrivateKey.PublicKey, caPrivateKey) + if err != nil { + return nil, nil, fmt.Errorf("failed to create server certificate: %w", err) + } + + serverKeyBytes := x509.MarshalPKCS1PrivateKey(serverPrivateKey) + + return serverCertBytes, serverKeyBytes, nil +} + +// createTLSSecret creates or updates a TLS secret in the specified namespace. +func createTLSSecret(ctx context.Context, f *framework.Framework, driverNamespace string, certBytes, keyBytes []byte) error { + ginkgo.By("Creating TLS secret") + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes}) + keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: keyBytes}) + + tlsSecret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: TLSSecretName, + Namespace: driverNamespace, + }, + Type: v1.SecretTypeTLS, + Data: map[string][]byte{ + "tls.crt": certPEM, + "tls.key": keyPEM, + }, + } + + client := f.ClientSet.CoreV1().Secrets(driverNamespace) + if _, err := client.Create(ctx, tlsSecret, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("failed to create or update TLS secret: %w", err) + } + + framework.Logf("TLS secret created successfully: %s", tlsSecret.Name) + return nil +} + +// createSnapshotMetadataSVC creates a Kubernetes service for the snapshot metadata. +func createSnapshotMetadataSVC(ctx context.Context, f *framework.Framework, driverName, driverNamespace string) error { + ginkgo.By("Creating Kubernetes service for snapshot metadata") + svc := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: CommonName, + Namespace: driverNamespace, + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "snapshot-metadata-port", + Port: ServicePort, + Protocol: "TCP", + TargetPort: intstr.FromInt(TargetPort), + }, + }, + Selector: map[string]string{ + AppSelectorKey: AppSelectorValue, + }, + }, + } + + client := f.ClientSet.CoreV1().Services(driverNamespace) + if _, err := client.Create(ctx, svc, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("failed to create service: %w", err) + } + framework.Logf("Service created successfully: %s", svc.Name) + + return nil +} + +// createSnapshotMetdataServiceCR creates a SnapshotMetadataService custom resource. +func createSnapshotMetdataServiceCR(ctx context.Context, f *framework.Framework, driverName, driverNamespace string, caCert *x509.Certificate) error { + ginkgo.By("Creating snapshot metadata service CR") + + sms := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": SnapshotMetadataServiceKind, + "apiVersion": SnapshotMetadataServiceAPIVersion, + "metadata": map[string]interface{}{ + "name": fmt.Sprintf("%s-%s", driverName, f.UniqueName), + }, + "spec": map[string]interface{}{ + "caCert": pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCert.Raw}), + "audience": SnapshotMetadataCRAudience, + "address": fmt.Sprintf("%s.%s:%d", CommonName, driverNamespace, ServicePort), + }, + }, + } + + gvr := schema.GroupVersionResource{ + Group: SnapshotMetadataServiceGroup, + Version: SnapshotMetadataServiceVersion, + Resource: SnapshotMetadataServiceResource, + } + + if _, err := f.DynamicClient.Resource(gvr).Create(ctx, sms, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("failed to create SnapshotMetadataService: %w", err) + } + + return nil +} + +// CreateSnapshotMetadataResources sets up the snapshot metadata resources. +// CRD creation is handled separately by the test runner script. +func CreateSnapshotMetadataResources(ctx context.Context, f *framework.Framework, driverName, driverNamespace string) error { + caCert, caPrivateKey, err := generateCA() + if err != nil { + return fmt.Errorf("failed to generate CA certificate: %w", err) + } + + serverCertBytes, serverKeyBytes, err := generateServerCert(driverNamespace, caCert, caPrivateKey) + if err != nil { + return fmt.Errorf("failed to generate server certificate: %w", err) + } + + if err := createTLSSecret(ctx, f, driverNamespace, serverCertBytes, serverKeyBytes); err != nil { + return fmt.Errorf("failed to create TLS secret: %w", err) + } + + if err := createSnapshotMetadataSVC(ctx, f, driverName, driverNamespace); err != nil { + return fmt.Errorf("failed to create snapshot metadata svc: %w", err) + } + + if err := createSnapshotMetdataServiceCR(ctx, f, driverName, driverNamespace, caCert); err != nil { + return fmt.Errorf("failed to create SnapshotMetadataService CR: %w", err) + } + + return nil +} + +// CleanupSnapshotMetadataResources cleans up the snapshot metadata resources. +func CleanupSnapshotMetadataResources(ctx context.Context, f *framework.Framework, driverName, driverNamespace string) error { + ginkgo.By("Cleaning up snapshot metadata resources") + + // Delete SnapshotMetadataService CR + gvr := schema.GroupVersionResource{ + Group: SnapshotMetadataServiceGroup, + Version: SnapshotMetadataServiceVersion, + Resource: SnapshotMetadataServiceResource, + } + + crName := fmt.Sprintf("%s-%s", driverName, f.UniqueName) + if err := f.DynamicClient.Resource(gvr).Delete(ctx, crName, metav1.DeleteOptions{}); err != nil { + framework.Logf("Warning: failed to delete SnapshotMetadataService CR %s: %v", crName, err) + } + + // Delete Service + if err := f.ClientSet.CoreV1().Services(driverNamespace).Delete(ctx, CommonName, metav1.DeleteOptions{}); err != nil { + framework.Logf("Warning: failed to delete service %s: %v", CommonName, err) + } + + // Delete TLS Secret + if err := f.ClientSet.CoreV1().Secrets(driverNamespace).Delete(ctx, TLSSecretName, metav1.DeleteOptions{}); err != nil { + framework.Logf("Warning: failed to delete TLS secret %s: %v", TLSSecretName, err) + } + + return nil +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go index 9a40ff43f2..2106c8366a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go @@ -37,6 +37,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" @@ -687,6 +688,66 @@ func WaitForNamespacedGVRDeletion(ctx context.Context, c dynamic.Interface, gvr return fmt.Errorf("%s %s in namespace %s is not deleted within %v", gvr.Resource, objectName, ns, timeout) } +// WaitForOwnedResourcesDeleted waits until all objects of the given GVR +// in the namespace (or cluster-scoped if ns=="") with the specified ownerUID are deleted. +func WaitForOwnedResourcesDeleted(ctx context.Context, + c dynamic.Interface, + gvr schema.GroupVersionResource, + ns string, // empty for cluster-scoped resources + ownerUID types.UID, + poll, timeout time.Duration) error { + scope := "cluster-scoped" + if ns != "" { + scope = fmt.Sprintf("namespace %s", ns) + } + framework.Logf("Waiting up to %v for all %s %s owned by %s to be deleted", timeout, gvr.Resource, scope, ownerUID) + + successful := WaitUntil(poll, timeout, func() bool { + var list *unstructured.UnstructuredList + var err error + if ns == "" { + list, err = c.Resource(gvr).List(ctx, metav1.ListOptions{}) + } else { + list, err = c.Resource(gvr).Namespace(ns).List(ctx, metav1.ListOptions{}) + } + if err != nil { + framework.Logf("List %s %s returned error: %v", gvr.Resource, scope, err) + return false + } + + for _, item := range list.Items { + for _, owner := range item.GetOwnerReferences() { + if owner.UID == ownerUID { + framework.Logf("%s %s is still present, waiting...", gvr.Resource, item.GetName()) + return false + } + } + } + + framework.Logf("All %s %s owned by %s have been deleted", gvr.Resource, scope, ownerUID) + return true + }) + + if successful { + return nil + } + return fmt.Errorf("some %s %s owned by %s were not deleted within %v", gvr.Resource, scope, ownerUID, timeout) +} + +// FilterResourcesByOwner filters unstructured resources to only those owned by the specified owner kind and UID +func FilterResourcesByOwner(resources []unstructured.Unstructured, ownerKind string, ownerUID types.UID) []unstructured.Unstructured { + var filtered []unstructured.Unstructured + for _, resource := range resources { + for _, owner := range resource.GetOwnerReferences() { + if owner.Kind == ownerKind && owner.UID == ownerUID { + filtered = append(filtered, resource) + break + } + } + } + return filtered +} + // WaitUntil runs checkDone until a timeout is reached func WaitUntil(poll, timeout time.Duration, checkDone func() bool) bool { // TODO (pohly): replace with gomega.Eventually diff --git a/vendor/k8s.io/kubernetes/test/e2e/suites.go b/vendor/k8s.io/kubernetes/test/e2e/suites.go index 1493142b1c..ba3e26fd09 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/suites.go +++ b/vendor/k8s.io/kubernetes/test/e2e/suites.go @@ -41,9 +41,6 @@ func AfterSuiteActions(ctx context.Context) { framework.Logf("Error gathering metrics: %v", err) } } - if framework.TestContext.NodeKiller.NodeKillerStop != nil { - framework.TestContext.NodeKiller.NodeKillerStop() - } } func gatherTestSuiteMetrics(ctx context.Context) error { diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/OWNERS b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/OWNERS index 03cc9aff5b..8a274491d4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/OWNERS +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/OWNERS @@ -1,6 +1,7 @@ # See the OWNERS docs at https://go.k8s.io/owners approvers: + - sig-node-approvers - klueska - pohly reviewers: diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/dra-test-driver-proxy.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/dra-test-driver-proxy.yaml index 6c7da12638..f01aca4a9f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/dra-test-driver-proxy.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/dra/dra-test-driver-proxy.yaml @@ -47,7 +47,7 @@ spec: containers: - name: pause - image: registry.k8s.io/sig-storage/hostpathplugin:v1.16.1 + image: registry.k8s.io/sig-storage/hostpathplugin:to-be-replaced # Version and actual registry get patched in during deployment. command: - /bin/sh - -c diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml index cd2916ea67..2adb015a99 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml @@ -8,7 +8,7 @@ metadata: spec: containers: - name: primary - image: registry.k8s.io/e2e-test-images/agnhost:2.54 + image: registry.k8s.io/e2e-test-images/agnhost:2.63.0 env: - name: PRIMARY value: "true" @@ -21,7 +21,7 @@ spec: - mountPath: /agnhost-primary-data name: data - name: sentinel - image: registry.k8s.io/e2e-test-images/agnhost:2.54 + image: registry.k8s.io/e2e-test-images/agnhost:2.63.0 env: - name: SENTINEL value: "true" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml index ccaa4bab6e..7aa24c7062 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml @@ -18,7 +18,7 @@ spec: spec: containers: - name: etcd - image: registry.k8s.io/etcd:3.2.24 + image: registry.k8s.io/etcd:3.6.8-0 imagePullPolicy: Always ports: - containerPort: 2380 diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/backup-client-rbac.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/backup-client-rbac.yaml new file mode 100644 index 0000000000..cab762efa6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/backup-client-rbac.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: backup-app-service-account +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: external-snapshot-metadata-client-runner +rules: +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + - volumesnapshotcontents + verbs: + - get + - list + - watch +# Access to discover SnapshotMetadataService resources +- apiGroups: + - cbt.storage.k8s.io + resources: + - snapshotmetadataservices + verbs: + - get + - list +## Access to create sa tokens with tokenrequests API if client needs to generate SA token +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: backup-app-cluster-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-snapshot-metadata-client-runner +subjects: +- kind: ServiceAccount + name: backup-app-service-account diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/cbt.storage.k8s.io_snapshotmetadataservices.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/cbt.storage.k8s.io_snapshotmetadataservices.yaml new file mode 100644 index 0000000000..de75d40132 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/cbt.storage.k8s.io_snapshotmetadataservices.yaml @@ -0,0 +1,76 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshot-metadata/pull/2" + name: snapshotmetadataservices.cbt.storage.k8s.io +spec: + group: cbt.storage.k8s.io + names: + kind: SnapshotMetadataService + listKind: SnapshotMetadataServiceList + plural: snapshotmetadataservices + shortNames: + - sms + singular: snapshotmetadataservice + scope: Cluster + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: |- + SnapshotMetadataService is the Schema for the snapshotmetadataservices API + The presence of a SnapshotMetadataService CR advertises the existence of a CSI + driver's Kubernetes SnapshotMetadata gRPC service. + An audience scoped Kubernetes authentication bearer token must be passed in the + "security_token" field of each gRPC call made by a Kubernetes backup client. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Required. + properties: + address: + description: |- + The TCP endpoint address of the gRPC service. + Required. + type: string + audience: + description: |- + The audience string value expected in a client's authentication token passed + in the "security_token" field of each gRPC call. + Required. + type: string + caCert: + description: |- + Certificate authority bundle needed by the client to validate the service. + Required. + format: byte + type: string + required: + - address + - audience + - caCert + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/rbac.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/rbac.yaml new file mode 100644 index 0000000000..9fba26d23b --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/rbac.yaml @@ -0,0 +1,42 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: hostpath.csi.k8s.io + app.kubernetes.io/part-of: csi-driver-host-path + name: external-snapshot-metadata-runner +rules: +- apiGroups: + - cbt.storage.k8s.io + resources: + - snapshotmetadataservices + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - get +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - get +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + - volumesnapshotcontents + verbs: + - get + - list diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/run_snapshot_metadata_e2e.sh b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/run_snapshot_metadata_e2e.sh new file mode 100644 index 0000000000..e7abb0a889 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/run_snapshot_metadata_e2e.sh @@ -0,0 +1,325 @@ +#!/bin/sh +# Copyright 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. + +# hack script for running a kind e2e +# must be run with a kubernetes checkout in $PWD (IE from the checkout) +# Usage: SKIP="ginkgo skip regex" FOCUS="ginkgo focus regex" kind-e2e.sh + +set -o errexit -o nounset -o xtrace + +# Settings: +# SKIP: ginkgo skip regex +# FOCUS: ginkgo focus regex (defaults to [Conformance] if unset; set to "" to run all tests) +# LABEL_FILTER: ginkgo label query for selecting tests (see "Spec Labels" in https://onsi.github.io/ginkgo/#filtering-specs) +# +# The default is to focus on conformance tests when FOCUS is unset. To run all +# tests (no focus filter), explicitly set FOCUS="". Serial tests get skipped when +# parallel testing is enabled. Using LABEL_FILTER instead of combining SKIP and +# FOCUS is recommended (more expressive, easier to read than regexp). +# +# FEATURE_GATES: +# JSON or YAML encoding of a string/bool map: {"FeatureGateA": true, "FeatureGateB": false} +# Enables or disables feature gates in the entire cluster. +# RUNTIME_CONFIG: +# JSON or YAML encoding of a string/string (!) map: {"apia.example.com/v1alpha1": "true", "apib.example.com/v1beta1": "false"} +# Enables API groups in the apiserver via --runtime-config. + +# cleanup logic for cleanup on exit +CLEANED_UP=false +cleanup() { + if [ "$CLEANED_UP" = "true" ]; then + return + fi + # KIND_CREATE_ATTEMPTED is true once we: kind create + if [ "${KIND_CREATE_ATTEMPTED:-}" = true ]; then + kind "export" logs "${ARTIFACTS}" || true + kind delete cluster || true + fi + rm -f _output/bin/e2e.test || true + # remove our tempdir, this needs to be last, or it will prevent kind delete + if [ -n "${TMP_DIR:-}" ]; then + rm -rf "${TMP_DIR:?}" + fi + CLEANED_UP=true +} + +# setup signal handlers +# shellcheck disable=SC2317 # this is not unreachable code +signal_handler() { + if [ -n "${GINKGO_PID:-}" ]; then + kill -TERM "$GINKGO_PID" || true + fi + cleanup +} +trap signal_handler INT TERM + +# build kubernetes / node image, e2e binaries +build() { + # build the node image w/ kubernetes + kind build node-image -v 1 + # Ginkgo v1 is used by Kubernetes 1.24 and earlier, fallback if v2 is not available. + GINKGO_SRC_DIR="vendor/github.com/onsi/ginkgo/v2/ginkgo" + if [ ! -d "$GINKGO_SRC_DIR" ]; then + GINKGO_SRC_DIR="vendor/github.com/onsi/ginkgo/ginkgo" + fi + # make sure we have e2e requirements + make all WHAT="cmd/kubectl test/e2e/e2e.test ${GINKGO_SRC_DIR}" + + # Ensure the built kubectl is used instead of system + export PATH="${PWD}/_output/bin:$PATH" +} + +# up a cluster with kind +create_cluster() { + # Default Log level for all components in test clusters + KIND_CLUSTER_LOG_LEVEL=${KIND_CLUSTER_LOG_LEVEL:-4} + + # JSON or YAML map injected into featureGates config + feature_gates="${FEATURE_GATES:-{\}}" + # --runtime-config argument value passed to the API server, again as a map + runtime_config="${RUNTIME_CONFIG:-{\}}" + + # create the config file + cat < "${ARTIFACTS}/kind-config.yaml" +# config for 1 control plane node and 2 workers (necessary for conformance) +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: + ipFamily: ${IP_FAMILY:-ipv4} + kubeProxyMode: ${KUBE_PROXY_MODE:-iptables} + # don't pass through host search paths + # TODO: possibly a reasonable default in the future for kind ... + dnsSearch: [] +nodes: +- role: control-plane +- role: worker +- role: worker +featureGates: ${feature_gates} +runtimeConfig: ${runtime_config} +kubeadmConfigPatches: +# v1beta4 for the future (v1.35.0+ ?) +# https://github.com/kubernetes-sigs/kind/issues/3847 +# TODO: drop v1beta3 when we no longer need versions that use it +- | + kind: ClusterConfiguration + apiVersion: kubeadm.k8s.io/v1beta4 + apiServer: + extraArgs: + - name: "v" + value: "${KIND_CLUSTER_LOG_LEVEL}" + controllerManager: + extraArgs: + - name: "v" + value: "${KIND_CLUSTER_LOG_LEVEL}" + scheduler: + extraArgs: + - name: "v" + value: "${KIND_CLUSTER_LOG_LEVEL}" + --- + kind: InitConfiguration + apiVersion: kubeadm.k8s.io/v1beta4 + nodeRegistration: + kubeletExtraArgs: + - name: "v" + value: "${KIND_CLUSTER_LOG_LEVEL}" + - name: "container-log-max-files" + value: "10" + - name: "container-log-max-size" + value: "100Mi" + --- + kind: JoinConfiguration + apiVersion: kubeadm.k8s.io/v1beta4 + nodeRegistration: + kubeletExtraArgs: + - name: "v" + value: "${KIND_CLUSTER_LOG_LEVEL}" + # Warning: these flags appear to be load bearing / impact performance + # See: https://github.com/kubernetes-sigs/kind/pull/4046 + # Be careful when updating these. + # Most CI jobs should not need them, but some CI jobs might. + - name: "container-log-max-files" + value: "10" + - name: "container-log-max-size" + value: "100Mi" +# v1beta3 for v1.23.0 ... ? +- | + kind: ClusterConfiguration + apiVersion: kubeadm.k8s.io/v1beta3 + apiServer: + extraArgs: + "v": "${KIND_CLUSTER_LOG_LEVEL}" + controllerManager: + extraArgs: + "v": "${KIND_CLUSTER_LOG_LEVEL}" + scheduler: + extraArgs: + "v": "${KIND_CLUSTER_LOG_LEVEL}" + --- + kind: InitConfiguration + apiVersion: kubeadm.k8s.io/v1beta3 + nodeRegistration: + kubeletExtraArgs: + "v": "${KIND_CLUSTER_LOG_LEVEL}" + "container-log-max-files": "10" + "container-log-max-size": "100Mi" + --- + kind: JoinConfiguration + apiVersion: kubeadm.k8s.io/v1beta3 + nodeRegistration: + kubeletExtraArgs: + "v": "${KIND_CLUSTER_LOG_LEVEL}" + # Warning: these flags appear to be load bearing / impact performance + # See: https://github.com/kubernetes-sigs/kind/pull/4046 + # Be careful when updating these. + # Most CI jobs should not need them, but some CI jobs might. + "container-log-max-files": "10" + "container-log-max-size": "100Mi" +EOF + # NOTE: must match the number of workers above + NUM_NODES=2 + # actually create the cluster + # TODO(BenTheElder): settle on verbosity for this script + KIND_CREATE_ATTEMPTED=true + kind create cluster \ + --image=kindest/node:latest \ + --retain \ + --wait=1m \ + -v=3 \ + "--config=${ARTIFACTS}/kind-config.yaml" + + # debug cluster version + kubectl version + + # Patch kube-proxy to set the verbosity level + kubectl patch -n kube-system daemonset/kube-proxy \ + --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/command/-", "value": "--v='"${KIND_CLUSTER_LOG_LEVEL}"'" }]' +} + +# run e2es with ginkgo-e2e.sh +run_tests() { + # IPv6 clusters need some CoreDNS changes in order to work in k8s CI: + # 1. k8s CI doesn´t offer IPv6 connectivity, so CoreDNS should be configured + # to work in an offline environment: + # https://github.com/coredns/coredns/issues/2494#issuecomment-457215452 + # 2. k8s CI adds following domains to resolv.conf search field: + # c.k8s-prow-builds.internal google.internal. + # CoreDNS should handle those domains and answer with NXDOMAIN instead of SERVFAIL + # otherwise pods stops trying to resolve the domain. + if [ "${IP_FAMILY:-ipv4}" = "ipv6" ]; then + # Get the current config + original_coredns=$(kubectl get -oyaml -n=kube-system configmap/coredns) + echo "Original CoreDNS config:" + echo "${original_coredns}" + # Patch it + fixed_coredns=$( + printf '%s' "${original_coredns}" | sed \ + -e 's/^.*kubernetes cluster\.local/& internal/' \ + -e '/^.*upstream$/d' \ + -e '/^.*fallthrough.*$/d' \ + -e '/^.*forward . \/etc\/resolv.conf$/d' \ + -e '/^.*loop$/d' \ + ) + echo "Patched CoreDNS config:" + echo "${fixed_coredns}" + printf '%s' "${fixed_coredns}" | kubectl apply -f - + fi + + # ginkgo regexes and label filter + SKIP="${SKIP:-}" + LABEL_FILTER="${LABEL_FILTER:-}" + # Only default to Conformance if FOCUS was not explicitly set. + # This allows FOCUS="" to run all tests (no focus filter). + if [ "${FOCUS+set}" != "set" ]; then + if [ -z "${LABEL_FILTER}" ]; then + FOCUS="\\[Conformance\\]" + else + FOCUS="" + fi + fi + # if we set PARALLEL=true, skip serial tests set --ginkgo-parallel + if [ "${PARALLEL:-false}" = "true" ]; then + export GINKGO_PARALLEL=y + if [ -z "${SKIP}" ]; then + SKIP="\\[Serial\\]" + else + SKIP="\\[Serial\\]|${SKIP}" + fi + fi + + # setting this env prevents ginkgo e2e from trying to run provider setup + export KUBERNETES_CONFORMANCE_TEST='y' + # setting these is required to make RuntimeClass tests work ... :/ + export KUBE_CONTAINER_RUNTIME=remote + export KUBE_CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock + export KUBE_CONTAINER_RUNTIME_NAME=containerd + export SNAPSHOTTER_VERSION="${SNAPSHOTTER_VERSION:-v8.4.0}" + echo "SNAPSHOTTER_VERSION is $SNAPSHOTTER_VERSION" + + # Enable SnapshotMetadata tests in csi-driver-hostpath + export CSI_PROW_ENABLE_SNAPSHOT_METADATA=true + + # Install snapshot CRDs + kubectl apply -f ./cluster/addons/volumesnapshots/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml || exit 1 + kubectl apply -f ./cluster/addons/volumesnapshots/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml || exit 1 + kubectl apply -f ./cluster/addons/volumesnapshots/crd/snapshot.storage.k8s.io_volumesnapshots.yaml || exit 1 + + # Install SnapshotMetadataService CRD + kubectl apply -f test/e2e/testing-manifests/storage-csi/external-snapshot-metadata/cbt.storage.k8s.io_snapshotmetadataservices.yaml || exit 1 + + # Deploy snapshot controller + kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/"${SNAPSHOTTER_VERSION}"/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml || exit 1 + kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/"${SNAPSHOTTER_VERSION}"/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml || exit 1 + + ./hack/ginkgo-e2e.sh \ + '--provider=skeleton' "--num-nodes=${NUM_NODES}" \ + "--ginkgo.focus=${FOCUS}" "--ginkgo.skip=${SKIP}" "--ginkgo.label-filter=${LABEL_FILTER}" \ + "--report-dir=${ARTIFACTS}" '--disable-log-dump=true' & + GINKGO_PID=$! + wait "$GINKGO_PID" +} + +main() { + # create temp dir and setup cleanup + TMP_DIR=$(mktemp -d) + + # ensure artifacts (results) directory exists when not in CI + export ARTIFACTS="${ARTIFACTS:-${PWD}/_artifacts}" + mkdir -p "${ARTIFACTS}" + + # export the KUBECONFIG to a unique path for testing + KUBECONFIG="${HOME}/.kube/kind-test-config" + export KUBECONFIG + echo "exported KUBECONFIG=${KUBECONFIG}" + + # debug kind version + kind version + + # build kubernetes + build + # in CI attempt to release some memory after building + if [ -n "${KUBETEST_IN_DOCKER:-}" ]; then + sync || true + echo 1 > /proc/sys/vm/drop_caches || true + fi + + # create the cluster and run tests + res=0 + create_cluster || res=$? + run_tests || res=$? + cleanup || res=$? + exit $res +} + +main diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml index 9f79eb4da3..4a50349cd4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml @@ -219,7 +219,7 @@ spec: serviceAccountName: csi-hostpathplugin-sa containers: - name: hostpath - image: registry.k8s.io/sig-storage/hostpathplugin:v1.16.1 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.1 args: - "--drivername=hostpath.csi.k8s.io" - "--v=5" @@ -262,7 +262,7 @@ spec: name: dev-dir - name: csi-external-health-monitor-controller - image: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.12.1 + image: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.17.0 args: - "--v=5" - "--csi-address=$(ADDRESS)" @@ -276,7 +276,7 @@ spec: mountPath: /csi - name: node-driver-registrar - image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.15.0 + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -304,13 +304,13 @@ spec: volumeMounts: - mountPath: /csi name: socket-dir - image: registry.k8s.io/sig-storage/livenessprobe:v2.17.0 + image: registry.k8s.io/sig-storage/livenessprobe:v2.18.0 args: - --csi-address=/csi/csi.sock - --health-port=9898 - name: csi-attacher - image: registry.k8s.io/sig-storage/csi-attacher:v4.10.0 + image: registry.k8s.io/sig-storage/csi-attacher:v4.11.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -324,7 +324,7 @@ spec: name: socket-dir - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v5.3.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v6.1.1 args: - -v=5 - --csi-address=/csi/csi.sock @@ -340,7 +340,7 @@ spec: name: socket-dir - name: csi-resizer - image: registry.k8s.io/sig-storage/csi-resizer:v1.14.0 + image: registry.k8s.io/sig-storage/csi-resizer:v2.1.0 args: - -v=5 - -csi-address=/csi/csi.sock @@ -354,7 +354,7 @@ spec: name: socket-dir - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.4.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0 args: - -v=5 - --csi-address=/csi/csi.sock diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml index ed77430bf0..9f7809b08b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml @@ -21,7 +21,7 @@ spec: serviceAccountName: csi-gce-pd-controller-sa containers: - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.3.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0 args: - "--v=5" - "--csi-address=/csi/csi.sock" @@ -39,7 +39,7 @@ spec: - name: socket-dir mountPath: /csi - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v5.1.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v5.2.0 args: - "--v=5" - "--csi-address=/csi/csi.sock" @@ -73,7 +73,7 @@ spec: - name: socket-dir mountPath: /csi - name: csi-attacher - image: registry.k8s.io/sig-storage/csi-attacher:v4.8.0 + image: registry.k8s.io/sig-storage/csi-attacher:v4.8.1 args: - "--v=5" - "--csi-address=/csi/csi.sock" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml index 30a82723ab..99d9f9ce2a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/node_ds.yaml @@ -13,7 +13,7 @@ spec: spec: containers: - name: csi-driver-registrar - image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.13.0 + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 args: - "--v=5" - "--csi-address=/csi/csi.sock" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml index 080fe5cb01..2fe67ffb71 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml @@ -237,7 +237,7 @@ spec: serviceAccountName: csi-hostpathplugin-sa containers: - name: hostpath - image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.0 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.1 args: - "--drivername=hostpath.csi.k8s.io" - "--v=5" @@ -281,7 +281,7 @@ spec: name: dev-dir - name: csi-external-health-monitor-controller - image: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.16.0 + image: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.17.0 args: - "--v=5" - "--csi-address=$(ADDRESS)" @@ -295,7 +295,7 @@ spec: mountPath: /csi - name: node-driver-registrar - image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.15.0 + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -323,13 +323,13 @@ spec: volumeMounts: - mountPath: /csi name: socket-dir - image: registry.k8s.io/sig-storage/livenessprobe:v2.17.0 + image: registry.k8s.io/sig-storage/livenessprobe:v2.18.0 args: - --csi-address=/csi/csi.sock - --health-port=9898 - name: csi-attacher - image: registry.k8s.io/sig-storage/csi-attacher:v4.10.0 + image: registry.k8s.io/sig-storage/csi-attacher:v4.11.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -343,7 +343,7 @@ spec: name: socket-dir - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v6.0.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v6.1.1 args: - -v=5 - --csi-address=/csi/csi.sock @@ -359,7 +359,7 @@ spec: name: socket-dir - name: csi-resizer - image: registry.k8s.io/sig-storage/csi-resizer:v2.0.0 + image: registry.k8s.io/sig-storage/csi-resizer:v2.1.0 args: - -v=5 - -csi-address=/csi/csi.sock @@ -373,7 +373,7 @@ spec: name: socket-dir - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.4.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0 args: - -v=5 - --csi-address=/csi/csi.sock @@ -386,6 +386,23 @@ spec: - mountPath: /csi name: socket-dir + - name: csi-snapshot-metadata + image: registry.k8s.io/sig-storage/csi-snapshot-metadata:v0.2.0 + imagePullPolicy: IfNotPresent + args: + - --csi-address=/csi/csi.sock + - --tls-cert=/tmp/certificates/tls.crt + - --tls-key=/tmp/certificates/tls.key + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /tmp/certificates + name: csi-snapshot-metadata-server-certs + readOnly: true + # end csi containers volumes: @@ -415,4 +432,8 @@ spec: path: /dev type: Directory name: dev-dir + - name: csi-snapshot-metadata-server-certs + secret: + defaultMode: 420 + secretName: csi-snapshot-metadata-server-certs # end csi volumes diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-testing.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-testing.yaml index 19c9888eec..1a9d12c7ad 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-testing.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-testing.yaml @@ -66,7 +66,7 @@ spec: topologyKey: kubernetes.io/hostname containers: - name: socat - image: registry.k8s.io/sig-storage/hostpathplugin:v1.15.0 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.1 command: - socat args: diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-attacher.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-attacher.yaml index f2f7850f08..40a2a58587 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-attacher.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-attacher.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-attacher - image: registry.k8s.io/sig-storage/csi-attacher:v4.10.0 + image: registry.k8s.io/sig-storage/csi-attacher:v4.11.0 args: - --v=5 - --csi-address=$(ADDRESS) diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-resizer.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-resizer.yaml index 0133796e72..7415c5eade 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-resizer.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-resizer.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-resizer - image: registry.k8s.io/sig-storage/csi-resizer:v2.0.0 + image: registry.k8s.io/sig-storage/csi-resizer:v2.1.0 args: - "--v=5" - "--csi-address=$(ADDRESS)" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml index 15c4bb5230..130721db8d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.4.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0 args: - "--v=5" - "--csi-address=$(ADDRESS)" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml index fbac7b5fb3..5f85ae7422 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v6.0.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v6.1.1 args: - "--csi-address=$(ADDRESS)" # Topology support is needed for the pod rescheduling test @@ -34,7 +34,7 @@ spec: - mountPath: /csi name: socket-dir - name: driver-registrar - image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.15.0 + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -53,7 +53,7 @@ spec: - mountPath: /registration name: registration-dir - name: mock - image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.0 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.1 args: - "--drivername=mock.storage.k8s.io" - "--nodeid=$(KUBE_NODE_NAME)" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml index 0530c9a472..956adbf70a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v6.0.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v6.1.1 args: - "--csi-address=$(ADDRESS)" # Topology support is needed for the pod rescheduling test @@ -35,7 +35,7 @@ spec: - mountPath: /csi name: socket-dir - name: driver-registrar - image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.15.0 + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 args: - --v=5 - --csi-address=/csi/csi.sock @@ -53,7 +53,7 @@ spec: - mountPath: /registration name: registration-dir - name: mock - image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.0 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.17.1 args: - -v=5 - -nodeid=$(KUBE_NODE_NAME) diff --git a/vendor/k8s.io/kubernetes/test/utils/audit.go b/vendor/k8s.io/kubernetes/test/utils/audit.go index cc5bf1338a..11264b3706 100644 --- a/vendor/k8s.io/kubernetes/test/utils/audit.go +++ b/vendor/k8s.io/kubernetes/test/utils/audit.go @@ -34,20 +34,23 @@ import ( // AuditEvent is a simplified representation of an audit event for testing purposes type AuditEvent struct { - ID types.UID - Level auditinternal.Level - Stage auditinternal.Stage - RequestURI string - Verb string - Code int32 - User string - ImpersonatedUser string - ImpersonatedGroups string - Resource string - Namespace string - RequestObject bool - ResponseObject bool - AuthorizeDecision string + ID types.UID + Level auditinternal.Level + Stage auditinternal.Stage + RequestURI string + Verb string + Code int32 + StatusMessage string + User string + ImpersonatedUser string + ImpersonatedUID string + ImpersonatedGroups string + ImpersonationConstraint *string + Resource string + Namespace string + RequestObject bool + ResponseObject bool + AuthorizeDecision string // The Check functions in this package takes ownerships of these maps. You should // not reference these maps after calling the Check functions. @@ -147,6 +150,7 @@ func testEventFromInternalFiltered(e *auditinternal.Event, customAnnotationsFilt } if e.ResponseStatus != nil { event.Code = e.ResponseStatus.Code + event.StatusMessage = e.ResponseStatus.Message } if e.ResponseObject != nil { event.ResponseObject = true @@ -156,9 +160,13 @@ func testEventFromInternalFiltered(e *auditinternal.Event, customAnnotationsFilt } if e.ImpersonatedUser != nil { event.ImpersonatedUser = e.ImpersonatedUser.Username + event.ImpersonatedUID = e.ImpersonatedUser.UID sort.Strings(e.ImpersonatedUser.Groups) event.ImpersonatedGroups = strings.Join(e.ImpersonatedUser.Groups, ",") } + if e.AuthenticationMetadata != nil { + event.ImpersonationConstraint = &e.AuthenticationMetadata.ImpersonationConstraint + } event.AuthorizeDecision = e.Annotations["authorization.k8s.io/decision"] for k, v := range e.Annotations { if strings.HasPrefix(k, mutating.PatchAuditAnnotationPrefix) { diff --git a/vendor/k8s.io/kubernetes/test/utils/density_utils.go b/vendor/k8s.io/kubernetes/test/utils/density_utils.go index e0747c4894..f0ed2149c9 100644 --- a/vendor/k8s.io/kubernetes/test/utils/density_utils.go +++ b/vendor/k8s.io/kubernetes/test/utils/density_utils.go @@ -43,7 +43,7 @@ func AddLabelsToNode(c clientset.Interface, nodeName string, labels map[string]s labelString := "{" + strings.Join(tokens, ",") + "}" patch := fmt.Sprintf(`{"metadata":{"labels":%v}}`, labelString) var err error - for attempt := 0; attempt < retries; attempt++ { + for range retries { _, err = c.CoreV1().Nodes().Patch(context.TODO(), nodeName, types.MergePatchType, []byte(patch), metav1.PatchOptions{}) if err != nil { if !apierrors.IsConflict(err) { @@ -62,7 +62,7 @@ func AddLabelsToNode(c clientset.Interface, nodeName string, labels map[string]s func RemoveLabelOffNode(c clientset.Interface, nodeName string, labelKeys []string) error { var node *v1.Node var err error - for attempt := 0; attempt < retries; attempt++ { + for range retries { node, err = c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) if err != nil { return err diff --git a/vendor/k8s.io/kubernetes/test/utils/deployment.go b/vendor/k8s.io/kubernetes/test/utils/deployment.go index eaa618a6ce..04e787d5de 100644 --- a/vendor/k8s.io/kubernetes/test/utils/deployment.go +++ b/vendor/k8s.io/kubernetes/test/utils/deployment.go @@ -25,12 +25,12 @@ import ( apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/dump" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" podutil "k8s.io/kubernetes/pkg/api/v1/pod" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" labelsutil "k8s.io/kubernetes/pkg/util/labels" + "k8s.io/utils/dump" ) type LogfFn func(format string, args ...interface{}) diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go index f2c4e5e181..02bb51ec14 100644 --- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go @@ -169,8 +169,8 @@ const ( InvalidRegistryImage // IpcUtils image IpcUtils - // JessieDnsutils image - JessieDnsutils + // GlibcDnsTesting image (formerly JessieDnsutils) + GlibcDnsTesting // Kitten image Kitten // Nautilus image @@ -185,8 +185,8 @@ const ( NodePerfNpbEp // NodePerfNpbIs image NodePerfNpbIs - // NodePerfTfWideDeep image - NodePerfTfWideDeep + // NodePerfPytorchWideDeep image + NodePerfPytorchWideDeep // Nonewprivs image Nonewprivs // NonRoot runs with a default user of 1234 @@ -209,33 +209,33 @@ const ( func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config) { configs := map[ImageID]Config{} configs[AgnhostPrev] = Config{list.PromoterE2eRegistry, "agnhost", "2.55"} - configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.59"} + configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.63.0"} configs[AgnhostPrivate] = Config{list.PrivateRegistry, "agnhost", "2.6"} configs[APIServer] = Config{list.PromoterE2eRegistry, "sample-apiserver", "1.29.2"} configs[AppArmorLoader] = Config{list.PromoterE2eRegistry, "apparmor-loader", "1.4"} configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.37.0-1"} - configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.8.7"} - configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.6.6-0"} + configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.9.3"} + configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.6.8-0"} configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"} - configs[IpcUtils] = Config{list.PromoterE2eRegistry, "ipc-utils", "1.3"} - configs[JessieDnsutils] = Config{list.PromoterE2eRegistry, "jessie-dnsutils", "1.7"} - configs[Kitten] = Config{list.PromoterE2eRegistry, "kitten", "1.7"} - configs[Nautilus] = Config{list.PromoterE2eRegistry, "nautilus", "1.7"} + configs[IpcUtils] = Config{list.PromoterE2eRegistry, "ipc-utils", "1.4"} + configs[GlibcDnsTesting] = Config{list.PromoterE2eRegistry, "glibc-dns-testing", "2.0.0"} + configs[Kitten] = Config{list.PromoterE2eRegistry, "kitten", "1.8"} + configs[Nautilus] = Config{list.PromoterE2eRegistry, "nautilus", "1.8"} configs[NFSProvisioner] = Config{list.SigStorageRegistry, "nfs-provisioner", "v4.0.8"} - configs[Nginx] = Config{list.PromoterE2eRegistry, "nginx", "1.14-4"} - configs[NginxNew] = Config{list.PromoterE2eRegistry, "nginx", "1.15-4"} - configs[NodePerfNpbEp] = Config{list.PromoterE2eRegistry, "node-perf/npb-ep", "1.2"} - configs[NodePerfNpbIs] = Config{list.PromoterE2eRegistry, "node-perf/npb-is", "1.2"} - configs[NodePerfTfWideDeep] = Config{list.PromoterE2eRegistry, "node-perf/tf-wide-deep", "1.3"} - configs[Nonewprivs] = Config{list.PromoterE2eRegistry, "nonewprivs", "1.3"} - configs[NonRoot] = Config{list.PromoterE2eRegistry, "nonroot", "1.4"} + configs[Nginx] = Config{list.PromoterE2eRegistry, "nginx", "1.15-4"} + configs[NginxNew] = Config{list.PromoterE2eRegistry, "nginx", "1.27-0"} + configs[NodePerfNpbEp] = Config{list.PromoterE2eRegistry, "node-perf/npb-ep", "1.6.0"} + configs[NodePerfNpbIs] = Config{list.PromoterE2eRegistry, "node-perf/npb-is", "1.7.0"} + configs[NodePerfPytorchWideDeep] = Config{list.PromoterE2eRegistry, "node-perf/pytorch-wide-deep", "1.0.0"} + configs[Nonewprivs] = Config{list.PromoterE2eRegistry, "nonewprivs", "1.4"} + configs[NonRoot] = Config{list.PromoterE2eRegistry, "nonroot", "1.5"} // Pause - when these values are updated, also update cmd/kubelet/app/options/container_runtime.go - configs[Pause] = Config{list.GcRegistry, "pause", "3.10.1"} + configs[Pause] = Config{list.GcRegistry, "pause", "3.10.2"} configs[Perl] = Config{list.PromoterE2eRegistry, "perl", "5.26"} configs[RegressionIssue74839] = Config{list.PromoterE2eRegistry, "regression-issue-74839", "1.4"} - configs[ResourceConsumer] = Config{list.PromoterE2eRegistry, "resource-consumer", "1.13"} - configs[VolumeNFSServer] = Config{list.PromoterE2eRegistry, "volume/nfs", "1.4"} - configs[VolumeISCSIServer] = Config{list.PromoterE2eRegistry, "volume/iscsi", "2.6"} + configs[ResourceConsumer] = Config{list.PromoterE2eRegistry, "resource-consumer", "1.14"} + configs[VolumeNFSServer] = Config{list.PromoterE2eRegistry, "volume/nfs", "1.6.0"} + configs[VolumeISCSIServer] = Config{list.PromoterE2eRegistry, "volume/iscsi", "2.7"} // This adds more config entries. Those have no pre-defined ImageID number, // but will be used via ReplaceRegistryInImageURL when deploying diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/assert.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/assert.go new file mode 100644 index 0000000000..02b35aa455 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/assert.go @@ -0,0 +1,349 @@ +/* +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 ktesting + +import ( + "context" + "errors" + "fmt" + "reflect" + + "github.com/onsi/gomega" + "github.com/onsi/gomega/format" + gtypes "github.com/onsi/gomega/types" +) + +// FailureError is an error where the error string is meant to be passed to +// [TContext.Fatal] directly, i.e. adding some prefix like "unexpected error" is not +// necessary. It is also not necessary to dump the error struct. +type FailureError struct { + Msg string + FullStackTrace string +} + +func (f FailureError) Error() string { + return f.Msg +} + +func (f FailureError) Backtrace() string { + return f.FullStackTrace +} + +func (f FailureError) Is(target error) bool { + return target == ErrFailure +} + +// ErrFailure is an empty error that can be wrapped to indicate that an error +// is a FailureError. It can also be used to test for a FailureError:. +// +// return fmt.Errorf("some problem%w", ErrFailure) +// ... +// err := someOperation() +// if errors.Is(err, ErrFailure) { +// ... +// } +var ErrFailure error = FailureError{} + +func gomegaAssertion(tCtx TContext, fatal bool, actual interface{}, extra ...interface{}) gomega.Assertion { + testingT := gtypes.GomegaTestingT(tCtx) + if !fatal { + testingT = assertTestingT{tCtx} + } + return gomega.NewWithT(testingT).Expect(actual, extra...) +} + +// assertTestingT implements Fatalf (the only function used by Gomega for +// reporting failures) using TContext.Errorf, i.e. testing continues after a +// failed assertion. The Helper method gets passed through. +type assertTestingT struct { + TContext +} + +var _ gtypes.GomegaTestingT = assertTestingT{} + +func (a assertTestingT) Fatalf(format string, args ...any) { + a.Helper() + a.Errorf(format, args...) +} + +// ExpectNoError asserts that no error has occurred and fails the test if it does. +// +// As in [gomega], the optional explanation can be: +// - a [fmt.Sprintf] format string plus its arguments +// - a function returning a string, which will be called +// lazily to construct the explanation if needed +// +// If an explanation is provided, then it replaces the default "Unexpected +// error" in the failure message. It's combined with additional details by +// adding a colon at the end, as when wrapping an error. Therefore it should +// not end with a punctuation mark or line break. +// +// Using ExpectNoError instead of the corresponding Gomega or testify +// assertions has the advantage that the failure message is short (good for +// aggregation in https://go.k8s.io/triage) with more details captured in the +// test log output (good when investigating one particular failure). +// +// Helper packages should return errors that are derived from [FailureError]. +// The test code then is forced to check for that error by the normal +// linter and should provide additional context for the failure, just +// as it would when printing or wrapping an error: +// +// tCtx.ExpectNoError(somehelper.CreateSomething(tCtx, ...), "creating the first foobar") +// tCtx.ExpectNoError(somehelper.CreateSomething(tCtx, ...), "creating the second foobar") +func (tCtx TContext) ExpectNoError(err error, explain ...interface{}) { + tCtx.Helper() + tCtx.noError(tCtx.Fatalf, err, explain...) +} + +// AssertNoError is a variant of ExpectNoError which reports an unexpected +// error without aborting the test. It returns true if there was no error. +func (tCtx TContext) AssertNoError(err error, explain ...interface{}) bool { + tCtx.Helper() + return tCtx.noError(tCtx.Errorf, err, explain...) +} + +func (tCtx TContext) noError(failf func(format string, args ...any), err error, explain ...interface{}) bool { + if err == nil { + return true + } + + tCtx.Helper() + description := buildDescription(explain...) + + if errors.Is(err, ErrFailure) { + var failure FailureError + if tCtx.capture == nil && errors.As(err, &failure) { + if backtrace := failure.Backtrace(); backtrace != "" { + if description != "" { + tCtx.Log(description) + } + tCtx.Logf("Failed at:\n%s", backtrace) + } + } + if description != "" { + failf("%s: %s", description, err.Error()) + return false + } + failf("%s", err.Error()) + return false + } + + if description == "" { + description = "Unexpected error" + } + if tCtx.capture == nil { + tCtx.Logf("%s:\n%s", description, format.Object(err, 0)) + } + failf("%s: %v", description, err.Error()) + return false +} + +func buildDescription(explain ...interface{}) string { + switch len(explain) { + case 0: + return "" + case 1: + if describe, ok := explain[0].(func() string); ok { + return describe() + } + } + return fmt.Sprintf(explain[0].(string), explain[1:]...) +} + +// Eventually wraps [gomega.Eventually]. Supported argument types are: +// - A function with a `tCtx ktesting.TContext` or `ctx context.Context` +// parameter plus additional parameters and arbitrary return values. +// - A value which changes over time, usually a channel. +// +// For functions, the context is provided by Eventually. Additional parameters +// must be passed via WithParameters. The first return value is passed to the Gomega +// matcher, all others (in particular an additional error) must be null. +// As a special case, a function with `tCtx ktesting.TContext` and no return +// values can be combined with gomega.Succeed as matcher. +// +// In contrast to direct usage of [gomega.Eventually], making additional +// assertions inside the callback function is okay in all cases as long as they +// use the TContext that is passed in. An assertion failure is considered +// temporary, so Eventually will continue to poll. This can be used to check a +// value with multiple assertions instead of writing a custom matcher: +// +// cb := func(tCtx ktesting.TContext) { +// value, err := doSomething(...) +// tCtx.ExpectNoError(err, "something failed") +// tCtx.Assert(value.a).To(gomega.Equal(42), "the answer") +// tCtx.Assert(value.b).To(gomega.Equal("the fish"), "thanks") +// } +// tCtx.Eventually(cb).Should(gomega.Succeed()) +// +// The test stops in case of a failure. To continue, use AssertEventually. +// +// The default Gomega poll interval and timeout are used. Setting a specific +// timeout may be useful: +// +// tCtx.Eventually(cb).Timeout(5 * time.Second).Should(gomega.Succeed(), "foobar should succeed") +// +// Canceling the context in the callback only affects code in the callback. The +// context passed to Eventually is not getting canceled. To abort polling +// immediately because the expected condition is known to not be reached +// anymore, use [gomega.StopTrying]: +// +// cb := func(func(tCtx ktesting.TContext) int { +// value, err := doSomething(...) +// if errors.Is(err, SomeFinalErr) { +// // This message completely replaces the normal +// // failure message and thus should include all +// // relevant information. +// // +// // github.com/onsi/gomega/format is a good way +// // to format arbitrary data. It uses indention +// // and falls back to YAML for Kubernetes API +// // structs for readability. +// gomega.StopTrying("permanent failure, last value:\n%s", format.Object(value, 1 /* indent one level */)). +// Wrap(err).Now() +// } +// tCtx.ExpectNoError(err, "something failed") +// return value +// } +// tCtx.Eventually(cb).Should(gomega.Equal(42), "should be the answer to everything") +// +// To poll again after some specific timeout, use [gomega.TryAgainAfter]. This is +// particularly useful in [Consistently] to ignore some intermittent error. +// +// cb := func(func(tCtx ktesting.TContext) int { +// value, err := doSomething(...) +// var intermittentErr SomeIntermittentError +// if errors.As(err, &intermittentErr) { +// gomega.TryAgainAfter(intermittentErr.RetryPeriod).Wrap(err).Now() +// } +// tCtx.ExpectNoError(err, "something failed") +// return value +// } +// tCtx.Eventually(cb).Should(gomega.Equal(42), "should be the answer to everything") +func (tCtx TContext) Eventually(arg any) gomega.AsyncAssertion { + tCtx.Helper() + return tCtx.newAsyncAssertion(gomega.NewWithT(tCtx).Eventually, arg) +} + +// AssertEventually is a variant of Eventually which merely records a failure +// without stopping the test. +func (tCtx TContext) AssertEventually(arg any) gomega.AsyncAssertion { + tCtx.Helper() + return tCtx.newAsyncAssertion(gomega.NewWithT(assertTestingT{tCtx}).Eventually, arg) +} + +// Consistently wraps [gomega.Consistently] the same way as [Eventually] wraps +// [gomega.Eventually]. +func (tCtx TContext) Consistently(arg any) gomega.AsyncAssertion { + tCtx.Helper() + return tCtx.newAsyncAssertion(gomega.NewWithT(tCtx).Consistently, arg) +} + +// AssertConsistently is a variant of Consistently which merely records a failure +// without stopping the test. +func (tCtx TContext) AssertConsistently(arg any) gomega.AsyncAssertion { + tCtx.Helper() + return tCtx.newAsyncAssertion(gomega.NewWithT(assertTestingT{tCtx}).Consistently, arg) +} + +func (tCtx TContext) newAsyncAssertion(eventuallyOrConsistently func(actualOrCtx any, args ...any) gomega.AsyncAssertion, arg any) gomega.AsyncAssertion { + tCtx.Helper() + // switch arg := arg.(type) { + // case func(tCtx TContext): + // // Tricky to handle via reflect, so let's cover this directly... + // return eventuallyOrConsistently(tCtx, func(g gomega.Gomega, ctx context.Context) (err error) { + // tCtx := WithContext(tCtx, ctx) + // tCtx, finalize := WithError(tCtx, &err) + // defer finalize() + // arg(tCtx) + // }) + // default: + v := reflect.ValueOf(arg) + if v.Kind() != reflect.Func { + // Gomega must deal with it. + return eventuallyOrConsistently(tCtx, arg) + } + t := v.Type() + if t.NumIn() == 0 || t.In(0) != tContextType { + // Not a function we can wrap. + return eventuallyOrConsistently(tCtx, arg) + } + // Build a wrapper function with context instead of TContext as first parameter. + // The wrapper then builds that TContext when called and invokes the actual function. + in := make([]reflect.Type, t.NumIn()) + in[0] = contextType + for i := 1; i < t.NumIn(); i++ { + in[i] = t.In(i) + } + out := make([]reflect.Type, t.NumOut()) + for i := range t.NumOut() { + out[i] = t.Out(i) + } + // The last result must always be an error because we need the ability to return assertion + // failures, so we may have to add an error result value if the function doesn't + // already have it. + addErrResult := t.NumOut() == 0 || t.Out(t.NumOut()-1) != errorType + if addErrResult { + out = append(out, errorType) + } + wrapperType := reflect.FuncOf(in, out, t.IsVariadic()) + wrapper := reflect.MakeFunc(wrapperType, func(args []reflect.Value) (results []reflect.Value) { + var err error + tCtx, finalize := tCtx.WithContext(args[0].Interface().(context.Context)). + WithCancel(). + WithError(&err) + args[0] = reflect.ValueOf(tCtx) + defer func() { + // This runs *after* finalize. + // If we are returning normally, then we must inject back the err + // value that was set by finalize. + if r := recover(); r != nil { + // Nope, no results needed. + panic(r) + } + errValue := reflect.ValueOf(err) + if err == nil { + // reflect doesn't like this ("returned zero Value"). + // We need a value of the right type. + errValue = reflect.New(errorType).Elem() + } + // If the call panicked and the panic was recoved + // by finalize(), then results is still nil. + // We need to fill in null values. + if len(results) == 0 && t.NumOut() > 0 { + for i := range t.NumOut() { + results = append(results, reflect.New(t.Out(i)).Elem()) + } + } + if addErrResult { + results = append(results, errValue) + return + } + if results[len(results)-1].IsNil() && err != nil { + results[len(results)-1] = errValue + } + }() + defer finalize() // Must be called directly, otherwise it cannot recover a panic. + return v.Call(args) + }) + return eventuallyOrConsistently(tCtx, wrapper.Interface()) +} + +var ( + contextType = reflect.TypeFor[context.Context]() + errorType = reflect.TypeFor[error]() + tContextType = reflect.TypeFor[TContext]() +) diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/clientcontext.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/clientcontext.go new file mode 100644 index 0000000000..713821cb32 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/clientcontext.go @@ -0,0 +1,53 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "fmt" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/client-go/discovery/cached/memory" + "k8s.io/client-go/dynamic" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" +) + +// WithRESTConfig initializes all client-go clients with new clients +// created for the config. The current test name gets included in the UserAgent. +func (tCtx TContext) WithRESTConfig(cfg *rest.Config) TContext { + cfg = rest.CopyConfig(cfg) + cfg.UserAgent = fmt.Sprintf("%s -- %s", rest.DefaultKubernetesUserAgent(), tCtx.Name()) + + tCtx.restConfig = cfg + tCtx.client = clientset.NewForConfigOrDie(cfg) + tCtx.dynamic = dynamic.NewForConfigOrDie(cfg) + tCtx.apiextensions = apiextensions.NewForConfigOrDie(cfg) + cachedDiscovery := memory.NewMemCacheClient(tCtx.client.Discovery()) + tCtx.restMapper = restmapper.NewDeferredDiscoveryRESTMapper(cachedDiscovery) + return tCtx +} + +// WithClients uses an existing config and clients. +func (tCtx TContext) WithClients(cfg *rest.Config, mapper *restmapper.DeferredDiscoveryRESTMapper, client clientset.Interface, dynamic dynamic.Interface, apiextensions apiextensions.Interface) TContext { + tCtx.restConfig = cfg + tCtx.restMapper = mapper + tCtx.client = client + tCtx.dynamic = dynamic + tCtx.apiextensions = apiextensions + return tCtx +} diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/contexthelper.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/contexthelper.go new file mode 100644 index 0000000000..b6f6263a4a --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/contexthelper.go @@ -0,0 +1,105 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + "fmt" + "time" +) + +// cleanupErr creates a cause when canceling a context because the test has completed. +// It is a context.Canceled error. +func cleanupErr(testName string) error { + return canceledError(fmt.Sprintf("test %s is cleaning up", testName)) +} + +type canceledError string + +func (c canceledError) Error() string { return string(c) } + +func (c canceledError) Is(target error) bool { + return target == context.Canceled +} + +// withTimeout corresponds to [context.WithTimeout]. In contrast to +// [context.WithTimeout], it automatically cancels during test cleanup, provides +// the given cause when the deadline is reached, and its cancel function +// requires a cause. +func withTimeout(ctx context.Context, tb TB, timeout time.Duration, timeoutCause string) (context.Context, func(cause string)) { + tb.Helper() + + now := time.Now() + + cancelCtx, cancel := context.WithCancelCause(ctx) + after := time.NewTimer(timeout) + stopCtx, stop := context.WithCancel(ctx) // Only used internally, doesn't need a cause. + done := make(chan struct{}) + tb.Cleanup(func() { + cancel(cleanupErr(tb.Name())) + stop() + // Wait for goroutine termination. This is important because + // otherwise the goroutine might log through tb *after* the + // test has already finished, which causes a panic. + <-done + }) + go func() { + defer close(done) + select { + case <-stopCtx.Done(): + after.Stop() + // No need to set a cause here. The cause or error of + // the parent context will be used. + case <-after.C: + // Code using this tCtx may or may not log the + // information above when it runs into the + // cancellation. It's better if we do it, just to be on + // the safe side. + // + // Would be nice to log this with the source code location + // of our caller, but testing.Logf does not support that. + tb.Log(fmt.Sprintf("\nINFO: canceling context: %s\n", timeoutCause)) + cancel(canceledError(timeoutCause)) + } + }() + + // Determine which deadline is sooner: ours or that of our parent. + deadline := now.Add(timeout) + if parentDeadline, ok := ctx.Deadline(); ok { + if deadline.After(parentDeadline) { + deadline = parentDeadline + } + } + + // We always have a deadline. + return deadlineContext{Context: cancelCtx, deadline: deadline}, func(cause string) { + var cancelCause error + if cause != "" { + cancelCause = canceledError(cause) + } + cancel(cancelCause) + } +} + +type deadlineContext struct { + context.Context + deadline time.Time +} + +func (d deadlineContext) Deadline() (time.Time, bool) { + return d.deadline, true +} diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/doc.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/doc.go new file mode 100644 index 0000000000..3207f311bc --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/doc.go @@ -0,0 +1,32 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package ktesting is a wrapper around k8s.io/klog/v2/ktesting. In contrast +// to the klog package, this one is opinionated and tailored towards testing +// Kubernetes. +// +// Importing it +// - adds the -v command line flag +// - enables better dumping of complex datatypes +// - sets the default verbosity to 5 (can be changed with [SetDefaultVerbosity]) +// +// It also adds additional APIs and types for unit and integration tests +// which are too experimental for klog and/or are unrelated to logging. +// The ktesting package itself takes care of managing a test context +// with deadlines, timeouts, cancellation, and some common attributes +// as first-class members of the API. Sub-packages have additional APIs +// for propagating values via the context, implemented via [WithValue]. +package ktesting diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/errorcontext.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/errorcontext.go new file mode 100644 index 0000000000..0316b54809 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/errorcontext.go @@ -0,0 +1,245 @@ +/* +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 ktesting + +import ( + "errors" + "fmt" + "strings" +) + +// WithError creates a context where test failures are collected and stored in +// the provided error instance when the caller is done. Use it like this: +// +// func doSomething(tCtx ktesting.TContext) (finalErr error) { +// tCtx, finalize := WithError(tCtx, &finalErr) +// defer finalize() +// ... +// tCtx.Fatal("some failure") +// +// Any error already stored in the variable will get overwritten by finalize if +// there were test failures, otherwise the variable is left unchanged. +// If there were multiple test errors, then the error will wrap all of +// them with errors.Join. +// +// Test failures are not propagated to the parent context. +// WithRESTConfig initializes all client-go clients with new clients +// created for the config. The current test name gets included in the UserAgent. +func (tCtx TContext) WithError(err *error) (TContext, func()) { + tCtx.capture = &capture{} + + return tCtx, func() { + // Recover has to be called in the deferred function. When called inside + // a function called by a deferred function (like finalize below), it + // returns nil. + if e := recover(); e != nil { + if _, ok := e.(fatalWithError); !ok { + // Not our own panic, pass it on instead of setting the error. + panic(e) + } + } + + tCtx.finalize(err) + } +} + +func (tCtx TContext) finalize(err *error) { + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + errs := tCtx.capture.errors + if tCtx.capture.failed && len(errs) == 0 { + errs = []error{errFailedWithNoExplanation} + } + if len(errs) == 0 { + return + } + *err = failures{errors.Join(errs...)} +} + +type failures struct { + error +} + +func (e failures) GomegaString() string { + // We don't need to repeat the string. Errors already get formatted once by Gomega itself, + // then it calls GomegaString for a summary that isn't necessary anymore. + return "" +} + +// buildHeader handles: +// - "ERROR:" -> use both prefix and suffix when we have a header, otherwise just the suffix +// - "" -> use suffix only if we have a header +func (tCtx TContext) buildHeader(prefix, suffix string) string { + if tCtx.perTestHeader != nil { + return prefix + tCtx.perTestHeader() + suffix + } + if prefix != "" { + return suffix + } + return "" +} + +// indent either indents all follow-up lines or all lines including the first one. +func indent(msg string, all bool) string { + header := "" + if all { + header = "\t" + } + return header + strings.ReplaceAll(msg, "\n", "\n\t") +} + +func (tCtx TContext) Skip(args ...any) { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintln. + msg := strings.TrimSpace(fmt.Sprintln(args...)) + tCtx.TB().Skip("SKIP:", tCtx.buildHeader(" ", " ")+tCtx.steps+indent(msg, false)) +} + +func (tCtx TContext) Skipf(format string, args ...any) { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintf. + msg := strings.TrimSpace(fmt.Sprintf(format, args...)) + tCtx.TB().Skip("SKIP:", tCtx.buildHeader(" ", " ")+tCtx.steps+indent(msg, false)) +} + +func (tCtx TContext) Log(args ...any) { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintln. + msg := strings.TrimSpace(fmt.Sprintln(args...)) + tCtx.TB().Log(tCtx.buildHeader("", " ") + tCtx.steps + indent(msg, false)) +} + +func (tCtx TContext) Logf(format string, args ...any) { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintf. + msg := strings.TrimSpace(fmt.Sprintf(format, args...)) + tCtx.TB().Log(tCtx.buildHeader("", " ") + tCtx.steps + indent(msg, false)) +} + +func (tCtx TContext) Error(args ...any) { + if tCtx.capture == nil { + tCtx.Helper() + msg := strings.TrimSpace(fmt.Sprintln(args...)) + // ERROR *before* header to make it stand out as failure. + tCtx.TB().Error("ERROR:" + tCtx.buildHeader(" ", "\n") + indent(tCtx.steps+msg, true)) + return + } + + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + // Gomega adds a leading newline in https://github.com/onsi/gomega/blob/f804ac6ada8d36164ecae0513295de8affce1245/internal/gomega.go#L37 + // Let's strip that at start and end because ktesting will make errors + // stand out more with the "ERROR" prefix, so there's no need for additional + // line breaks. Besides, Sprintln (required for `go vet printf`) also + // adds a trailing newline that we don't want. + msg := strings.TrimSpace(fmt.Sprintln(args...)) + tCtx.capture.errors = append(tCtx.capture.errors, errors.New(tCtx.steps+msg)) + tCtx.capture.failed = true +} + +func (tCtx TContext) Errorf(format string, args ...any) { + if tCtx.capture == nil { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintln. + msg := strings.TrimSpace(fmt.Sprintf(format, args...)) + // ERROR *before* header to make it stand out as failure. + tCtx.TB().Error("ERROR:" + tCtx.buildHeader(" ", "\n") + indent(tCtx.steps+msg, true)) + return + } + + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + msg := strings.TrimSpace(fmt.Sprintf(format, args...)) + tCtx.capture.errors = append(tCtx.capture.errors, errors.New(tCtx.steps+msg)) + tCtx.capture.failed = true +} + +func (tCtx TContext) Fail() { + if tCtx.capture == nil { + tCtx.TB().Fail() + return + } + + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + tCtx.capture.failed = true +} + +func (tCtx TContext) FailNow() { + if tCtx.capture == nil { + tCtx.TB().FailNow() + return + } + + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + tCtx.capture.failed = true + panic(failed) +} + +func (tCtx TContext) Failed() bool { + if tCtx.capture == nil { + return tCtx.TB().Failed() + } + + tCtx.capture.mutex.Lock() + defer tCtx.capture.mutex.Unlock() + + return tCtx.capture.failed +} + +func (tCtx TContext) Fatal(args ...any) { + if tCtx.capture == nil { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintln. + msg := strings.TrimSpace(fmt.Sprintln(args...)) + // FATAL ERROR *before* header to make it stand out as failure. + tCtx.TB().Fatal("FATAL ERROR:" + tCtx.buildHeader(" ", "\n") + indent(tCtx.steps+msg, true)) + } + + tCtx.Error(args...) + tCtx.FailNow() +} + +func (tCtx TContext) Fatalf(format string, args ...any) { + if tCtx.capture == nil { + tCtx.Helper() + // Enable `go vet printf` by directly calling fmt.Sprintf. + msg := strings.TrimSpace(fmt.Sprintf(format, args...)) + // FATAL ERROR *before* header to make it stand out as failure. + tCtx.TB().Fatal("FATAL ERROR:" + tCtx.buildHeader(" ", "\n") + indent(tCtx.steps+msg, true)) + return + } + + tCtx.Errorf(format, args...) + tCtx.FailNow() +} + +// fatalWithError is the internal type that should never get propagated up. The +// only case where that can happen is when the developer forgot to call +// finalize via defer. The string explains that, in case that developers get to +// see it. +type fatalWithError string + +const failed = fatalWithError("WithError TContext encountered a fatal error, but the finalize function was not called via defer as it should have been.") + +var errFailedWithNoExplanation = errors.New("WithError context was marked as failed without recording an error") diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/initoption/initoption.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/initoption/initoption.go new file mode 100644 index 0000000000..d65aa515e5 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/initoption/initoption.go @@ -0,0 +1,40 @@ +/* +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 initoption + +import "k8s.io/kubernetes/test/utils/ktesting/internal" + +// InitOption is a functional option for Init and InitCtx. +type InitOption func(c *internal.InitConfig) + +// PerTestOutput controls whether a per-test logger gets +// set up by Init. Has no effect in InitCtx. +func PerTestOutput(enabled bool) InitOption { + return func(c *internal.InitConfig) { + c.PerTestOutput = enabled + } +} + +// BufferLogs controls whether log entries are captured in memory in addition +// to being printed. Off by default. Unit tests that want to verify that +// log entries are emitted as expected can turn this on and then retrieve +// the captured log through the Underlier LogSink interface. +func BufferLogs(enabled bool) InitOption { + return func(c *internal.InitConfig) { + c.BufferLogs = enabled + } +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/doc.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/internal/config.go similarity index 78% rename from vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/doc.go rename to vendor/k8s.io/kubernetes/test/utils/ktesting/internal/config.go index 16f4439906..88403a00e8 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/doc.go +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/internal/config.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +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. @@ -14,7 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. +package internal -// Package fake has the automatically generated clients. -package fake +type InitConfig struct { + PerTestOutput bool + BufferLogs bool +} diff --git a/vendor/k8s.io/cri-client/pkg/internal/log.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/klogcontext.go similarity index 62% rename from vendor/k8s.io/cri-client/pkg/internal/log.go rename to vendor/k8s.io/kubernetes/test/utils/ktesting/klogcontext.go index d3d3dd4e31..f9a42e2ba6 100644 --- a/vendor/k8s.io/cri-client/pkg/internal/log.go +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/klogcontext.go @@ -14,20 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package internal +package ktesting -import "k8s.io/klog/v2" +import ( + "fmt" + "time" +) -func Log(logger *klog.Logger, level int, msg string, keyAndValues ...any) { - if logger == nil { - return - } - logger.V(level).Info(msg, keyAndValues...) -} +var timeNow = time.Now // Can be stubbed out for testing. -func LogErr(logger *klog.Logger, err error, msg string, keyAndValues ...any) { - if logger == nil { - return - } - logger.Error(err, msg, keyAndValues...) +func klogHeader() string { + now := timeNow() + _, month, day := now.Date() + hour, minute, second := now.Clock() + return fmt.Sprintf("I%02d%02d %02d:%02d:%02d.%06d]", + month, day, hour, minute, second, now.Nanosecond()/1000) } diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/ktesting.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/ktesting.go new file mode 100644 index 0000000000..3099ca0753 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/ktesting.go @@ -0,0 +1,55 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + "flag" + "fmt" + "testing" + + "k8s.io/klog/v2" + + // Initialize command line parameters. + _ "k8s.io/component-base/logs/testinit" +) + +// SetDefaultVerbosity can be called during init to modify the default +// log verbosity of the program. +// +// Note that this immediately reconfigures the klog verbosity, already before +// flag parsing. If the verbosity is non-zero and SetDefaultVerbosity is called +// during init, then other init functions might start logging where normally +// they wouldn't log anything. Should this occur, then the right fix is to +// remove those log calls because logging during init is discouraged. It leads +// to unpredictable output (init order is not specified) and/or is useless +// (logging not initialized during init and thus conditional log output gets +// omitted). +func SetDefaultVerbosity(v int) { + f := flag.CommandLine.Lookup("v") + _ = f.Value.Set(fmt.Sprintf("%d", v)) +} + +// NewTestContext is a drop-in replacement for ktesting.NewTestContext. +// +// The result can be cast to a TContext and has the same functionality +// (for example, it gets cancelled at the end of the test). +// It's returned as a context.Context to avoid breaking code which expects that type. +func NewTestContext(tb testing.TB) (klog.Logger, context.Context) { + tCtx := Init(tb) + return tCtx.Logger(), tCtx +} diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/signals.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals.go new file mode 100644 index 0000000000..4edef18bd9 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals.go @@ -0,0 +1,236 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "os/signal" + "strings" + "sync" + "testing" +) + +var ( + // defaultProgressReporter is inactive until init is called. + defaultProgressReporter = &progressReporter{} + + // interruptCtx tracks whether the process got interrupted via SIGINT. + // In that case, interrupted gets called to cancel interruptCtx with + // a suitable message. + // + // This gets set up once per process and never gets reset. + interruptCtx, interrupted = context.WithCancelCause(context.Background()) +) + +const ginkgoSpecContextKey = "GINKGO_SPEC_CONTEXT" + +type ginkgoReporter interface { + AttachProgressReporter(reporter func() string) func() +} + +type progressReporter struct { + // initMutex protects initialization and finalization of the reporter. + initMutex sync.Mutex + + usageCount int64 + wg sync.WaitGroup + testCtx context.Context + signalChannel chan os.Signal + progressChannel chan os.Signal + + // reportMutex protects report creation and settings. + reportMutex sync.Mutex + reporterCounter int64 + reporters map[int64]func() string + out io.Writer + closeOut func() error +} + +var _ ginkgoReporter = &progressReporter{} + +// init is invoked by Init. It returns the context to be used for the +// new TContext. +// +// By default, that is just context.Background. In a Go unit test, it +// is a context connected to os.Interrupt. +// +// Once activated like that in a Go unit test, the progressReporter implements +// support for triggering a progress report in a running test when sending it a +// USR1 signal, similar to the corresponding Ginkgo feature. +// +// This support is active until the last test terminates. +func (p *progressReporter) init(tb TB) context.Context { + if _, ok := tb.(testing.TB); !ok { + // Not in a Go unit test. + return context.Background() + } + + tb.Helper() + + // If already interrupted, then don't start the new test. + // This is necessary because normally CTRL-C would exit + // the entire process immediately. Now we keep running + // to clean up. + if interruptCtx.Err() != nil { + tb.Fatalf("testing has been interrupted: %v", context.Cause(interruptCtx)) + } + + p.initMutex.Lock() + defer p.initMutex.Unlock() + + p.usageCount++ + tb.Cleanup(p.finalize) + if p.usageCount > 1 { + // Was already initialized. + return p.testCtx + } + + // Might have been set for testing purposes. + if p.out == nil { + // os.Stderr gets redirected by "go test". "go test -v" has to be + // used to see that output while a test runs. + // + // Opening /dev/tty during init avoids the redirection. + // May fail, depending on the OS, in which case + // os.Stderr is used. + if console, err := os.OpenFile("/dev/tty", os.O_RDWR|os.O_APPEND, 0); err == nil { + p.out = console + p.closeOut = console.Close + + } else { + p.out = os.Stdout + p.closeOut = nil + } + } + + p.signalChannel = make(chan os.Signal) + signal.Notify(p.signalChannel, os.Interrupt) + p.wg.Go(func() { + _, ok := <-p.signalChannel + if ok { + _, _ = fmt.Fprint(p.out, "\n\nINFO: canceling test context: received interrupt signal\n\n") + interrupted(errors.New("received interrupt signal")) + } + }) + + // This reimplements the contract between Ginkgo and Gomega for progress reporting. + // When using Ginkgo contexts, Ginkgo will implement it. This here is for "go test". + // + // nolint:staticcheck // It complains about using a plain string. This can only be fixed + // by Ginkgo and Gomega formalizing this interface and define a type (somewhere... + // probably cannot be in either Ginkgo or Gomega). + p.testCtx = context.WithValue(interruptCtx, ginkgoSpecContextKey, defaultProgressReporter) + + p.progressChannel = make(chan os.Signal, 1) + // progressSignals will be empty on Windows. + if len(progressSignals) > 0 { + signal.Notify(p.progressChannel, progressSignals...) + } + + p.wg.Go(p.run) + + return p.testCtx +} + +func (p *progressReporter) finalize() { + p.initMutex.Lock() + defer p.initMutex.Unlock() + + p.usageCount-- + if p.usageCount > 0 { + // Still in use. + return + } + + signal.Stop(p.signalChannel) + close(p.signalChannel) + signal.Stop(p.progressChannel) + close(p.progressChannel) + p.wg.Wait() + + // Now that all goroutines are stopped, we can clean up some more. + if p.closeOut != nil { + _ = p.closeOut() + p.out = nil + } +} + +// AttachProgressReporter implements Gomega's contextWithAttachProgressReporter. +func (p *progressReporter) AttachProgressReporter(reporter func() string) func() { + p.reportMutex.Lock() + defer p.reportMutex.Unlock() + + // TODO (?): identify the caller and record that for dumpProgress. + p.reporterCounter++ + id := p.reporterCounter + if p.reporters == nil { + p.reporters = make(map[int64]func() string) + } + p.reporters[id] = reporter + return func() { + p.detachProgressReporter(id) + } +} + +func (p *progressReporter) detachProgressReporter(id int64) { + p.reportMutex.Lock() + defer p.reportMutex.Unlock() + + delete(p.reporters, id) +} + +func (p *progressReporter) run() { + for { + _, ok := <-p.progressChannel + if !ok { + // Shut down. + return + } + p.dumpProgress() + } +} + +// dumpProgress is less useful than the Ginkgo progress report. We can't fix +// that we don't know which tests are currently running and instead have to +// rely on "go test -v" for that. +// +// But perhaps dumping goroutines and their callstacks is useful anyway? TODO: +// look at how Ginkgo does it and replicate some of it. +func (p *progressReporter) dumpProgress() { + p.reportMutex.Lock() + defer p.reportMutex.Unlock() + + var buffer strings.Builder + buffer.WriteString("You requested a progress report.\n") + if len(p.reporters) == 0 { + buffer.WriteString("Currently there is no information about test progress available.\n") + } + for _, reporter := range p.reporters { + report := reporter() + buffer.WriteRune('\n') + buffer.WriteString(report) + if !strings.HasSuffix(report, "\n") { + buffer.WriteRune('\n') + } + } + + _, _ = p.out.Write([]byte(buffer.String())) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.protomessage.pb.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals_non_win.go similarity index 65% rename from vendor/k8s.io/apimachinery/pkg/util/intstr/generated.protomessage.pb.go rename to vendor/k8s.io/kubernetes/test/utils/ktesting/signals_non_win.go index 2853a01830..cb11d7c0dc 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.protomessage.pb.go +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals_non_win.go @@ -1,8 +1,7 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release +//go:build !windows /* -Copyright The Kubernetes Authors. +Copyright 2023 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,8 +16,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. +package ktesting -package intstr +import ( + "os" + "syscall" +) -func (*IntOrString) ProtoMessage() {} +var ( + // If there ever is a non-Windows build platform that doesn't + // have SIGUSR1, then we need to add another exception for it. + progressSignals = []os.Signal{syscall.SIGUSR1} +) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/generated_expansion.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals_win.go similarity index 78% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/generated_expansion.go rename to vendor/k8s.io/kubernetes/test/utils/ktesting/signals_win.go index 6f1704f1ee..6ff7e49d4f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/generated_expansion.go +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/signals_win.go @@ -1,5 +1,7 @@ +//go:build windows + /* -Copyright The Kubernetes Authors. +Copyright 2023 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +16,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. +package ktesting -package v2beta1 +import ( + "os" +) -type HorizontalPodAutoscalerExpansion interface{} +var ( + progressSignals = []os.Signal{} +) diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/stepcontext.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/stepcontext.go new file mode 100644 index 0000000000..13db3c79a7 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/stepcontext.go @@ -0,0 +1,77 @@ +/* +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 ktesting + +// WithStep creates a context where a prefix is added to all errors and log +// messages, similar to how errors are wrapped. This can be nested, leaving a +// trail of "bread crumbs" that help figure out where in a test some problem +// occurred or why some log output gets written: +// +// ERROR: bake cake: set heat for baking: oven not found +// +// The string should describe the operation that is about to happen ("starting +// the controller", "list items") or what is being operated on ("HTTP server"). +// Multiple different prefixes get concatenated with a colon. +func (tCtx TContext) WithStep(step string) TContext { + tCtx.steps += step + ": " + return tCtx +} + +// Step is useful when the context with the step information is +// used more than once: +// +// ktesting.Step(tCtx, "step 1", func(tCtx ktesting.TContext) { +// tCtx.Log(...) +// if (... ) { +// tCtx.Failf(...) +// } +// )} +// +// Inside the callback, the tCtx variable is the one where the step +// has been added. This avoids the need to introduce multiple different +// context variables and risk of using the wrong one. +func (tCtx TContext) Step(step string, cb func(tCtx TContext)) { + tCtx.Helper() + cb(tCtx.WithStep(step)) +} + +// Value intercepts a search for the special "GINKGO_SPEC_CONTEXT" and +// wraps the underlying reporter so that the steps are visible in the report. +func (tCtx TContext) Value(key any) any { + if tCtx.steps != "" { + if s, ok := key.(string); ok && s == ginkgoSpecContextKey { + if reporter, ok := tCtx.Context.Value(key).(ginkgoReporter); ok { + return ginkgoReporter(&stepReporter{reporter: reporter, steps: tCtx.steps}) + } + } + } + return tCtx.Context.Value(key) +} + +type stepReporter struct { + reporter ginkgoReporter + steps string +} + +var _ ginkgoReporter = &stepReporter{} + +func (s *stepReporter) AttachProgressReporter(reporter func() string) func() { + return s.reporter.AttachProgressReporter(func() string { + report := reporter() + return s.steps + report + }) +} diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/tcontext.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/tcontext.go new file mode 100644 index 0000000000..c900252719 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/tcontext.go @@ -0,0 +1,595 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + "flag" + "fmt" + "strings" + "sync" + "testing" + "testing/synctest" + "time" + + "github.com/go-logr/logr" + "github.com/onsi/gomega" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/client-go/dynamic" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" + "k8s.io/klog/v2" + "k8s.io/klog/v2/ktesting" + "k8s.io/kubernetes/test/utils/format" + "k8s.io/kubernetes/test/utils/ktesting/initoption" + "k8s.io/kubernetes/test/utils/ktesting/internal" +) + +// Underlier is the additional interface implemented by the per-test LogSink +// behind [TContext.Logger]. Together with [initoption.BufferLogs] it can be +// used to capture log output in memory to check it in tests. +type Underlier = ktesting.Underlier + +// CleanupGracePeriod is the time that a [TContext] gets canceled before the +// deadline of its underlying test suite (usually determined via "go test +// -timeout"). This gives the running test(s) time to fail with an informative +// timeout error. After that, all cleanup callbacks then have the remaining +// time to complete before the test binary is killed. +// +// For this to work, each blocking calls in a test must respect the +// cancellation of the [TContext]. +// +// When using Ginkgo to manage the test suite and running tests, the +// CleanupGracePeriod is ignored because Ginkgo itself manages timeouts. +const CleanupGracePeriod = 5 * time.Second + +// TB is the interface common to [testing.T], [testing.B], [testing.F] and +// [github.com/onsi/ginkgo/v2] which ktesting relies upon itself or +// passes through (like Chdir, TempDir). +// +// In contrast to [testing.TB], it can be implemented also outside of the +// testing package. +// +// Fatal/Error/Skip are used by ktesting instead of Log + FailNow/Failed/SkipNow +// because when implemented by Ginkgo it is better to pass the reason for +// a failure or skip directly to Ginkgo in the method intended for that purpose. +type TB interface { + Attr(key, value string) + Chdir(dir string) + Cleanup(func()) + Error(args ...any) + Errorf(format string, args ...any) + Fail() + FailNow() + Failed() bool + Fatal(args ...any) + Fatalf(format string, args ...any) + Helper() + Log(args ...any) + Logf(format string, args ...any) + Name() string + Setenv(key, value string) + Skip(args ...any) + Skipf(format string, args ...any) + SkipNow() + Skipped() bool + TempDir() string +} + +// ContextTB adds support for cleanup callbacks with explicit context +// parameter. This is used when integrating with Ginkgo: then CleanupCtx +// gets implemented via ginkgo.DeferCleanup. +type ContextTB interface { + TB + CleanupCtx(func(ctx context.Context)) +} + +// Init can be called in a unit or integration test to create +// a test context which: +// - has a per-test logger with verbosity derived from the -v command line flag +// - gets canceled when the test finishes (via [TB.Cleanup]) +// +// Note that the test context supports the interfaces of [TB] and +// [context.Context] and thus can be used like one of those where needed. +// It also has additional methods for retrieving the logger and canceling +// the context early, which can be useful in tests which want to wait +// for goroutines to terminate after cancellation. +// +// If the [TB] implementation also implements [ContextTB], then +// [TContext.CleanupCtx] uses [ContextTB.CleanupCtx] and uses +// the context passed into that callback. This can be used to let +// Ginkgo create a fresh context for cleanup code. +// +// Can be called more than once per test to get different contexts with +// independent cancellation. The default behavior describe above can be +// modified via optional functional options defined in [initoption]. +func Init(tb TB, opts ...InitOption) TContext { + tb.Helper() + + c := internal.InitConfig{ + PerTestOutput: true, + } + for _, opt := range opts { + opt(&c) + } + + // We don't need a Deadline implementation, testing.B doesn't have it. + // But if we have one, we'll use it to set a timeout shortly before + // the deadline. This needs to come before we wrap tb. + deadlineTB, deadlineOK := tb.(interface { + Deadline() (time.Time, bool) + }) + + ctx := defaultProgressReporter.init(tb) + var header func() string + if c.PerTestOutput { + logger := newLogger(tb, c.BufferLogs) + ctx = klog.NewContext(ctx, logger) + header = klogHeader + } + + var cancelTimeout func(cause string) + if deadlineOK { + if deadline, ok := deadlineTB.Deadline(); ok { + timeLeft := time.Until(deadline) + timeLeft -= CleanupGracePeriod + ctx, cancelTimeout = withTimeout(ctx, tb, timeLeft, fmt.Sprintf("test suite deadline (%s) is close, need to clean up before the %s cleanup grace period", deadline.Truncate(time.Second), CleanupGracePeriod)) + } + } + + // Construct new TContext with context and settings as determined above. + tCtx := InitCtx(ctx, tb) + if cancelTimeout != nil { + tCtx.cancel = cancelTimeout + } else { + tCtx = tCtx.WithCancel() + tCtx.Cleanup(func() { + tCtx.Cancel(cleanupErr(tCtx.Name()).Error()) + }) + } + tCtx.perTestHeader = header + + return tCtx +} + +func newLogger(tb TB, bufferLogs bool) klog.Logger { + config := ktesting.NewConfig( + ktesting.AnyToString(func(v interface{}) string { + // For basic types where the string + // representation is "obvious" we use + // fmt.Sprintf because format.Object always + // adds a <"type"> prefix, which is too long + // for simple values. + switch v := v.(type) { + case int, int32, int64, uint, uint32, uint64, float32, float64, bool: + return fmt.Sprintf("%v", v) + case string: + return v + default: + return strings.TrimSpace(format.Object(v, 1)) + } + }), + ktesting.VerbosityFlagName("v"), + ktesting.VModuleFlagName("vmodule"), + ktesting.BufferLogs(bufferLogs), + ) + + // Copy klog settings instead of making the ktesting logger + // configurable directly. + var fs flag.FlagSet + config.AddFlags(&fs) + for _, name := range []string{"v", "vmodule"} { + from := flag.CommandLine.Lookup(name) + to := fs.Lookup(name) + if err := to.Value.Set(from.Value.String()); err != nil { + panic(err) + } + } + + // Ensure consistent logging: this klog.Logger writes to tb, adding the + // date/time header, and our own wrapper emulates that behavior for + // Log/Logf/... + logger := ktesting.NewLogger(tb, config) + return logger +} + +type InitOption = initoption.InitOption + +// InitCtx is a variant of [Init] which uses an already existing context and +// whatever logger and timeouts are stored there. +// Functional options are part of the API, but currently +// there are none which have an effect. +func InitCtx(ctx context.Context, tb TB, _ ...InitOption) TContext { + return TContext{ + Context: ctx, + testingTB: testingTB{TB: tb}, + } +} + +// withTB constructs a new TContext with a different TB instance. +// +// This is used internally to set up some of the context, in particular +// clients, in the root test and then run sub-tests: +// +// func TestSomething(t *testing.T) { +// tCtx := ktesting.Init(t) +// ... +// tCtx = ktesting.WithRESTConfig(tCtx, config) +// +// t.Run("sub", func (t *testing.T) { +// tCtx := ktesting.WithTB(tCtx, t) +// ... +// }) +// +// withTB sets up cancellation for the sub-test and uses per-test output. +func (tCtx TContext) withTB(tb TB) TContext { + tCtx.testingTB.TB = tb + if tCtx.perTestHeader != nil { + logger := newLogger(tb, false /* don't buffer logs in sub-test */) + tCtx.Context = klog.NewContext(tCtx.Context, logger) + } + return tCtx.WithCancel() +} + +// run implements the different Run and SyncTest methods. It's not an exported +// method because tCtx.Run is more discoverable (same usage as +// with normal Go). +func run(tCtx TContext, name string, syncTest bool, cb func(tCtx TContext)) bool { + tCtx.Helper() + switch tb := tCtx.TB().(type) { + case *testing.T: + if syncTest { + f := func(t *testing.T) { + // We must not propagate the parent's + // cancellation channel into the bubble, + // it causes "panic: receive on synctest channel from outside bubble". + // + // Sync tests shouldn't need the overall suite timeout, + // so this seems okay. + tCtx.isSyncTest = true + tCtx = tCtx.WithoutCancel().withTB(t) + cb(tCtx) + } + if name != "" { + return tb.Run(name, func(t *testing.T) { synctest.Test(t, f) }) + } + synctest.Test(tb, f) + return true + } + return tb.Run(name, func(t *testing.T) { + cb(tCtx.withTB(t)) + }) + case *testing.B: + if !syncTest { + return tb.Run(name, func(b *testing.B) { + cb(tCtx.withTB(b)) + }) + } + } + + what := "Run" + if syncTest { + what = "SyncTest" + } + tCtx.Fatalf("%s not implemented, underlying %T does not support it", what, tCtx.TB()) + + return false +} + +// WithContext constructs a new TContext with a different Context instance. +// This can be used in callbacks which receive a Context, for example +// from Gomega: +// +// gomega.Eventually(tCtx, func(ctx context.Context) { +// tCtx := ktesting.WithContext(tCtx, ctx) +// ... +// +// This is important because the Context in the callback could have +// a different deadline than in the parent TContext. +func (tCtx TContext) WithContext(ctx context.Context) TContext { + logger := tCtx.Logger() + tCtx.Context = ctx + if _, err := logr.FromContext(ctx); err != nil { + // Keep using the logger from the parent context. + tCtx = tCtx.WithLogger(logger) + } + return tCtx +} + +// WithValue wraps [context.WithValue] such that the result is again a TContext. +func (tCtx TContext) WithValue(key, val any) TContext { + ctx := context.WithValue(tCtx, key, val) + return tCtx.WithContext(ctx) +} + +// TContext implements [context.Context], [testing.TB] and some additional +// methods. [TContext] is the public pointer type for referencing a TC. +// Variables are usually called tCtx. To ensure that test code does not +// use `t` directly unintentionally, it is recommended to use two functions: +// +// func TestSomething(t *testing.T) { testSomething(ktesting.Init(t)) } +// func testSomething(tCtx ktesting.TContext) { ... } +// +// Log output is associated with the current test and includes a header similar +// to klog, which enables post-processing to distinguish between log output +// (starts with header) and failure messages (header comes later). Errors +// ([Error], [Errorf]) are recorded with "ERROR" as prefix, fatal errors +// ([Fatal], [Fatalf]) with "FATAL ERROR". Indention is used to ensure that +// follow-up lines belonging to the same log entry can be handled properly +// by post-processing and to make the header stand out more. +// +// tCtx provides features offered by Ginkgo also when using normal Go [testing]: +// - The context contains a deadline that expires soon enough before +// the overall timeout that cleanup code can still run. +// - Cleanup callbacks can get their own, separate contexts when +// registered via [CleanupCtx]. +// - CTRL-C aborts, prints a progress report, and then cleans up +// before terminating. +// - SIGUSR1 prints a progress report without aborting. +// +// Progress reporting is more informative when doing polling with +// [gomega.Eventually] and [gomega.Consistently]. Without that, it +// can only report which tests are active. +type TContext struct { + // Context makes the methods of the underlying context + // available. It must not be modified. + context.Context + + // testingTB makes the methods of the underlying test implementation + // available. Its embedded TB must not be modified. + testingTB + + // perTestHeader is an optional function which produces a klog-like perTestHeader when + // not using some global logger. + perTestHeader func() string + + // for Cancel + cancel func(cause string) + + // steps is a concatenation ("step1: step2: step3: ") of steps passed to WithStep. + // It's empty if there are no steps. + steps string + + // for SyncTest + isSyncTest bool + + // for WithClient + restConfig *rest.Config + restMapper *restmapper.DeferredDiscoveryRESTMapper + client clientset.Interface + dynamic dynamic.Interface + apiextensions apiextensions.Interface + + // for WithNamespace + namespace string + + // capture, if non-nil, changes Error/Errorf/Fatal/Fatalf/Fail/FailNow so + // that they intercept the problem and convert to errors. Log messages + // are passed through. + // + // Used by WithError. + capture *capture +} + +type capture struct { + mutex sync.Mutex + errors []error + failed bool +} + +// testingTB is needed to avoid a name conflict +// between field and method in tContext. +type testingTB struct { + // TB makes the methods of the underlying test implementation available. + // In particular Helper must be called directly, not via a wrapper. + // It must not be modified. + TB +} + +// Parallel signals that this test is to be run in parallel with (and +// only with) other parallel tests. In other words, it needs to be +// called in each test which is meant to run in parallel. +// +// Only supported in Go unit tests, calling it elsewhere causes a test failure. +// +// When a unit test is run multiple times due to use of -test.count or -test.cpu, +// multiple instances of a single test never run in parallel with each other. +func (tCtx TContext) Parallel() { + if tb, ok := tCtx.TB().(interface{ Parallel() }); ok { + tb.Parallel() + } else { + tCtx.Fatalf("Parallel not implemented, underlying %T does not support it", tCtx.TB()) + } +} + +// Cancel can be invoked to cancel the context before the test is completed. +// Tests which use the context to control goroutines and then wait for +// termination of those goroutines must call Cancel to avoid a deadlock. +// +// The cause, if non-empty, is turned into an error which is equivalent +// to context.Canceled. context.Cause will return that error for the +// context. +func (tCtx TContext) Cancel(cause string) { + if tCtx.cancel != nil { + tCtx.cancel(cause) + } +} + +// CleanupCtx registers a callback that will get invoked when the test +// has finished. Callbacks get invoked in last-in-first-out order (LIFO). +// +// Using CleanupCtx is preferred because of the automatic context cancellation. +// The following broken (!) cleanup code will use a canceled context, +// which is not desirable: +// +// // tCtx gets canceled when the test ends and before the callback runs. +// tCtx.Cleanup(func() { /* do something with the test's tCtx */ }) +// +// A safer way to run cleanup code is: +// +// tCtx.CleanupCtx(func (tCtx ktesting.TContext) { /* do something with the cleanup's tCtx */ }) +// +// The logger and clients are the same as in the TContext that CleanupCtx +// is invoked on. +func (tCtx TContext) CleanupCtx(cb func(TContext)) { + tCtx.Helper() + + if tb, ok := tCtx.TB().(ContextTB); ok { + // Use context from base TB (most likely Ginkgo). + tb.CleanupCtx(func(ctx context.Context) { + tCtx := tCtx.WithContext(ctx) + cb(tCtx) + }) + return + } + + tCtx.Cleanup(func() { + // Use new context. This is the code path for "go test". The + // context then has *no* deadline. In the code path above for + // Ginkgo, Ginkgo is more sophisticated and also applies + // timeouts to cleanup calls which accept a context. + childCtx := tCtx.WithContext(context.WithoutCancel(tCtx)) + cb(childCtx) + }) +} + +// Run runs cb as a subtest called name. It blocks until cb returns or +// calls t.Parallel to become a parallel test. +// +// Only supported in Go unit tests or benchmarks. It fails the current +// test when called elsewhere. +func (tCtx TContext) Run(name string, cb func(tCtx TContext)) bool { + return run(tCtx, name, false, cb) +} + +// SyncTest uses [synctest.Test] to execute the callback inside a bubble. +// Creates a new subtest if the name is non-empty, otherwise it creates +// the bubble directly in the current test context. +// +// Only works in Go unit tests. +func (tCtx TContext) SyncTest(name string, cb func(tCtx TContext)) bool { + return run(tCtx, name, true, cb) +} + +// IsSyncTest returns true if the context was created by SyncTest. +// +// Inside such a context, Wait is usable. This can be used in +// code which runs inside synctest bubbles and outside: +// - Inside a bubble, Wait can be used to block until +// background activity has settled down (= "durably blocked"). +// Eventually and Consistently both call Wait and then check +// the condition. +// - Outside, polling or some synchronization mechanism has to be used. +func (tCtx TContext) IsSyncTest() bool { + return tCtx.isSyncTest +} + +// Wait calls [synctest.Wait] and thus ensures that all background +// activity has settled down (= "durably blocked"). +// +// Only works inside a bubble started by SyncTest (can be checked with +// IsSyncTest), panics elsewhere. +func (tCtx TContext) Wait() { + synctest.Wait() +} + +// TB returns the underlying TB. This can be used to "break the glass" +// and cast back into a testing.T or TB. Calling TB is necessary +// because TContext wraps the underlying TB. +// +// For example, in benchmarks it is necessary to cast back to +// a testing.B because not all benchmark-only methods are provided. +// This examples uses separate functions again to ensure that +// b isn't used unintentionally: +// +// func BenchmarkSomething(b *testing.B) { benchmarkSomething(ktesting.Init(b) } +// func benchmarkSomething(tCtx ktesting.TContext) { +// ... set up with tCtx ... +// for tCtx.TB().(*testing.B).Loop() { +// ... +// } +// } +func (tCtx TContext) TB() TB { return tCtx.testingTB.TB } + +// Logger returns a logger for the current test. This is a shortcut +// for calling klog.FromContext. +// +// Output emitted via this logger and the TB interface (like Logf) +// is formatted consistently. The TB interface generates a single +// message string, while Logger enables structured logging and can +// be passed down into code which expects a logger. +// +// To skip intermediate helper functions during stack unwinding, +// TB.Helper can be called in those functions. +func (tCtx TContext) Logger() klog.Logger { + return klog.FromContext(tCtx.Context) +} + +// RESTConfig returns a copy of the config for a rest client with the UserAgent +// set to include the current test name or nil if not available. Several typed +// clients using this config are available through [Client], [Dynamic], +// [APIExtensions]. +func (tCtx TContext) RESTConfig() *rest.Config { + return rest.CopyConfig(tCtx.restConfig) +} + +func (tCtx TContext) RESTMapper() *restmapper.DeferredDiscoveryRESTMapper { return tCtx.restMapper } +func (tCtx TContext) Client() clientset.Interface { return tCtx.client } +func (tCtx TContext) Dynamic() dynamic.Interface { return tCtx.dynamic } +func (tCtx TContext) APIExtensions() apiextensions.Interface { return tCtx.apiextensions } + +// Expect wraps [gomega.Expect] such that a failure will be reported via +// [TContext.Fatal]. As with [gomega.Expect], additional values +// may get passed. Those values then all must be nil for the assertion +// to pass. This can be used with functions which return a value +// plus error. The error gets checked automatically. +// +// myAmazingThing := func(int, error) { ...} +// tCtx.Expect(myAmazingThing()).Should(gomega.Equal(1)) +func (tCtx TContext) Expect(actual interface{}, extra ...interface{}) gomega.Assertion { + return gomegaAssertion(tCtx, true, actual, extra...) +} + +// Require is an alias for Expect. +func (tCtx TContext) Require(actual interface{}, extra ...interface{}) gomega.Assertion { + return gomegaAssertion(tCtx, true, actual, extra...) +} + +// Assert also wraps [gomega.Expect], but in contrast to Expect = Require, +// it reports a failure through [TContext.Error]. This makes it possible +// to test several different assertions. +func (tCtx TContext) Assert(actual interface{}, extra ...interface{}) gomega.Assertion { + return gomegaAssertion(tCtx, false, actual, extra...) +} + +// WithNamespace creates a new context with a Kubernetes namespace name for retrieval through [Namespace]. +func (tCtx TContext) WithNamespace(namespace string) TContext { + tCtx.namespace = namespace + return tCtx +} + +// Namespace returns the Kubernetes namespace name that was set previously +// through WithNamespace and the empty string if none is available. +// +// This namespace is the one to be used by tests which need to create namespace-scoped +// objects. The name is guaranteed to be unique for the test context, so tests running +// in parallel need to be set up so that each test has its own namespace. +func (tCtx TContext) Namespace() string { + return tCtx.namespace +} diff --git a/vendor/k8s.io/kubernetes/test/utils/ktesting/withcontext.go b/vendor/k8s.io/kubernetes/test/utils/ktesting/withcontext.go new file mode 100644 index 0000000000..adfb7a13a8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/ktesting/withcontext.go @@ -0,0 +1,73 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ktesting + +import ( + "context" + "time" + + "k8s.io/klog/v2" +) + +// WithCancel sets up cancellation in a [TContext.Cleanup] callback and +// constructs a new TContext where [TContext.Cancel] cancels only the new +// context. +func (tCtx TContext) WithCancel() TContext { + ctx, cancel := context.WithCancelCause(tCtx) + + tCtx.Context = ctx + tCtx.cancel = func(cause string) { + var cancelCause error + if cause != "" { + cancelCause = canceledError(cause) + } + cancel(cancelCause) + } + return tCtx +} + +// WithoutCancel causes the returned context to ignore cancellation of its parent. +// Calling Cancel will only cancel the new context. +// This matches [context.WithoutCancel]. +func (tCtx TContext) WithoutCancel() TContext { + ctx := context.WithoutCancel(tCtx) + + tCtx.Context = ctx + tCtx = tCtx.WithCancel() // Re-create a cancelable TContext. + return tCtx +} + +// WithTimeout sets up new context with a timeout. Canceling the timeout gets +// registered in a cleanup callback. [TContext.Cancel] cancels only +// the new context. The cause is used as reason why the context is canceled +// once the timeout is reached. It may be empty, in which case the usual +// "context canceled" error is used. +func (tCtx TContext) WithTimeout(timeout time.Duration, timeoutCause string) TContext { + ctx, cancel := withTimeout(tCtx, tCtx.TB(), timeout, timeoutCause) + + tCtx.Context = ctx + tCtx.cancel = cancel + return tCtx +} + +// WithLogger constructs a new context with a different logger. +func (tCtx TContext) WithLogger(logger klog.Logger) TContext { + ctx := klog.NewContext(tCtx, logger) + + tCtx.Context = ctx + return tCtx +} diff --git a/vendor/k8s.io/kubernetes/test/utils/runners.go b/vendor/k8s.io/kubernetes/test/utils/runners.go index 62c769f040..51c2c6587d 100644 --- a/vendor/k8s.io/kubernetes/test/utils/runners.go +++ b/vendor/k8s.io/kubernetes/test/utils/runners.go @@ -734,7 +734,7 @@ func StartPods(c clientset.Interface, replicas int, namespace string, podNamePre panic("StartPods: number of replicas must be non-zero") } startPodsID := string(uuid.NewUUID()) // So that we can label and find them - for i := 0; i < replicas; i++ { + for i := range replicas { podName := fmt.Sprintf("%v-%v", podNamePrefix, i) pod.ObjectMeta.Name = podName pod.ObjectMeta.Labels["name"] = podName @@ -1048,7 +1048,7 @@ func DoPrepareNode(ctx context.Context, client clientset.Interface, node *v1.Nod if len(patch) == 0 { return nil } - for attempt := 0; attempt < retries; attempt++ { + for range retries { if _, err = client.CoreV1().Nodes().Patch(ctx, node.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err == nil { break } @@ -1061,7 +1061,7 @@ func DoPrepareNode(ctx context.Context, client clientset.Interface, node *v1.Nod return fmt.Errorf("too many conflicts when applying patch %v to Node %v: %s", string(patch), node.Name, err) } - for attempt := 0; attempt < retries; attempt++ { + for range retries { if err = strategy.PrepareDependentObjects(ctx, node, client); err == nil { break } diff --git a/vendor/k8s.io/kubernetes/test/utils/update_resources.go b/vendor/k8s.io/kubernetes/test/utils/update_resources.go index af5a59fc2f..1cccaa07c7 100644 --- a/vendor/k8s.io/kubernetes/test/utils/update_resources.go +++ b/vendor/k8s.io/kubernetes/test/utils/update_resources.go @@ -50,7 +50,7 @@ func ScaleResourceWithRetries(scalesGetter scaleclient.ScalesGetter, namespace, ResourceVersion: "", } waitForReplicas := scale.NewRetryParams(waitRetryInterval, waitRetryTimeout) - cond := RetryErrorCondition(scale.ScaleCondition(scaler, preconditions, namespace, name, size, nil, gvr, false)) + cond := RetryErrorCondition(scale.ScaleCondition(scaler, preconditions, namespace, name, size, nil, nil, gvr, false)) err := wait.PollUntilContextTimeout(context.Background(), updateRetryInterval, updateRetryTimeout, true, cond) if err == nil { err = scale.WaitForScaleHasDesiredReplicas(scalesGetter, gvr.GroupResource(), name, namespace, size, waitForReplicas) diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go index 28be1d2e87..59068c7f3d 100644 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go +++ b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux package apparmor diff --git a/vendor/k8s.io/mount-utils/mount_helper_unix.go b/vendor/k8s.io/mount-utils/mount_helper_unix.go index 6c74eb9ca7..8b2a4d6f2f 100644 --- a/vendor/k8s.io/mount-utils/mount_helper_unix.go +++ b/vendor/k8s.io/mount-utils/mount_helper_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/mount_helper_windows.go b/vendor/k8s.io/mount-utils/mount_helper_windows.go index 995fd5a0cd..8eed7a94c3 100644 --- a/vendor/k8s.io/mount-utils/mount_helper_windows.go +++ b/vendor/k8s.io/mount-utils/mount_helper_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2019 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/mount_linux.go b/vendor/k8s.io/mount-utils/mount_linux.go index 9c0b6d554f..c74a4f2f2c 100644 --- a/vendor/k8s.io/mount-utils/mount_linux.go +++ b/vendor/k8s.io/mount-utils/mount_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/mount_unsupported.go b/vendor/k8s.io/mount-utils/mount_unsupported.go index 0345904a01..9dc7d81d17 100644 --- a/vendor/k8s.io/mount-utils/mount_unsupported.go +++ b/vendor/k8s.io/mount-utils/mount_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows /* Copyright 2014 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/mount_windows.go b/vendor/k8s.io/mount-utils/mount_windows.go index 682cb0f011..d63c182cca 100644 --- a/vendor/k8s.io/mount-utils/mount_windows.go +++ b/vendor/k8s.io/mount-utils/mount_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows /* Copyright 2017 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/resizefs_linux.go b/vendor/k8s.io/mount-utils/resizefs_linux.go index 3eaf46a49a..79712c005d 100644 --- a/vendor/k8s.io/mount-utils/resizefs_linux.go +++ b/vendor/k8s.io/mount-utils/resizefs_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/mount-utils/resizefs_unsupported.go b/vendor/k8s.io/mount-utils/resizefs_unsupported.go index 88b8b2410b..813e4a3eb5 100644 --- a/vendor/k8s.io/mount-utils/resizefs_unsupported.go +++ b/vendor/k8s.io/mount-utils/resizefs_unsupported.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* Copyright 2021 The Kubernetes Authors. diff --git a/vendor/k8s.io/pod-security-admission/policy/registry.go b/vendor/k8s.io/pod-security-admission/policy/registry.go index 1648ff020c..aa9ea5b2b0 100644 --- a/vendor/k8s.io/pod-security-admission/policy/registry.go +++ b/vendor/k8s.io/pod-security-admission/policy/registry.go @@ -18,7 +18,7 @@ package policy import ( "fmt" - "sort" + "slices" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -163,8 +163,8 @@ func populate(r *checkRegistry, validChecks []Check) { } // Sort the IDs to maintain consistent error messages. - sort.Slice(restrictedIDs, func(i, j int) bool { return restrictedIDs[i] < restrictedIDs[j] }) - sort.Slice(baselineIDs, func(i, j int) bool { return baselineIDs[i] < baselineIDs[j] }) + slices.Sort(restrictedIDs) + slices.Sort(baselineIDs) orderedIDs := append(baselineIDs, restrictedIDs...) // Baseline checks first, then restricted. for v := api.MajorMinorVersion(1, 0); v.Older(nextMinor(r.maxVersion)); v = nextMinor(v) { diff --git a/vendor/k8s.io/pod-security-admission/test/fixtures_procMount.go b/vendor/k8s.io/pod-security-admission/test/fixtures_procMount.go index 73917dd164..d1733b02ca 100644 --- a/vendor/k8s.io/pod-security-admission/test/fixtures_procMount.go +++ b/vendor/k8s.io/pod-security-admission/test/fixtures_procMount.go @@ -18,7 +18,6 @@ package test import ( corev1 "k8s.io/api/core/v1" - "k8s.io/component-base/featuregate" "k8s.io/pod-security-admission/api" "k8s.io/utils/ptr" ) @@ -38,7 +37,6 @@ func init() { }), } }, - failRequiresFeatures: []featuregate.Feature{"ProcMountType"}, generateFail: func(p *corev1.Pod) []*corev1.Pod { p = ensureSecurityContext(p) return []*corev1.Pod{ @@ -89,8 +87,7 @@ func init() { return retval }, - failRequiresFeatures: []featuregate.Feature{"ProcMountType"}, - failRequiresError: true, // the only combination that can fail the 1.35 baseline check also fails validation + failRequiresError: true, // the only combination that can fail the 1.35 baseline check also fails validation generateFail: func(p *corev1.Pod) []*corev1.Pod { p = ensureSecurityContext(p) return []*corev1.Pod{ @@ -129,7 +126,6 @@ func init() { }), } }, - failRequiresFeatures: []featuregate.Feature{"ProcMountType"}, generateFail: func(p *corev1.Pod) []*corev1.Pod { p = ensureSecurityContext(p) return []*corev1.Pod{ diff --git a/vendor/github.com/libopenstorage/openstorage/LICENSE b/vendor/k8s.io/streaming/LICENSE similarity index 94% rename from vendor/github.com/libopenstorage/openstorage/LICENSE rename to vendor/k8s.io/streaming/LICENSE index bcab93af98..d645695673 100644 --- a/vendor/github.com/libopenstorage/openstorage/LICENSE +++ b/vendor/k8s.io/streaming/LICENSE @@ -176,7 +176,18 @@ END OF TERMS AND CONDITIONS - Copyright 2015 Openstorage.org. + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/doc.go b/vendor/k8s.io/streaming/pkg/httpstream/doc.go similarity index 75% rename from vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/doc.go rename to vendor/k8s.io/streaming/pkg/httpstream/doc.go index 06fd344c01..1da83f14b1 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/doc.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2015 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. @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated typed clients. -package v2beta1 +// Package httpstream adds multiplexed streaming support to HTTP requests and +// responses via connection upgrades. +package httpstream diff --git a/vendor/k8s.io/streaming/pkg/httpstream/httpstream.go b/vendor/k8s.io/streaming/pkg/httpstream/httpstream.go new file mode 100644 index 0000000000..a7c8d897dc --- /dev/null +++ b/vendor/k8s.io/streaming/pkg/httpstream/httpstream.go @@ -0,0 +1,201 @@ +/* +Copyright 2015 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 httpstream + +import ( + "errors" + "fmt" + "io" + "net/http" + "strings" + "time" +) + +const ( + HeaderConnection = "Connection" + HeaderUpgrade = "Upgrade" + HeaderProtocolVersion = "X-Stream-Protocol-Version" + HeaderAcceptedProtocolVersions = "X-Accepted-Stream-Protocol-Versions" +) + +// NewStreamHandler defines a function that is called when a new Stream is +// received. If no error is returned, the Stream is accepted; otherwise, +// the stream is rejected. After the reply frame has been sent, replySent is closed. +type NewStreamHandler func(stream Stream, replySent <-chan struct{}) error + +// NoOpNewStreamHandler is a stream handler that accepts a new stream and +// performs no other logic. +func NoOpNewStreamHandler(stream Stream, replySent <-chan struct{}) error { return nil } + +// Dialer knows how to open a streaming connection to a server. +type Dialer interface { + + // Dial opens a streaming connection to a server using one of the protocols + // specified (in order of most preferred to least preferred). + Dial(protocols ...string) (Connection, string, error) +} + +// UpgradeRoundTripper is a type of http.RoundTripper that is able to upgrade +// HTTP requests to support multiplexed bidirectional streams. After RoundTrip() +// is invoked, if the upgrade is successful, clients may retrieve the upgraded +// connection by calling UpgradeRoundTripper.Connection(). +type UpgradeRoundTripper interface { + http.RoundTripper + // NewConnection validates the response and creates a new Connection. + NewConnection(resp *http.Response) (Connection, error) +} + +// ResponseUpgrader knows how to upgrade HTTP requests and responses to +// add streaming support to them. +type ResponseUpgrader interface { + // UpgradeResponse upgrades an HTTP response to one that supports multiplexed + // streams. newStreamHandler will be called asynchronously whenever the + // other end of the upgraded connection creates a new stream. + UpgradeResponse(w http.ResponseWriter, req *http.Request, newStreamHandler NewStreamHandler) Connection +} + +// Connection represents an upgraded HTTP connection. +type Connection interface { + // CreateStream creates a new Stream with the supplied headers. + CreateStream(headers http.Header) (Stream, error) + // Close resets all streams and closes the connection. + Close() error + // CloseChan returns a channel that is closed when the underlying connection is closed. + CloseChan() <-chan bool + // SetIdleTimeout sets the amount of time the connection may remain idle before + // it is automatically closed. + SetIdleTimeout(timeout time.Duration) + // RemoveStreams can be used to remove a set of streams from the Connection. + RemoveStreams(streams ...Stream) +} + +// Stream represents a bidirectional communications channel that is part of an +// upgraded connection. +type Stream interface { + io.ReadWriteCloser + // Reset closes both directions of the stream, indicating that neither client + // or server can use it any more. + Reset() error + // Headers returns the headers used to create the stream. + Headers() http.Header + // Identifier returns the stream's ID. + Identifier() uint32 +} + +// UpgradeFailureError encapsulates the cause for why the streaming +// upgrade request failed. Implements error interface. +type UpgradeFailureError struct { + Cause error +} + +func (u *UpgradeFailureError) Error() string { + return fmt.Sprintf("unable to upgrade streaming request: %s", u.Cause) +} + +// IsUpgradeFailure returns true if the passed error is (or wrapped error contains) +// the UpgradeFailureError. +func IsUpgradeFailure(err error) bool { + if err == nil { + return false + } + var upgradeErr *UpgradeFailureError + return errors.As(err, &upgradeErr) +} + +// isHTTPSProxyError returns true if error is Gorilla/Websockets HTTPS Proxy dial error; +// false otherwise (see https://github.com/kubernetes/kubernetes/issues/126134). +func IsHTTPSProxyError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "proxy: unknown scheme: https") +} + +// IsUpgradeRequest returns true if the given request is a connection upgrade request +func IsUpgradeRequest(req *http.Request) bool { + for _, h := range req.Header[http.CanonicalHeaderKey(HeaderConnection)] { + if strings.Contains(strings.ToLower(h), strings.ToLower(HeaderUpgrade)) { + return true + } + } + return false +} + +func negotiateProtocol(clientProtocols, serverProtocols []string) string { + for i := range clientProtocols { + for j := range serverProtocols { + if clientProtocols[i] == serverProtocols[j] { + return clientProtocols[i] + } + } + } + return "" +} + +func commaSeparatedHeaderValues(header []string) []string { + var parsedClientProtocols []string + for i := range header { + for _, clientProtocol := range strings.Split(header[i], ",") { + if proto := strings.Trim(clientProtocol, " "); len(proto) > 0 { + parsedClientProtocols = append(parsedClientProtocols, proto) + } + } + } + return parsedClientProtocols +} + +// Handshake performs a subprotocol negotiation. If the client did request a +// subprotocol, Handshake will select the first common value found in +// serverProtocols, otherwise it will return an error and write an HTTP BadRequest to the response. +// If a match is found, Handshake adds a response header indicating the chosen subprotocol. +// If no match is found, HTTP forbidden is returned, along with a response header containing +// the list of protocols the server can accept. +func Handshake(req *http.Request, w http.ResponseWriter, serverProtocols []string) (string, error) { + if len(serverProtocols) == 0 { + panic(fmt.Errorf("unable to upgrade: serverProtocols is required")) + } + values, ok := req.Header[http.CanonicalHeaderKey(HeaderProtocolVersion)] + if !ok { + err := fmt.Errorf("unable to upgrade: header %s does not exist in request with %d headers", HeaderProtocolVersion, len(req.Header)) + http.Error(w, err.Error(), http.StatusBadRequest) + return "", err + } + if len(values) == 0 { + err := fmt.Errorf("unable to upgrade: header %s is empty", HeaderProtocolVersion) + http.Error(w, err.Error(), http.StatusBadRequest) + return "", err + } + clientProtocols := commaSeparatedHeaderValues(values) + if len(clientProtocols) == 0 { + err := fmt.Errorf("unable to upgrade: header %s contains %s, but no valid protocols", HeaderProtocolVersion, values) + http.Error(w, err.Error(), http.StatusBadRequest) + return "", err + } + + negotiatedProtocol := negotiateProtocol(clientProtocols, serverProtocols) + if len(negotiatedProtocol) == 0 { + for i := range serverProtocols { + w.Header().Add(HeaderAcceptedProtocolVersions, serverProtocols[i]) + } + err := fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols) + http.Error(w, err.Error(), http.StatusForbidden) + return "", err + } + + w.Header().Add(HeaderProtocolVersion, negotiatedProtocol) + return negotiatedProtocol, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go b/vendor/k8s.io/streaming/pkg/httpstream/spdy/connection.go similarity index 97% rename from vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go rename to vendor/k8s.io/streaming/pkg/httpstream/spdy/connection.go index d4ceab84f0..4a4003b62b 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/spdy/connection.go @@ -23,8 +23,8 @@ import ( "time" "github.com/moby/spdystream" - "k8s.io/apimachinery/pkg/util/httpstream" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" ) // connection maintains state about a spdystream.Connection and its associated @@ -169,6 +169,7 @@ func (c *connection) newSpdyStream(stream *spdystream.Stream) { err := c.newStreamHandler(stream, replySent) rejectStream := (err != nil) if rejectStream { + //nolint:logcheck // Hopefully this never gets triggered. klog.Warningf("Stream rejected: %v", err) stream.Reset() return @@ -195,6 +196,7 @@ func (c *connection) sendPings(period time.Duration) { case <-t.C: } if _, err := c.ping(); err != nil { + //nolint:logcheck // Hopefully this never gets triggered. klog.V(3).Infof("SPDY Ping failed: %v", err) // Continue, in case this is a transient failure. // c.conn.CloseChan above will tell us when the connection is diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go b/vendor/k8s.io/streaming/pkg/httpstream/spdy/roundtripper.go similarity index 65% rename from vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go rename to vendor/k8s.io/streaming/pkg/httpstream/spdy/roundtripper.go index ed131d112f..41cd65f64f 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/spdy/roundtripper.go @@ -21,6 +21,7 @@ import ( "context" "crypto/tls" "encoding/base64" + "encoding/json" "errors" "fmt" "io" @@ -28,18 +29,13 @@ import ( "net/http" "net/http/httputil" "net/url" + "os" "strings" "time" "golang.org/x/net/proxy" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/httpstream" - utilnet "k8s.io/apimachinery/pkg/util/net" - apiproxy "k8s.io/apimachinery/pkg/util/proxy" - "k8s.io/apimachinery/third_party/forked/golang/netutil" + "k8s.io/streaming/pkg/httpstream" + utilnet "k8s.io/utils/net" ) // SpdyRoundTripper knows how to upgrade an HTTP request to one that supports @@ -62,7 +58,8 @@ type SpdyRoundTripper struct { // Dialer is the dialer used to connect. Used if non-nil. Dialer *net.Dialer - // proxier knows which proxy to use given a request, defaults to http.ProxyFromEnvironment + // proxier knows which proxy to use given a request, defaults to a proxier that + // preserves NO_PROXY CIDR behavior while delegating to http.ProxyFromEnvironment. // Used primarily for mocking the proxy discovery in tests. proxier func(req *http.Request) (*url.URL, error) @@ -75,9 +72,19 @@ type SpdyRoundTripper struct { upgradeTransport http.RoundTripper } -var _ utilnet.TLSClientConfigHolder = &SpdyRoundTripper{} +type tlsClientConfigHolder interface { + TLSClientConfig() *tls.Config +} + +type roundTripperWrapper interface { + http.RoundTripper + WrappedRoundTripper() http.RoundTripper +} + +type dialFunc func(ctx context.Context, network, addr string) (net.Conn, error) + +var _ tlsClientConfigHolder = &SpdyRoundTripper{} var _ httpstream.UpgradeRoundTripper = &SpdyRoundTripper{} -var _ utilnet.Dialer = &SpdyRoundTripper{} // NewRoundTripper creates a new SpdyRoundTripper that will use the specified // tlsConfig. @@ -106,14 +113,14 @@ func NewRoundTripperWithConfig(cfg RoundTripperConfig) (*SpdyRoundTripper, error if cfg.TLS != nil || cfg.Proxier != nil { return nil, fmt.Errorf("SpdyRoundTripper: UpgradeTransport is mutually exclusive to TLSConfig or Proxier") } - tlsConfig, err := utilnet.TLSClientConfig(cfg.UpgradeTransport) + tlsConfig, err := tlsConfigForTransport(cfg.UpgradeTransport) if err != nil { - return nil, fmt.Errorf("SpdyRoundTripper: Unable to retrieve TLSConfig from UpgradeTransport: %v", err) + return nil, fmt.Errorf("SpdyRoundTripper: unable to retrieve TLS config from UpgradeTransport: %w", err) } cfg.TLS = tlsConfig } if cfg.Proxier == nil { - cfg.Proxier = utilnet.NewProxierWithNoProxyCIDR(http.ProxyFromEnvironment) + cfg.Proxier = newProxierWithNoProxyCIDR(http.ProxyFromEnvironment) } return &SpdyRoundTripper{ tlsConfig: cfg.TLS, @@ -123,6 +130,47 @@ func NewRoundTripperWithConfig(cfg RoundTripperConfig) (*SpdyRoundTripper, error }, nil } +// newProxierWithNoProxyCIDR preserves CIDR matching in NO_PROXY/no_proxy while +// delegating all other behavior to the supplied proxy function. +func newProxierWithNoProxyCIDR(delegate func(req *http.Request) (*url.URL, error)) func(req *http.Request) (*url.URL, error) { + noProxyEnv := os.Getenv("NO_PROXY") + if noProxyEnv == "" { + noProxyEnv = os.Getenv("no_proxy") + } + noProxyRules := strings.Split(noProxyEnv, ",") + + cidrs := make([]*net.IPNet, 0, len(noProxyRules)) + for _, noProxyRule := range noProxyRules { + noProxyRule = strings.TrimSpace(noProxyRule) + if noProxyRule == "" { + continue + } + _, cidr, err := utilnet.ParseCIDRSloppy(noProxyRule) + if err == nil { + cidrs = append(cidrs, cidr) + } + } + + if len(cidrs) == 0 { + return delegate + } + + return func(req *http.Request) (*url.URL, error) { + ip := utilnet.ParseIPSloppy(req.URL.Hostname()) + if ip == nil { + return delegate(req) + } + + for _, cidr := range cidrs { + if cidr.Contains(ip) { + return nil, nil + } + } + + return delegate(req) + } +} + // RoundTripperConfig is a set of options for an SpdyRoundTripper. type RoundTripperConfig struct { // TLS configuration used by the round tripper if UpgradeTransport not present. @@ -144,12 +192,12 @@ func (s *SpdyRoundTripper) TLSClientConfig() *tls.Config { return s.tlsConfig } -// Dial implements k8s.io/apimachinery/pkg/util/net.Dialer. +// Dial opens a network connection for an upgrade request. func (s *SpdyRoundTripper) Dial(req *http.Request) (net.Conn, error) { var conn net.Conn var err error if s.upgradeTransport != nil { - conn, err = apiproxy.DialURL(req.Context(), req.URL, s.upgradeTransport) + conn, err = dialURLWithTransport(req.Context(), req.URL, s.upgradeTransport) } else { conn, err = s.dial(req) } @@ -190,7 +238,7 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) { // dialWithHttpProxy dials the host specified by url through an http or an https proxy. func (s *SpdyRoundTripper) dialWithHttpProxy(req *http.Request, proxyURL *url.URL) (net.Conn, error) { // ensure we use a canonical host with proxyReq - targetHost := netutil.CanonicalAddr(req.URL) + targetHost := canonicalAddr(req.URL) // proxying logic adapted from http://blog.h6t.eu/post/74098062923/golang-websocket-with-http-proxy-support proxyReq := http.Request{ @@ -234,8 +282,8 @@ func (s *SpdyRoundTripper) dialWithHttpProxy(req *http.Request, proxyURL *url.UR // dialWithSocks5Proxy dials the host specified by url through a socks5 proxy. func (s *SpdyRoundTripper) dialWithSocks5Proxy(req *http.Request, proxyURL *url.URL) (net.Conn, error) { // ensure we use a canonical host with proxyReq - targetHost := netutil.CanonicalAddr(req.URL) - proxyDialAddr := netutil.CanonicalAddr(proxyURL) + targetHost := canonicalAddr(req.URL) + proxyDialAddr := canonicalAddr(proxyURL) var auth *proxy.Auth if proxyURL.User != nil { @@ -304,7 +352,7 @@ func (s *SpdyRoundTripper) tlsConn(ctx context.Context, rwc net.Conn, targetHost // dialWithoutProxy dials the host specified by url, using TLS if appropriate. func (s *SpdyRoundTripper) dialWithoutProxy(ctx context.Context, url *url.URL) (net.Conn, error) { - dialAddr := netutil.CanonicalAddr(url) + dialAddr := canonicalAddr(url) dialer := s.Dialer if dialer == nil { dialer = &net.Dialer{} @@ -336,7 +384,8 @@ func (s *SpdyRoundTripper) proxyAuth(proxyURL *url.URL) string { // clients may call SpdyRoundTripper.Connection() to retrieve the upgraded // connection. func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - req = utilnet.CloneRequest(req) + req = req.Clone(req.Context()) + req.Header = req.Header.Clone() req.Header.Add(httpstream.HeaderConnection, httpstream.HeaderUpgrade) req.Header.Add(httpstream.HeaderUpgrade, HeaderSpdy31) @@ -365,35 +414,159 @@ func (s *SpdyRoundTripper) NewConnection(resp *http.Response) (httpstream.Connec upgradeHeader := strings.ToLower(resp.Header.Get(httpstream.HeaderUpgrade)) if (resp.StatusCode != http.StatusSwitchingProtocols) || !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(HeaderSpdy31)) { defer resp.Body.Close() - responseError := "" responseErrorBytes, err := io.ReadAll(resp.Body) if err != nil { - responseError = "unable to read error from server response" - } else { - // TODO: I don't belong here, I should be abstracted from this class - if obj, _, err := statusCodecs.UniversalDecoder().Decode(responseErrorBytes, nil, &metav1.Status{}); err == nil { - if status, ok := obj.(*metav1.Status); ok { - return nil, &apierrors.StatusError{ErrStatus: *status} + return nil, fmt.Errorf("unable to upgrade connection: unable to read error from server response") + } + return nil, fmt.Errorf("unable to upgrade connection: %s", upgradeErrorMessage(responseErrorBytes)) + } + + return NewClientConnectionWithPings(s.conn, s.pingPeriod) +} + +func tlsConfigForTransport(transport http.RoundTripper) (*tls.Config, error) { + if transport == nil { + return nil, nil + } + switch transport := transport.(type) { + case *http.Transport: + return transport.TLSClientConfig, nil + case tlsClientConfigHolder: + return transport.TLSClientConfig(), nil + case roundTripperWrapper: + return tlsConfigForTransport(transport.WrappedRoundTripper()) + default: + return nil, fmt.Errorf("transport %T does not expose TLS client config", transport) + } +} + +func canonicalAddr(url *url.URL) string { + host := url.Hostname() + port := url.Port() + if len(port) == 0 { + switch strings.ToLower(url.Scheme) { + case "http", "ws": + port = "80" + case "https", "wss": + port = "443" + } + } + return net.JoinHostPort(host, port) +} + +func upgradeErrorMessage(responseErrorBytes []byte) string { + type statusLike struct { + Message string `json:"message"` + Error string `json:"error"` + } + + var status statusLike + if err := json.Unmarshal(responseErrorBytes, &status); err == nil { + if msg := strings.TrimSpace(status.Message); msg != "" { + return msg + } + if msg := strings.TrimSpace(status.Error); msg != "" { + return msg + } + } + + msg := strings.TrimSpace(string(responseErrorBytes)) + if msg == "" { + return "empty server response" + } + return msg +} + +func dialURLWithTransport(ctx context.Context, url *url.URL, transport http.RoundTripper) (net.Conn, error) { + dialAddr := canonicalAddr(url) + + dialer, err := dialerFor(transport) + if err != nil { + dialer = nil + } + + switch url.Scheme { + case "http": + if dialer != nil { + return dialer(ctx, "tcp", dialAddr) + } + var d net.Dialer + return d.DialContext(ctx, "tcp", dialAddr) + case "https": + tlsConfig, err := tlsConfigForTransport(transport) + if err != nil { + tlsConfig = nil + } + + if dialer != nil { + netConn, err := dialer(ctx, "tcp", dialAddr) + if err != nil { + return nil, err + } + + if tlsConfig == nil { + tlsConfig = &tls.Config{InsecureSkipVerify: true} + } else if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { + inferredHost := dialAddr + if host, _, err := net.SplitHostPort(dialAddr); err == nil { + inferredHost = host } + tlsConfigCopy := tlsConfig.Clone() + tlsConfigCopy.ServerName = inferredHost + tlsConfig = tlsConfigCopy + } + + if supportsHTTP11(tlsConfig.NextProtos) { + tlsConfig = tlsConfig.Clone() + tlsConfig.NextProtos = []string{"http/1.1"} } - responseError = string(responseErrorBytes) - responseError = strings.TrimSpace(responseError) + + tlsConn := tls.Client(netConn, tlsConfig) + if err := tlsConn.HandshakeContext(ctx); err != nil { + netConn.Close() + return nil, err + } + return tlsConn, nil } - return nil, fmt.Errorf("unable to upgrade connection: %s", responseError) + tlsDialer := tls.Dialer{Config: tlsConfig} + return tlsDialer.DialContext(ctx, "tcp", dialAddr) + default: + return nil, fmt.Errorf("unknown scheme: %s", url.Scheme) } - - return NewClientConnectionWithPings(s.conn, s.pingPeriod) } -// statusScheme is private scheme for the decoding here until someone fixes the TODO in NewConnection -var statusScheme = runtime.NewScheme() +func dialerFor(transport http.RoundTripper) (dialFunc, error) { + if transport == nil { + return nil, nil + } -// ParameterCodec knows about query parameters used with the meta v1 API spec. -var statusCodecs = serializer.NewCodecFactory(statusScheme) + switch transport := transport.(type) { + case *http.Transport: + if transport.DialContext != nil { + return transport.DialContext, nil + } + if transport.Dial != nil { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + return transport.Dial(network, addr) + }, nil + } + return nil, nil + case roundTripperWrapper: + return dialerFor(transport.WrappedRoundTripper()) + default: + return nil, fmt.Errorf("unknown transport type: %T", transport) + } +} -func init() { - statusScheme.AddUnversionedTypes(metav1.SchemeGroupVersion, - &metav1.Status{}, - ) +func supportsHTTP11(nextProtos []string) bool { + if len(nextProtos) == 0 { + return true + } + for _, proto := range nextProtos { + if proto == "http/1.1" { + return true + } + } + return false } diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go b/vendor/k8s.io/streaming/pkg/httpstream/spdy/upgrade.go similarity index 93% rename from vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go rename to vendor/k8s.io/streaming/pkg/httpstream/spdy/upgrade.go index d30ae2fa3d..df47029f4a 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/spdy/upgrade.go @@ -26,8 +26,8 @@ import ( "sync/atomic" "time" - "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/runtime" ) const HeaderSpdy31 = "SPDY/3.1" @@ -105,14 +105,14 @@ func (u responseUpgrader) UpgradeResponse(w http.ResponseWriter, req *http.Reque conn, bufrw, err := hijacker.Hijack() if err != nil { - runtime.HandleError(fmt.Errorf("unable to upgrade: error hijacking response: %v", err)) + runtime.HandleErrorWithContext(req.Context(), err, "Unable to upgrade: error hijacking response") return nil } connWithBuf := &connWrapper{Conn: conn, bufReader: bufrw.Reader} spdyConn, err := NewServerConnectionWithPings(connWithBuf, newStreamHandler, u.pingPeriod) if err != nil { - runtime.HandleError(fmt.Errorf("unable to upgrade: error creating SPDY server connection: %v", err)) + runtime.HandleErrorWithContext(req.Context(), err, "Unable to upgrade: error creating SPDY server connection") return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/conn.go b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/conn.go similarity index 88% rename from vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/conn.go rename to vendor/k8s.io/streaming/pkg/httpstream/wsstream/conn.go index 2e477fee2a..eae80ab4d3 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/conn.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/conn.go @@ -26,11 +26,9 @@ import ( "golang.org/x/net/websocket" - "k8s.io/apimachinery/pkg/util/httpstream" - "k8s.io/apimachinery/pkg/util/portforward" - "k8s.io/apimachinery/pkg/util/remotecommand" - "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/klog/v2" + "k8s.io/streaming/pkg/httpstream" + "k8s.io/streaming/pkg/runtime" ) const WebSocketProtocolHeader = "Sec-Websocket-Protocol" @@ -65,6 +63,8 @@ const ChannelWebSocketProtocol = "channel.k8s.io" // CLOSE const Base64ChannelWebSocketProtocol = "base64.channel.k8s.io" +const streamCloseSignal = 255 + type codecType int const ( @@ -126,8 +126,16 @@ func IsWebSocketRequestWithTunnelingProtocol(req *http.Request) bool { // IgnoreReceives reads from a WebSocket until it is closed, then returns. If timeout is set, the // read and write deadlines are pushed every time a new message is received. +// +// Contextual logging: IgnoreReceivesWithLogger should be used instead of IgnoreReceives in code which uses contextual logging. func IgnoreReceives(ws *websocket.Conn, timeout time.Duration) { - defer runtime.HandleCrash() + IgnoreReceivesWithLogger(klog.Background(), ws, timeout) +} + +// IgnoreReceivesWithLogger reads from a WebSocket until it is closed, then returns. If timeout is set, the +// read and write deadlines are pushed every time a new message is received. +func IgnoreReceivesWithLogger(logger klog.Logger, ws *websocket.Conn, timeout time.Duration) { + defer runtime.HandleCrashWithLogger(logger) var data []byte for { resetTimeout(ws, timeout) @@ -236,7 +244,7 @@ func (conn *Conn) Open(w http.ResponseWriter, req *http.Request) (string, []io.R // "conn.ready" and then blocks until serving is complete. select { case <-conn.ready: - klog.V(8).Infof("websocket server initialized--serving") + klog.FromContext(req.Context()).V(8).Info("websocket server initialized--serving") case <-serveHTTPComplete: // websocket server returned before completing initialization; cleanup and return error. conn.closeNonThreadSafe() //nolint:errcheck @@ -316,13 +324,13 @@ func (conn *Conn) Close() error { // supports the stream close signal (currently only V5 remotecommand); // false otherwise. func protocolSupportsStreamClose(protocol string) bool { - return protocol == remotecommand.StreamProtocolV5Name + return protocol == "v5.channel.k8s.io" } // protocolSupportsWebsocketTunneling returns true if the passed protocol // is a tunneled Kubernetes spdy protocol; false otherwise. func protocolSupportsWebsocketTunneling(protocol string) bool { - return strings.HasPrefix(protocol, portforward.WebsocketsSPDYTunnelingPrefix) && strings.HasSuffix(protocol, portforward.KubernetesSuffix) + return strings.HasPrefix(protocol, "SPDY/3.1+") && strings.HasSuffix(protocol, ".k8s.io") } // handle implements a websocket handler. @@ -330,30 +338,36 @@ func (conn *Conn) handle(ws *websocket.Conn) { conn.initialize(ws) defer conn.Close() supportsStreamClose := protocolSupportsStreamClose(conn.selectedProtocol) + // conn.handle is typically used on the server-side and thus we have a request, + // but don't assume that and use klog.Background as fallback. + logger := klog.Background() + if req := ws.Request(); req != nil { + logger = klog.FromContext(req.Context()) + } for { conn.resetTimeout() var data []byte if err := websocket.Message.Receive(ws, &data); err != nil { if err != io.EOF { - klog.Errorf("Error on socket receive: %v", err) + logger.Error(err, "Error on socket receive") } break } if len(data) == 0 { continue } - if supportsStreamClose && data[0] == remotecommand.StreamClose { + if supportsStreamClose && data[0] == streamCloseSignal { if len(data) != 2 { - klog.Errorf("Single channel byte should follow stream close signal. Got %d bytes", len(data)-1) + logger.Error(nil, "Single channel byte should follow stream close signal", "receivedLength", len(data)-1) break } else { channel := data[1] if int(channel) >= len(conn.channels) { - klog.Errorf("Close is targeted for a channel %d that is not valid, possible protocol error", channel) + logger.Error(nil, "Close is targeted for a channel that is not valid, possible protocol error", "channel", channel) break } - klog.V(4).Infof("Received half-close signal from client; close %d stream", channel) + logger.V(4).Info("Received half-close signal from client, close stream", "channel", channel) conn.channels[channel].Close() // After first Close, other closes are noop. } continue @@ -364,11 +378,11 @@ func (conn *Conn) handle(ws *websocket.Conn) { } data = data[1:] if int(channel) >= len(conn.channels) { - klog.V(6).Infof("Frame is targeted for a reader %d that is not valid, possible protocol error", channel) + logger.V(6).Info("Frame is targeted for a reader that is not valid, possible protocol error", "channel", channel) continue } if _, err := conn.channels[channel].DataFromSocket(data); err != nil { - klog.Errorf("Unable to write frame (%d bytes) to %d: %v", len(data), channel, err) + logger.Error(err, "Unable to write frame", "sendLength", len(data), "channel", channel, "err", err) continue } } diff --git a/vendor/k8s.io/streaming/pkg/httpstream/wsstream/doc.go b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/doc.go new file mode 100644 index 0000000000..a57e8df60a --- /dev/null +++ b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/doc.go @@ -0,0 +1,69 @@ +/* +Copyright 2015 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 wsstream contains utilities for streaming content over WebSockets. +// The Conn type allows callers to multiplex multiple read/write channels over +// a single websocket. +// +// "channel.k8s.io" +// +// The Websocket RemoteCommand subprotocol "channel.k8s.io" prepends each binary message with a +// byte indicating the channel number (zero indexed) the message was sent on. Messages in both +// directions should prefix their messages with this channel byte. Used for remote execution, +// the channel numbers are by convention defined to match the POSIX file-descriptors assigned +// to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is performed on the raw +// subprotocol - writes are sent as they are received by the server. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "channel.k8s.io" +// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) +// READ []byte{1, 10} # receive "\n" on channel 1 (STDOUT) +// CLOSE +// +// "v2.channel.k8s.io" +// +// The second Websocket subprotocol version "v2.channel.k8s.io" is the same as version 1, +// but it is the first "versioned" subprotocol. +// +// "v3.channel.k8s.io" +// +// The third version of the Websocket RemoteCommand subprotocol adds another channel +// for terminal resizing events. This channel is prepended with the byte '3', and it +// transmits two window sizes (encoding TerminalSize struct) with integers in the range +// (0,65536]. +// +// "v4.channel.k8s.io" +// +// The fourth version of the Websocket RemoteCommand subprotocol adds a channel for +// errors. This channel returns structured errors containing process exit codes. The +// error is "apierrors.StatusError{}". +// +// "v5.channel.k8s.io" +// +// The fifth version of the Websocket RemoteCommand subprotocol adds a CLOSE signal, +// which is sent as the first byte of the message. The second byte is the channel +// id. This CLOSE signal is handled by the websocket server by closing the stream, +// allowing the other streams to complete transmission if necessary, and gracefully +// shutdown the connection. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "v5.channel.k8s.io" +// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) +// WRITE []byte{255, 0} # send CLOSE signal (STDIN) +// CLOSE +package wsstream diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/stream.go b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/stream.go similarity index 81% rename from vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/stream.go rename to vendor/k8s.io/streaming/pkg/httpstream/wsstream/stream.go index ba7e6a519a..38cc41a23d 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/wsstream/stream.go +++ b/vendor/k8s.io/streaming/pkg/httpstream/wsstream/stream.go @@ -17,6 +17,7 @@ limitations under the License. package wsstream import ( + "context" "encoding/base64" "io" "net/http" @@ -25,7 +26,8 @@ import ( "golang.org/x/net/websocket" - "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" + "k8s.io/streaming/pkg/runtime" ) // The WebSocket subprotocol "binary.k8s.io" will only send messages to the @@ -56,6 +58,7 @@ func NewDefaultReaderProtocols() map[string]ReaderProtocolConfig { // Reader supports returning an arbitrary byte stream over a websocket channel. type Reader struct { + logger klog.Logger err chan error r io.Reader ping bool @@ -63,7 +66,7 @@ type Reader struct { protocols map[string]ReaderProtocolConfig selectedProtocol string - handleCrash func(additionalHandlers ...func(interface{})) // overridable for testing + handleCrash func(ctx context.Context, additionalHandlers ...func(context.Context, interface{})) // overridable for testing } // NewReader creates a WebSocket pipe that will copy the contents of r to a provided @@ -72,13 +75,26 @@ type Reader struct { // // The protocols parameter maps subprotocol names to StreamProtocols. The empty string // subprotocol name is used if websocket.Config.Protocol is empty. +// +//logcheck:context // NewReaderWithLogger should be used instead of NewReader in code which supports contextual logging. func NewReader(r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { + return NewReaderWithLogger(klog.Background(), r, ping, protocols) +} + +// NewReaderWithLogger creates a WebSocket pipe that will copy the contents of r to a provided +// WebSocket connection. If ping is true, a zero length message will be sent to the client +// before the stream begins reading. +// +// The protocols parameter maps subprotocol names to StreamProtocols. The empty string +// subprotocol name is used if websocket.Config.Protocol is empty. +func NewReaderWithLogger(logger klog.Logger, r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { return &Reader{ + logger: logger, r: r, err: make(chan error), ping: ping, protocols: protocols, - handleCrash: runtime.HandleCrash, + handleCrash: runtime.HandleCrashWithContext, } } @@ -100,7 +116,7 @@ func (r *Reader) handshake(config *websocket.Config, req *http.Request) error { // method completes. func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error { go func() { - defer r.handleCrash() + defer r.handleCrash(req.Context()) websocket.Server{Handshake: r.handshake, Handler: r.handle}.ServeHTTP(w, req) }() return <-r.err @@ -122,10 +138,10 @@ func (r *Reader) handle(ws *websocket.Conn) { defer closeConn() go func() { - defer runtime.HandleCrash() + defer runtime.HandleCrashWithLogger(r.logger) // This blocks until the connection is closed. // Client should not send anything. - IgnoreReceives(ws, r.timeout) + IgnoreReceivesWithLogger(r.logger, ws, r.timeout) // Once the client closes, we should also close closeConn() }() diff --git a/vendor/k8s.io/streaming/pkg/runtime/runtime.go b/vendor/k8s.io/streaming/pkg/runtime/runtime.go new file mode 100644 index 0000000000..25a70b735e --- /dev/null +++ b/vendor/k8s.io/streaming/pkg/runtime/runtime.go @@ -0,0 +1,62 @@ +/* +Copyright 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 runtime + +import ( + "context" + "fmt" + + "k8s.io/klog/v2" +) + +// HandleError logs an asynchronous error. +func HandleError(err error) { + if err == nil { + return + } + klog.Background().Error(err, "Unhandled Error") +} + +// HandleErrorWithContext logs an asynchronous error with contextual logging when available. +func HandleErrorWithContext(ctx context.Context, err error, msg string, keysAndValues ...interface{}) { + if err == nil { + return + } + klog.FromContext(ctx).Error(err, msg, keysAndValues...) +} + +// HandleCrash recovers from panic and logs it. +func HandleCrash() { + HandleCrashWithLogger(klog.Background()) +} + +// HandleCrashWithContext recovers from panic and logs it with the context logger. +func HandleCrashWithContext(ctx context.Context, additionalHandlers ...func(context.Context, interface{})) { + if r := recover(); r != nil { + for _, fn := range additionalHandlers { + fn(ctx, r) + } + klog.FromContext(ctx).Error(fmt.Errorf("%v", r), "Observed a panic") + } +} + +// HandleCrashWithLogger recovers from panic and logs it using the provided logger. +func HandleCrashWithLogger(logger klog.Logger) { + if r := recover(); r != nil { + logger.Error(fmt.Errorf("%v", r), "Observed a panic") + } +} diff --git a/vendor/k8s.io/utils/cpuset/cpuset.go b/vendor/k8s.io/utils/cpuset/cpuset.go index 52912d95bc..a29447b8ac 100644 --- a/vendor/k8s.io/utils/cpuset/cpuset.go +++ b/vendor/k8s.io/utils/cpuset/cpuset.go @@ -210,9 +210,7 @@ func Parse(s string) (CPUSet, error) { // Split CPU list string: // "0-5,34,46-48" => ["0-5", "34", "46-48"] - ranges := strings.Split(s, ",") - - for _, r := range ranges { + for r := range strings.SplitSeq(s, ",") { boundaries := strings.SplitN(r, "-", 2) if len(boundaries) == 1 { // Handle ranges that consist of only one element like "34". diff --git a/vendor/k8s.io/utils/cpuset/numcpu.go b/vendor/k8s.io/utils/cpuset/numcpu.go new file mode 100644 index 0000000000..40e7bd3a83 --- /dev/null +++ b/vendor/k8s.io/utils/cpuset/numcpu.go @@ -0,0 +1,50 @@ +/* +Copyright 2026 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 cpuset + +import ( + "fmt" + "os" + "strings" +) + +// onlineCPUsPath is the sysfs file listing the host's online CPUs. It is a +// variable so tests can point it at a fixture. +var onlineCPUsPath = "/sys/devices/system/cpu/online" + +// NumCPU returns the number of CPUs that are online on the host, read from +// /sys/devices/system/cpu/online. The file holds a cpu list such as "0-3,8-11"; +// see https://docs.kernel.org/admin-guide/cputopology.html for the format. +// +// Unlike runtime.NumCPU, the result is not affected by the calling process's +// CPU affinity (its cgroup cpuset), so it reflects the whole machine. This is +// what you want when sizing a host-wide resource by CPU count. +// +// NumCPU returns an error if the online file cannot be read or parsed, for +// example on non-Linux platforms. Callers that need a value regardless should +// fall back to runtime.NumCPU. +func NumCPU() (int, error) { + data, err := os.ReadFile(onlineCPUsPath) + if err != nil { + return 0, err + } + set, err := Parse(strings.TrimSpace(string(data))) + if err != nil { + return 0, fmt.Errorf("parsing %q: %w", onlineCPUsPath, err) + } + return set.Size(), nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/dump/dump.go b/vendor/k8s.io/utils/dump/dump.go similarity index 93% rename from vendor/k8s.io/apimachinery/pkg/util/dump/dump.go rename to vendor/k8s.io/utils/dump/dump.go index cf61ef76ae..d50465b372 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/dump/dump.go +++ b/vendor/k8s.io/utils/dump/dump.go @@ -39,16 +39,16 @@ var prettyPrintConfigForHash = &spew.ConfigState{ // Pretty wrap the spew.Sdump with Indent, and disabled methods like error() and String() // The output may change over time, so for guaranteed output please take more direct control -func Pretty(a interface{}) string { +func Pretty(a any) string { return prettyPrintConfig.Sdump(a) } // ForHash keeps the original Spew.Sprintf format to ensure the same checksum -func ForHash(a interface{}) string { +func ForHash(a any) string { return prettyPrintConfigForHash.Sprintf("%#v", a) } // OneLine outputs the object in one line -func OneLine(a interface{}) string { +func OneLine(a any) string { return prettyPrintConfig.Sprintf("%#v", a) } diff --git a/vendor/k8s.io/utils/inotify/inotify_linux.go b/vendor/k8s.io/utils/inotify/inotify_linux.go index 2b9eabbdc7..8b024c11a3 100644 --- a/vendor/k8s.io/utils/inotify/inotify_linux.go +++ b/vendor/k8s.io/utils/inotify/inotify_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/vendor/k8s.io/utils/internal/third_party/forked/golang/golang-lru/lru.go b/vendor/k8s.io/utils/internal/third_party/forked/golang/golang-lru/lru.go index fd4db44072..f486aa6434 100644 --- a/vendor/k8s.io/utils/internal/third_party/forked/golang/golang-lru/lru.go +++ b/vendor/k8s.io/utils/internal/third_party/forked/golang/golang-lru/lru.go @@ -27,18 +27,18 @@ type Cache struct { // OnEvicted optionally specifies a callback function to be // executed when an entry is purged from the cache. - OnEvicted func(key Key, value interface{}) + OnEvicted func(key Key, value any) ll *list.List - cache map[interface{}]*list.Element + cache map[any]*list.Element } // A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators -type Key interface{} +type Key any type entry struct { key Key - value interface{} + value any } // New creates a new Cache. @@ -48,14 +48,14 @@ func New(maxEntries int) *Cache { return &Cache{ MaxEntries: maxEntries, ll: list.New(), - cache: make(map[interface{}]*list.Element), + cache: make(map[any]*list.Element), } } // Add adds a value to the cache. -func (c *Cache) Add(key Key, value interface{}) { +func (c *Cache) Add(key Key, value any) { if c.cache == nil { - c.cache = make(map[interface{}]*list.Element) + c.cache = make(map[any]*list.Element) c.ll = list.New() } if ee, ok := c.cache[key]; ok { @@ -71,7 +71,7 @@ func (c *Cache) Add(key Key, value interface{}) { } // Get looks up a key's value from the cache. -func (c *Cache) Get(key Key) (value interface{}, ok bool) { +func (c *Cache) Get(key Key) (value any, ok bool) { if c.cache == nil { return } diff --git a/vendor/k8s.io/utils/internal/third_party/forked/golang/net/ip.go b/vendor/k8s.io/utils/internal/third_party/forked/golang/net/ip.go index 4340b6e748..407c246364 100644 --- a/vendor/k8s.io/utils/internal/third_party/forked/golang/net/ip.go +++ b/vendor/k8s.io/utils/internal/third_party/forked/golang/net/ip.go @@ -41,7 +41,7 @@ var IPv4 = stdnet.IPv4 // Parse IPv4 address (d.d.d.d). func parseIPv4(s string) IP { var p [IPv4len]byte - for i := 0; i < IPv4len; i++ { + for i := range IPv4len { if len(s) == 0 { // Missing octets. return nil diff --git a/vendor/k8s.io/utils/io/read.go b/vendor/k8s.io/utils/io/read.go index f0af3c8ec8..7323e78d02 100644 --- a/vendor/k8s.io/utils/io/read.go +++ b/vendor/k8s.io/utils/io/read.go @@ -45,7 +45,7 @@ func consistentReadSync(filename string, attempts int, sync func(int)) ([]byte, if err != nil { return nil, err } - for i := 0; i < attempts; i++ { + for i := range attempts { if sync != nil { sync(i) } diff --git a/vendor/k8s.io/utils/lru/lru.go b/vendor/k8s.io/utils/lru/lru.go index 40c22ece13..4fad3f6ddd 100644 --- a/vendor/k8s.io/utils/lru/lru.go +++ b/vendor/k8s.io/utils/lru/lru.go @@ -23,7 +23,7 @@ import ( ) type Key = groupcache.Key -type EvictionFunc = func(key Key, value interface{}) +type EvictionFunc = func(key Key, value any) // Cache is a thread-safe fixed size LRU cache. type Cache struct { @@ -57,14 +57,14 @@ func (c *Cache) SetEvictionFunc(f EvictionFunc) error { } // Add adds a value to the cache. -func (c *Cache) Add(key Key, value interface{}) { +func (c *Cache) Add(key Key, value any) { c.lock.Lock() defer c.lock.Unlock() c.cache.Add(key, value) } // Get looks up a key's value from the cache. -func (c *Cache) Get(key Key) (value interface{}, ok bool) { +func (c *Cache) Get(key Key) (value any, ok bool) { c.lock.Lock() defer c.lock.Unlock() return c.cache.Get(key) diff --git a/vendor/k8s.io/utils/ptr/OWNERS b/vendor/k8s.io/utils/ptr/OWNERS index 0d6392752a..55da8262a0 100644 --- a/vendor/k8s.io/utils/ptr/OWNERS +++ b/vendor/k8s.io/utils/ptr/OWNERS @@ -2,9 +2,11 @@ approvers: - apelisse +- skitt - stewart-yu - thockin reviewers: - apelisse +- skitt - stewart-yu - thockin diff --git a/vendor/k8s.io/utils/ptr/ptr.go b/vendor/k8s.io/utils/ptr/ptr.go index 659ed3b9e2..260f4f29ad 100644 --- a/vendor/k8s.io/utils/ptr/ptr.go +++ b/vendor/k8s.io/utils/ptr/ptr.go @@ -27,19 +27,19 @@ import ( // // This function is only valid for structs and pointers to structs. Any other // type will cause a panic. Passing a typed nil pointer will return true. -func AllPtrFieldsNil(obj interface{}) bool { +func AllPtrFieldsNil(obj any) bool { v := reflect.ValueOf(obj) if !v.IsValid() { panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj)) } - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { if v.IsNil() { return true } v = v.Elem() } for i := 0; i < v.NumField(); i++ { - if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() { + if v.Field(i).Kind() == reflect.Pointer && !v.Field(i).IsNil() { return false } } @@ -51,7 +51,7 @@ func To[T any](v T) *T { return &v } -// Deref dereferences ptr and returns the value it points to if no nil, or else +// Deref dereferences ptr and returns the value it points to if not nil, or else // returns def. func Deref[T any](ptr *T, def T) T { if ptr != nil { diff --git a/vendor/k8s.io/utils/strings/line_delimiter.go b/vendor/k8s.io/utils/strings/line_delimiter.go index 8907869c9e..749500b99e 100644 --- a/vendor/k8s.io/utils/strings/line_delimiter.go +++ b/vendor/k8s.io/utils/strings/line_delimiter.go @@ -45,8 +45,7 @@ func (ld *LineDelimiter) Write(buf []byte) (n int, err error) { // Flush all lines up until now. This will assume insert a linebreak at the current point of the stream. func (ld *LineDelimiter) Flush() (err error) { - lines := strings.Split(ld.buf.String(), "\n") - for _, line := range lines { + for line := range strings.SplitSeq(ld.buf.String(), "\n") { if _, err = ld.output.Write(ld.delimiter); err != nil { return } diff --git a/vendor/k8s.io/utils/third_party/forked/golang/LICENSE b/vendor/k8s.io/utils/third_party/forked/golang/LICENSE new file mode 100644 index 0000000000..7448756763 --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +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 +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/utils/third_party/forked/golang/PATENTS b/vendor/k8s.io/utils/third_party/forked/golang/PATENTS new file mode 100644 index 0000000000..733099041f --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/utils/third_party/forked/golang/btree/LICENSE b/vendor/k8s.io/utils/third_party/forked/golang/btree/LICENSE new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/btree/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/vendor/k8s.io/utils/third_party/forked/golang/btree/README.md b/vendor/k8s.io/utils/third_party/forked/golang/btree/README.md new file mode 100644 index 0000000000..643ad5e9db --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/btree/README.md @@ -0,0 +1,7 @@ +This package is forked from https://github.com/google/btree. + +The upstream repository is deprecated. Kubernetes maintains this fork to continue supporting existing usage. + +Only the subset of functionality required by Kubernetes is included. The implementation is based on the generic version introduced in Go 1.18. + +The core B-tree algorithm is unchanged from the upstream implementation. \ No newline at end of file diff --git a/vendor/k8s.io/utils/third_party/forked/golang/btree/btree.go b/vendor/k8s.io/utils/third_party/forked/golang/btree/btree.go new file mode 100644 index 0000000000..88c0352b2d --- /dev/null +++ b/vendor/k8s.io/utils/third_party/forked/golang/btree/btree.go @@ -0,0 +1,856 @@ +// Copyright 2014-2022 Google Inc. +// Copyright 2025 The Kubernetes Authors. +// +// This file is derived from github.com/google/btree and has been +// modified for use in the Kubernetes util package. +// +// 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 btree implements in-memory B-Trees of arbitrary degree. +// +// btree implements an in-memory B-Tree for use as an ordered data structure. +// It is not meant for persistent storage solutions. +// +// It has a flatter structure than an equivalent red-black or other binary tree, +// which in some cases yields better memory usage and/or performance. +// See some discussion on the matter here: +// +// http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html +// +// Note, though, that this project is in no way related to the C++ B-Tree +// implementation written about there. +// +// Within this tree, each node contains a slice of items and a (possibly nil) +// slice of children. For basic numeric values or raw structs, this can cause +// efficiency differences when compared to equivalent C++ template code that +// stores values in arrays within the node: +// - Due to the overhead of storing values as interfaces (each +// value needs to be stored as the value itself, then 2 words for the +// interface pointing to that value and its type), resulting in higher +// memory use. +// - Since interfaces can point to values anywhere in memory, values are +// most likely not stored in contiguous blocks, resulting in a higher +// number of cache misses. +// +// These issues don't tend to matter, though, when working with strings or other +// heap-allocated structures, since C++-equivalent structures also must store +// pointers and also distribute their values across the heap. +// +// This implementation is designed to be a drop-in replacement to gollrb.LLRB +// trees, (http://github.com/petar/gollrb), an excellent and probably the most +// widely used ordered tree implementation in the Go ecosystem currently. +// Its functions, therefore, exactly mirror those of +// llrb.LLRB where possible. Unlike gollrb, though, we currently don't +// support storing multiple equivalent values. +package btree + +import ( + "cmp" + "sort" + "sync" +) + +// DefaultFreeListSize is the default capacity of a BTree node free list. +const DefaultFreeListSize = 32 + +// FreeList represents a free list of btree nodes. By default each +// BTree has its own FreeList, but multiple BTrees can share the same +// FreeList, in particular when they're created with Clone. +// Two Btrees using the same freelist are safe for concurrent write access. +type FreeList[T any] struct { + mu sync.Mutex + freelist []*node[T] +} + +// NewFreeList creates a new free list. +// size is the maximum size of the returned free list. +func NewFreeList[T any](size int) *FreeList[T] { + return &FreeList[T]{freelist: make([]*node[T], 0, size)} +} + +func (f *FreeList[T]) newNode() (n *node[T]) { + f.mu.Lock() + index := len(f.freelist) - 1 + if index < 0 { + f.mu.Unlock() + return new(node[T]) + } + n = f.freelist[index] + f.freelist[index] = nil + f.freelist = f.freelist[:index] + f.mu.Unlock() + return +} + +func (f *FreeList[T]) freeNode(n *node[T]) (out bool) { + f.mu.Lock() + if len(f.freelist) < cap(f.freelist) { + f.freelist = append(f.freelist, n) + out = true + } + f.mu.Unlock() + return +} + +// ItemIterator allows callers of {A/De}scend* to iterate in-order over portions of +// the tree. When this function returns false, iteration will stop and the +// associated Ascend* function will immediately return. +type ItemIterator[T any] func(item T) bool + +// Less returns a default LessFunc that uses the '<' operator for types that support it. +func Less[T cmp.Ordered]() LessFunc[T] { + return func(a, b T) bool { return a < b } +} + +// NewOrdered creates a new B-Tree for ordered types. +func NewOrdered[T cmp.Ordered](degree int) *BTree[T] { + return New[T](degree, Less[T]()) +} + +// New creates a new B-Tree with the given degree. +// +// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items +// and 2-4 children). +// +// The passed-in LessFunc determines how objects of type T are ordered. +func New[T any](degree int, less LessFunc[T]) *BTree[T] { + return NewWithFreeList(degree, less, NewFreeList[T](DefaultFreeListSize)) +} + +// NewWithFreeList creates a new B-Tree that uses the given node free list. +func NewWithFreeList[T any](degree int, less LessFunc[T], f *FreeList[T]) *BTree[T] { + if degree <= 1 { + panic("bad degree") + } + return &BTree[T]{ + degree: degree, + cow: ©OnWriteContext[T]{freelist: f, less: less}, + } +} + +// items stores items in a node. +type items[T any] []T + +// insertAt inserts a value into the given index, pushing all subsequent values +// forward. +func (s *items[T]) insertAt(index int, item T) { + var zero T + *s = append(*s, zero) + if index < len(*s) { + copy((*s)[index+1:], (*s)[index:]) + } + (*s)[index] = item +} + +// removeAt removes a value at a given index, pulling all subsequent values +// back. +func (s *items[T]) removeAt(index int) T { + item := (*s)[index] + copy((*s)[index:], (*s)[index+1:]) + var zero T + (*s)[len(*s)-1] = zero + *s = (*s)[:len(*s)-1] + return item +} + +// pop removes and returns the last element in the list. +func (s *items[T]) pop() (out T) { + index := len(*s) - 1 + out = (*s)[index] + var zero T + (*s)[index] = zero + *s = (*s)[:index] + return +} + +// truncate truncates this instance at index so that it contains only the +// first index items. index must be less than or equal to length. +func (s *items[T]) truncate(index int) { + var toClear items[T] + *s, toClear = (*s)[:index], (*s)[index:] + var zero T + for i := 0; i < len(toClear); i++ { + toClear[i] = zero + } +} + +// find returns the index where the given item should be inserted into this +// list. 'found' is true if the item already exists in the list at the given +// index. +func (s items[T]) find(item T, less func(T, T) bool) (index int, found bool) { + i := sort.Search(len(s), func(i int) bool { + return less(item, s[i]) + }) + if i > 0 && !less(s[i-1], item) { + return i - 1, true + } + return i, false +} + +// node is an internal node in a tree. +// +// It must at all times maintain the invariant that either +// - len(children) == 0, len(items) unconstrained +// - len(children) == len(items) + 1 +type node[T any] struct { + items items[T] + children items[*node[T]] + cow *copyOnWriteContext[T] +} + +func (n *node[T]) mutableFor(cow *copyOnWriteContext[T]) *node[T] { + if n.cow == cow { + return n + } + out := cow.newNode() + if cap(out.items) >= len(n.items) { + out.items = out.items[:len(n.items)] + } else { + out.items = make(items[T], len(n.items), cap(n.items)) + } + copy(out.items, n.items) + // Copy children + if cap(out.children) >= len(n.children) { + out.children = out.children[:len(n.children)] + } else { + out.children = make(items[*node[T]], len(n.children), cap(n.children)) + } + copy(out.children, n.children) + return out +} + +func (n *node[T]) mutableChild(i int) *node[T] { + c := n.children[i].mutableFor(n.cow) + n.children[i] = c + return c +} + +// split splits the given node at the given index. The current node shrinks, +// and this function returns the item that existed at that index and a new node +// containing all items/children after it. +func (n *node[T]) split(i int) (T, *node[T]) { + item := n.items[i] + next := n.cow.newNode() + next.items = append(next.items, n.items[i+1:]...) + n.items.truncate(i) + if len(n.children) > 0 { + next.children = append(next.children, n.children[i+1:]...) + n.children.truncate(i + 1) + } + return item, next +} + +// maybeSplitChild checks if a child should be split, and if so splits it. +// Returns whether or not a split occurred. +func (n *node[T]) maybeSplitChild(i, maxItems int) bool { + if len(n.children[i].items) < maxItems { + return false + } + first := n.mutableChild(i) + item, second := first.split(maxItems / 2) + n.items.insertAt(i, item) + n.children.insertAt(i+1, second) + return true +} + +// insert inserts an item into the subtree rooted at this node, making sure +// no nodes in the subtree exceed maxItems items. Should an equivalent item be +// be found/replaced by insert, it will be returned. +func (n *node[T]) insert(item T, maxItems int) (_ T, _ bool) { + i, found := n.items.find(item, n.cow.less) + if found { + out := n.items[i] + n.items[i] = item + return out, true + } + if len(n.children) == 0 { + n.items.insertAt(i, item) + return + } + if n.maybeSplitChild(i, maxItems) { + inTree := n.items[i] + switch { + case n.cow.less(item, inTree): + // no change, we want first split node + case n.cow.less(inTree, item): + i++ // we want second split node + default: + out := n.items[i] + n.items[i] = item + return out, true + } + } + return n.mutableChild(i).insert(item, maxItems) +} + +// get finds the given key in the subtree and returns it. +func (n *node[T]) get(key T) (_ T, _ bool) { + i, found := n.items.find(key, n.cow.less) + if found { + return n.items[i], true + } else if len(n.children) > 0 { + return n.children[i].get(key) + } + return +} + +// min returns the first item in the subtree. +func min[T any](n *node[T]) (_ T, found bool) { + if n == nil { + return + } + for len(n.children) > 0 { + n = n.children[0] + } + if len(n.items) == 0 { + return + } + return n.items[0], true +} + +// max returns the last item in the subtree. +func max[T any](n *node[T]) (_ T, found bool) { + if n == nil { + return + } + for len(n.children) > 0 { + n = n.children[len(n.children)-1] + } + if len(n.items) == 0 { + return + } + return n.items[len(n.items)-1], true +} + +// toRemove details what item to remove in a node.remove call. +type toRemove int + +const ( + removeItem toRemove = iota // removes the given item + removeMin // removes smallest item in the subtree + removeMax // removes largest item in the subtree +) + +// remove removes an item from the subtree rooted at this node. +func (n *node[T]) remove(item T, minItems int, typ toRemove) (_ T, _ bool) { + var i int + var found bool + switch typ { + case removeMax: + if len(n.children) == 0 { + return n.items.pop(), true + } + i = len(n.items) + case removeMin: + if len(n.children) == 0 { + return n.items.removeAt(0), true + } + i = 0 + case removeItem: + i, found = n.items.find(item, n.cow.less) + if len(n.children) == 0 { + if found { + return n.items.removeAt(i), true + } + return + } + default: + panic("invalid type") + } + // If we get to here, we have children. + if len(n.children[i].items) <= minItems { + return n.growChildAndRemove(i, item, minItems, typ) + } + child := n.mutableChild(i) + // Either we had enough items to begin with, or we've done some + // merging/stealing, because we've got enough now and we're ready to return + // stuff. + if found { + // The item exists at index 'i', and the child we've selected can give us a + // predecessor, since if we've gotten here it's got > minItems items in it. + out := n.items[i] + // We use our special-case 'remove' call with typ=maxItem to pull the + // predecessor of item i (the rightmost leaf of our immediate left child) + // and set it into where we pulled the item from. + var zero T + n.items[i], _ = child.remove(zero, minItems, removeMax) + return out, true + } + // Final recursive call. Once we're here, we know that the item isn't in this + // node and that the child is big enough to remove from. + return child.remove(item, minItems, typ) +} + +// growChildAndRemove grows child 'i' to make sure it's possible to remove an +// item from it while keeping it at minItems, then calls remove to actually +// remove it. +// +// Most documentation says we have to do two sets of special casing: +// 1. item is in this node +// 2. item is in child +// +// In both cases, we need to handle the two subcases: +// +// A) node has enough values that it can spare one +// B) node doesn't have enough values +// +// For the latter, we have to check: +// +// a) left sibling has node to spare +// b) right sibling has node to spare +// c) we must merge +// +// To simplify our code here, we handle cases #1 and #2 the same: +// If a node doesn't have enough items, we make sure it does (using a,b,c). +// We then simply redo our remove call, and the second time (regardless of +// whether we're in case 1 or 2), we'll have enough items and can guarantee +// that we hit case A. +func (n *node[T]) growChildAndRemove(i int, item T, minItems int, typ toRemove) (T, bool) { + if i > 0 && len(n.children[i-1].items) > minItems { + // Steal from left child + child := n.mutableChild(i) + stealFrom := n.mutableChild(i - 1) + stolenItem := stealFrom.items.pop() + child.items.insertAt(0, n.items[i-1]) + n.items[i-1] = stolenItem + if len(stealFrom.children) > 0 { + child.children.insertAt(0, stealFrom.children.pop()) + } + } else if i < len(n.items) && len(n.children[i+1].items) > minItems { + // steal from right child + child := n.mutableChild(i) + stealFrom := n.mutableChild(i + 1) + stolenItem := stealFrom.items.removeAt(0) + child.items = append(child.items, n.items[i]) + n.items[i] = stolenItem + if len(stealFrom.children) > 0 { + child.children = append(child.children, stealFrom.children.removeAt(0)) + } + } else { + if i >= len(n.items) { + i-- + } + child := n.mutableChild(i) + // merge with right child + mergeItem := n.items.removeAt(i) + mergeChild := n.children.removeAt(i + 1) + child.items = append(child.items, mergeItem) + child.items = append(child.items, mergeChild.items...) + child.children = append(child.children, mergeChild.children...) + n.cow.freeNode(mergeChild) + } + return n.remove(item, minItems, typ) +} + +type direction int + +const ( + descend = direction(-1) + ascend = direction(+1) +) + +type optionalItem[T any] struct { + item T + valid bool +} + +func optional[T any](item T) optionalItem[T] { + return optionalItem[T]{item: item, valid: true} +} +func empty[T any]() optionalItem[T] { + return optionalItem[T]{} +} + +// iterate provides a simple method for iterating over elements in the tree. +// +// When ascending, the 'start' should be less than 'stop' and when descending, +// the 'start' should be greater than 'stop'. Setting 'includeStart' to true +// will force the iterator to include the first item when it equals 'start', +// thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a +// "greaterThan" or "lessThan" queries. +func (n *node[T]) iterate(dir direction, start, stop optionalItem[T], includeStart bool, hit bool, iter ItemIterator[T]) (bool, bool) { + var ok, found bool + var index int + switch dir { + case ascend: + if start.valid { + index, _ = n.items.find(start.item, n.cow.less) + } + for i := index; i < len(n.items); i++ { + if len(n.children) > 0 { + if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok { + return hit, false + } + } + if !includeStart && !hit && start.valid && !n.cow.less(start.item, n.items[i]) { + hit = true + continue + } + hit = true + if stop.valid && !n.cow.less(n.items[i], stop.item) { + return hit, false + } + if !iter(n.items[i]) { + return hit, false + } + } + if len(n.children) > 0 { + if hit, ok = n.children[len(n.children)-1].iterate(dir, start, stop, includeStart, hit, iter); !ok { + return hit, false + } + } + case descend: + if start.valid { + index, found = n.items.find(start.item, n.cow.less) + if !found { + index = index - 1 + } + } else { + index = len(n.items) - 1 + } + for i := index; i >= 0; i-- { + if start.valid && !n.cow.less(n.items[i], start.item) { + if !includeStart || hit || n.cow.less(start.item, n.items[i]) { + continue + } + } + if len(n.children) > 0 { + if hit, ok = n.children[i+1].iterate(dir, start, stop, includeStart, hit, iter); !ok { + return hit, false + } + } + if stop.valid && !n.cow.less(stop.item, n.items[i]) { + return hit, false // continue + } + hit = true + if !iter(n.items[i]) { + return hit, false + } + } + if len(n.children) > 0 { + if hit, ok = n.children[0].iterate(dir, start, stop, includeStart, hit, iter); !ok { + return hit, false + } + } + } + return hit, true +} + +// BTree is a generic implementation of a B-Tree. +// +// BTree stores items of type T in an ordered structure, allowing easy insertion, +// removal, and iteration. +// +// Write operations are not safe for concurrent mutation by multiple +// goroutines, but Read operations are. +type BTree[T any] struct { + degree int + length int + root *node[T] + cow *copyOnWriteContext[T] +} + +// LessFunc determines how to order a type 'T'. It should implement a strict +// ordering, and should return true if within that ordering, 'a' < 'b'. +type LessFunc[T any] func(a, b T) bool + +// copyOnWriteContext pointers determine node ownership... a tree with a write +// context equivalent to a node's write context is allowed to modify that node. +// A tree whose write context does not match a node's is not allowed to modify +// it, and must create a new, writable copy (IE: it's a Clone). +// +// When doing any write operation, we maintain the invariant that the current +// node's context is equal to the context of the tree that requested the write. +// We do this by, before we descend into any node, creating a copy with the +// correct context if the contexts don't match. +// +// Since the node we're currently visiting on any write has the requesting +// tree's context, that node is modifiable in place. Children of that node may +// not share context, but before we descend into them, we'll make a mutable +// copy. +type copyOnWriteContext[T any] struct { + freelist *FreeList[T] + less LessFunc[T] +} + +// Clone clones the btree, lazily. Clone should not be called concurrently, +// but the original tree (t) and the new tree (t2) can be used concurrently +// once the Clone call completes. +// +// The internal tree structure of b is marked read-only and shared between t and +// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes +// whenever one of b's original nodes would have been modified. Read operations +// should have no performance degredation. Write operations for both t and t2 +// will initially experience minor slow-downs caused by additional allocs and +// copies due to the aforementioned copy-on-write logic, but should converge to +// the original performance characteristics of the original tree. +func (t *BTree[T]) Clone() (t2 *BTree[T]) { + // Create two entirely new copy-on-write contexts. + // This operation effectively creates three trees: + // the original, shared nodes (old b.cow) + // the new b.cow nodes + // the new out.cow nodes + cow1, cow2 := *t.cow, *t.cow + out := *t + t.cow = &cow1 + out.cow = &cow2 + return &out +} + +// maxItems returns the max number of items to allow per node. +func (t *BTree[T]) maxItems() int { + return t.degree*2 - 1 +} + +// minItems returns the min number of items to allow per node (ignored for the +// root node). +func (t *BTree[T]) minItems() int { + return t.degree - 1 +} + +func (c *copyOnWriteContext[T]) newNode() (n *node[T]) { + n = c.freelist.newNode() + n.cow = c + return +} + +type freeType int + +const ( + ftFreelistFull freeType = iota // node was freed (available for GC, not stored in freelist) + ftStored // node was stored in the freelist for later use + ftNotOwned // node was ignored by COW, since it's owned by another one +) + +// freeNode frees a node within a given COW context, if it's owned by that +// context. It returns what happened to the node (see freeType const +// documentation). +func (c *copyOnWriteContext[T]) freeNode(n *node[T]) freeType { + if n.cow == c { + // clear to allow GC + n.items.truncate(0) + n.children.truncate(0) + n.cow = nil + if c.freelist.freeNode(n) { + return ftStored + } + return ftFreelistFull + } + return ftNotOwned +} + +// ReplaceOrInsert adds the given item to the tree. If an item in the tree +// already equals the given one, it is removed from the tree and returned, +// and the second return value is true. Otherwise, (zeroValue, false) +// +// nil cannot be added to the tree (will panic). +func (t *BTree[T]) ReplaceOrInsert(item T) (_ T, _ bool) { + if t.root == nil { + t.root = t.cow.newNode() + t.root.items = append(t.root.items, item) + t.length++ + return + } + t.root = t.root.mutableFor(t.cow) + if len(t.root.items) >= t.maxItems() { + item2, second := t.root.split(t.maxItems() / 2) + oldroot := t.root + t.root = t.cow.newNode() + t.root.items = append(t.root.items, item2) + t.root.children = append(t.root.children, oldroot, second) + } + out, outb := t.root.insert(item, t.maxItems()) + if !outb { + t.length++ + } + return out, outb +} + +// Delete removes an item equal to the passed in item from the tree, returning +// it. If no such item exists, returns (zeroValue, false). +func (t *BTree[T]) Delete(item T) (T, bool) { + return t.deleteItem(item, removeItem) +} + +// DeleteMin removes the smallest item in the tree and returns it. +// If no such item exists, returns (zeroValue, false). +func (t *BTree[T]) DeleteMin() (T, bool) { + var zero T + return t.deleteItem(zero, removeMin) +} + +// DeleteMax removes the largest item in the tree and returns it. +// If no such item exists, returns (zeroValue, false). +func (t *BTree[T]) DeleteMax() (T, bool) { + var zero T + return t.deleteItem(zero, removeMax) +} + +func (t *BTree[T]) deleteItem(item T, typ toRemove) (_ T, _ bool) { + if t.root == nil || len(t.root.items) == 0 { + return + } + t.root = t.root.mutableFor(t.cow) + out, outb := t.root.remove(item, t.minItems(), typ) + if len(t.root.items) == 0 && len(t.root.children) > 0 { + oldroot := t.root + t.root = t.root.children[0] + t.cow.freeNode(oldroot) + } + if outb { + t.length-- + } + return out, outb +} + +// AscendRange calls the iterator for every value in the tree within the range +// [greaterOrEqual, lessThan), until iterator returns false. +func (t *BTree[T]) AscendRange(greaterOrEqual, lessThan T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(ascend, optional[T](greaterOrEqual), optional[T](lessThan), true, false, iterator) +} + +// AscendLessThan calls the iterator for every value in the tree within the range +// [first, pivot), until iterator returns false. +func (t *BTree[T]) AscendLessThan(pivot T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(ascend, empty[T](), optional(pivot), false, false, iterator) +} + +// AscendGreaterOrEqual calls the iterator for every value in the tree within +// the range [pivot, last], until iterator returns false. +func (t *BTree[T]) AscendGreaterOrEqual(pivot T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(ascend, optional[T](pivot), empty[T](), true, false, iterator) +} + +// Ascend calls the iterator for every value in the tree within the range +// [first, last], until iterator returns false. +func (t *BTree[T]) Ascend(iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(ascend, empty[T](), empty[T](), false, false, iterator) +} + +// DescendRange calls the iterator for every value in the tree within the range +// [lessOrEqual, greaterThan), until iterator returns false. +func (t *BTree[T]) DescendRange(lessOrEqual, greaterThan T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(descend, optional[T](lessOrEqual), optional[T](greaterThan), true, false, iterator) +} + +// DescendLessOrEqual calls the iterator for every value in the tree within the range +// [pivot, first], until iterator returns false. +func (t *BTree[T]) DescendLessOrEqual(pivot T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(descend, optional[T](pivot), empty[T](), true, false, iterator) +} + +// DescendGreaterThan calls the iterator for every value in the tree within +// the range [last, pivot), until iterator returns false. +func (t *BTree[T]) DescendGreaterThan(pivot T, iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(descend, empty[T](), optional[T](pivot), false, false, iterator) +} + +// Descend calls the iterator for every value in the tree within the range +// [last, first], until iterator returns false. +func (t *BTree[T]) Descend(iterator ItemIterator[T]) { + if t.root == nil { + return + } + t.root.iterate(descend, empty[T](), empty[T](), false, false, iterator) +} + +// Get looks for the key item in the tree, returning it. It returns +// (zeroValue, false) if unable to find that item. +func (t *BTree[T]) Get(key T) (_ T, _ bool) { + if t.root == nil { + return + } + return t.root.get(key) +} + +// Min returns the smallest item in the tree, or (zeroValue, false) if the tree is empty. +func (t *BTree[T]) Min() (_ T, _ bool) { + return min(t.root) +} + +// Max returns the largest item in the tree, or (zeroValue, false) if the tree is empty. +func (t *BTree[T]) Max() (_ T, _ bool) { + return max(t.root) +} + +// Has returns true if the given key is in the tree. +func (t *BTree[T]) Has(key T) bool { + _, ok := t.Get(key) + return ok +} + +// Len returns the number of items currently in the tree. +func (t *BTree[T]) Len() int { + return t.length +} + +// Clear removes all items from the btree. If addNodesToFreelist is true, +// t's nodes are added to its freelist as part of this call, until the freelist +// is full. Otherwise, the root node is simply dereferenced and the subtree +// left to Go's normal GC processes. +// +// This can be much faster +// than calling Delete on all elements, because that requires finding/removing +// each element in the tree and updating the tree accordingly. It also is +// somewhat faster than creating a new tree to replace the old one, because +// nodes from the old tree are reclaimed into the freelist for use by the new +// one, instead of being lost to the garbage collector. +// +// This call takes: +// +// O(1): when addNodesToFreelist is false, this is a single operation. +// O(1): when the freelist is already full, it breaks out immediately +// O(freelist size): when the freelist is empty and the nodes are all owned +// by this tree, nodes are added to the freelist until full. +// O(tree size): when all nodes are owned by another tree, all nodes are +// iterated over looking for nodes to add to the freelist, and due to +// ownership, none are. +func (t *BTree[T]) Clear(addNodesToFreelist bool) { + if t.root != nil && addNodesToFreelist { + t.root.reset(t.cow) + } + t.root, t.length = nil, 0 +} + +// reset returns a subtree to the freelist. It breaks out immediately if the +// freelist is full, since the only benefit of iterating is to fill that +// freelist up. Returns true if parent reset call should continue. +func (n *node[T]) reset(c *copyOnWriteContext[T]) bool { + for _, child := range n.children { + if !child.reset(c) { + return false + } + } + return c.freeNode(n) != ftFreelistFull +} diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go index 559aebb59a..7fa5464501 100644 --- a/vendor/k8s.io/utils/trace/trace.go +++ b/vendor/k8s.io/utils/trace/trace.go @@ -34,7 +34,7 @@ var klogV = func(lvl klog.Level) bool { // Field is a key value pair that provides additional details about the trace. type Field struct { Key string - Value interface{} + Value any } func (f Field) format() string { diff --git a/vendor/modules.txt b/vendor/modules.txt index 9f30a15bf8..6fee687bc5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,7 +7,7 @@ # cel.dev/expr v0.25.1 ## explicit; go 1.23.0 cel.dev/expr -# cyphar.com/go-pathrs v0.2.1 +# cyphar.com/go-pathrs v0.2.2 ## explicit; go 1.18 cyphar.com/go-pathrs cyphar.com/go-pathrs/internal/fdutils @@ -144,9 +144,6 @@ github.com/antlr4-go/antlr/v4 # github.com/apparentlymart/go-cidr v1.1.0 ## explicit github.com/apparentlymart/go-cidr/cidr -# github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 -## explicit -github.com/armon/circbuf # github.com/ashanbrown/forbidigo v1.6.0 ## explicit; go 1.13 github.com/ashanbrown/forbidigo/forbidigo @@ -156,12 +153,10 @@ github.com/ashanbrown/makezero/makezero # github.com/ashcrow/osrelease v0.0.0-20180626175927-9b292693c55c ## explicit github.com/ashcrow/osrelease -# github.com/aws/aws-sdk-go v1.55.7 -## explicit; go 1.19 -github.com/aws/aws-sdk-go/aws/arn # github.com/aws/aws-sdk-go-v2 v1.42.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/aws +github.com/aws/aws-sdk-go-v2/aws/arn github.com/aws/aws-sdk-go-v2/aws/defaults github.com/aws/aws-sdk-go-v2/aws/middleware github.com/aws/aws-sdk-go-v2/aws/protocol/ec2query @@ -464,8 +459,8 @@ github.com/coreos/ignition/config/validate github.com/coreos/ignition/config/validate/astjson github.com/coreos/ignition/config/validate/astnode github.com/coreos/ignition/config/validate/report -# github.com/coreos/ignition/v2 v2.20.0 -## explicit; go 1.20 +# github.com/coreos/ignition/v2 v2.26.0 +## explicit; go 1.24.0 github.com/coreos/ignition/v2/config/merge github.com/coreos/ignition/v2/config/shared/errors github.com/coreos/ignition/v2/config/shared/parse @@ -558,7 +553,7 @@ github.com/docker/docker/api/types/versions ## explicit; go 1.21 github.com/docker/docker-credential-helpers/client github.com/docker/docker-credential-helpers/credentials -# github.com/docker/go-connections v0.5.0 +# github.com/docker/go-connections v0.6.0 ## explicit; go 1.18 github.com/docker/go-connections/tlsconfig # github.com/docker/go-units v0.5.0 @@ -597,7 +592,7 @@ github.com/firefart/nonamedreturns/analyzer ## explicit; go 1.17 github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify/internal -# github.com/fxamacker/cbor/v2 v2.9.0 +# github.com/fxamacker/cbor/v2 v2.9.2 ## explicit; go 1.20 github.com/fxamacker/cbor/v2 # github.com/fzipp/gocyclo v0.6.0 @@ -745,7 +740,7 @@ github.com/gobwas/glob/syntax/ast github.com/gobwas/glob/syntax/lexer github.com/gobwas/glob/util/runes github.com/gobwas/glob/util/strings -# github.com/godbus/dbus/v5 v5.1.1-0.20240921181615-a817f3cc4a9e +# github.com/godbus/dbus/v5 v5.2.2 ## explicit; go 1.20 github.com/godbus/dbus/v5 # github.com/gofrs/flock v0.13.0 @@ -937,8 +932,8 @@ github.com/golangci/unconvert # github.com/google/btree v1.1.3 ## explicit; go 1.18 github.com/google/btree -# github.com/google/cadvisor v0.53.0 -## explicit; go 1.23.0 +# github.com/google/cadvisor v0.56.2 +## explicit; go 1.24.0 github.com/google/cadvisor/cache/memory github.com/google/cadvisor/collector github.com/google/cadvisor/container @@ -958,6 +953,20 @@ github.com/google/cadvisor/container/systemd/install github.com/google/cadvisor/devicemapper github.com/google/cadvisor/events github.com/google/cadvisor/fs +github.com/google/cadvisor/fs/btrfs +github.com/google/cadvisor/fs/btrfs/install +github.com/google/cadvisor/fs/devicemapper +github.com/google/cadvisor/fs/devicemapper/install +github.com/google/cadvisor/fs/nfs +github.com/google/cadvisor/fs/nfs/install +github.com/google/cadvisor/fs/overlay +github.com/google/cadvisor/fs/overlay/install +github.com/google/cadvisor/fs/tmpfs +github.com/google/cadvisor/fs/tmpfs/install +github.com/google/cadvisor/fs/vfs +github.com/google/cadvisor/fs/vfs/install +github.com/google/cadvisor/fs/zfs +github.com/google/cadvisor/fs/zfs/install github.com/google/cadvisor/info/v1 github.com/google/cadvisor/info/v2 github.com/google/cadvisor/machine @@ -1027,7 +1036,7 @@ github.com/google/goexpect # github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f ## explicit github.com/google/goterm/term -# github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 +# github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 ## explicit; go 1.24.0 github.com/google/pprof/profile # github.com/google/renameio v0.1.0 @@ -1058,13 +1067,12 @@ github.com/gostaticanalysis/forcetypeassert # github.com/gostaticanalysis/nilerr v0.1.1 ## explicit; go 1.15 github.com/gostaticanalysis/nilerr -# github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 -## explicit -github.com/gregjones/httpcache -# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20210315223345-82c243799c99 -## explicit -github.com/grpc-ecosystem/go-grpc-prometheus -github.com/grpc-ecosystem/go-grpc-prometheus/packages/grpcstatus +# github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 +## explicit; go 1.21 +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus +# github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 +## explicit; go 1.23.0 +github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors # github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 ## explicit; go 1.24.0 github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule @@ -1112,9 +1120,6 @@ github.com/julz/importas # github.com/karamaru-alpha/copyloopvar v1.1.0 ## explicit; go 1.21 github.com/karamaru-alpha/copyloopvar -# github.com/karrick/godirwalk v1.17.0 -## explicit; go 1.13 -github.com/karrick/godirwalk # github.com/kisielk/errcheck v1.8.0 ## explicit; go 1.18 github.com/kisielk/errcheck/errcheck @@ -1153,15 +1158,6 @@ github.com/leonklingele/grouper/pkg/analyzer/globals github.com/leonklingele/grouper/pkg/analyzer/imports github.com/leonklingele/grouper/pkg/analyzer/types github.com/leonklingele/grouper/pkg/analyzer/vars -# github.com/libopenstorage/openstorage v1.0.0 -## explicit -github.com/libopenstorage/openstorage/api -github.com/libopenstorage/openstorage/api/client -github.com/libopenstorage/openstorage/api/client/volume -github.com/libopenstorage/openstorage/api/spec -github.com/libopenstorage/openstorage/pkg/parser -github.com/libopenstorage/openstorage/pkg/units -github.com/libopenstorage/openstorage/volume # github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de ## explicit github.com/liggitt/tabwriter @@ -1209,7 +1205,7 @@ github.com/moby/buildkit/frontend/dockerfile/command github.com/moby/buildkit/frontend/dockerfile/parser github.com/moby/buildkit/frontend/dockerfile/shell github.com/moby/buildkit/util/stack -# github.com/moby/spdystream v0.5.0 +# github.com/moby/spdystream v0.5.1 ## explicit; go 1.13 github.com/moby/spdystream github.com/moby/spdystream/spdy @@ -1235,9 +1231,6 @@ github.com/modern-go/concurrent # github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee ## explicit; go 1.12 github.com/modern-go/reflect2 -# github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 -## explicit -github.com/mohae/deepcopy # github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 ## explicit github.com/monochromegane/go-gitignore @@ -1288,8 +1281,8 @@ github.com/oklog/ulid/v2 github.com/olekukonko/tablewriter # github.com/onsi/ginkgo v1.16.5 ## explicit; go 1.16 -# github.com/onsi/ginkgo/v2 v2.27.2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7 -## explicit; go 1.23.0 +# github.com/onsi/ginkgo/v2 v2.28.0 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20260424201627-4d4cc33d669d +## explicit; go 1.24.0 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config github.com/onsi/ginkgo/v2/formatter @@ -1312,8 +1305,8 @@ github.com/onsi/ginkgo/v2/internal/reporters github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.38.2 -## explicit; go 1.23.0 +# github.com/onsi/gomega v1.39.1 +## explicit; go 1.24.0 github.com/onsi/gomega github.com/onsi/gomega/format github.com/onsi/gomega/gcustom @@ -1326,7 +1319,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/opencontainers/cgroups v0.0.3 +# github.com/opencontainers/cgroups v0.0.6 ## explicit; go 1.23.0 github.com/opencontainers/cgroups github.com/opencontainers/cgroups/devices/config @@ -1351,7 +1344,7 @@ github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift-eng/openshift-tests-extension v0.0.0-20260127124016-0fed2b824818 +# github.com/openshift-eng/openshift-tests-extension v0.0.0-20260707142426-572a3e9deb7a ## explicit; go 1.23.0 github.com/openshift-eng/openshift-tests-extension/pkg/cmd github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages @@ -1367,8 +1360,8 @@ github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo github.com/openshift-eng/openshift-tests-extension/pkg/junit github.com/openshift-eng/openshift-tests-extension/pkg/util/sets github.com/openshift-eng/openshift-tests-extension/pkg/version -# github.com/openshift/api v0.0.0-20260702202555-ef71f942ef6c -## explicit; go 1.25.0 +# github.com/openshift/api v0.0.0-20260715165912-72066cc9718b +## explicit; go 1.26.0 github.com/openshift/api github.com/openshift/api/annotations github.com/openshift/api/apiextensions @@ -1455,8 +1448,8 @@ github.com/openshift/api/template github.com/openshift/api/template/v1 github.com/openshift/api/user github.com/openshift/api/user/v1 -# github.com/openshift/client-go v0.0.0-20260703082747-24d059aea27a -## explicit; go 1.25.0 +# github.com/openshift/client-go v0.0.0-20260715172546-dac61734e0ec +## explicit; go 1.26.0 github.com/openshift/client-go/apps/applyconfigurations/apps/v1 github.com/openshift/client-go/apps/applyconfigurations/internal github.com/openshift/client-go/apps/clientset/versioned @@ -1610,8 +1603,8 @@ github.com/openshift/client-go/user/clientset/versioned/typed/user/v1 github.com/openshift/imagebuilder/dockerfile/command github.com/openshift/imagebuilder/dockerfile/parser github.com/openshift/imagebuilder/internal -# github.com/openshift/library-go v0.0.0-20260611115129-21dd5809a4b2 -## explicit; go 1.25.0 +# github.com/openshift/library-go v0.0.0-20260720123941-85336565c3c7 +## explicit; go 1.26.0 github.com/openshift/library-go/pkg/apiserver/jsonpatch github.com/openshift/library-go/pkg/authorization/hardcodedauthorizer github.com/openshift/library-go/pkg/certs @@ -1679,12 +1672,12 @@ github.com/prometheus/client_golang/prometheus/testutil/promlint/validations # github.com/prometheus/client_model v0.6.2 ## explicit; go 1.22.0 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.66.1 -## explicit; go 1.23.0 +# github.com/prometheus/common v0.67.5 +## explicit; go 1.24.0 github.com/prometheus/common/expfmt github.com/prometheus/common/model -# github.com/prometheus/procfs v0.17.0 -## explicit; go 1.23.0 +# github.com/prometheus/procfs v0.19.2 +## explicit; go 1.24.0 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util @@ -1779,8 +1772,6 @@ github.com/securego/gosec/v2/analyzers github.com/securego/gosec/v2/cwe github.com/securego/gosec/v2/issue github.com/securego/gosec/v2/rules -# github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 -## explicit; go 1.13 # github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c ## explicit github.com/shazow/go-diff/difflib @@ -1983,8 +1974,8 @@ go-simpler.org/musttag # go-simpler.org/sloglint v0.7.2 ## explicit; go 1.21 go-simpler.org/sloglint -# go.etcd.io/etcd/api/v3 v3.6.5 -## explicit; go 1.24 +# go.etcd.io/etcd/api/v3 v3.6.8 +## explicit; go 1.24.0 go.etcd.io/etcd/api/v3/authpb go.etcd.io/etcd/api/v3/etcdserverpb go.etcd.io/etcd/api/v3/membershippb @@ -1992,8 +1983,8 @@ go.etcd.io/etcd/api/v3/mvccpb go.etcd.io/etcd/api/v3/v3rpc/rpctypes go.etcd.io/etcd/api/v3/version go.etcd.io/etcd/api/v3/versionpb -# go.etcd.io/etcd/client/pkg/v3 v3.6.5 -## explicit; go 1.24 +# go.etcd.io/etcd/client/pkg/v3 v3.6.8 +## explicit; go 1.24.0 go.etcd.io/etcd/client/pkg/v3/fileutil go.etcd.io/etcd/client/pkg/v3/logutil go.etcd.io/etcd/client/pkg/v3/systemd @@ -2001,8 +1992,8 @@ go.etcd.io/etcd/client/pkg/v3/tlsutil go.etcd.io/etcd/client/pkg/v3/transport go.etcd.io/etcd/client/pkg/v3/types go.etcd.io/etcd/client/pkg/v3/verify -# go.etcd.io/etcd/client/v3 v3.6.5 -## explicit; go 1.24 +# go.etcd.io/etcd/client/v3 v3.6.8 +## explicit; go 1.24.0 go.etcd.io/etcd/client/v3 go.etcd.io/etcd/client/v3/credentials go.etcd.io/etcd/client/v3/internal/endpoint @@ -2012,20 +2003,20 @@ go.etcd.io/etcd/client/v3/kubernetes ## explicit; go 1.24.0 go.opentelemetry.io/auto/sdk go.opentelemetry.io/auto/sdk/internal/telemetry -# go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0 -## explicit; go 1.19 +# go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.65.0 +## explicit; go 1.24.0 go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful -go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconvutil -# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 -## explicit; go 1.23.0 +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful/internal/semconv +# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 +## explicit; go 1.24.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 -## explicit; go 1.23.0 +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 +## explicit; go 1.24.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv -# go.opentelemetry.io/otel v1.40.0 +# go.opentelemetry.io/otel v1.41.0 ## explicit; go 1.24.0 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -2034,16 +2025,17 @@ go.opentelemetry.io/otel/attribute/internal/xxhash go.opentelemetry.io/otel/baggage go.opentelemetry.io/otel/codes go.opentelemetry.io/otel/internal/baggage +go.opentelemetry.io/otel/internal/errorhandler go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/semconv/internal go.opentelemetry.io/otel/semconv/v1.12.0 go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.37.0 -go.opentelemetry.io/otel/semconv/v1.37.0/httpconv -go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv go.opentelemetry.io/otel/semconv/v1.39.0 +go.opentelemetry.io/otel/semconv/v1.39.0/httpconv go.opentelemetry.io/otel/semconv/v1.39.0/otelconv +go.opentelemetry.io/otel/semconv/v1.39.0/rpcconv # go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 ## explicit; go 1.24.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace @@ -2058,7 +2050,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x -# go.opentelemetry.io/otel/metric v1.40.0 +# go.opentelemetry.io/otel/metric v1.41.0 ## explicit; go 1.24.0 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded @@ -2072,7 +2064,7 @@ go.opentelemetry.io/otel/sdk/resource go.opentelemetry.io/otel/sdk/trace go.opentelemetry.io/otel/sdk/trace/internal/env go.opentelemetry.io/otel/sdk/trace/internal/observ -# go.opentelemetry.io/otel/trace v1.40.0 +# go.opentelemetry.io/otel/trace v1.41.0 ## explicit; go 1.24.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded @@ -2112,7 +2104,7 @@ go.uber.org/zap/internal/pool go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# go.yaml.in/yaml/v2 v2.4.3 +# go.yaml.in/yaml/v2 v2.4.4 ## explicit; go 1.15 go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 @@ -2147,7 +2139,7 @@ golang.org/x/crypto/scrypt golang.org/x/crypto/sha3 golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/exp v0.0.0-20250911091902-df9299821621 +# golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 ## explicit; go 1.24.0 golang.org/x/exp/constraints golang.org/x/exp/maps @@ -2161,9 +2153,8 @@ golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.56.0 +# golang.org/x/net v0.57.0 ## explicit; go 1.25.0 -golang.org/x/net/context golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset @@ -2231,8 +2222,8 @@ golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm golang.org/x/text/width -# golang.org/x/time v0.14.0 -## explicit; go 1.24.0 +# golang.org/x/time v0.15.0 +## explicit; go 1.25.0 golang.org/x/time/rate # golang.org/x/tools v0.47.0 ## explicit; go 1.25.0 @@ -2390,6 +2381,10 @@ google.golang.org/grpc/keepalive google.golang.org/grpc/mem google.golang.org/grpc/metadata google.golang.org/grpc/peer +google.golang.org/grpc/reflection +google.golang.org/grpc/reflection/grpc_reflection_v1 +google.golang.org/grpc/reflection/grpc_reflection_v1alpha +google.golang.org/grpc/reflection/internal google.golang.org/grpc/resolver google.golang.org/grpc/resolver/dns google.golang.org/grpc/resolver/manual @@ -2397,7 +2392,7 @@ google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/protobuf v1.36.11 +# google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af ## explicit; go 1.23 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson @@ -2638,8 +2633,8 @@ honnef.co/go/tools/stylecheck/st1021 honnef.co/go/tools/stylecheck/st1022 honnef.co/go/tools/stylecheck/st1023 honnef.co/go/tools/unused -# k8s.io/api v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/api v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 k8s.io/api/admissionregistration/v1 @@ -2658,8 +2653,6 @@ k8s.io/api/authorization/v1 k8s.io/api/authorization/v1beta1 k8s.io/api/autoscaling/v1 k8s.io/api/autoscaling/v2 -k8s.io/api/autoscaling/v2beta1 -k8s.io/api/autoscaling/v2beta2 k8s.io/api/batch/v1 k8s.io/api/batch/v1beta1 k8s.io/api/certificates/v1 @@ -2694,14 +2687,14 @@ k8s.io/api/resource/v1alpha3 k8s.io/api/resource/v1beta1 k8s.io/api/resource/v1beta2 k8s.io/api/scheduling/v1 -k8s.io/api/scheduling/v1alpha1 +k8s.io/api/scheduling/v1alpha2 k8s.io/api/scheduling/v1beta1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 k8s.io/api/storagemigration/v1beta1 -# k8s.io/apiextensions-apiserver v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/apiextensions-apiserver v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1 @@ -2719,8 +2712,8 @@ k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalint k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1 k8s.io/apiextensions-apiserver/pkg/features -# k8s.io/apimachinery v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/apimachinery v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/meta @@ -2732,7 +2725,6 @@ k8s.io/apimachinery/pkg/api/validate k8s.io/apimachinery/pkg/api/validate/constraints k8s.io/apimachinery/pkg/api/validate/content k8s.io/apimachinery/pkg/api/validation -k8s.io/apimachinery/pkg/api/validation/path k8s.io/apimachinery/pkg/apis/asn1 k8s.io/apimachinery/pkg/apis/meta/internalversion k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme @@ -2759,10 +2751,10 @@ k8s.io/apimachinery/pkg/runtime/serializer/recognizer k8s.io/apimachinery/pkg/runtime/serializer/streaming k8s.io/apimachinery/pkg/runtime/serializer/versioning k8s.io/apimachinery/pkg/selection +k8s.io/apimachinery/pkg/sharding k8s.io/apimachinery/pkg/types k8s.io/apimachinery/pkg/util/cache k8s.io/apimachinery/pkg/util/diff -k8s.io/apimachinery/pkg/util/dump k8s.io/apimachinery/pkg/util/duration k8s.io/apimachinery/pkg/util/errors k8s.io/apimachinery/pkg/util/framer @@ -2798,17 +2790,23 @@ 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.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/apiserver v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/apiserver/pkg/admission k8s.io/apiserver/pkg/admission/configuration k8s.io/apiserver/pkg/admission/initializer k8s.io/apiserver/pkg/admission/metrics k8s.io/apiserver/pkg/admission/plugin/authorizer k8s.io/apiserver/pkg/admission/plugin/cel +k8s.io/apiserver/pkg/admission/plugin/manifest +k8s.io/apiserver/pkg/admission/plugin/manifest/metrics k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle +k8s.io/apiserver/pkg/admission/plugin/policy/config +k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig +k8s.io/apiserver/pkg/admission/plugin/policy/config/apis/policyconfig/v1 k8s.io/apiserver/pkg/admission/plugin/policy/generic k8s.io/apiserver/pkg/admission/plugin/policy/internal/generic +k8s.io/apiserver/pkg/admission/plugin/policy/manifest/source k8s.io/apiserver/pkg/admission/plugin/policy/matching k8s.io/apiserver/pkg/admission/plugin/policy/mutating k8s.io/apiserver/pkg/admission/plugin/policy/mutating/metrics @@ -2819,9 +2817,10 @@ k8s.io/apiserver/pkg/admission/plugin/webhook k8s.io/apiserver/pkg/admission/plugin/webhook/config k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1 -k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1 k8s.io/apiserver/pkg/admission/plugin/webhook/errors k8s.io/apiserver/pkg/admission/plugin/webhook/generic +k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/loader +k8s.io/apiserver/pkg/admission/plugin/webhook/manifest/source k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions k8s.io/apiserver/pkg/admission/plugin/webhook/mutating k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace @@ -2879,6 +2878,7 @@ k8s.io/apiserver/pkg/endpoints/discovery/aggregated k8s.io/apiserver/pkg/endpoints/filterlatency k8s.io/apiserver/pkg/endpoints/filters k8s.io/apiserver/pkg/endpoints/filters/impersonation +k8s.io/apiserver/pkg/endpoints/filters/impersonation/metrics k8s.io/apiserver/pkg/endpoints/handlers k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager k8s.io/apiserver/pkg/endpoints/handlers/finisher @@ -2902,6 +2902,7 @@ k8s.io/apiserver/pkg/server/egressselector/metrics k8s.io/apiserver/pkg/server/filters k8s.io/apiserver/pkg/server/flagz k8s.io/apiserver/pkg/server/flagz/api/v1alpha1 +k8s.io/apiserver/pkg/server/flagz/api/v1beta1 k8s.io/apiserver/pkg/server/flagz/negotiate k8s.io/apiserver/pkg/server/healthz k8s.io/apiserver/pkg/server/httplog @@ -2915,13 +2916,16 @@ k8s.io/apiserver/pkg/server/routes k8s.io/apiserver/pkg/server/routine k8s.io/apiserver/pkg/server/statusz k8s.io/apiserver/pkg/server/statusz/api/v1alpha1 +k8s.io/apiserver/pkg/server/statusz/api/v1beta1 k8s.io/apiserver/pkg/server/statusz/negotiate k8s.io/apiserver/pkg/server/storage +k8s.io/apiserver/pkg/sharding k8s.io/apiserver/pkg/storage k8s.io/apiserver/pkg/storage/cacher k8s.io/apiserver/pkg/storage/cacher/delegator k8s.io/apiserver/pkg/storage/cacher/metrics k8s.io/apiserver/pkg/storage/cacher/progress +k8s.io/apiserver/pkg/storage/cacher/store k8s.io/apiserver/pkg/storage/errors k8s.io/apiserver/pkg/storage/etcd3 k8s.io/apiserver/pkg/storage/etcd3/etcd3retry @@ -2944,6 +2948,7 @@ k8s.io/apiserver/pkg/util/compatibility k8s.io/apiserver/pkg/util/configmetrics k8s.io/apiserver/pkg/util/dryrun k8s.io/apiserver/pkg/util/feature +k8s.io/apiserver/pkg/util/filesystem k8s.io/apiserver/pkg/util/flowcontrol k8s.io/apiserver/pkg/util/flowcontrol/debug k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing @@ -2955,6 +2960,8 @@ k8s.io/apiserver/pkg/util/flowcontrol/metrics k8s.io/apiserver/pkg/util/flowcontrol/request k8s.io/apiserver/pkg/util/flushwriter k8s.io/apiserver/pkg/util/peerproxy/metrics +k8s.io/apiserver/pkg/util/proxy +k8s.io/apiserver/pkg/util/proxy/metrics k8s.io/apiserver/pkg/util/shufflesharding k8s.io/apiserver/pkg/util/webhook k8s.io/apiserver/pkg/util/x509metrics @@ -2967,14 +2974,14 @@ k8s.io/apiserver/plugin/pkg/audit/webhook k8s.io/apiserver/plugin/pkg/authenticator/token/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics -# k8s.io/cli-runtime v0.35.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/cli-runtime v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/cli-runtime/pkg/genericclioptions k8s.io/cli-runtime/pkg/genericiooptions k8s.io/cli-runtime/pkg/printers k8s.io/cli-runtime/pkg/resource -# k8s.io/client-go v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/client-go v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/client-go/applyconfigurations k8s.io/client-go/applyconfigurations/admissionregistration/v1 k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1 @@ -2985,8 +2992,6 @@ k8s.io/client-go/applyconfigurations/apps/v1beta1 k8s.io/client-go/applyconfigurations/apps/v1beta2 k8s.io/client-go/applyconfigurations/autoscaling/v1 k8s.io/client-go/applyconfigurations/autoscaling/v2 -k8s.io/client-go/applyconfigurations/autoscaling/v2beta1 -k8s.io/client-go/applyconfigurations/autoscaling/v2beta2 k8s.io/client-go/applyconfigurations/batch/v1 k8s.io/client-go/applyconfigurations/batch/v1beta1 k8s.io/client-go/applyconfigurations/certificates/v1 @@ -3023,7 +3028,7 @@ k8s.io/client-go/applyconfigurations/resource/v1alpha3 k8s.io/client-go/applyconfigurations/resource/v1beta1 k8s.io/client-go/applyconfigurations/resource/v1beta2 k8s.io/client-go/applyconfigurations/scheduling/v1 -k8s.io/client-go/applyconfigurations/scheduling/v1alpha1 +k8s.io/client-go/applyconfigurations/scheduling/v1alpha2 k8s.io/client-go/applyconfigurations/scheduling/v1beta1 k8s.io/client-go/applyconfigurations/storage/v1 k8s.io/client-go/applyconfigurations/storage/v1alpha1 @@ -3054,8 +3059,6 @@ k8s.io/client-go/informers/apps/v1beta2 k8s.io/client-go/informers/autoscaling k8s.io/client-go/informers/autoscaling/v1 k8s.io/client-go/informers/autoscaling/v2 -k8s.io/client-go/informers/autoscaling/v2beta1 -k8s.io/client-go/informers/autoscaling/v2beta2 k8s.io/client-go/informers/batch k8s.io/client-go/informers/batch/v1 k8s.io/client-go/informers/batch/v1beta1 @@ -3104,7 +3107,7 @@ k8s.io/client-go/informers/resource/v1beta1 k8s.io/client-go/informers/resource/v1beta2 k8s.io/client-go/informers/scheduling k8s.io/client-go/informers/scheduling/v1 -k8s.io/client-go/informers/scheduling/v1alpha1 +k8s.io/client-go/informers/scheduling/v1alpha2 k8s.io/client-go/informers/scheduling/v1beta1 k8s.io/client-go/informers/storage k8s.io/client-go/informers/storage/v1 @@ -3143,10 +3146,6 @@ k8s.io/client-go/kubernetes/typed/autoscaling/v1 k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake k8s.io/client-go/kubernetes/typed/autoscaling/v2 k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake -k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1 -k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake -k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2 -k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake k8s.io/client-go/kubernetes/typed/batch/v1 k8s.io/client-go/kubernetes/typed/batch/v1/fake k8s.io/client-go/kubernetes/typed/batch/v1beta1 @@ -3213,8 +3212,8 @@ k8s.io/client-go/kubernetes/typed/resource/v1beta2 k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake k8s.io/client-go/kubernetes/typed/scheduling/v1 k8s.io/client-go/kubernetes/typed/scheduling/v1/fake -k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1 -k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake +k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2 +k8s.io/client-go/kubernetes/typed/scheduling/v1alpha2/fake k8s.io/client-go/kubernetes/typed/scheduling/v1beta1 k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake k8s.io/client-go/kubernetes/typed/storage/v1 @@ -3235,8 +3234,6 @@ k8s.io/client-go/listers/apps/v1beta1 k8s.io/client-go/listers/apps/v1beta2 k8s.io/client-go/listers/autoscaling/v1 k8s.io/client-go/listers/autoscaling/v2 -k8s.io/client-go/listers/autoscaling/v2beta1 -k8s.io/client-go/listers/autoscaling/v2beta2 k8s.io/client-go/listers/batch/v1 k8s.io/client-go/listers/batch/v1beta1 k8s.io/client-go/listers/certificates/v1 @@ -3270,7 +3267,7 @@ k8s.io/client-go/listers/resource/v1alpha3 k8s.io/client-go/listers/resource/v1beta1 k8s.io/client-go/listers/resource/v1beta2 k8s.io/client-go/listers/scheduling/v1 -k8s.io/client-go/listers/scheduling/v1alpha1 +k8s.io/client-go/listers/scheduling/v1alpha2 k8s.io/client-go/listers/scheduling/v1beta1 k8s.io/client-go/listers/storage/v1 k8s.io/client-go/listers/storage/v1alpha1 @@ -3304,6 +3301,7 @@ k8s.io/client-go/scale/scheme/extensionsint k8s.io/client-go/scale/scheme/extensionsv1beta1 k8s.io/client-go/testing k8s.io/client-go/third_party/forked/golang/template +k8s.io/client-go/third_party/forked/httpcache k8s.io/client-go/tools/auth k8s.io/client-go/tools/cache k8s.io/client-go/tools/cache/synctrack @@ -3340,8 +3338,8 @@ k8s.io/client-go/util/keyutil k8s.io/client-go/util/retry k8s.io/client-go/util/watchlist k8s.io/client-go/util/workqueue -# k8s.io/cloud-provider v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/cloud-provider v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/cloud-provider k8s.io/cloud-provider/api k8s.io/cloud-provider/app/config @@ -3357,8 +3355,8 @@ k8s.io/cloud-provider/options k8s.io/cloud-provider/volume k8s.io/cloud-provider/volume/errors k8s.io/cloud-provider/volume/helpers -# k8s.io/code-generator v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/code-generator v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/code-generator k8s.io/code-generator/cmd/applyconfiguration-gen k8s.io/code-generator/cmd/applyconfiguration-gen/args @@ -3393,8 +3391,8 @@ k8s.io/code-generator/cmd/register-gen/generators k8s.io/code-generator/pkg/namer k8s.io/code-generator/pkg/util k8s.io/code-generator/third_party/forked/golang/reflect -# k8s.io/component-base v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/component-base v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/component-base/cli k8s.io/component-base/cli/flag k8s.io/component-base/codec @@ -3412,7 +3410,9 @@ k8s.io/component-base/logs/klogflags k8s.io/component-base/logs/logreduction k8s.io/component-base/logs/testinit k8s.io/component-base/metrics +k8s.io/component-base/metrics/api/v1 k8s.io/component-base/metrics/features +k8s.io/component-base/metrics/internal k8s.io/component-base/metrics/legacyregistry k8s.io/component-base/metrics/prometheus/compatversion k8s.io/component-base/metrics/prometheus/feature @@ -3425,23 +3425,26 @@ k8s.io/component-base/tracing/api/v1 k8s.io/component-base/version k8s.io/component-base/version/verflag k8s.io/component-base/zpages/features -# k8s.io/component-helpers v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/component-helpers v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/component-helpers/apimachinery/lease k8s.io/component-helpers/node/topology k8s.io/component-helpers/node/util k8s.io/component-helpers/node/util/sysctl k8s.io/component-helpers/nodedeclaredfeatures k8s.io/component-helpers/nodedeclaredfeatures/features +k8s.io/component-helpers/nodedeclaredfeatures/features/extendwebsocketstokubelet k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers +k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork +k8s.io/component-helpers/nodedeclaredfeatures/types k8s.io/component-helpers/resource k8s.io/component-helpers/scheduling/corev1 k8s.io/component-helpers/scheduling/corev1/nodeaffinity k8s.io/component-helpers/storage/ephemeral k8s.io/component-helpers/storage/volume -# k8s.io/controller-manager v0.32.1 => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/controller-manager v0.32.1 => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/controller-manager/config k8s.io/controller-manager/config/v1 k8s.io/controller-manager/config/v1alpha1 @@ -3452,24 +3455,29 @@ k8s.io/controller-manager/pkg/features k8s.io/controller-manager/pkg/features/register k8s.io/controller-manager/pkg/leadermigration/config k8s.io/controller-manager/pkg/leadermigration/options -# k8s.io/cri-api v0.35.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/cri-api v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/cri-api/pkg/apis k8s.io/cri-api/pkg/apis/runtime/v1 k8s.io/cri-api/pkg/apis/testing k8s.io/cri-api/pkg/errors -# k8s.io/cri-client v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/cri-client v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/cri-client/pkg -k8s.io/cri-client/pkg/internal k8s.io/cri-client/pkg/logs k8s.io/cri-client/pkg/util -# k8s.io/csi-translation-lib v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/cri-streaming v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/cri-streaming v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 +k8s.io/cri-streaming/pkg/streaming +k8s.io/cri-streaming/pkg/streaming/internal/httpresponse +k8s.io/cri-streaming/pkg/streaming/portforward +k8s.io/cri-streaming/pkg/streaming/remotecommand +# k8s.io/csi-translation-lib v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/csi-translation-lib k8s.io/csi-translation-lib/plugins -# k8s.io/dynamic-resource-allocation v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/dynamic-resource-allocation v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/dynamic-resource-allocation/api k8s.io/dynamic-resource-allocation/cel k8s.io/dynamic-resource-allocation/deviceclass/extendedresourcecache @@ -3499,21 +3507,24 @@ k8s.io/klog/v2/internal/serialize k8s.io/klog/v2/internal/severity k8s.io/klog/v2/internal/sloghandler k8s.io/klog/v2/internal/verbosity +k8s.io/klog/v2/ktesting k8s.io/klog/v2/textlogger -# k8s.io/kms v0.35.1 -## explicit; go 1.25.0 +# k8s.io/kms v0.36.2 +## explicit; go 1.26.0 k8s.io/kms/apis/v1beta1 k8s.io/kms/apis/v2 k8s.io/kms/pkg/service k8s.io/kms/pkg/util -# k8s.io/kube-aggregator v0.35.1 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/kube-aggregator v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/kube-aggregator/pkg/apis/apiregistration k8s.io/kube-aggregator/pkg/apis/apiregistration/v1 k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1 +k8s.io/kube-aggregator/pkg/client/applyconfiguration/apiregistration/v1 +k8s.io/kube-aggregator/pkg/client/applyconfiguration/internal k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1 -# k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288 +# k8s.io/kube-openapi v0.0.0-20260718133925-74c0ba7c0470 ## explicit; go 1.24.0 k8s.io/kube-openapi/cmd/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen/args @@ -3546,13 +3557,13 @@ k8s.io/kube-openapi/pkg/validation/errors k8s.io/kube-openapi/pkg/validation/spec k8s.io/kube-openapi/pkg/validation/strfmt k8s.io/kube-openapi/pkg/validation/strfmt/bson -# k8s.io/kube-scheduler v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/kube-scheduler v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/kube-scheduler/config/v1 k8s.io/kube-scheduler/extender/v1 k8s.io/kube-scheduler/framework -# k8s.io/kubectl v0.35.0 => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/kubectl v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/kubectl/pkg/cmd/util k8s.io/kubectl/pkg/drain k8s.io/kubectl/pkg/scale @@ -3565,8 +3576,8 @@ k8s.io/kubectl/pkg/util/storage k8s.io/kubectl/pkg/util/templates k8s.io/kubectl/pkg/util/term k8s.io/kubectl/pkg/validation -# k8s.io/kubelet v0.35.0 => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/kubelet v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/kubelet/config/v1 k8s.io/kubelet/config/v1alpha1 k8s.io/kubelet/config/v1beta1 @@ -3583,13 +3594,11 @@ k8s.io/kubelet/pkg/apis/dra/v1beta1 k8s.io/kubelet/pkg/apis/pluginregistration/v1 k8s.io/kubelet/pkg/apis/podresources/v1 k8s.io/kubelet/pkg/apis/podresources/v1alpha1 +k8s.io/kubelet/pkg/apis/pods/v1alpha1 k8s.io/kubelet/pkg/apis/stats/v1alpha1 -k8s.io/kubelet/pkg/cri/streaming -k8s.io/kubelet/pkg/cri/streaming/portforward -k8s.io/kubelet/pkg/cri/streaming/remotecommand k8s.io/kubelet/pkg/types -# k8s.io/kubernetes v1.35.0 => github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/kubernetes v1.36.2 => github.com/openshift/kubernetes v1.30.1-0.20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/kubernetes/cmd/kubelet/app k8s.io/kubernetes/cmd/kubelet/app/options k8s.io/kubernetes/pkg/api/legacyscheme @@ -3626,10 +3635,12 @@ k8s.io/kubernetes/pkg/client/conditions k8s.io/kubernetes/pkg/cluster/ports k8s.io/kubernetes/pkg/controller k8s.io/kubernetes/pkg/controller/daemon +k8s.io/kubernetes/pkg/controller/daemon/metrics k8s.io/kubernetes/pkg/controller/daemon/util k8s.io/kubernetes/pkg/controller/deployment/util k8s.io/kubernetes/pkg/controller/tainteviction k8s.io/kubernetes/pkg/controller/tainteviction/metrics +k8s.io/kubernetes/pkg/controller/util/consistency k8s.io/kubernetes/pkg/controller/util/node k8s.io/kubernetes/pkg/credentialprovider k8s.io/kubernetes/pkg/credentialprovider/plugin @@ -3647,6 +3658,7 @@ k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1 k8s.io/kubernetes/pkg/kubelet/apis/config/validation k8s.io/kubernetes/pkg/kubelet/apis/grpc k8s.io/kubernetes/pkg/kubelet/apis/podresources +k8s.io/kubernetes/pkg/kubelet/apis/pods k8s.io/kubernetes/pkg/kubelet/cadvisor k8s.io/kubernetes/pkg/kubelet/certificate k8s.io/kubernetes/pkg/kubelet/certificate/bootstrap @@ -3668,6 +3680,7 @@ k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin k8s.io/kubernetes/pkg/kubelet/cm/dra/state k8s.io/kubernetes/pkg/kubelet/cm/memorymanager k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state +k8s.io/kubernetes/pkg/kubelet/cm/qos k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates k8s.io/kubernetes/pkg/kubelet/cm/topologymanager k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask @@ -3762,7 +3775,6 @@ k8s.io/kubernetes/pkg/scheduler/backend/cache k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger k8s.io/kubernetes/pkg/scheduler/backend/heap k8s.io/kubernetes/pkg/scheduler/backend/queue -k8s.io/kubernetes/pkg/scheduler/backend/workloadmanager k8s.io/kubernetes/pkg/scheduler/framework k8s.io/kubernetes/pkg/scheduler/framework/api_calls k8s.io/kubernetes/pkg/scheduler/framework/parallelize @@ -3783,10 +3795,12 @@ k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits +k8s.io/kubernetes/pkg/scheduler/framework/plugins/podgrouppodscount k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration +k8s.io/kubernetes/pkg/scheduler/framework/plugins/topologyaware k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions @@ -3814,7 +3828,6 @@ k8s.io/kubernetes/pkg/util/parsers k8s.io/kubernetes/pkg/util/pod k8s.io/kubernetes/pkg/util/removeall k8s.io/kubernetes/pkg/util/rlimit -k8s.io/kubernetes/pkg/util/slice k8s.io/kubernetes/pkg/util/tail k8s.io/kubernetes/pkg/util/taints k8s.io/kubernetes/pkg/volume @@ -3832,7 +3845,6 @@ k8s.io/kubernetes/pkg/volume/image k8s.io/kubernetes/pkg/volume/iscsi k8s.io/kubernetes/pkg/volume/local k8s.io/kubernetes/pkg/volume/nfs -k8s.io/kubernetes/pkg/volume/portworx k8s.io/kubernetes/pkg/volume/projected k8s.io/kubernetes/pkg/volume/secret k8s.io/kubernetes/pkg/volume/util @@ -3888,6 +3900,7 @@ k8s.io/kubernetes/test/e2e/framework/ssh k8s.io/kubernetes/test/e2e/framework/testfiles k8s.io/kubernetes/test/e2e/framework/volume k8s.io/kubernetes/test/e2e/framework/websocket +k8s.io/kubernetes/test/e2e/invariants/logcheck k8s.io/kubernetes/test/e2e/perftype k8s.io/kubernetes/test/e2e/reporters k8s.io/kubernetes/test/e2e/storage/drivers @@ -3902,24 +3915,34 @@ k8s.io/kubernetes/test/e2e/testing-manifests k8s.io/kubernetes/test/utils k8s.io/kubernetes/test/utils/format k8s.io/kubernetes/test/utils/image +k8s.io/kubernetes/test/utils/ktesting +k8s.io/kubernetes/test/utils/ktesting/initoption +k8s.io/kubernetes/test/utils/ktesting/internal k8s.io/kubernetes/test/utils/kubeconfig k8s.io/kubernetes/third_party/forked/golang/expansion k8s.io/kubernetes/third_party/forked/libcontainer/apparmor k8s.io/kubernetes/third_party/forked/libcontainer/utils -# k8s.io/mount-utils v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/mount-utils v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/mount-utils -# k8s.io/pod-security-admission v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260305123649-d18f3f005eaa -## explicit; go 1.25.0 +# k8s.io/pod-security-admission v0.0.0 => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 k8s.io/pod-security-admission/api k8s.io/pod-security-admission/policy k8s.io/pod-security-admission/test -# k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 -## explicit; go 1.23 +# k8s.io/streaming v0.36.2 => github.com/openshift/kubernetes/staging/src/k8s.io/streaming v0.0.0-20260716191900-78acd4d422b2 +## explicit; go 1.26.0 +k8s.io/streaming/pkg/httpstream +k8s.io/streaming/pkg/httpstream/spdy +k8s.io/streaming/pkg/httpstream/wsstream +k8s.io/streaming/pkg/runtime +# k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 +## explicit; go 1.25 k8s.io/utils/buffer k8s.io/utils/clock k8s.io/utils/clock/testing k8s.io/utils/cpuset +k8s.io/utils/dump k8s.io/utils/exec k8s.io/utils/inotify k8s.io/utils/integer @@ -3933,6 +3956,7 @@ k8s.io/utils/path k8s.io/utils/pointer k8s.io/utils/ptr k8s.io/utils/strings +k8s.io/utils/third_party/forked/golang/btree k8s.io/utils/trace # mvdan.cc/gofumpt v0.7.0 ## explicit; go 1.22 @@ -3944,14 +3968,14 @@ mvdan.cc/gofumpt/internal/version # mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f ## explicit; go 1.21 mvdan.cc/unparam/check -# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 +# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 ## explicit; go 1.21 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client -# sigs.k8s.io/controller-runtime v0.23.0 -## explicit; go 1.25.0 +# sigs.k8s.io/controller-runtime v0.24.1 +## explicit; go 1.26.0 sigs.k8s.io/controller-runtime/pkg/certwatcher sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics sigs.k8s.io/controller-runtime/pkg/client @@ -3988,8 +4012,8 @@ sigs.k8s.io/kube-storage-version-migrator/pkg/apis/migration/v1alpha1 sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset/scheme sigs.k8s.io/kube-storage-version-migrator/pkg/clients/clientset/typed/migration/v1alpha1 -# sigs.k8s.io/kustomize/api v0.20.1 -## explicit; go 1.22.7 +# sigs.k8s.io/kustomize/api v0.21.1 +## explicit; go 1.24.0 sigs.k8s.io/kustomize/api/filters/annotations sigs.k8s.io/kustomize/api/filters/fieldspec sigs.k8s.io/kustomize/api/filters/filtersutil @@ -4034,8 +4058,8 @@ sigs.k8s.io/kustomize/api/provider sigs.k8s.io/kustomize/api/resmap sigs.k8s.io/kustomize/api/resource sigs.k8s.io/kustomize/api/types -# sigs.k8s.io/kustomize/kyaml v0.20.1 -## explicit; go 1.22.7 +# sigs.k8s.io/kustomize/kyaml v0.21.1 +## explicit; go 1.24.0 sigs.k8s.io/kustomize/kyaml/comments sigs.k8s.io/kustomize/kyaml/errors sigs.k8s.io/kustomize/kyaml/ext @@ -4070,7 +4094,7 @@ sigs.k8s.io/kustomize/kyaml/yaml/walk ## explicit; go 1.18 sigs.k8s.io/randfill sigs.k8s.io/randfill/bytesource -# sigs.k8s.io/structured-merge-diff/v6 v6.3.2 +# sigs.k8s.io/structured-merge-diff/v6 v6.4.2 ## explicit; go 1.23 sigs.k8s.io/structured-merge-diff/v6/fieldpath sigs.k8s.io/structured-merge-diff/v6/merge @@ -4081,35 +4105,37 @@ sigs.k8s.io/structured-merge-diff/v6/value ## explicit; go 1.22 sigs.k8s.io/yaml sigs.k8s.io/yaml/kyaml -# github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251120221002-696928a6a0d7 -# k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/apiextensions-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/apimachinery => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/cli-runtime => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/cluster-bootstrap => github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/code-generator => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/component-base => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/component-helpers => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/cri-api => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/cri-client => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/csi-translation-lib => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/dynamic-resource-allocation => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/endpointslice => github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/externaljwt => github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kube-controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kube-proxy => github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kube-scheduler => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kubectl => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20260305123649-d18f3f005eaa -# k8s.io/metrics => github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/mount-utils => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/pod-security-admission => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/sample-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260305123649-d18f3f005eaa -# k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260305123649-d18f3f005eaa +# github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20260424201627-4d4cc33d669d +# k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/apiextensions-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/apimachinery => github.com/openshift/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cli-runtime => github.com/openshift/kubernetes/staging/src/k8s.io/cli-runtime v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/client-go => github.com/openshift/kubernetes/staging/src/k8s.io/client-go v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cloud-provider => github.com/openshift/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cluster-bootstrap => github.com/openshift/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/code-generator => github.com/openshift/kubernetes/staging/src/k8s.io/code-generator v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/component-base => github.com/openshift/kubernetes/staging/src/k8s.io/component-base v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/component-helpers => github.com/openshift/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cri-api => github.com/openshift/kubernetes/staging/src/k8s.io/cri-api v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cri-client => github.com/openshift/kubernetes/staging/src/k8s.io/cri-client v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/cri-streaming => github.com/openshift/kubernetes/staging/src/k8s.io/cri-streaming v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/csi-translation-lib => github.com/openshift/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/dynamic-resource-allocation => github.com/openshift/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/endpointslice => github.com/openshift/kubernetes/staging/src/k8s.io/endpointslice v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/externaljwt => github.com/openshift/kubernetes/staging/src/k8s.io/externaljwt v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kube-aggregator => github.com/openshift/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kube-controller-manager => github.com/openshift/kubernetes/staging/src/k8s.io/kube-controller-manager v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kube-proxy => github.com/openshift/kubernetes/staging/src/k8s.io/kube-proxy v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kube-scheduler => github.com/openshift/kubernetes/staging/src/k8s.io/kube-scheduler v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kubectl => github.com/openshift/kubernetes/staging/src/k8s.io/kubectl v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20260716191900-78acd4d422b2 +# k8s.io/metrics => github.com/openshift/kubernetes/staging/src/k8s.io/metrics v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/mount-utils => github.com/openshift/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/pod-security-admission => github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/sample-apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/sample-cli-plugin => github.com/openshift/kubernetes/staging/src/k8s.io/sample-cli-plugin v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/sample-controller => github.com/openshift/kubernetes/staging/src/k8s.io/sample-controller v0.0.0-20260716191900-78acd4d422b2 +# k8s.io/streaming => github.com/openshift/kubernetes/staging/src/k8s.io/streaming v0.0.0-20260716191900-78acd4d422b2 diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go index 0831f3e632..b94c40e439 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go @@ -102,7 +102,6 @@ type Packet struct { Type PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=PacketType" json:"type,omitempty"` // Types that are assignable to Payload: - // // *Packet_DialRequest // *Packet_DialResponse // *Packet_Data diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/errors.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/errors.go index b00e071232..1e21519250 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/errors.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/errors.go @@ -34,7 +34,7 @@ type ErrResourceDiscoveryFailed map[schema.GroupVersion]error // Error implements the error interface. func (e *ErrResourceDiscoveryFailed) Error() string { - subErrors := []string{} + subErrors := make([]string, 0, len(*e)) for k, v := range *e { subErrors = append(subErrors, fmt.Sprintf("%s: %v", k, v)) } @@ -43,7 +43,7 @@ func (e *ErrResourceDiscoveryFailed) Error() string { } func (e *ErrResourceDiscoveryFailed) Unwrap() []error { - subErrors := []error{} + subErrors := make([]error, 0, len(*e)) for gv, err := range *e { if apierrors.IsNotFound(err) { err = &meta.NoResourceMatchError{PartialResource: gv.WithResource("")} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go index 7a7a0d1145..ef5d0fee97 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/restmapper.go @@ -28,7 +28,6 @@ import ( "k8s.io/client-go/discovery" "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" - "k8s.io/utils/ptr" ) // NewDynamicRESTMapper returns a dynamic RESTMapper for cfg. The dynamic @@ -197,7 +196,7 @@ func (m *mapper) addKnownGroupAndReload(groupName string, versions ...string) er } } if len(failedGroups) > 0 { - return ptr.To(ErrResourceDiscoveryFailed(failedGroups)) + return new(ErrResourceDiscoveryFailed(failedGroups)) } return nil } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/applyconfigurations.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/applyconfigurations.go index 97192050f9..3a1864847d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/applyconfigurations.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/applyconfigurations.go @@ -39,28 +39,6 @@ func ApplyConfigurationFromUnstructured(u *unstructured.Unstructured) runtime.Ap return &unstructuredApplyConfiguration{Unstructured: u} } -type applyconfigurationRuntimeObject struct { - runtime.ApplyConfiguration -} - -func (a *applyconfigurationRuntimeObject) GetObjectKind() schema.ObjectKind { - return a -} - -func (a *applyconfigurationRuntimeObject) GroupVersionKind() schema.GroupVersionKind { - return schema.GroupVersionKind{} -} - -func (a *applyconfigurationRuntimeObject) SetGroupVersionKind(gvk schema.GroupVersionKind) {} - -func (a *applyconfigurationRuntimeObject) DeepCopyObject() runtime.Object { - panic("applyconfigurationRuntimeObject does not support DeepCopyObject") -} - -func runtimeObjectFromApplyConfiguration(ac runtime.ApplyConfiguration) runtime.Object { - return &applyconfigurationRuntimeObject{ApplyConfiguration: ac} -} - func gvkFromApplyConfiguration(ac applyConfiguration) (schema.GroupVersionKind, error) { var gvk schema.GroupVersionKind gv, err := schema.ParseGroupVersion(ptr.Deref(ac.GetAPIVersion(), "")) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go index a6b921171a..c5bd9f0b8c 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go @@ -21,7 +21,6 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" - "k8s.io/utils/ptr" ) // {{{ "Functional" Option Interfaces @@ -741,12 +740,12 @@ type UnsafeDisableDeepCopyOption bool // ApplyToGet applies this configuration to the given an Get options. func (d UnsafeDisableDeepCopyOption) ApplyToGet(opts *GetOptions) { - opts.UnsafeDisableDeepCopy = ptr.To(bool(d)) + opts.UnsafeDisableDeepCopy = new(bool(d)) } // ApplyToList applies this configuration to the given an List options. func (d UnsafeDisableDeepCopyOption) ApplyToList(opts *ListOptions) { - opts.UnsafeDisableDeepCopy = ptr.To(bool(d)) + opts.UnsafeDisableDeepCopy = new(bool(d)) } // UnsafeDisableDeepCopy indicates not to deep copy objects during list objects. @@ -953,19 +952,19 @@ var ForceOwnership = forceOwnership{} type forceOwnership struct{} func (forceOwnership) ApplyToPatch(opts *PatchOptions) { - opts.Force = ptr.To(true) + opts.Force = new(true) } func (forceOwnership) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) { - opts.Force = ptr.To(true) + opts.Force = new(true) } func (forceOwnership) ApplyToApply(opts *ApplyOptions) { - opts.Force = ptr.To(true) + opts.Force = new(true) } func (forceOwnership) ApplyToSubResourceApply(opts *SubResourceApplyOptions) { - opts.Force = ptr.To(true) + opts.Force = new(true) } // }}} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go index 66ae2e4a5c..5a85941725 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go @@ -21,6 +21,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/json" "k8s.io/client-go/util/apply" ) @@ -146,17 +147,29 @@ func (c *typedClient) Apply(ctx context.Context, obj runtime.ApplyConfiguration, applyOpts := &ApplyOptions{} applyOpts.ApplyOptions(opts) - return req. + resp := req. NamespaceIfScoped(o.namespace, o.isNamespaced()). Resource(o.resource()). Name(o.name). VersionedParams(applyOpts.AsPatchOptions(), c.paramCodec). - Do(ctx). - // This is hacky, it is required because `Into` takes a `runtime.Object` and - // that is not implemented by the ApplyConfigurations. The generated clients - // don't have this problem because they deserialize into the api type, not the - // apply configuration: https://github.com/kubernetes/kubernetes/blob/22f5e01a37c0bc6a5f494dec14dd4e3688ee1d55/staging/src/k8s.io/client-go/gentype/type.go#L296-L317 - Into(runtimeObjectFromApplyConfiguration(obj)) + Do(ctx) + if err := resp.Error(); err != nil { + return err + } + + var contentType string + body, err := resp. + ContentType(&contentType). + Raw() + if err != nil { + return err + } + + if contentType != "application/json" { + return fmt.Errorf("unexpected content type %q in apply response, expected application/json", contentType) + } + + return json.Unmarshal(body, obj) } // Get implements client.Client. @@ -324,16 +337,28 @@ func (c *typedClient) ApplySubResource(ctx context.Context, obj runtime.ApplyCon return fmt.Errorf("failed to create apply request: %w", err) } - return req. + resp := req. NamespaceIfScoped(o.namespace, o.isNamespaced()). Resource(o.resource()). Name(o.name). SubResource(subResource). VersionedParams(applyOpts.AsPatchOptions(), c.paramCodec). - Do(ctx). - // This is hacky, it is required because `Into` takes a `runtime.Object` and - // that is not implemented by the ApplyConfigurations. The generated clients - // don't have this problem because they deserialize into the api type, not the - // apply configuration: https://github.com/kubernetes/kubernetes/blob/22f5e01a37c0bc6a5f494dec14dd4e3688ee1d55/staging/src/k8s.io/client-go/gentype/type.go#L296-L317 - Into(runtimeObjectFromApplyConfiguration(obj)) + Do(ctx) + if err := resp.Error(); err != nil { + return err + } + + var contentType string + respBody, err := resp. + ContentType(&contentType). + Raw() + if err != nil { + return err + } + + if contentType != "application/json" { + return fmt.Errorf("unexpected content type %q in apply response, expected application/json", contentType) + } + + return json.Unmarshal(respBody, obj) } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go index 8ed2224cfe..da9b4fb67d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go @@ -38,7 +38,6 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/util/retry" - "k8s.io/utils/ptr" "sigs.k8s.io/yaml" "sigs.k8s.io/controller-runtime/pkg/client" @@ -362,7 +361,7 @@ func modifyConversionWebhooks(crds []*apiextensionsv1.CustomResourceDefinition, if err != nil { return err } - url := ptr.To(fmt.Sprintf("https://%s/convert", hostPort)) + url := new(fmt.Sprintf("https://%s/convert", hostPort)) for i := range crds { // Continue if we're preserving unknown fields. diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go index 2bdf0c7c47..d2332b7ddf 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/procattr_unix.go @@ -24,7 +24,7 @@ import ( // GetSysProcAttr returns the SysProcAttr to use for the process, // for unix systems this returns a SysProcAttr with Setpgid set to true, -// which inherits the parent's process group id. +// which creates a new process group for the child process. func GetSysProcAttr() *unix.SysProcAttr { return &unix.SysProcAttr{ Setpgid: true, diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go index 0d541921e2..f1bfda425f 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go @@ -193,7 +193,7 @@ func (ps *State) Start(stdout, stderr io.Writer) (err error) { close(pollerStopCh) if ps.Cmd != nil { // intentionally ignore this -- we might've crashed, failed to start, etc - ps.Cmd.Process.Signal(syscall.SIGTERM) //nolint:errcheck + _ = signalProcess(ps.Cmd.Process, syscall.SIGTERM) } return fmt.Errorf("timeout waiting for process %s to start", path.Base(ps.Path)) } @@ -256,7 +256,7 @@ func (ps *State) Stop() error { if done, _ := ps.Exited(); done { return nil } - if err := ps.Cmd.Process.Signal(syscall.SIGTERM); err != nil { + if err := signalProcess(ps.Cmd.Process, syscall.SIGTERM); err != nil { return fmt.Errorf("unable to signal for process %s to stop: %w", ps.Path, err) } @@ -266,7 +266,7 @@ func (ps *State) Stop() error { case <-ps.waitDone: break case <-timedOut: - if err := ps.Cmd.Process.Signal(syscall.SIGKILL); err != nil { + if err := signalProcess(ps.Cmd.Process, syscall.SIGKILL); err != nil { return fmt.Errorf("unable to kill process %s: %w", ps.Path, err) } return fmt.Errorf("timeout waiting for process %s to stop", path.Base(ps.Path)) diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.protomessage.pb.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_other.go similarity index 65% rename from vendor/k8s.io/apimachinery/pkg/api/resource/generated.protomessage.pb.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_other.go index 712e155c3e..5cbce8f416 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/resource/generated.protomessage.pb.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_other.go @@ -1,8 +1,7 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release +//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos /* -Copyright The Kubernetes Authors. +Copyright 2026 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. @@ -17,10 +16,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. +package process -package resource +import ( + "os" + "syscall" +) -func (*Quantity) ProtoMessage() {} - -func (*QuantityValue) ProtoMessage() {} +func signalProcess(process *os.Process, sig syscall.Signal) error { + return process.Signal(sig) +} diff --git a/vendor/k8s.io/api/scheduling/v1beta1/generated.protomessage.pb.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_unix.go similarity index 64% rename from vendor/k8s.io/api/scheduling/v1beta1/generated.protomessage.pb.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_unix.go index 0c7339ae79..d86fc97213 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/generated.protomessage.pb.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/signal_unix.go @@ -1,8 +1,7 @@ -//go:build kubernetes_protomessage_one_more_release -// +build kubernetes_protomessage_one_more_release +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos /* -Copyright The Kubernetes Authors. +Copyright 2026 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. @@ -17,10 +16,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by go-to-protobuf. DO NOT EDIT. +package process -package v1beta1 +import ( + "os" + "syscall" +) -func (*PriorityClass) ProtoMessage() {} - -func (*PriorityClassList) ProtoMessage() {} +func signalProcess(process *os.Process, sig syscall.Signal) error { + return syscall.Kill(-process.Pid, sig) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go index 55ebe21773..30f6d89a0a 100644 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go @@ -60,6 +60,35 @@ import ( ) // Builder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds. +// +// Deprecated: This helper is only useful in api packages, but api packages should be +// easy to import and hence have minimal dependencies. Typically, these dependencies +// include only the standard library, k8s.io/apimachinery and other api packages. +// +// Use the apimachinery builder instead: +// +// import ( +// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +// "k8s.io/apimachinery/pkg/runtime" +// "k8s.io/apimachinery/pkg/runtime/schema" +// ) +// +// const GroupName = "" +// +// var ( +// SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} +// SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) +// AddToScheme = SchemeBuilder.AddToScheme +// ) +// +// func addKnownTypes(scheme *runtime.Scheme) error { +// scheme.AddKnownTypes(SchemeGroupVersion, +// &Pod{}, +// ) +// +// metav1.AddToGroupVersion(scheme, SchemeGroupVersion) +// return nil +// } type Builder struct { GroupVersion schema.GroupVersion runtime.SchemeBuilder diff --git a/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go b/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go index ff83420cb1..c25cf82823 100644 --- a/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go +++ b/vendor/sigs.k8s.io/kustomize/api/filters/nameref/nameref.go @@ -205,16 +205,14 @@ func getRoleRefGvk(n *resource.Resource) (*resid.Gvk, error) { return nil, err } if apiGroup.IsNil() { - return nil, fmt.Errorf( - "apiGroup cannot be found in roleRef %s", roleRef.MustString()) + return nil, fmt.Errorf("apiGroup cannot be found in roleRef %s", roleRef.MustString()) } kind, err := roleRef.Pipe(yaml.Lookup("kind")) if err != nil { return nil, err } if kind.IsNil() { - return nil, fmt.Errorf( - "kind cannot be found in roleRef %s", roleRef.MustString()) + return nil, fmt.Errorf("kind cannot be found in roleRef %s", roleRef.MustString()) } return &resid.Gvk{ Group: apiGroup.YNode().Value, diff --git a/vendor/sigs.k8s.io/kustomize/api/filters/replacement/replacement.go b/vendor/sigs.k8s.io/kustomize/api/filters/replacement/replacement.go index 56e70d8756..8afc646d26 100644 --- a/vendor/sigs.k8s.io/kustomize/api/filters/replacement/replacement.go +++ b/vendor/sigs.k8s.io/kustomize/api/filters/replacement/replacement.go @@ -4,6 +4,7 @@ package replacement import ( + "encoding/json" "fmt" "strings" @@ -11,7 +12,6 @@ import ( "sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/errors" - "sigs.k8s.io/kustomize/kyaml/resid" kyaml_utils "sigs.k8s.io/kustomize/kyaml/utils" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -117,6 +117,10 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors [] if len(selector.FieldPaths) == 0 { selector.FieldPaths = []string{types.DefaultReplacementFieldPath} } + tsr, err := types.NewTargetSelectorRegex(selector) + if err != nil { + return nil, fmt.Errorf("error creating target selector: %w", err) + } for _, possibleTarget := range nodes { ids, err := utils.MakeResIds(possibleTarget) if err != nil { @@ -132,9 +136,13 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors [] continue } + if tsr.RejectsAny(ids) { + continue + } + // filter targets by matching resource IDs for _, id := range ids { - if id.IsSelectedBy(selector.Select.ResId) && !containsRejectId(selector.Reject, ids) { + if tsr.Selects(id) { err := copyValueToTarget(possibleTarget, value, selector) if err != nil { return nil, err @@ -175,43 +183,37 @@ func matchesAnnoAndLabelSelector(n *yaml.RNode, selector *types.Selector) (bool, return annoMatch && labelMatch, nil } -func containsRejectId(rejects []*types.Selector, ids []resid.ResId) bool { - for _, r := range rejects { - if r.ResId.IsEmpty() { - continue - } - for _, id := range ids { - if id.IsSelectedBy(r.ResId) { - return true - } - } - } - return false -} - func copyValueToTarget(target *yaml.RNode, value *yaml.RNode, selector *types.TargetSelector) error { for _, fp := range selector.FieldPaths { createKind := yaml.Kind(0) // do not create if selector.Options != nil && selector.Options.Create { createKind = value.YNode().Kind } + + // Check if this fieldPath contains structured data access + if err := setValueInStructuredData(target, value, fp, createKind); err == nil { + // Successfully handled as structured data + continue + } + + // Fall back to normal path handling targetFieldList, err := target.Pipe(&yaml.PathMatcher{ Path: kyaml_utils.SmarterPathSplitter(fp, "."), Create: createKind}) if err != nil { - return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0)) //nolint:govet + return errors.WrapPrefixf(err, "%s", fieldRetrievalError(fp, createKind != 0)) } targetFields, err := targetFieldList.Elements() if err != nil { - return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0)) //nolint:govet + return errors.WrapPrefixf(err, "%s", fieldRetrievalError(fp, createKind != 0)) } if len(targetFields) == 0 { - return errors.Errorf(fieldRetrievalError(fp, createKind != 0)) //nolint:govet + return errors.Errorf("%s", fieldRetrievalError(fp, createKind != 0)) } for _, t := range targetFields { if err := setFieldValue(selector.Options, t, value); err != nil { - return err + return fmt.Errorf("%w", err) } } } @@ -254,3 +256,146 @@ func setFieldValue(options *types.FieldOptions, targetField *yaml.RNode, value * return nil } + +// setValueInStructuredData handles setting values within structured data (JSON/YAML) in scalar fields +func setValueInStructuredData(target *yaml.RNode, value *yaml.RNode, fieldPath string, createKind yaml.Kind) error { + pathParts := kyaml_utils.SmarterPathSplitter(fieldPath, ".") + if len(pathParts) < 2 { + return fmt.Errorf("not a structured data path") + } + + // Find the potential scalar field that might contain structured data + var scalarFieldPath []string + var structuredDataPath []string + var foundScalar = false + + // Try to find where the scalar field ends and structured data begins + for i := 1; i <= len(pathParts); i++ { + potentialScalarPath := pathParts[:i] + scalarField, err := target.Pipe(yaml.Lookup(potentialScalarPath...)) + if err != nil { + continue + } + if scalarField != nil && scalarField.YNode().Kind == yaml.ScalarNode && i < len(pathParts) { + // Try to parse the scalar value as structured data + scalarValue := scalarField.YNode().Value + var parsedNode yaml.Node + if err := yaml.Unmarshal([]byte(scalarValue), &parsedNode); err == nil { + // Successfully parsed - this is structured data + scalarFieldPath = potentialScalarPath + structuredDataPath = pathParts[i:] + foundScalar = true + break + } + } + } + + if !foundScalar { + return fmt.Errorf("no structured data found in path") + } + + // Get the scalar field containing structured data + scalarField, err := target.Pipe(yaml.Lookup(scalarFieldPath...)) + if err != nil { + return fmt.Errorf("%w", err) + } + + // Parse the structured data + scalarValue := scalarField.YNode().Value + var parsedNode yaml.Node + if err := yaml.Unmarshal([]byte(scalarValue), &parsedNode); err != nil { + return fmt.Errorf("%w", err) + } + + structuredData := yaml.NewRNode(&parsedNode) + + // Navigate to the target location within the structured data + targetInStructured, err := structuredData.Pipe(&yaml.PathMatcher{ + Path: structuredDataPath, + Create: createKind, + }) + if err != nil { + return fmt.Errorf("%w", err) + } + + targetFields, err := targetInStructured.Elements() + if err != nil { + return fmt.Errorf("%w", err) + } + + if len(targetFields) == 0 { + return fmt.Errorf("unable to find field in structured data") + } + + // Set the value in the structured data + for _, t := range targetFields { + if t.YNode().Kind == yaml.ScalarNode { + t.YNode().Value = value.YNode().Value + } else { + t.SetYNode(value.YNode()) + } + } + + // Serialize the modified structured data back to the scalar field + // Try to detect if original was JSON or YAML and preserve formatting + serializedData, err := serializeStructuredData(structuredData, scalarValue) + if err != nil { + return fmt.Errorf("%w", err) + } + + // Update the original scalar field + scalarField.YNode().Value = serializedData + + return nil +} + +// serializeStructuredData handles the serialization of structured data back to string format +// preserving the original format (JSON vs YAML) and style (pretty vs compact) +func serializeStructuredData(structuredData *yaml.RNode, originalValue string) (string, error) { + firstChar := rune(strings.TrimSpace(originalValue)[0]) + if firstChar == '{' || firstChar == '[' { + return serializeAsJSON(structuredData, originalValue) + } + + // Fallback to YAML format + return serializeAsYAML(structuredData) +} + +// serializeAsJSON converts structured data back to JSON format +func serializeAsJSON(structuredData *yaml.RNode, originalValue string) (string, error) { + modifiedData, err := structuredData.String() + if err != nil { + return "", fmt.Errorf("failed to serialize structured data: %w", err) + } + + // Parse the YAML output as JSON + var jsonData interface{} + if err := yaml.Unmarshal([]byte(modifiedData), &jsonData); err != nil { + return "", fmt.Errorf("failed to unmarshal YAML data: %w", err) + } + + // Check if original was pretty-printed by looking for newlines and indentation + if strings.Contains(originalValue, "\n") && strings.Contains(originalValue, " ") { + // Pretty-print the JSON to match original formatting + if prettyJSON, err := json.MarshalIndent(jsonData, "", " "); err == nil { + return string(prettyJSON), nil + } + } + + // Compact JSON + if compactJSON, err := json.Marshal(jsonData); err == nil { + return string(compactJSON), nil + } + + return "", fmt.Errorf("failed to marshal JSON data") +} + +// serializeAsYAML converts structured data back to YAML format +func serializeAsYAML(structuredData *yaml.RNode) (string, error) { + modifiedData, err := structuredData.String() + if err != nil { + return "", fmt.Errorf("failed to serialize YAML data: %w", err) + } + + return strings.TrimSpace(modifiedData), nil +} diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/AnnotationsTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/AnnotationsTransformer.go index 0910c472b8..d3b3fc8c20 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/AnnotationsTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/AnnotationsTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on AnnotationsTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ConfigMapGenerator.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ConfigMapGenerator.go index dc18bce858..180a6c2c11 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ConfigMapGenerator.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ConfigMapGenerator.go @@ -1,6 +1,4 @@ // Code generated by pluginator on ConfigMapGenerator; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HashTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HashTransformer.go index ec23312651..08dd37d063 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HashTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HashTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on HashTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HelmChartInflationGenerator.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HelmChartInflationGenerator.go index 5811e73eca..aed01081a2 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HelmChartInflationGenerator.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/HelmChartInflationGenerator.go @@ -1,6 +1,4 @@ // Code generated by pluginator on HelmChartInflationGenerator; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( @@ -13,6 +11,7 @@ import ( "slices" "strings" + "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/errors" @@ -178,12 +177,11 @@ func (p *HelmChartInflationGeneratorPlugin) runHelmCommand( } if err != nil { helm := p.h.GeneralConfig().HelmConfig.Command - //nolint:govet err = errors.WrapPrefixf( fmt.Errorf( "unable to run: '%s %s' with env=%s (is '%s' installed?): %w", helm, strings.Join(args, " "), env, helm, err), - errorOutput, + "%s", errorOutput, ) } return stdout.Bytes(), err @@ -297,6 +295,9 @@ func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err er rm, resMapErr := p.h.ResmapFactory().NewResMapFromBytes(stdout) if resMapErr == nil { + if err := p.markHelmGeneratedResources(rm); err != nil { + return nil, err + } return rm, nil } // try to remove the contents before first "---" because @@ -312,6 +313,9 @@ func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err er if err != nil { return nil, fmt.Errorf("could not parse rnode slice into resource map: %w", err) } + if err := p.markHelmGeneratedResources(rm); err != nil { + return nil, err + } return rm, nil } return nil, fmt.Errorf("could not parse bytes into resource map: %w", resMapErr) @@ -354,9 +358,18 @@ func (p *HelmChartInflationGeneratorPlugin) chartExistsLocally() (string, bool) return path, s.IsDir() } -// checkHelmVersion will return an error if the helm version is not V3 +func (p *HelmChartInflationGeneratorPlugin) markHelmGeneratedResources(rm resmap.ResMap) error { + for _, r := range rm.Resources() { + if err := r.RNode.PipeE(kyaml.SetAnnotation(konfig.HelmGeneratedAnnotation, "true")); err != nil { + return fmt.Errorf("failed to set helm annotation: %w", err) + } + } + return nil +} + +// checkHelmVersion will return an error if the helm version is not V3 or V4 func (p *HelmChartInflationGeneratorPlugin) checkHelmVersion() error { - stdout, err := p.runHelmCommand([]string{"version", "-c", "--short"}) + stdout, err := p.runHelmCommand([]string{"version", "--short"}) if err != nil { return err } @@ -372,8 +385,8 @@ func (p *HelmChartInflationGeneratorPlugin) checkHelmVersion() error { v = v[1:] } majorVersion := strings.Split(v, ".")[0] - if majorVersion != "3" { - return fmt.Errorf("this plugin requires helm V3 but got v%s", v) + if majorVersion != "3" && majorVersion != "4" { + return fmt.Errorf("this plugin requires helm V3 or V4 but got v%s", v) } return nil } diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/IAMPolicyGenerator.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/IAMPolicyGenerator.go index cfb1fa81b6..314e60c7c4 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/IAMPolicyGenerator.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/IAMPolicyGenerator.go @@ -1,6 +1,4 @@ // Code generated by pluginator on IAMPolicyGenerator; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ImageTagTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ImageTagTransformer.go index ffde73a7a1..c5284cb70d 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ImageTagTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ImageTagTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on ImageTagTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/LabelTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/LabelTransformer.go index c45731b54b..8ebbd19f78 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/LabelTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/LabelTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on LabelTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/NamespaceTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/NamespaceTransformer.go index d839fb9751..3b98195b3f 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/NamespaceTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/NamespaceTransformer.go @@ -1,12 +1,11 @@ // Code generated by pluginator on NamespaceTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( "fmt" "sigs.k8s.io/kustomize/api/filters/namespace" + "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/errors" @@ -53,6 +52,10 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error { // Don't mutate empty objects? continue } + if annotations := r.GetAnnotations(konfig.HelmGeneratedAnnotation); annotations[konfig.HelmGeneratedAnnotation] == "true" { + // Don't apply namespace on Helm generated manifest. Helm should take care of it. + continue + } r.StorePreviousId() if err := r.ApplyFilter(namespace.Filter{ Namespace: p.Namespace, diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchJson6902Transformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchJson6902Transformer.go index 04625e5109..348863263f 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchJson6902Transformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchJson6902Transformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on PatchJson6902Transformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchStrategicMergeTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchStrategicMergeTransformer.go index d68f2425ea..29f8f2b9d7 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchStrategicMergeTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchStrategicMergeTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on PatchStrategicMergeTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchTransformer.go index 05d96f23ca..442291d11c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PatchTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on PatchTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( @@ -24,10 +22,10 @@ type PatchTransformerPlugin struct { patchText string // patchSource is patch source message patchSource string - Path string `json:"path,omitempty" yaml:"path,omitempty"` - Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` - Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` - Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` + Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` + Options *types.PatchArgs `json:"options,omitempty" yaml:"options,omitempty"` } func (p *PatchTransformerPlugin) Config(h *resmap.PluginHelpers, c []byte) error { @@ -70,10 +68,14 @@ func (p *PatchTransformerPlugin) Config(h *resmap.PluginHelpers, c []byte) error if errSM == nil { p.smPatches = patchesSM for _, loadedPatch := range p.smPatches { - if p.Options["allowNameChange"] { + if p.Options == nil { + continue + } + + if p.Options.AllowNameChange { loadedPatch.AllowNameChange() } - if p.Options["allowKindChange"] { + if p.Options.AllowKindChange { loadedPatch.AllowKindChange() } } @@ -87,7 +89,10 @@ func (p *PatchTransformerPlugin) Transform(m resmap.ResMap) error { if p.smPatches != nil { return p.transformStrategicMerge(m) } - return p.transformJson6902(m) + if p.jsonPatches != nil { + return p.transformJson6902(m) + } + return nil } // transformStrategicMerge applies each loaded strategic merge patch diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PrefixTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PrefixTransformer.go index 33700bb4b1..fc26de228f 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PrefixTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/PrefixTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on PrefixTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplacementTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplacementTransformer.go index ef0c932128..795af7b87b 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplacementTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplacementTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on ReplacementTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplicaCountTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplicaCountTransformer.go index c87d64251c..afbd4b105c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplicaCountTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ReplicaCountTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on ReplicaCountTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SecretGenerator.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SecretGenerator.go index 2a4ef1c903..fbb4efa402 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SecretGenerator.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SecretGenerator.go @@ -1,6 +1,4 @@ // Code generated by pluginator on SecretGenerator; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SortOrderTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SortOrderTransformer.go index 90e290719e..8b88b129f9 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SortOrderTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SortOrderTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on SortOrderTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SuffixTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SuffixTransformer.go index 31b5b8fea0..2999711ab6 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SuffixTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/SuffixTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on SuffixTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ValueAddTransformer.go b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ValueAddTransformer.go index 1d70c98c2c..2bab5b6b66 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ValueAddTransformer.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/builtins/ValueAddTransformer.go @@ -1,6 +1,4 @@ // Code generated by pluginator on ValueAddTransformer; DO NOT EDIT. -// pluginator {(devel) unknown } - package builtins import ( diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/loader/fileloader.go b/vendor/sigs.k8s.io/kustomize/api/internal/loader/fileloader.go index 69b8295eb7..e4202815c9 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/loader/fileloader.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/loader/fileloader.go @@ -169,7 +169,7 @@ func (fl *FileLoader) New(path string) (ifc.Loader, error) { } root, err := filesys.ConfirmDir(fl.fSys, fl.root.Join(path)) if err != nil { - return nil, errors.WrapPrefixf(err, ErrRtNotDir.Error()) //nolint:govet + return nil, errors.WrapPrefixf(err, "%s", ErrRtNotDir.Error()) } if err = fl.errIfGitContainmentViolation(root); err != nil { return nil, err @@ -311,7 +311,11 @@ func (fl *FileLoader) httpClientGetContent(path string) ([]byte, error) { } else { hc = &http.Client{} } - resp, err := hc.Get(path) + parsedURL, err := url.ParseRequestURI(path) + if err != nil { + return nil, errors.Wrap(err) + } + resp, err := hc.Get(parsedURL.String()) if err != nil { return nil, errors.Wrap(err) } diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/loader/loader.go b/vendor/sigs.k8s.io/kustomize/api/internal/loader/loader.go index 60b254fa7e..36b246fb4e 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/loader/loader.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/loader/loader.go @@ -28,7 +28,7 @@ func NewLoader( } root, err := filesys.ConfirmDir(fSys, target) if err != nil { - return nil, errors.WrapPrefixf(err, ErrRtNotDir.Error()) //nolint:govet + return nil, errors.WrapPrefixf(err, "%s", ErrRtNotDir.Error()) } return newLoaderAtConfirmedDir( lr, root, fSys, nil, git.ClonerUsingGitExec), nil diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/execplugin/execplugin.go b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/execplugin/execplugin.go index f6c1dba3ce..f6cc0b53f5 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/execplugin/execplugin.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/execplugin/execplugin.go @@ -161,14 +161,13 @@ func (p *ExecPlugin) invokePlugin(input []byte) ([]byte, error) { _, err = f.Write(p.cfg) if err != nil { return nil, errors.WrapPrefixf( - err, "writing plugin config to "+f.Name()) + err, "writing plugin config to %s", f.Name()) } err = f.Close() if err != nil { return nil, errors.WrapPrefixf( - err, "closing plugin config file "+f.Name()) + err, "closing plugin config file %s", f.Name()) } - //nolint:gosec cmd := exec.Command( p.path, append([]string{f.Name()}, p.args...)...) cmd.Env = p.getEnv() @@ -180,10 +179,9 @@ func (p *ExecPlugin) invokePlugin(input []byte) ([]byte, error) { } result, err := cmd.Output() if err != nil { - //nolint:govet return nil, errors.WrapPrefixf( - fmt.Errorf("failure in plugin configured via %s; %w", - f.Name(), err), stdErr.String()) + fmt.Errorf("failure in plugin configured via %s; %w", f.Name(), err), + "%s", stdErr.String()) } return result, os.Remove(f.Name()) } diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go index 2edf8791ff..afae8940df 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/plugins/loader/loader.go @@ -251,7 +251,7 @@ func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) return nil, errors.Errorf("plugin %s with mount path '%s' is not permitted; "+ "mount paths must be relative to the current kustomization directory", res.OrgId(), mount.Src) } - if strings.HasPrefix(filepath.Clean(mount.Src), "../") { + if strings.HasPrefix(filepath.Clean(mount.Src), "..") { return nil, errors.Errorf("plugin %s with mount path '%s' is not permitted; "+ "mount paths must be under the current kustomization directory", res.OrgId(), mount.Src) } diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go index 5f1d1095a1..eeb23bf70c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget.go @@ -29,13 +29,14 @@ import ( // KustTarget encapsulates the entirety of a kustomization build. type KustTarget struct { - kustomization *types.Kustomization - kustFileName string - ldr ifc.Loader - validator ifc.Validator - rFactory *resmap.Factory - pLdr *loader.Loader - origin *resource.Origin + kustomization *types.Kustomization + kustFileName string + ldr ifc.Loader + validator ifc.Validator + rFactory *resmap.Factory + pLdr *loader.Loader + origin *resource.Origin + helmRootNamespace string // namespace inherited from parent kustomization for HelmCharts } // NewKustTarget returns a new instance of KustTarget. @@ -496,6 +497,16 @@ func (kt *KustTarget) accumulateDirectory( } subKt.kustomization.BuildMetadata = kt.kustomization.BuildMetadata subKt.origin = kt.origin + // Propagate namespace to child kustomization's helmRootNamespace for HelmCharts + // This ensures Helm charts in base kustomizations inherit namespace from overlays + // without affecting other transformers like patches + // Fixes https://github.com/kubernetes-sigs/kustomize/issues/6031 + // Fixes https://github.com/kubernetes-sigs/kustomize/issues/6027 + if kt.kustomization.Namespace != "" { + subKt.helmRootNamespace = kt.kustomization.Namespace + } else if kt.helmRootNamespace != "" { + subKt.helmRootNamespace = kt.helmRootNamespace + } var bytes []byte if openApiPath, exists := subKt.Kustomization().OpenAPI["path"]; exists { bytes, err = ldr.Load(openApiPath) diff --git a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go index 1ba028a36f..aa57e1295c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go +++ b/vendor/sigs.k8s.io/kustomize/api/internal/target/kusttarget_configplugin.go @@ -166,6 +166,16 @@ var generatorConfigurators = map[builtinhelpers.BuiltinPluginType]func( for _, chart := range kt.kustomization.HelmCharts { c.HelmGlobals = globals c.HelmChart = chart + // Pass kustomize namespace to helm + // Fixes https://github.com/kubernetes-sigs/kustomize/issues/5566 + // Also propagate parent namespace for multi-level kustomization hierarchies + if c.HelmChart.Namespace == "" { + if kt.kustomization.Namespace != "" { + c.HelmChart.Namespace = kt.kustomization.Namespace + } else if kt.helmRootNamespace != "" { + c.HelmChart.Namespace = kt.helmRootNamespace + } + } p := f() if err = kt.configureBuiltinPlugin(p, c, bpt); err != nil { return nil, err @@ -250,10 +260,10 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func( return } var c struct { - Path string `json:"path,omitempty" yaml:"path,omitempty"` - Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` - Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` - Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Patch string `json:"patch,omitempty" yaml:"patch,omitempty"` + Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"` + Options *types.PatchArgs `json:"options,omitempty" yaml:"options,omitempty"` } for _, pc := range kt.kustomization.Patches { c.Target = pc.Target diff --git a/vendor/sigs.k8s.io/kustomize/api/konfig/general.go b/vendor/sigs.k8s.io/kustomize/api/konfig/general.go index 712bfe7894..c661883883 100644 --- a/vendor/sigs.k8s.io/kustomize/api/konfig/general.go +++ b/vendor/sigs.k8s.io/kustomize/api/konfig/general.go @@ -46,4 +46,7 @@ const ( // Label key that indicates the resources are validated by a validator ValidatedByLabelKey = "validated-by" + + // Annotation key for marking helm-generated resources to skip namespace transformation + HelmGeneratedAnnotation = ConfigAnnoDomain + "/helm-generated" ) diff --git a/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go b/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go index f6443539f1..33578a0bbe 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go +++ b/vendor/sigs.k8s.io/kustomize/api/resmap/reswrangler.go @@ -597,7 +597,7 @@ func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error { default: return fmt.Errorf( - "id %#v exists; behavior must be merge or replace", id) + "id %#v exists; can not use behavior: '%s', behavior must be merge or replace", id, res.Behavior()) } i, err := m.Replace(res) if err != nil { diff --git a/vendor/sigs.k8s.io/kustomize/api/resource/resource.go b/vendor/sigs.k8s.io/kustomize/api/resource/resource.go index 9884a672c5..dc6995799b 100644 --- a/vendor/sigs.k8s.io/kustomize/api/resource/resource.go +++ b/vendor/sigs.k8s.io/kustomize/api/resource/resource.go @@ -11,6 +11,7 @@ import ( "sigs.k8s.io/kustomize/api/filters/patchstrategicmerge" "sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/internal/utils" + "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" @@ -47,6 +48,8 @@ var BuildAnnotations = []string{ kioutil.LegacyPathAnnotation, kioutil.LegacyIndexAnnotation, kioutil.LegacyIdAnnotation, + + konfig.HelmGeneratedAnnotation, } func (r *Resource) ResetRNode(incoming *Resource) { diff --git a/vendor/sigs.k8s.io/kustomize/api/types/patch.go b/vendor/sigs.k8s.io/kustomize/api/types/patch.go index 5310a6e66d..7ad141975c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/patch.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/patch.go @@ -3,8 +3,6 @@ package types -import "reflect" - // Patch represent either a Strategic Merge Patch or a JSON patch // and its targets. // The content of the patch can either be from a file @@ -20,15 +18,17 @@ type Patch struct { Target *Selector `json:"target,omitempty" yaml:"target,omitempty"` // Options is a list of options for the patch - Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"` + Options *PatchArgs `json:"options,omitempty" yaml:"options,omitempty"` } // Equals return true if p equals o. func (p *Patch) Equals(o Patch) bool { targetEqual := (p.Target == o.Target) || (p.Target != nil && o.Target != nil && *p.Target == *o.Target) + optionsEqual := (p.Options == o.Options) || + (p.Options != nil && o.Options != nil && *p.Options == *o.Options) return p.Path == o.Path && p.Patch == o.Patch && targetEqual && - reflect.DeepEqual(p.Options, o.Options) + optionsEqual } diff --git a/vendor/sigs.k8s.io/kustomize/api/types/patchargs.go b/vendor/sigs.k8s.io/kustomize/api/types/patchargs.go new file mode 100644 index 0000000000..453849fa6b --- /dev/null +++ b/vendor/sigs.k8s.io/kustomize/api/types/patchargs.go @@ -0,0 +1,13 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package types + +// PatchArgs represent set of options on resources of a patch. +type PatchArgs struct { + // AllowNameChange allows name changes to the resource. + AllowNameChange bool `json:"allowNameChange,omitempty" yaml:"allowNameChange,omitempty"` + + // AllowKindChange allows kind changes to the resource. + AllowKindChange bool `json:"allowKindChange,omitempty" yaml:"allowKindChange,omitempty"` +} diff --git a/vendor/sigs.k8s.io/kustomize/api/types/replacement.go b/vendor/sigs.k8s.io/kustomize/api/types/replacement.go index b110322e78..dd8ed5dc4c 100644 --- a/vendor/sigs.k8s.io/kustomize/api/types/replacement.go +++ b/vendor/sigs.k8s.io/kustomize/api/types/replacement.go @@ -66,6 +66,53 @@ type TargetSelector struct { Options *FieldOptions `json:"options,omitempty" yaml:"options,omitempty"` } +type TargetSelectorRegex struct { + targetSelector *TargetSelector + selectRegex *SelectorRegex + rejectRegex []*SelectorRegex +} + +func NewTargetSelectorRegex(ts *TargetSelector) (*TargetSelectorRegex, error) { + tsr := new(TargetSelectorRegex) + tsr.targetSelector = ts + var err error + + tsr.selectRegex, err = NewSelectorRegex(ts.Select) + if err != nil { + return nil, err + } + + rej := []*SelectorRegex{} + for _, r := range ts.Reject { + rr, err := NewSelectorRegex(r) + if err != nil { + return nil, err + } + rej = append(rej, rr) + } + tsr.rejectRegex = rej + + return tsr, nil +} + +func (tsr *TargetSelectorRegex) Selects(id resid.ResId) bool { + return tsr.selectRegex.MatchGvk(id.Gvk) && tsr.selectRegex.MatchName(id.Name) && tsr.selectRegex.MatchNamespace(id.Namespace) +} + +func (tsr *TargetSelectorRegex) RejectsAny(ids []resid.ResId) bool { + for _, r := range tsr.rejectRegex { + if r.selector.ResId.IsEmpty() { + continue + } + for _, id := range ids { + if r.MatchGvk(id.Gvk) && r.MatchName(id.Name) && r.MatchNamespace(id.Namespace) { + return true + } + } + } + return false +} + // FieldOptions refine the interpretation of FieldPaths. type FieldOptions struct { // Used to split/join the field. diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/filesys/filesystem.go b/vendor/sigs.k8s.io/kustomize/kyaml/filesys/filesystem.go index c29d5ad8a7..4e1c3d8966 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/filesys/filesystem.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/filesys/filesystem.go @@ -4,7 +4,6 @@ package filesys import ( - "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/errors" @@ -78,8 +77,7 @@ func ConfirmDir(fSys FileSystem, path string) (ConfirmedDir, error) { return "", errors.WrapPrefixf(err, "not a valid directory") } if f != "" { - //nolint:govet - return "", errors.WrapPrefixf(errors.Errorf("file is not directory"), fmt.Sprintf("'%s'", path)) + return "", errors.WrapPrefixf(errors.Errorf("file is not directory"), "'%s'", path) } return d, nil } diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/exec/exec.go b/vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/exec/exec.go index 562dab30f7..7425d183e5 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/exec/exec.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/exec/exec.go @@ -37,7 +37,7 @@ func (c *Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { } func (c *Filter) Run(reader io.Reader, writer io.Writer) error { - cmd := exec.Command(c.Path, c.Args...) //nolint:gosec + cmd := exec.Command(c.Path, c.Args...) cmd.Env = append(os.Environ(), c.Env...) cmd.Stdin = reader cmd.Stdout = writer diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/kio/kioutil/kioutil.go b/vendor/sigs.k8s.io/kustomize/kyaml/kio/kioutil/kioutil.go index 510ecae18f..818d6ca006 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/kio/kioutil/kioutil.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/kio/kioutil/kioutil.go @@ -387,7 +387,7 @@ func ConfirmInternalAnnotationUnchanged(r1 *yaml.RNode, r2 *yaml.RNode, exclusio for _, key := range keys { errorString = errorString + key + ", " } - return errors.Errorf(errorString[0 : len(errorString)-2]) + return errors.Errorf("%s", errorString[0:len(errorString)-2]) } return nil diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go b/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go index 609a791f39..d7eeda7932 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/kio/pkgio_reader.go @@ -268,7 +268,7 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) { // to another location. relPath, err := filepath.Rel(pathRelativeTo, path) if err != nil { - return errors.WrapPrefixf(err, pathRelativeTo) + return errors.WrapPrefixf(err, "%s", pathRelativeTo) } if match, err := r.shouldSkipFile(path, relPath, ignoreFilesMatcher); err != nil { return err @@ -280,7 +280,7 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) { r.initReaderAnnotations(relPath, info) nodes, err := r.readFile(path, info) if err != nil { - return errors.WrapPrefixf(err, path) + return errors.WrapPrefixf(err, "%s", path) } operand = append(operand, nodes...) return nil diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/runfn/runfn.go b/vendor/sigs.k8s.io/kustomize/kyaml/runfn/runfn.go index bf8863c572..4fd175cd88 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/runfn/runfn.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/runfn/runfn.go @@ -230,7 +230,7 @@ func (r RunFns) runFunctions( } } if len(errs) > 0 { - return fmt.Errorf(strings.Join(errs, "\n---\n")) + return fmt.Errorf("%s", strings.Join(errs, "\n---\n")) } return nil } diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/fns.go b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/fns.go index 740a28ed02..9c26055ed7 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/fns.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/fns.go @@ -830,6 +830,10 @@ func (e *InvalidNodeKindError) Error() string { return msg } +func (e *InvalidNodeKindError) Unwrap() error { + return errors.Errorf("InvalidNodeKindError") +} + func (e *InvalidNodeKindError) ActualNodeKind() Kind { return e.node.YNode().Kind } diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/match.go b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/match.go index 28ea03ca6f..1e70de3c94 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/match.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/match.go @@ -14,7 +14,7 @@ import ( ) // PathMatcher returns all RNodes matching the path wrapped in a SequenceNode. -// Lists may have multiple elements matching the path, and each matching element +// Lists may have multiple elements matching the pafunc cleanPath(path []string) []string {g element // is added to the return result. // If Path points to a SequenceNode, the SequenceNode is wrapped in another SequenceNode // If Path does not contain any lists, the result is still wrapped in a SequenceNode of len == 1 @@ -137,10 +137,14 @@ func (p *PathMatcher) visitEveryElem(elem *RNode) error { func (p *PathMatcher) doField(rn *RNode) (*RNode, error) { // lookup the field field, err := rn.Pipe(Get(p.Path[0])) - if err != nil || (!IsCreate(p.Create) && field == nil) { + if err != nil { return nil, err } + if !IsCreate(p.Create) && field == nil { + return nil, nil + } + if IsCreate(p.Create) && field == nil { var nextPart string if len(p.Path) > 1 { @@ -154,6 +158,11 @@ func (p *PathMatcher) doField(rn *RNode) (*RNode, error) { } } + // Check if the field is a scalar and there are remaining path segments + if field != nil && field.YNode().Kind == yaml.ScalarNode && len(p.Path) > 1 { + return p.handleStructuredDataInScalar(field) + } + // recurse on the field, removing the first element of the path pm := &PathMatcher{Path: p.Path[1:], Create: p.Create} p.val, err = pm.filter(field) @@ -253,12 +262,12 @@ func (p *PathMatcher) doSeq(rn *RNode) (*RNode, error) { func (p *PathMatcher) visitPrimitiveElem(elem *RNode) error { r, err := regexp.Compile(p.matchRegex) if err != nil { - return err + return fmt.Errorf("%w", err) } str, err := elem.String() if err != nil { - return err + return fmt.Errorf("%w", err) } str = strings.TrimSpace(str) if !r.MatchString(str) { @@ -272,7 +281,7 @@ func (p *PathMatcher) visitPrimitiveElem(elem *RNode) error { func (p *PathMatcher) visitElem(elem *RNode) error { r, err := regexp.Compile(p.matchRegex) if err != nil { - return err + return fmt.Errorf("%w", err) } // check if this elements field matches the regex @@ -282,7 +291,7 @@ func (p *PathMatcher) visitElem(elem *RNode) error { } str, err := val.Value.String() if err != nil { - return err + return fmt.Errorf("%w", err) } str = strings.TrimSpace(str) if !r.MatchString(str) { @@ -331,3 +340,26 @@ func cleanPath(path []string) []string { } return p } + +// handleStructuredDataInScalar processes a scalar field that contains structured data (JSON/YAML) +// and allows path navigation within that structured data +func (p *PathMatcher) handleStructuredDataInScalar(scalarField *RNode) (*RNode, error) { + scalarValue := scalarField.YNode().Value + var parsedNode yaml.Node + if err := yaml.Unmarshal([]byte(scalarValue), &parsedNode); err != nil { + return nil, fmt.Errorf("%w", err) + } + + // Create a structured field from the parsed data + structuredField := NewRNode(&parsedNode) + + // Process the remaining path on the structured data + pm := &PathMatcher{Path: p.Path[1:], Create: p.Create} + result, err := pm.filter(structuredField) + if err != nil { + return nil, err + } + p.Matches = pm.Matches + + return result, nil +} diff --git a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go index 0059ec2eb9..43cad97e5d 100644 --- a/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go +++ b/vendor/sigs.k8s.io/kustomize/kyaml/yaml/rnode.go @@ -718,10 +718,11 @@ func (rn *RNode) MustString() string { // Content returns Node Content field. func (rn *RNode) Content() []*yaml.Node { - if rn == nil { + yNode := rn.YNode() + if yNode == nil { return nil } - return rn.YNode().Content + return yNode.Content } // Fields returns the list of field names for a MappingNode. @@ -756,7 +757,11 @@ func (rn *RNode) FieldRNodes() ([]*RNode, error) { // Field returns a fieldName, fieldValue pair for MappingNodes. // Returns nil for non-MappingNodes. func (rn *RNode) Field(field string) *MapNode { - if rn.YNode().Kind != yaml.MappingNode { + yNode := rn.YNode() + if yNode == nil { + return nil + } + if yNode.Kind != yaml.MappingNode { return nil } var result *MapNode @@ -892,7 +897,11 @@ func (rn *RNode) ElementValuesList(keys []string) ([][]string, error) { // Element returns the element in the list which contains the field matching the value. // Returns nil for non-SequenceNodes or if no Element matches. func (rn *RNode) Element(key, value string) *RNode { - if rn.YNode().Kind != yaml.SequenceNode { + yNode := rn.YNode() + if yNode == nil { + return nil + } + if yNode.Kind != yaml.SequenceNode { return nil } elem, err := rn.Pipe(MatchElement(key, value)) @@ -906,7 +915,11 @@ func (rn *RNode) Element(key, value string) *RNode { // corresponding values[i]. // Returns nil for non-SequenceNodes or if no Element matches. func (rn *RNode) ElementList(keys []string, values []string) *RNode { - if rn.YNode().Kind != yaml.SequenceNode { + yNode := rn.YNode() + if yNode == nil { + return nil + } + if yNode.Kind != yaml.SequenceNode { return nil } elem, err := rn.Pipe(MatchElementList(keys, values)) @@ -960,12 +973,17 @@ func (rn *RNode) GetAssociativeKey() string { // MarshalJSON creates a byte slice from the RNode. func (rn *RNode) MarshalJSON() ([]byte, error) { + yNode := rn.YNode() + if yNode == nil { + return []byte("null"), nil + } + s, err := rn.String() if err != nil { return nil, err } - if rn.YNode().Kind == SequenceNode { + if yNode.Kind == SequenceNode { var a []interface{} if err := Unmarshal([]byte(s), &a); err != nil { return nil, err @@ -977,6 +995,7 @@ func (rn *RNode) MarshalJSON() ([]byte, error) { if err := Unmarshal([]byte(s), &m); err != nil { return nil, err } + return json.Marshal(m) } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go index 73436912cd..f1607601c4 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go @@ -19,7 +19,7 @@ package fieldpath import ( "fmt" "iter" - "sort" + "slices" "strings" "sigs.k8s.io/structured-merge-diff/v6/value" @@ -255,19 +255,13 @@ func (s PathElementSet) Copy() PathElementSet { // Insert adds pe to the set. func (s *PathElementSet) Insert(pe PathElement) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a, b PathElement) int { + return a.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, pe) + if found { return } - if s.members[loc].Equals(pe) { - return - } - s.members = append(s.members, PathElement{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = pe + s.members = slices.Insert(s.members, loc, pe) } // Union returns a set containing elements that appear in either s or s2. @@ -344,16 +338,10 @@ func (s *PathElementSet) Size() int { return len(s.members) } // Has returns true if pe is a member of the set. func (s *PathElementSet) Has(pe PathElement) bool { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].Less(pe) + _, found := slices.BinarySearchFunc(s.members, pe, func(a, b PathElement) int { + return a.Compare(b) }) - if loc == len(s.members) { - return false - } - if s.members[loc].Equals(pe) { - return true - } - return false + return found } // Equals returns true if s and s2 have exactly the same members. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go index ff7ee510c2..ca50b84e99 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go @@ -17,7 +17,7 @@ limitations under the License. package fieldpath import ( - "sort" + "slices" "sigs.k8s.io/structured-merge-diff/v6/value" ) @@ -82,32 +82,23 @@ func MakePathElementMap(size int) PathElementMap { // Insert adds the pathelement and associated value in the map. // If insert is called twice with the same PathElement, the value is replaced. func (s *PathElementMap) Insert(pe PathElement, v interface{}) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].PathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a pathElementValue, b PathElement) int { + return a.PathElement.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, pathElementValue{pe, v}) - return - } - if s.members[loc].PathElement.Equals(pe) { + if found { s.members[loc].Value = v return } - s.members = append(s.members, pathElementValue{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = pathElementValue{pe, v} + s.members = slices.Insert(s.members, loc, pathElementValue{PathElement: pe, Value: v}) } // Get retrieves the value associated with the given PathElement from the map. // (nil, false) is returned if there is no such PathElement. func (s *PathElementMap) Get(pe PathElement) (interface{}, bool) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].PathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a pathElementValue, b PathElement) int { + return a.PathElement.Compare(b) }) - if loc == len(s.members) { - return nil, false - } - if s.members[loc].PathElement.Equals(pe) { + if found { return s.members[loc].Value, true } return nil, false diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go index f4b00c2ee5..b2f62dc693 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go @@ -97,6 +97,14 @@ func DeserializePathElement(s string) (PathElement, error) { if err != nil { return PathElement{}, err } + // Lookahead validates that there is no unexpected trailing data. + // io.EOF is a successful termination indicator; all other errors or trailing data fail. + if iter.WhatIsNext(); iter.Error != io.EOF { + if iter.Error == nil { + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + } + return PathElement{}, iter.Error + } return PathElement{Value: &v}, nil case peKeySepBytes[0]: iter := readPool.BorrowIterator(b) @@ -112,8 +120,16 @@ func DeserializePathElement(s string) (PathElement, error) { fields = append(fields, value.Field{Name: key, Value: v}) return true }) + // Lookahead validates that there is no unexpected trailing data. + // io.EOF is a successful termination indicator; all other errors or trailing data fail. + if iter.WhatIsNext(); iter.Error != io.EOF { + if iter.Error == nil { + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + } + return PathElement{}, iter.Error + } fields.Sort() - return PathElement{Key: &fields}, iter.Error + return PathElement{Key: &fields}, nil case peIndexSepBytes[0]: i, err := strconv.Atoi(s[2:]) if err != nil { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go index b992b93c5f..6701f17ee9 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go @@ -175,6 +175,17 @@ func (s *Set) FromJSON(r io.Reader) error { } else { *s = *found } + if iter.Error != nil { + return iter.Error + } + if iter.WhatIsNext(); iter.Error == nil { + // Piggy back on scanner aware error reporting here. + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + return iter.Error + } + if iter.Error == io.EOF { + return nil + } return iter.Error } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go index d2d8c8a42b..d7fe643be2 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go @@ -19,6 +19,7 @@ package fieldpath import ( "fmt" "iter" + "slices" "sort" "strings" @@ -486,19 +487,13 @@ func (s *SetNodeMap) Copy() SetNodeMap { // Descend adds pe to the set if necessary, returning the associated subset. func (s *SetNodeMap) Descend(pe PathElement) *Set { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].pathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a setNode, b PathElement) int { + return a.pathElement.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, setNode{pathElement: pe, set: &Set{}}) + if found { return s.members[loc].set } - if s.members[loc].pathElement.Equals(pe) { - return s.members[loc].set - } - s.members = append(s.members, setNode{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = setNode{pathElement: pe, set: &Set{}} + s.members = slices.Insert(s.members, loc, setNode{pathElement: pe, set: &Set{}}) return s.members[loc].set } @@ -523,13 +518,10 @@ func (s *SetNodeMap) Empty() bool { // Get returns (the associated set, true) or (nil, false) if there is none. func (s *SetNodeMap) Get(pe PathElement) (*Set, bool) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].pathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a setNode, b PathElement) int { + return a.pathElement.Compare(b) }) - if loc == len(s.members) { - return nil, false - } - if s.members[loc].pathElement.Equals(pe) { + if found { return s.members[loc].set, true } return nil, false diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go index c8138a6548..4c0e30b257 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go @@ -62,6 +62,10 @@ type TypeRef struct { // If this field is nil, then it has no effect. // See `Map` and `List` for more information about `ElementRelationship` ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"` + + // Nullable indicates that an explicit null is a valid value, + // corresponding to OpenAPI's `nullable: true`. + Nullable bool `yaml:"nullable,omitempty"` } // Atom represents the smallest possible pieces of the type system. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go index b668eff833..e1fa5c95dd 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go @@ -55,6 +55,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool { if a.ElementRelationship != b.ElementRelationship { return false } + if a.Nullable != b.Nullable { + return false + } return a.Inlined.Equals(&b.Inlined) } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go index 6eb6c36df3..4eb367b657 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go @@ -69,6 +69,9 @@ var SchemaSchemaYAML = `types: - name: elementRelationship type: scalar: string + - name: nullable + type: + scalar: boolean - name: scalar scalar: string - name: map diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go index 0db1734f94..78ba6f50d0 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/typed/remove.go @@ -75,7 +75,6 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) { } var newItems []interface{} - hadMatches := false iter := l.RangeUsing(w.allocator) defer w.allocator.Free(iter) for iter.Next() { @@ -99,26 +98,12 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) { continue } if isPrefixMatch { - // Removing nested items within this list item and preserve if it becomes empty - hadMatches = true - wasMap := item.IsMap() - wasList := item.IsList() item = removeItemsWithSchema(item, w.toRemove.WithPrefix(pe), w.schema, t.ElementType, w.shouldExtract) - // If item returned null but we're removing items within the structure(not the item itself), - // preserve the empty container structure - if item.IsNull() && !w.shouldExtract { - if wasMap { - item = value.NewValueInterface(map[string]interface{}{}) - } else if wasList { - item = value.NewValueInterface([]interface{}{}) - } - } } newItems = append(newItems, item.Unstructured()) } } - // Preserve empty lists (non-nil) instead of converting to null when items were matched and removed - if len(newItems) > 0 || (hadMatches && !w.shouldExtract) { + if len(newItems) > 0 { w.out = newItems } return nil @@ -156,7 +141,6 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors { } newMap := map[string]interface{}{} - hadMatches := false m.Iterate(func(k string, val value.Value) bool { pe := fieldpath.PathElement{FieldName: &k} path, _ := fieldpath.MakePath(pe) @@ -174,19 +158,7 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors { return true } if subset := w.toRemove.WithPrefix(pe); !subset.Empty() { - hadMatches = true - wasMap := val.IsMap() - wasList := val.IsList() val = removeItemsWithSchema(val, subset, w.schema, fieldType, w.shouldExtract) - // If val returned null but we're removing items within the structure (not the field itself), - // preserve the empty container structure - if val.IsNull() && !w.shouldExtract { - if wasMap { - val = value.NewValueInterface(map[string]interface{}{}) - } else if wasList { - val = value.NewValueInterface([]interface{}{}) - } - } } else { // don't save values not on the path when we shouldExtract. if w.shouldExtract { @@ -196,8 +168,7 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors { newMap[k] = val.Unstructured() return true }) - // Preserve empty maps (non-nil) instead of converting to null when items were matched and removed - if len(newMap) > 0 || (hadMatches && !w.shouldExtract) { + if len(newMap) > 0 { w.out = newMap } return nil diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go index f70cd41674..acbfe8ceba 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go @@ -16,6 +16,8 @@ limitations under the License. package value +import "reflect" + // Allocator provides a value object allocation strategy. // Value objects can be allocated by passing an allocator to the "Using" // receiver functions on the value interfaces, e.g. Map.ZipUsing(allocator, ...). @@ -24,8 +26,8 @@ package value type Allocator interface { // Free gives the allocator back any value objects returned by the "Using" // receiver functions on the value interfaces. - // interface{} may be any of: Value, Map, List or Range. - Free(interface{}) + // any may be any of: Value, Map, List or Range. + Free(any) // The unexported functions are for "Using" receiver functions of the value types // to request what they need from the allocator. @@ -74,7 +76,7 @@ func (p *heapAllocator) allocListReflectRange() *listReflectRange { return &listReflectRange{vr: &valueReflect{}} } -func (p *heapAllocator) Free(_ interface{}) {} +func (p *heapAllocator) Free(_ any) {} // NewFreelistAllocator creates freelist based allocator. // This allocator provides fast allocation and freeing of short lived value objects. @@ -89,25 +91,25 @@ func (p *heapAllocator) Free(_ interface{}) {} // for all temporary value access. func NewFreelistAllocator() Allocator { return &freelistAllocator{ - valueUnstructured: &freelist{new: func() interface{} { + valueUnstructured: &freelist[*valueUnstructured]{new: func() *valueUnstructured { return &valueUnstructured{} }}, - listUnstructuredRange: &freelist{new: func() interface{} { + listUnstructuredRange: &freelist[*listUnstructuredRange]{new: func() *listUnstructuredRange { return &listUnstructuredRange{vv: &valueUnstructured{}} }}, - valueReflect: &freelist{new: func() interface{} { + valueReflect: &freelist[*valueReflect]{new: func() *valueReflect { return &valueReflect{} }}, - mapReflect: &freelist{new: func() interface{} { + mapReflect: &freelist[*mapReflect]{new: func() *mapReflect { return &mapReflect{} }}, - structReflect: &freelist{new: func() interface{} { + structReflect: &freelist[*structReflect]{new: func() *structReflect { return &structReflect{} }}, - listReflect: &freelist{new: func() interface{} { + listReflect: &freelist[*listReflect]{new: func() *listReflect { return &listReflect{} }}, - listReflectRange: &freelist{new: func() interface{} { + listReflectRange: &freelist[*listReflectRange]{new: func() *listReflectRange { return &listReflectRange{vr: &valueReflect{}} }}, } @@ -119,22 +121,22 @@ func NewFreelistAllocator() Allocator { const freelistMaxSize = 1000 type freelistAllocator struct { - valueUnstructured *freelist - listUnstructuredRange *freelist - valueReflect *freelist - mapReflect *freelist - structReflect *freelist - listReflect *freelist - listReflectRange *freelist + valueUnstructured *freelist[*valueUnstructured] + listUnstructuredRange *freelist[*listUnstructuredRange] + valueReflect *freelist[*valueReflect] + mapReflect *freelist[*mapReflect] + structReflect *freelist[*structReflect] + listReflect *freelist[*listReflect] + listReflectRange *freelist[*listReflectRange] } -type freelist struct { - list []interface{} - new func() interface{} +type freelist[T any] struct { + list []T + new func() T } -func (f *freelist) allocate() interface{} { - var w2 interface{} +func (f *freelist[T]) allocate() T { + var w2 T if n := len(f.list); n > 0 { w2, f.list = f.list[n-1], f.list[:n-1] } else { @@ -143,61 +145,73 @@ func (f *freelist) allocate() interface{} { return w2 } -func (f *freelist) free(v interface{}) { +func (f *freelist[T]) free(v T) { if len(f.list) < freelistMaxSize { f.list = append(f.list, v) } } -func (w *freelistAllocator) Free(value interface{}) { +func (w *freelistAllocator) Free(value any) { switch v := value.(type) { case *valueUnstructured: v.Value = nil // don't hold references to unstructured objects w.valueUnstructured.free(v) case *listUnstructuredRange: + v.list = nil // don't hold references to unstructured objects v.vv.Value = nil // don't hold references to unstructured objects w.listUnstructuredRange.free(v) case *valueReflect: - v.ParentMapKey = nil v.ParentMap = nil + v.ParentMapKey = nil + v.Value = reflect.Value{} // don't hold references to reflected objects w.valueReflect.free(v) case *mapReflect: + v.valueReflect.ParentMap = nil + v.valueReflect.ParentMapKey = nil + v.valueReflect.Value = reflect.Value{} // don't hold references to reflected objects w.mapReflect.free(v) case *structReflect: + v.valueReflect.ParentMap = nil + v.valueReflect.ParentMapKey = nil + v.valueReflect.Value = reflect.Value{} // don't hold references to reflected objects w.structReflect.free(v) case *listReflect: + v.Value = reflect.Value{} // don't hold references to reflected objects w.listReflect.free(v) case *listReflectRange: - v.vr.ParentMapKey = nil + v.list = reflect.Value{} // don't hold references to reflected objects v.vr.ParentMap = nil + v.vr.ParentMapKey = nil + v.vr.Value = reflect.Value{} // don't hold references to reflected objects + v.entry = nil w.listReflectRange.free(v) } } func (w *freelistAllocator) allocValueUnstructured() *valueUnstructured { - return w.valueUnstructured.allocate().(*valueUnstructured) + return w.valueUnstructured.allocate() } func (w *freelistAllocator) allocListUnstructuredRange() *listUnstructuredRange { - return w.listUnstructuredRange.allocate().(*listUnstructuredRange) + return w.listUnstructuredRange.allocate() } func (w *freelistAllocator) allocValueReflect() *valueReflect { - return w.valueReflect.allocate().(*valueReflect) + return w.valueReflect.allocate() } func (w *freelistAllocator) allocStructReflect() *structReflect { - return w.structReflect.allocate().(*structReflect) + return w.structReflect.allocate() } func (w *freelistAllocator) allocMapReflect() *mapReflect { - return w.mapReflect.allocate().(*mapReflect) + return w.mapReflect.allocate() } func (w *freelistAllocator) allocListReflect() *listReflect { - return w.listReflect.allocate().(*listReflect) + return w.listReflect.allocate() } func (w *freelistAllocator) allocListReflectRange() *listReflectRange { - return w.listReflectRange.allocate().(*listReflectRange) + return w.listReflectRange.allocate() } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go index 3aadceb222..db25613734 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go @@ -76,11 +76,16 @@ func OmitZeroFunc(t reflect.Type) func(reflect.Value) bool { // but is based on the highly efficient approach from https://golang.org/src/encoding/json/encode.go func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitempty bool, omitzero func(reflect.Value) bool) { + // Skip unexported non-embedded fields, matching encoding/json behavior. + if f.PkgPath != "" && !f.Anonymous { + return "", true, false, false, nil + } tag := f.Tag.Get("json") if tag == "-" { return "", true, false, false, nil } name, opts := parseTag(tag) + inline = f.Anonymous && name == "" if name == "" { name = f.Name } @@ -89,7 +94,7 @@ func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitzero = OmitZeroFunc(f.Type) } - return name, false, opts.Contains("inline"), opts.Contains("omitempty"), omitzero + return name, false, inline, opts.Contains("omitempty"), omitzero } func isEmpty(v reflect.Value) bool { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go index 75b7085c3e..f4f4c2b44d 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go @@ -39,14 +39,28 @@ type UnstructuredConverter interface { ToUnstructured() interface{} } +// UnstructuredConverterWithError is implemented instead of UnstructuredConverter by types for which +// some, but not all, values can be converted directly to unstructured. If a type implements both +// UnstructuredConverter and UnstructuredConverterWithError, its UnstructuredConverterWithError +// implementation takes precedence during conversion. +type UnstructuredConverterWithError interface { + json.Marshaler // require that json.Marshaler is implemented + + // ToUnstructured returns the unstructured representation, or a non-nil error if the value + // cannot be converted to unstructured. + ToUnstructuredWithError() (any, error) +} + // TypeReflectCacheEntry keeps data gathered using reflection about how a type is converted to/from unstructured. type TypeReflectCacheEntry struct { - isJsonMarshaler bool - ptrIsJsonMarshaler bool - isJsonUnmarshaler bool - ptrIsJsonUnmarshaler bool - isStringConvertable bool - ptrIsStringConvertable bool + isJsonMarshaler bool + ptrIsJsonMarshaler bool + isJsonUnmarshaler bool + ptrIsJsonUnmarshaler bool + isUnstructuredConverter bool + ptrIsUnstructuredConverter bool + isUnstructuredConverterWithError bool + ptrIsUnstructuredConverterWithError bool structFields map[string]*FieldCacheEntry orderedStructFields []*FieldCacheEntry @@ -93,9 +107,10 @@ func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value { return structVal } -var marshalerType = reflect.TypeOf(new(json.Marshaler)).Elem() -var unmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem() -var unstructuredConvertableType = reflect.TypeOf(new(UnstructuredConverter)).Elem() +var marshalerType = reflect.TypeFor[json.Marshaler]() +var unmarshalerType = reflect.TypeFor[json.Unmarshaler]() +var unstructuredConverterType = reflect.TypeFor[UnstructuredConverter]() +var unstructuredConverterWithErrorType = reflect.TypeFor[UnstructuredConverterWithError]() var defaultReflectCache = newReflectCache() // TypeReflectEntryOf returns the TypeReflectCacheEntry of the provided reflect.Type. @@ -122,11 +137,13 @@ func typeReflectEntryOf(cm reflectCacheMap, t reflect.Type, updates reflectCache return record } typeEntry := &TypeReflectCacheEntry{ - isJsonMarshaler: t.Implements(marshalerType), - ptrIsJsonMarshaler: reflect.PtrTo(t).Implements(marshalerType), - isJsonUnmarshaler: reflect.PtrTo(t).Implements(unmarshalerType), - isStringConvertable: t.Implements(unstructuredConvertableType), - ptrIsStringConvertable: reflect.PtrTo(t).Implements(unstructuredConvertableType), + isJsonMarshaler: t.Implements(marshalerType), + ptrIsJsonMarshaler: reflect.PointerTo(t).Implements(marshalerType), + isJsonUnmarshaler: reflect.PointerTo(t).Implements(unmarshalerType), + isUnstructuredConverter: t.Implements(unstructuredConverterType), + ptrIsUnstructuredConverter: reflect.PointerTo(t).Implements(unstructuredConverterType), + isUnstructuredConverterWithError: t.Implements(unstructuredConverterWithErrorType), + ptrIsUnstructuredConverterWithError: reflect.PointerTo(t).Implements(unstructuredConverterWithErrorType), } if t.Kind() == reflect.Struct { fieldEntries := map[string]*FieldCacheEntry{} @@ -190,7 +207,7 @@ func (e TypeReflectCacheEntry) OrderedFields() []*FieldCacheEntry { // CanConvertToUnstructured returns true if this TypeReflectCacheEntry can convert values of its type to unstructured. func (e TypeReflectCacheEntry) CanConvertToUnstructured() bool { - return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isStringConvertable || e.ptrIsStringConvertable + return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isUnstructuredConverter || e.ptrIsUnstructuredConverter || e.isUnstructuredConverterWithError || e.ptrIsUnstructuredConverterWithError } // ToUnstructured converts the provided value to unstructured and returns it. @@ -206,7 +223,7 @@ func (e TypeReflectCacheEntry) ToUnstructured(sv reflect.Value) (interface{}, er // Check if the object has a custom string converter and use it if available, since it is much more efficient // than round tripping through json. if converter, ok := e.getUnstructuredConverter(sv); ok { - return converter.ToUnstructured(), nil + return converter.ToUnstructuredWithError() } // Check if the object has a custom JSON marshaller/unmarshaller. if marshaler, ok := e.getJsonMarshaler(sv); ok { @@ -318,16 +335,26 @@ func (e TypeReflectCacheEntry) getJsonUnmarshaler(v reflect.Value) (json.Unmarsh return v.Addr().Interface().(json.Unmarshaler), true } -func (e TypeReflectCacheEntry) getUnstructuredConverter(v reflect.Value) (UnstructuredConverter, bool) { - if e.isStringConvertable { - return v.Interface().(UnstructuredConverter), true - } - if e.ptrIsStringConvertable { +type unstructuredConverterWithNilError struct { + UnstructuredConverter +} + +func (c unstructuredConverterWithNilError) ToUnstructuredWithError() (any, error) { + return c.UnstructuredConverter.ToUnstructured(), nil +} + +func (e TypeReflectCacheEntry) getUnstructuredConverter(v reflect.Value) (UnstructuredConverterWithError, bool) { + switch { + case e.isUnstructuredConverterWithError: + return v.Interface().(UnstructuredConverterWithError), true + case e.ptrIsUnstructuredConverterWithError && v.CanAddr(): // Check pointer receivers if v is not a pointer - if v.CanAddr() { - v = v.Addr() - return v.Interface().(UnstructuredConverter), true - } + return v.Addr().Interface().(UnstructuredConverterWithError), true + case e.isUnstructuredConverter: + return unstructuredConverterWithNilError{v.Interface().(UnstructuredConverter)}, true + case e.ptrIsUnstructuredConverter && v.CanAddr(): + // Check pointer receivers if v is not a pointer + return unstructuredConverterWithNilError{v.Addr().Interface().(UnstructuredConverter)}, true } return nil, false } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go index 140b99038e..167848ebeb 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go @@ -118,6 +118,11 @@ func readJSONIter(iter *jsoniter.Iterator) (Value, error) { if iter.Error != nil && iter.Error != io.EOF { return nil, iter.Error } + if iter.WhatIsNext(); iter.Error == nil { + // Piggy back on scanner aware error reporting here. + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + return nil, iter.Error + } return NewValueInterface(v), nil } From 4c56c264f8bfcd1915f7b7c03694534272e46a64 Mon Sep 17 00:00:00 2001 From: Fabio Proietti Date: Tue, 28 Jul 2026 11:41:15 +0200 Subject: [PATCH 2/2] Applied 'go mod tidy' 'go mod vendor' 'go mod verify' to new rebase --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index 4a6b8837fc..ea7bf57077 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,6 @@ require ( github.com/openshift-eng/openshift-tests-extension v0.0.0-20260707142426-572a3e9deb7a github.com/openshift/api v0.0.0-20260724065811-356624ff036f github.com/openshift/client-go v0.0.0-20260715172546-dac61734e0ec - github.com/openshift/imagebuilder v1.2.21 github.com/openshift/library-go v0.0.0-20260720123941-85336565c3c7 github.com/openshift/runtime-utils v0.0.0-20230921210328-7bdb5b9c177b